mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-07-25 08:55:00 +00:00
Compare commits
60 Commits
2.2.2
...
28b6db7845
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28b6db7845 | ||
|
|
7709fbe168 | ||
|
|
692b906b82 | ||
|
|
aece4a9632 | ||
|
|
2cd1a6e4ab | ||
|
|
8af0b227cc | ||
|
|
5f44339fa5 | ||
|
|
7d5aef07e2 | ||
|
|
b39ee97ccc | ||
|
|
72a6eb9729 | ||
|
|
9651a19805 | ||
|
|
413ab782a8 | ||
|
|
9343c6f56f | ||
|
|
9dc73a686a | ||
|
|
6da1331018 | ||
|
|
cda2e0657f | ||
|
|
ab8dfefd90 | ||
|
|
b96fad5e5b | ||
|
|
2d350e6073 | ||
|
|
ea6ef5c775 | ||
|
|
9007e20b2f | ||
|
|
508e3d920f | ||
|
|
18e023dd77 | ||
|
|
d3204df536 | ||
|
|
162e72182f | ||
|
|
1c1dd005c8 | ||
|
|
40c27e2bee | ||
|
|
c273ac2a01 | ||
|
|
f978998521 | ||
|
|
c319c856ed | ||
|
|
cdb442ea48 | ||
|
|
f977bffff2 | ||
|
|
dabaca4b70 | ||
|
|
26b9b1438d | ||
|
|
1994b2cf1c | ||
|
|
2f224e6a6a | ||
|
|
96ec2097cc | ||
|
|
7b9b1f4957 | ||
|
|
f0b5f039d3 | ||
|
|
5ceb40b600 | ||
|
|
2cec8cbed5 | ||
|
|
1b8aeb03cb | ||
|
|
eead50b287 | ||
|
|
4ff0e3aa13 | ||
|
|
979f00ce75 | ||
|
|
ed3d322fd5 | ||
|
|
d9f54eb9d4 | ||
|
|
7d8da00f79 | ||
|
|
f087d58cbe | ||
|
|
eb740e97d4 | ||
|
|
44a2151dbf | ||
|
|
83288b9020 | ||
|
|
4c6898ee6e | ||
|
|
f5eae12146 | ||
|
|
f632fad9d4 | ||
|
|
74edb72249 | ||
|
|
91129ed381 | ||
|
|
7b8d627552 | ||
|
|
6175a5028b | ||
|
|
8e34860d6c |
@@ -4,6 +4,7 @@
|
||||
# SPDX-FileCopyrightText: 2024, Ansible Project
|
||||
|
||||
skip_list:
|
||||
- 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
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:8.0.0
|
||||
- container: legacy
|
||||
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
|
||||
|
||||
pool: Standard
|
||||
|
||||
stages:
|
||||
@@ -129,7 +128,6 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
nameFormat: "{0}"
|
||||
testFormat: 2.17/{0}
|
||||
targets:
|
||||
@@ -140,24 +138,6 @@ stages:
|
||||
- name: Lint
|
||||
test: lint
|
||||
|
||||
# 2.16 is LTS
|
||||
- stage: Sanity_2_16
|
||||
displayName: Ansible 2.16 Sanity & Units & Lint
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
nameFormat: "{0}"
|
||||
testFormat: 2.16/{0}
|
||||
targets:
|
||||
- name: Sanity
|
||||
test: sanity
|
||||
- name: Units
|
||||
test: units
|
||||
- name: Lint
|
||||
test: lint
|
||||
|
||||
## Docker
|
||||
- stage: Docker_devel
|
||||
displayName: Docker devel
|
||||
@@ -169,10 +149,10 @@ stages:
|
||||
targets:
|
||||
- name: Fedora 44
|
||||
test: fedora44
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- name: Ubuntu 24.04
|
||||
test: ubuntu2404
|
||||
- name: Ubuntu 26.04
|
||||
test: ubuntu2604
|
||||
|
||||
- stage: Docker_2_21
|
||||
displayName: Docker 2.21
|
||||
@@ -180,10 +160,10 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.21/linux/{0}/1
|
||||
testFormat: devel/linux/{0}/1
|
||||
targets:
|
||||
- name: Fedora 43
|
||||
test: fedora43
|
||||
- name: Fedora 44
|
||||
test: fedora44
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- name: Ubuntu 24.04
|
||||
@@ -240,7 +220,6 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.17/linux/{0}/1
|
||||
targets:
|
||||
- name: Fedora 39
|
||||
@@ -248,20 +227,6 @@ stages:
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
|
||||
- stage: Docker_2_16
|
||||
displayName: Docker 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.16/linux/{0}/1
|
||||
targets:
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
|
||||
## Remote
|
||||
- stage: Remote_devel
|
||||
displayName: Remote devel
|
||||
@@ -271,10 +236,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.2
|
||||
test: rhel/10.2
|
||||
- name: RHEL 9.8
|
||||
test: rhel/9.8
|
||||
- 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
|
||||
@@ -286,7 +251,7 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.21/{0}/1
|
||||
testFormat: devel/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
@@ -326,8 +291,8 @@ stages:
|
||||
test: rhel/10.1
|
||||
- name: RHEL 9.7
|
||||
test: rhel/9.7
|
||||
- name: FreeBSD 14.3
|
||||
test: freebsd/14.3
|
||||
- name: FreeBSD 14.2
|
||||
test: freebsd/14.2
|
||||
- name: FreeBSD 13.5
|
||||
test: freebsd/13.5
|
||||
|
||||
@@ -352,34 +317,19 @@ stages:
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.17/{0}/1
|
||||
targets:
|
||||
# 2.17 remote target doesn't have RHEL 9 image
|
||||
- name: RHEL 10.0
|
||||
test: rhel/10.0
|
||||
- name: FreeBSD 13.5
|
||||
test: freebsd/13.5
|
||||
|
||||
- stage: Remote_2_16
|
||||
displayName: Remote 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
container: legacy
|
||||
testFormat: 2.16/{0}/1
|
||||
targets:
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
|
||||
## Finally
|
||||
|
||||
- stage: Summary
|
||||
condition: succeededOrFailed()
|
||||
dependsOn:
|
||||
- Sanity_2_16
|
||||
- Remote_2_16
|
||||
- Docker_2_16
|
||||
- Sanity_2_17
|
||||
- Remote_2_17
|
||||
- Docker_2_17
|
||||
|
||||
@@ -14,12 +14,6 @@ parameters:
|
||||
type: object
|
||||
default: []
|
||||
|
||||
# An optional container resource name to use for the test jobs.
|
||||
# Defaults to "default" if not specified.
|
||||
- name: container
|
||||
type: string
|
||||
default: default
|
||||
|
||||
# An optional format string used to generate the job name.
|
||||
# - {0} is the name of an item in the targets list.
|
||||
- name: nameFormat
|
||||
@@ -49,7 +43,6 @@ parameters:
|
||||
jobs:
|
||||
- template: test.yml
|
||||
parameters:
|
||||
container: ${{ parameters.container }}
|
||||
jobs:
|
||||
- ${{ if eq(length(parameters.groups), 0) }}:
|
||||
- ${{ each target in parameters.targets }}:
|
||||
|
||||
@@ -7,17 +7,11 @@ parameters:
|
||||
- name: jobs
|
||||
type: object
|
||||
|
||||
# An optional container resource name to use for the test jobs.
|
||||
# Defaults to "default" if not specified.
|
||||
- name: container
|
||||
type: string
|
||||
default: default
|
||||
|
||||
jobs:
|
||||
- ${{ each job in parameters.jobs }}:
|
||||
- job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
|
||||
displayName: ${{ job.name }}
|
||||
container: ${{ parameters.container }}
|
||||
container: default
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
|
||||
102
CHANGELOG.rst
102
CHANGELOG.rst
@@ -4,108 +4,6 @@ ansible.posix Release Notes
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
v2.2.2
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the minor release of the ``ansible.posix`` collection.
|
||||
This changelog contains all changes to the modules and plugins
|
||||
in the stable-2 branch that have been added after the release of
|
||||
``ansible.posix`` 2.2.1
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- README - Added ``Red Hat Automation Hub`` as correct contact information for Red Hat Ansible Automation Platform subscribers.
|
||||
|
||||
v2.2.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the minor release of the ``ansible.posix`` collection.
|
||||
This changelog contains all changes to the modules and plugins
|
||||
in the stable-2 branch that have been added after the release of
|
||||
``ansible.posix`` 2.2.0
|
||||
|
||||
Security Fixes
|
||||
--------------
|
||||
|
||||
- authorized_key - fix local privilege escalation via symlink-following when running as root (https://github.com/ansible-collections/ansible.posix/issues/759).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- sysctl - reload sysctl only if the sysctl file is ``/etc/sysctl.conf`` or ``/etc/sysctl.conf.local`` (https://github.com/ansible-collections/ansible.posix/issues/663).
|
||||
|
||||
v2.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the minor release of the ``ansible.posix`` collection.
|
||||
This changelog contains all changes to the modules and plugins
|
||||
in the stable-2 branch that have been added after the release of
|
||||
``ansible.posix`` 2.1.0
|
||||
|
||||
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).
|
||||
- firewalld_info - use module.warn instead of passing ``warnings`` to ``exit_json`` (https://github.com/ansible-collections/ansible.posix/issues/710).
|
||||
- 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 - Add option to provide a different date/time format (https://github.com/ansible-collections/ansible.posix/issues/279).
|
||||
- profile_tasks callback - fix deprecated ``ansible.module_utils.six`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
||||
- removed ANSIBLE_METADATA from remaining plugins.
|
||||
- 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).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- acl - correctly assert needed changes when pointing to a directory and recursive is set to true.
|
||||
- ansible.posix.authorized_key - fixes error on permission denied in authorized_key module (https://github.com/ansible-collections/ansible.posix/issues/462).
|
||||
- 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).
|
||||
- patch - removed use of deprecated ``_AnsibleActionDone`` API (https://github.com/ansible-collections/ansible.posix/pull/687).
|
||||
|
||||
v2.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is the minor release of the ``ansible.posix`` collection.
|
||||
This changelog contains all changes to the modules and plugins
|
||||
in the stable-2 branch that have been added after the release of
|
||||
``ansible.posix`` 2.0.0
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- profile_tasks and profile_roles callback plugins - avoid deleted/deprecated callback functions, instead use modern interface that was introduced a longer time ago (https://github.com/ansible-collections/ansible.posix/issues/650).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- ansible.posix.cgroup_perf_recap - fixes json module load path (https://github.com/ansible-collections/ansible.posix/issues/630).
|
||||
|
||||
v2.0.0
|
||||
======
|
||||
|
||||
|
||||
16
README.md
16
README.md
@@ -78,15 +78,10 @@ ansible-doc -t callback ansible.posix.profile_tasks
|
||||
|
||||
The following ansible-core versions have been tested with this collection:
|
||||
|
||||
- ansible-core 2.22 (devel)
|
||||
- ansible-core 2.21 (stable)
|
||||
- ansible-core 2.20 (stable)
|
||||
- ansible-core 2.19 (stable)
|
||||
- ansible-core 2.18 (LTS)
|
||||
- ansible-core 2.17 (EoL)
|
||||
- ansible-core 2.16 (EoL)
|
||||
|
||||
For most up to date support info, see the [ansible-core support matrix](https://docs.ansible.com/projects/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix)
|
||||
- ansible-core 2.20 (devel)
|
||||
- ansible-core 2.19 (stable) *
|
||||
- ansible-core 2.18 (stable)
|
||||
- ansible-core 2.17 (stable)
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -99,8 +94,7 @@ We welcome community contributions to this collection. For more details, see [Co
|
||||
|
||||
## Support
|
||||
|
||||
* Community users can find help through the [Communication](#Communication) section.
|
||||
* Red Hat Ansible Automation Platform subscribers can request support through [Automation Hub](https://console.redhat.com/ansible/automation-hub/collections/published/ansible/posix/) by using the "Create issue" button on the collection page.
|
||||
See [Communication](#Communication) section.
|
||||
|
||||
## Release Notes and Roadmap
|
||||
|
||||
|
||||
@@ -490,132 +490,3 @@ releases:
|
||||
- 597_remove_fstab_comment_on_updating.yml
|
||||
- 598_icmp_block_inversion.yml
|
||||
release_date: '2024-12-04'
|
||||
2.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- ansible.posix.cgroup_perf_recap - fixes json module load path (https://github.com/ansible-collections/ansible.posix/issues/630).
|
||||
minor_changes:
|
||||
- profile_tasks and profile_roles callback plugins - avoid deleted/deprecated
|
||||
callback functions, instead use modern interface that was introduced a longer
|
||||
time ago (https://github.com/ansible-collections/ansible.posix/issues/650).
|
||||
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
|
||||
|
||||
This changelog contains all changes to the modules and plugins
|
||||
|
||||
in the stable-2 branch that have been added after the release of
|
||||
|
||||
``ansible.posix`` 2.0.0'
|
||||
fragments:
|
||||
- 2.1.0.yml
|
||||
- 631_fixes_module_path.yml
|
||||
- 642_ci_add_rhel10.yml
|
||||
- 650-profile_tasks_roles.yml
|
||||
- 654_ci_bump_core_version.yml
|
||||
release_date: '2025-07-16'
|
||||
2.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- acl - correctly assert needed changes when pointing to a directory and recursive
|
||||
is set to true.
|
||||
- ansible.posix.authorized_key - fixes error on permission denied in authorized_key
|
||||
module (https://github.com/ansible-collections/ansible.posix/issues/462).
|
||||
- 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).
|
||||
- patch - removed use of deprecated ``_AnsibleActionDone`` API (https://github.com/ansible-collections/ansible.posix/pull/687).
|
||||
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).
|
||||
- firewalld_info - use module.warn instead of passing ``warnings`` to ``exit_json``
|
||||
(https://github.com/ansible-collections/ansible.posix/issues/710).
|
||||
- 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 - Add option to provide a different date/time format (https://github.com/ansible-collections/ansible.posix/issues/279).
|
||||
- profile_tasks callback - fix deprecated ``ansible.module_utils.six`` import
|
||||
(https://github.com/ansible-collections/ansible.posix/issues/686).
|
||||
- removed ANSIBLE_METADATA from remaining plugins.
|
||||
- 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).
|
||||
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
|
||||
|
||||
This changelog contains all changes to the modules and plugins
|
||||
|
||||
in the stable-2 branch that have been added after the release of
|
||||
|
||||
``ansible.posix`` 2.1.0'
|
||||
fragments:
|
||||
- 2.2.0.yml
|
||||
- 626_profile_tasks_datetime_format.yml
|
||||
- 638_fix_recursive_acl.yml
|
||||
- 639_fix_authorized_key.yml
|
||||
- 660_ci_azp_syntax.yml
|
||||
- 665_update_readme_20250728.yml
|
||||
- 666_azp_update_20250728.yml
|
||||
- 670-deprecations.yml
|
||||
- 673_update_ci_20250805.yml
|
||||
- 682_update_ci_20250929.yml
|
||||
- 686_fix_deprecated_imports.yml
|
||||
- 693_azp_update_20251205.yml
|
||||
- ansible_metadata_removed.yml
|
||||
- firewalld_info_warnings.yml
|
||||
- patch_removed.yml
|
||||
release_date: '2026-05-18'
|
||||
2.2.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- sysctl - reload sysctl only if the sysctl file is ``/etc/sysctl.conf`` or
|
||||
``/etc/sysctl.conf.local`` (https://github.com/ansible-collections/ansible.posix/issues/663).
|
||||
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
|
||||
|
||||
This changelog contains all changes to the modules and plugins
|
||||
|
||||
in the stable-2 branch that have been added after the release of
|
||||
|
||||
``ansible.posix`` 2.2.0'
|
||||
security_fixes:
|
||||
- authorized_key - fix local privilege escalation via symlink-following when
|
||||
running as root (https://github.com/ansible-collections/ansible.posix/issues/759).
|
||||
fragments:
|
||||
- 2.2.1.yml
|
||||
- 643-sysctl-docs.yml
|
||||
- 751_ci_test_container_update.yml
|
||||
- 755_ci_test_container_update.yml
|
||||
- 759_cve_2026_11837.yml
|
||||
- 763_ci_azp_update_devel.yml
|
||||
- freebsd_sysctl.yml
|
||||
release_date: '2026-07-01'
|
||||
2.2.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- README - Added ``Red Hat Automation Hub`` as correct contact information for
|
||||
Red Hat Ansible Automation Platform subscribers.
|
||||
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
|
||||
|
||||
This changelog contains all changes to the modules and plugins
|
||||
|
||||
in the stable-2 branch that have been added after the release of
|
||||
|
||||
``ansible.posix`` 2.2.1'
|
||||
fragments:
|
||||
- 2.2.2.yml
|
||||
- 767_remove_unsupported_version_skip.yml
|
||||
- 768_update_support_section.yml
|
||||
release_date: '2026-07-08'
|
||||
|
||||
2
changelogs/fragments/603_bump_version_3.yml
Normal file
2
changelogs/fragments/603_bump_version_3.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
trivial:
|
||||
- Bump version to 3.0.0 for the next release (https://github.com/ansible-collections/ansible.posix/issues/603).
|
||||
2
changelogs/fragments/618_ci_remove_ubuntu2004.yml
Normal file
2
changelogs/fragments/618_ci_remove_ubuntu2004.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
trivial:
|
||||
- Remove ubuntu20.04 from CI tests (https://github.com/ansible-collections/ansible.posix/issues/612).
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- profile_tasks - Add option to provide a different date/time format (https://github.com/ansible-collections/ansible.posix/issues/279).
|
||||
6
changelogs/fragments/631_fixes_module_path.yml
Normal file
6
changelogs/fragments/631_fixes_module_path.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
bugfixes:
|
||||
- ansible.posix.cgroup_perf_recap - fixes json module load path (https://github.com/ansible-collections/ansible.posix/issues/630).
|
||||
trivial:
|
||||
- ansible.posix.seboolean - remove unnecessary condition from seboolean integration tests (https://github.com/ansible-collections/ansible.posix/issues/630).
|
||||
- ansible.posix.selinux - optimize conditions for selinux integration tests (https://github.com/ansible-collections/ansible.posix/issues/630).
|
||||
3
changelogs/fragments/639_fix_authorized_key.yml
Normal file
3
changelogs/fragments/639_fix_authorized_key.yml
Normal 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).
|
||||
2
changelogs/fragments/642_ci_add_rhel10.yml
Normal file
2
changelogs/fragments/642_ci_add_rhel10.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
trivial:
|
||||
- Add Red Hat Enterprise Linux 10.0 to the CI matrix (https://github.com/ansible-collections/ansible.posix/issues/642).
|
||||
2
changelogs/fragments/650-profile_tasks_roles.yml
Normal file
2
changelogs/fragments/650-profile_tasks_roles.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- "profile_tasks and profile_roles callback plugins - avoid deleted/deprecated callback functions, instead use modern interface that was introduced a longer time ago (https://github.com/ansible-collections/ansible.posix/issues/650)."
|
||||
3
changelogs/fragments/654_ci_bump_core_version.yml
Normal file
3
changelogs/fragments/654_ci_bump_core_version.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
trivial:
|
||||
- Bump ansible-core version to 2.20 of devel branch and add 2.19 to CI
|
||||
2
changelogs/fragments/660_ci_azp_syntax.yml
Normal file
2
changelogs/fragments/660_ci_azp_syntax.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
trivial:
|
||||
- AZP - fixed syntax error in CI test.
|
||||
3
changelogs/fragments/665_update_readme_20250728.yml
Normal file
3
changelogs/fragments/665_update_readme_20250728.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
trivial:
|
||||
- README - Update README to reflect Ansible Core 2.19 release.
|
||||
3
changelogs/fragments/666_azp_update_20250728.yml
Normal file
3
changelogs/fragments/666_azp_update_20250728.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
trivial:
|
||||
- AZP - Update AZP matrix to follow ansible-test changes.
|
||||
3
changelogs/fragments/670-deprecations.yml
Normal file
3
changelogs/fragments/670-deprecations.yml
Normal 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)."
|
||||
2
changelogs/fragments/673_update_ci_20250805.yml
Normal file
2
changelogs/fragments/673_update_ci_20250805.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
trivial:
|
||||
- Update AZP CI matrix (https://github.com/ansible-collections/ansible.posix/issues/673).
|
||||
4
changelogs/fragments/682_update_ci_20250929.yml
Normal file
4
changelogs/fragments/682_update_ci_20250929.yml
Normal 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.
|
||||
5
changelogs/fragments/693_azp_update_20251205.yml
Normal file
5
changelogs/fragments/693_azp_update_20251205.yml
Normal 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.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
namespace: ansible
|
||||
name: posix
|
||||
version: 2.2.2
|
||||
version: 3.0.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (github.com/ansible)
|
||||
|
||||
@@ -20,8 +20,8 @@ __metaclass__ = type
|
||||
|
||||
import os
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleAction, AnsibleActionFail
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.errors import AnsibleError, AnsibleAction, _AnsibleActionDone, AnsibleActionFail
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
@@ -46,8 +46,7 @@ class ActionModule(ActionBase):
|
||||
elif remote_src:
|
||||
# everything is remote, so we just execute the module
|
||||
# without changing any of the module arguments
|
||||
result.update(self._execute_module(task_vars=task_vars))
|
||||
return result
|
||||
raise _AnsibleActionDone(result=self._execute_module(task_vars=task_vars))
|
||||
|
||||
try:
|
||||
src = self._find_needle('files', src)
|
||||
|
||||
@@ -18,11 +18,12 @@ 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.common.text.converters import to_text
|
||||
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.parsing.convert_bool import boolean
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.plugins.loader import connection_loader
|
||||
@@ -416,7 +417,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, str):
|
||||
if isinstance(tmp_rsync_opts, string_types):
|
||||
tmp_rsync_opts = tmp_rsync_opts.split(',')
|
||||
elif isinstance(tmp_rsync_opts, (int, float)):
|
||||
tmp_rsync_opts = [to_text(tmp_rsync_opts)]
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
name: cgroup_perf_recap
|
||||
@@ -138,7 +141,8 @@ from abc import ABCMeta, abstractmethod
|
||||
|
||||
from functools import partial
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.six import with_metaclass
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
@@ -154,7 +158,7 @@ def dict_fromkeys(keys, default=None):
|
||||
return d
|
||||
|
||||
|
||||
class BaseProf(threading.Thread, metaclass=ABCMeta):
|
||||
class BaseProf(with_metaclass(ABCMeta, threading.Thread)):
|
||||
def __init__(self, path, obj=None, writer=None):
|
||||
threading.Thread.__init__(self) # pylint: disable=non-parent-init-called
|
||||
self.obj = obj
|
||||
|
||||
@@ -48,7 +48,7 @@ import json
|
||||
from functools import partial
|
||||
|
||||
from ansible.inventory.host import Host
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import copy
|
||||
from functools import partial
|
||||
|
||||
from ansible.inventory.host import Host
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import collections
|
||||
import time
|
||||
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
from functools import reduce
|
||||
from ansible.module_utils.six.moves import reduce
|
||||
|
||||
# define start time
|
||||
t0 = tn = time.time()
|
||||
|
||||
@@ -86,7 +86,7 @@ import collections
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from functools import reduce
|
||||
from ansible.module_utils.six.moves import reduce
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ import os
|
||||
import platform
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
||||
def split_entry(entry):
|
||||
@@ -244,16 +244,16 @@ def acl_changed(module, cmd, entry, use_nfsv4_acls=False):
|
||||
lines = run_acl(module, cmd)
|
||||
counter = 0
|
||||
for line in lines:
|
||||
if not use_nfsv4_acls and not line.endswith('*,*'):
|
||||
return True
|
||||
if line.endswith('*,*') and not use_nfsv4_acls:
|
||||
return False
|
||||
# if use_nfsv4_acls and entry is listed
|
||||
if use_nfsv4_acls and entry == line:
|
||||
counter += 1
|
||||
|
||||
# The current 'nfs4_setfacl --test' lists a new entry,
|
||||
# which will be added at the top of the list, followed by the existing entries.
|
||||
# So if the entry has already been registered, the entry should be found twice.
|
||||
if not use_nfsv4_acls or counter == 2:
|
||||
# which will be added at the top of list, followed by the existing entries.
|
||||
# So if the entry has already been registered, the entry should be find twice.
|
||||
if counter == 2:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@@ -121,10 +121,10 @@ EXAMPLES = r'''
|
||||
ansible.posix.authorized_key:
|
||||
user: deploy
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- public_keys/doe-jane
|
||||
- public_keys/doe-john
|
||||
key: '{{ item }}'
|
||||
with_file:
|
||||
- public_keys/doe-jane
|
||||
- public_keys/doe-john
|
||||
|
||||
- name: Set authorized key defining key options
|
||||
ansible.posix.authorized_key:
|
||||
@@ -229,17 +229,10 @@ import errno
|
||||
import traceback
|
||||
from operator import itemgetter
|
||||
|
||||
# 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._text import to_native
|
||||
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):
|
||||
@@ -307,17 +300,6 @@ class keydict(dict):
|
||||
return [item[1] for item in self.items()]
|
||||
|
||||
|
||||
def _safe_open_write(module, path, follow):
|
||||
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
|
||||
if not follow and hasattr(os, 'O_NOFOLLOW'):
|
||||
flags |= os.O_NOFOLLOW
|
||||
try:
|
||||
fd = os.open(path, flags, int('0600', 8))
|
||||
except OSError as e:
|
||||
module.fail_json(msg="File open failed %s : %s" % (path, to_native(e)))
|
||||
return fd
|
||||
|
||||
|
||||
def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False):
|
||||
"""
|
||||
Calculate name of authorized keys file, optionally creating the
|
||||
@@ -370,7 +352,7 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||
module.fail_json(msg="Failed to create directory %s : %s" % (sshdir, to_native(e)))
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(sshdir, False)
|
||||
os.chown(sshdir, uid, gid, follow_symlinks=follow)
|
||||
os.chown(sshdir, uid, gid)
|
||||
os.chmod(sshdir, int('0700', 8))
|
||||
|
||||
if not os.path.exists(keysfile):
|
||||
@@ -378,13 +360,16 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||
if not os.path.exists(basedir):
|
||||
os.makedirs(basedir)
|
||||
|
||||
fd = _safe_open_write(module, keysfile, follow)
|
||||
os.close(fd)
|
||||
f = None
|
||||
try:
|
||||
f = open(keysfile, "w") # touches file so we can set ownership and perms
|
||||
finally:
|
||||
f.close()
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(keysfile, False)
|
||||
|
||||
try:
|
||||
os.chown(keysfile, uid, gid, follow_symlinks=follow)
|
||||
os.chown(keysfile, uid, gid)
|
||||
os.chmod(keysfile, int('0600', 8))
|
||||
except OSError:
|
||||
pass
|
||||
@@ -615,7 +600,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, follow)
|
||||
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
|
||||
existing_content = readfile(module, params["keyfile"])
|
||||
existing_keys = parsekeys(module, existing_content)
|
||||
|
||||
@@ -704,11 +689,6 @@ def enforce_state(module, params):
|
||||
|
||||
if not module.check_mode:
|
||||
writefile(module, filename, new_content)
|
||||
user_entry = pwd.getpwnam(user)
|
||||
uid = user_entry.pw_uid
|
||||
gid = user_entry.pw_gid
|
||||
os.chown(filename, uid, gid, follow_symlinks=follow)
|
||||
os.chmod(filename, int('0600', 8))
|
||||
params['changed'] = True
|
||||
|
||||
return params
|
||||
|
||||
@@ -210,7 +210,7 @@ firewalld_info:
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils._text 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
|
||||
|
||||
@@ -333,6 +333,10 @@ def main():
|
||||
if not HAS_FIREWALLD:
|
||||
module.fail_json(msg=missing_required_lib('python-firewall'))
|
||||
|
||||
# If you want to show warning messages in the task running process,
|
||||
# you can append the message to the 'warn' list.
|
||||
warn = list()
|
||||
|
||||
try:
|
||||
client = fw_client.FirewallClient()
|
||||
|
||||
@@ -352,7 +356,8 @@ def main():
|
||||
collect_zones = list(set(specified_zones) & set(all_zones))
|
||||
ignore_zones = list(set(specified_zones) - set(collect_zones))
|
||||
if ignore_zones:
|
||||
module.warn('Please note: zone:(%s) have been ignored in the gathering process.' % ", ".join(ignore_zones))
|
||||
warn.append(
|
||||
'Please note: zone:(%s) have been ignored in the gathering process.' % ','.join(ignore_zones))
|
||||
else:
|
||||
collect_zones = get_all_zones(client)
|
||||
|
||||
@@ -391,6 +396,7 @@ def main():
|
||||
result['collected_zones'] = collect_zones
|
||||
result['undefined_zones'] = ignore_zones
|
||||
result['firewalld_info'] = firewalld_info
|
||||
result['warnings'] = warn
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
|
||||
@@ -225,7 +225,8 @@ import platform
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.ansible.posix.plugins.module_utils.mount import ismount
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
|
||||
|
||||
@@ -278,7 +279,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 args.items()])
|
||||
escaped_args = dict([(k, _escape_fstab(v)) for k, v in iteritems(args)])
|
||||
new_line = '%(src)s %(name)s %(fstype)s %(opts)s %(dump)s %(passno)s\n'
|
||||
|
||||
if platform.system() == 'SunOS':
|
||||
|
||||
@@ -106,7 +106,7 @@ import os
|
||||
import platform
|
||||
from traceback import format_exc
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
||||
class PatchError(Exception):
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
@@ -70,7 +73,7 @@ import os
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
|
||||
|
||||
def locally_installed(module, pkgname):
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
@@ -68,7 +71,7 @@ import os
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
|
||||
|
||||
def rpm_ostree_transaction(module):
|
||||
|
||||
@@ -73,7 +73,7 @@ except ImportError:
|
||||
HAVE_SEMANAGE = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
||||
|
||||
|
||||
|
||||
@@ -367,16 +367,9 @@ 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.common.text.converters import to_bytes, to_native
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
|
||||
|
||||
client_addr = None
|
||||
|
||||
@@ -44,7 +44,6 @@ options:
|
||||
- If V(true), performs a C(/sbin/sysctl -p) if the O(sysctl_file) is
|
||||
updated. If V(false), does not reload C(sysctl) even if the
|
||||
O(sysctl_file) is updated.
|
||||
- For FreeBSD, can not be used with O(sysctl_file) other than C(/etc/sysctl.conf) or C(/etc/sysctl.conf.local).
|
||||
type: bool
|
||||
default: true
|
||||
sysctl_file:
|
||||
@@ -57,17 +56,6 @@ options:
|
||||
- Verify token value with the sysctl command and set with C(-w) if necessary.
|
||||
type: bool
|
||||
default: false
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
description: Can run in check_mode and return changed status prediction without modifying target.
|
||||
diff_mode:
|
||||
support: none
|
||||
description: Does not support differences output.
|
||||
platform:
|
||||
platforms: posix
|
||||
support: full
|
||||
description: Supported on POSIX-compliant systems.
|
||||
author:
|
||||
- David CHANIAL (@davixx)
|
||||
'''
|
||||
@@ -119,20 +107,12 @@ EXAMPLES = r'''
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# 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.common.text.converters import to_native
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
||||
class SysctlModule(object):
|
||||
@@ -167,11 +147,6 @@ class SysctlModule(object):
|
||||
|
||||
self.platform = platform.system().lower()
|
||||
|
||||
# system specific tests
|
||||
freebsd_sysctl_files = ['/etc/sysctl.conf', '/etc/sysctl.conf.local']
|
||||
if self.platform == 'freebsd' and self.sysctl_file not in freebsd_sysctl_files and self.args['reload']:
|
||||
self.module.fail_json(msg="%s can not be reloaded. Set reload=False." % self.sysctl_file)
|
||||
|
||||
# Whitespace is bad
|
||||
self.args['name'] = self.args['name'].strip()
|
||||
self.args['value'] = self._parse_value(self.args['value'])
|
||||
|
||||
@@ -13,7 +13,8 @@ DOCUMENTATION = '''
|
||||
- shell_common
|
||||
'''
|
||||
|
||||
from shlex import quote as shlex_quote
|
||||
from ansible.module_utils.six import text_type
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.plugins.shell import ShellBase
|
||||
|
||||
|
||||
@@ -42,5 +43,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(str(v))) for k, v in kwargs.items() if v is not None]
|
||||
ret += ['%s=%s' % (k, shlex_quote(text_type(v))) for k, v in kwargs.items() if v is not None]
|
||||
return 'env %s' % ' '.join(ret)
|
||||
|
||||
@@ -13,7 +13,8 @@ DOCUMENTATION = '''
|
||||
- shell_common
|
||||
'''
|
||||
|
||||
from shlex import quote as shlex_quote
|
||||
from ansible.module_utils.six import text_type
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.plugins.shell.sh import ShellModule as ShModule
|
||||
|
||||
|
||||
@@ -41,7 +42,7 @@ class ShellModule(ShModule):
|
||||
if v is None:
|
||||
ret.append('set -e %s;' % k)
|
||||
else:
|
||||
ret.append('set -lx %s %s;' % (k, shlex_quote(str(v))))
|
||||
ret.append('set -lx %s %s;' % (k, shlex_quote(text_type(v))))
|
||||
return ' '.join(ret)
|
||||
|
||||
def build_module_command(self, env_string, shebang, cmd, arg_path=None):
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
---
|
||||
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# 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/>.
|
||||
|
||||
- name: Create ansible user
|
||||
ansible.builtin.user:
|
||||
@@ -29,17 +43,15 @@
|
||||
|
||||
- name: Create ansible dir
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
path: "{{ test_dir }}"
|
||||
state: directory
|
||||
mode: "{{ item.mode }}"
|
||||
loop:
|
||||
- { path: "{{ test_dir }}", mode: "0755" }
|
||||
- { path: "{{ test_recursive_dir }}", mode: "0755" }
|
||||
mode: "0755"
|
||||
|
||||
- name: Install acl package
|
||||
ansible.builtin.package:
|
||||
name: acl
|
||||
state: present
|
||||
|
||||
##############################################################################
|
||||
- name: Grant ansible user read access to a file
|
||||
ansible.posix.acl:
|
||||
@@ -237,38 +249,3 @@
|
||||
- "'default:mask::rwx' in getfacl_output.stdout_lines"
|
||||
- "'default:other::r-x' in getfacl_output.stdout_lines"
|
||||
- "'default:group:{{ test_group }}:rw-' not in getfacl_output.stdout_lines"
|
||||
|
||||
##############################################################################
|
||||
|
||||
- name: create file
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ test_recursive_dir }}/txt.txt"
|
||||
mode: '0440'
|
||||
content: "hw"
|
||||
|
||||
- name: Change ACLs recursively
|
||||
ansible.posix.acl:
|
||||
path: "{{ test_recursive_dir }}"
|
||||
entity: "{{ test_user }}"
|
||||
etype: user
|
||||
permissions: rX
|
||||
state: present
|
||||
recursive: true
|
||||
register: output_acl_change
|
||||
|
||||
- name: Remove ACLs recursively again
|
||||
ansible.posix.acl:
|
||||
path: "{{ test_recursive_dir }}"
|
||||
entity: "{{ test_user }}"
|
||||
etype: user
|
||||
permissions: r
|
||||
state: present
|
||||
recursive: true
|
||||
register: output_acl_remove
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- output_acl_change is changed
|
||||
- output_acl_change is not failed
|
||||
- output_acl_remove is changed
|
||||
- output_acl_remove is not failed
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
---
|
||||
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# 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/>.
|
||||
|
||||
- name: Test ACL
|
||||
vars:
|
||||
@@ -8,7 +22,6 @@
|
||||
test_group: ansible_group
|
||||
test_file: "{{ output_dir }}/ansible file"
|
||||
test_dir: "{{ output_dir }}/ansible_dir/with some space"
|
||||
test_recursive_dir: "{{ output_dir }}/recursive_dir"
|
||||
block:
|
||||
- name: Include tests task file
|
||||
ansible.builtin.include_tasks: acl.yml
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
#
|
||||
# Check: keysfile is symlink and follow=false
|
||||
#
|
||||
- name: Try to add key with keysfile as symlink
|
||||
ansible.posix.authorized_key:
|
||||
user: testuser
|
||||
key: "{{ rsa_key_basic }}"
|
||||
state: present
|
||||
manage_dir: false
|
||||
follow: false
|
||||
|
||||
- name: Assert target file ownership unchanged
|
||||
ansible.builtin.stat:
|
||||
path: /tmp/symlink_test_target/target_file
|
||||
register: target_file_stat
|
||||
|
||||
- name: Verify target file is still owned by root
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- target_file_stat.stat.uid == 0
|
||||
...
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
- name: Remove testuser
|
||||
ansible.builtin.user:
|
||||
name: testuser
|
||||
state: absent
|
||||
remove: true
|
||||
|
||||
- name: Remove symlink target directory
|
||||
ansible.builtin.file:
|
||||
path: /tmp/symlink_test_target
|
||||
state: absent
|
||||
...
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
- name: Create testuser for symlink tests
|
||||
ansible.builtin.user:
|
||||
name: testuser
|
||||
create_home: true
|
||||
register: testuser_result
|
||||
|
||||
- name: Create symlink target directory
|
||||
ansible.builtin.file:
|
||||
path: /tmp/symlink_test_target
|
||||
state: directory
|
||||
owner: root
|
||||
mode: '0700'
|
||||
|
||||
- name: Create a target file owned by root
|
||||
ansible.builtin.copy:
|
||||
dest: /tmp/symlink_test_target/target_file
|
||||
content: "sensitive data"
|
||||
owner: root
|
||||
mode: '0600'
|
||||
|
||||
- name: Remove .ssh directory if exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ testuser_result.home }}/.ssh"
|
||||
state: absent
|
||||
|
||||
- name: Create .ssh directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ testuser_result.home }}/.ssh"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
|
||||
- name: Create symlink from authorized_keys to target file
|
||||
ansible.builtin.file:
|
||||
src: /tmp/symlink_test_target/target_file
|
||||
dest: "{{ testuser_result.home }}/.ssh/authorized_keys"
|
||||
state: link
|
||||
...
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
- name: Setup for testing environment
|
||||
- name: Setup testing environment
|
||||
ansible.builtin.import_tasks: setup_steps.yml
|
||||
|
||||
- name: Test for multiple keys handling
|
||||
@@ -37,12 +37,3 @@
|
||||
|
||||
- name: Test for permission denied files
|
||||
ansible.builtin.import_tasks: check_permissions.yml
|
||||
|
||||
- name: CVE-2026-11837 Setup for symlink tests
|
||||
ansible.builtin.import_tasks: check_symlink_setup.yml
|
||||
|
||||
- name: CVE-2026-11837 Test for symlink tests
|
||||
ansible.builtin.import_tasks: check_symlink.yml
|
||||
|
||||
- name: CVE-2026-11837 Cleanup symlink test
|
||||
ansible.builtin.import_tasks: check_symlink_cleanup.yml
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
- name: Assert turn active_zones true
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.collected_zones == ['public']
|
||||
|
||||
- name: Ensure firewalld_zones with zone list
|
||||
ansible.posix.firewalld_info:
|
||||
@@ -32,6 +31,3 @@
|
||||
- name: Assert specified zones
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.collected_zones == ['public']
|
||||
- result.undefined_zones == ['invalid_zone']
|
||||
- '"invalid_zone" in result.warnings[0]'
|
||||
|
||||
1
tests/sanity/ignore-2.14.txt
Normal file
1
tests/sanity/ignore-2.14.txt
Normal file
@@ -0,0 +1 @@
|
||||
tests/utils/shippable/check_matrix.py replace-urlopen
|
||||
1
tests/sanity/ignore-2.15.txt
Normal file
1
tests/sanity/ignore-2.15.txt
Normal file
@@ -0,0 +1 @@
|
||||
tests/utils/shippable/check_matrix.py replace-urlopen
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins/action/synchronize.py pylint:ansible-bad-import-from
|
||||
plugins/callback/cgroup_perf_recap.py pylint:ansible-bad-import-from
|
||||
plugins/modules/mount.py pylint:ansible-bad-import-from
|
||||
plugins/modules/sysctl.py pylint:ansible-bad-import-from
|
||||
plugins/shell/csh.py pylint:ansible-bad-import-from
|
||||
plugins/shell/fish.py pylint:ansible-bad-import-from
|
||||
tests/unit/mock/procenv.py pylint:ansible-bad-import-from
|
||||
tests/unit/mock/yaml_helper.py pylint:ansible-bad-import-from
|
||||
tests/unit/modules/conftest.py pylint:ansible-bad-import-from
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins/action/synchronize.py pylint:ansible-bad-import-from
|
||||
plugins/callback/cgroup_perf_recap.py pylint:ansible-bad-import-from
|
||||
plugins/modules/mount.py pylint:ansible-bad-import-from
|
||||
plugins/modules/sysctl.py pylint:ansible-bad-import-from
|
||||
plugins/shell/csh.py pylint:ansible-bad-import-from
|
||||
plugins/shell/fish.py pylint:ansible-bad-import-from
|
||||
tests/unit/mock/procenv.py pylint:ansible-bad-import-from
|
||||
tests/unit/mock/yaml_helper.py pylint:ansible-bad-import-from
|
||||
tests/unit/modules/conftest.py pylint:ansible-bad-import-from
|
||||
|
||||
34
tests/unit/compat/builtins.py
Normal file
34
tests/unit/compat/builtins.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# (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__']
|
||||
116
tests/unit/mock/loader.py
Normal file
116
tests/unit/mock/loader.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# (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
|
||||
9
tests/unit/mock/path.py
Normal file
9
tests/unit/mock/path.py
Normal file
@@ -0,0 +1,9 @@
|
||||
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)
|
||||
90
tests/unit/mock/procenv.py
Normal file
90
tests/unit/mock/procenv.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# (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)
|
||||
39
tests/unit/mock/vault_helper.py
Normal file
39
tests/unit/mock/vault_helper.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# 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)
|
||||
125
tests/unit/mock/yaml_helper.py
Normal file
125
tests/unit/mock/yaml_helper.py
Normal file
@@ -0,0 +1,125 @@
|
||||
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}
|
||||
32
tests/unit/modules/conftest.py
Normal file
32
tests/unit/modules/conftest.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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))
|
||||
@@ -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.common.text.converters import to_bytes
|
||||
from ansible.module_utils._text import to_bytes
|
||||
|
||||
from ansible_collections.ansible.posix.plugins.modules.mount import (
|
||||
get_linux_mounts,
|
||||
|
||||
51
tests/unit/modules/utils.py
Normal file
51
tests/unit/modules/utils.py
Normal file
@@ -0,0 +1,51 @@
|
||||
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)
|
||||
@@ -0,0 +1,42 @@
|
||||
boto3
|
||||
placebo
|
||||
pycrypto
|
||||
passlib
|
||||
pypsrp
|
||||
python-memcached
|
||||
pytz
|
||||
pyvmomi
|
||||
redis
|
||||
requests
|
||||
setuptools > 0.6 # pytest-xdist installed via requirements does not work with very old setuptools (sanity_ok)
|
||||
unittest2 ; python_version < '2.7'
|
||||
importlib ; python_version < '2.7'
|
||||
netaddr
|
||||
ipaddress
|
||||
netapp-lib
|
||||
solidfire-sdk-python
|
||||
|
||||
# requirements for F5 specific modules
|
||||
f5-sdk ; python_version >= '2.7'
|
||||
f5-icontrol-rest ; python_version >= '2.7'
|
||||
deepdiff
|
||||
|
||||
# requirement for Fortinet specific modules
|
||||
pyFMG
|
||||
|
||||
# requirement for aci_rest module
|
||||
xmljson
|
||||
|
||||
# requirement for winrm connection plugin tests
|
||||
pexpect
|
||||
|
||||
# requirement for the linode module
|
||||
linode-python # APIv3
|
||||
linode_api4 ; python_version > '2.6' # APIv4
|
||||
|
||||
# requirement for the gitlab module
|
||||
python-gitlab
|
||||
httmock
|
||||
|
||||
# requirment for kubevirt modules
|
||||
openshift ; python_version >= '2.7'
|
||||
|
||||
@@ -65,16 +65,13 @@ fi
|
||||
export ANSIBLE_COLLECTIONS_PATH="${PWD}/../../../"
|
||||
|
||||
# START: HACK install dependencies
|
||||
if [ "${ansible_version}" == "2.16" ]; then
|
||||
# Note: Since community.general 12.x dropped support for ansible-core 2.16,
|
||||
# we need to use stable-11 for ansible-core 2.16.
|
||||
target_branch='stable-11'
|
||||
if [ "${ansible_version}" == "2.9" ] || [ "${ansible_version}" == "2.10" ]; then
|
||||
# Note: Since community.general 5.x, Ansible Core versions prior to 2.11 are not supported.
|
||||
# So we need to use 4.8.1 for Ansible 2.9 and Ansible Engine 2.10.
|
||||
retry git clone --depth=1 --single-branch -b 4.8.1 https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/community/general"
|
||||
else
|
||||
target_branch='main'
|
||||
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/community/general"
|
||||
fi
|
||||
|
||||
retry git clone --depth=1 --single-branch -b "${target_branch}" https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/community/general"
|
||||
|
||||
# Note: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
|
||||
# END: HACK
|
||||
|
||||
|
||||
Reference in New Issue
Block a user