Merge branch 'main' into last_wins

This commit is contained in:
Adam Miller 2024-01-10 08:41:00 -06:00 committed by GitHub
commit f392e407f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
125 changed files with 4879 additions and 2388 deletions

View file

@ -1,3 +1,4 @@
---
trigger:
batch: true
branches:
@ -13,7 +14,7 @@ pr:
- stable-*
schedules:
- cron: 0 9 * * *
- cron: "0 9 * * *"
displayName: Nightly
always: true
branches:
@ -36,13 +37,68 @@ variables:
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:1.9.0
image: quay.io/ansible/azure-pipelines-test-container:main
pool: Standard
stages:
## Docker
- stage: Sanity_devel
displayName: Ansible devel sanity
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: devel/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- name: Lint
test: lint
- stage: Sanity_2_16
displayName: Ansible 2.16 sanity
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.16/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- name: Lint
test: lint
- stage: Sanity_2_15
displayName: Ansible 2.15 sanity
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.15/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- stage: Sanity_2_14
displayName: Ansible 2.14 sanity
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.14/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
## Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
@ -51,136 +107,67 @@ stages:
parameters:
testFormat: devel/linux/{0}/1
targets:
- name: CentOS 7
test: centos7
- name: Fedora 34
test: fedora34
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Fedora 39
test: fedora39
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_13
displayName: Docker 2.13
- name: Ubuntu 22.04
test: ubuntu2204
- stage: Docker_2_16
displayName: Docker 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/linux/{0}/1
testFormat: 2.16/linux/{0}/1
targets:
- name: CentOS 7
test: centos7
- name: Fedora 34
test: fedora34
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Fedora 38
test: fedora38
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_12
displayName: Docker 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 33
test: fedora33
- name: Fedora 34
test: fedora34
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_11
displayName: Docker 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.11/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 32
test: fedora32
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_10
displayName: Docker 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04
test: ubuntu1604
- name: Ubuntu 18.04
test: ubuntu1804
- stage: Docker_2_9
displayName: Docker 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04
test: ubuntu1604
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 22.04
test: ubuntu2204
## Remote
- stage: Docker_2_15
displayName: Docker 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.15/linux/{0}/1
targets:
- name: CentOS 7
test: centos7
- name: Fedora 37
test: fedora37
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 20.04
test: ubuntu2004
- name: Ubuntu 22.04
test: ubuntu2204
- stage: Docker_2_14
displayName: Docker 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.14/linux/{0}/1
targets:
- name: CentOS 7
test: centos7
- name: Fedora 36
test: fedora36
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 20.04
test: ubuntu2004
- name: Ubuntu 22.04
test: ubuntu2204
## Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
@ -189,122 +176,71 @@ stages:
parameters:
testFormat: devel/{0}/1
targets:
- name: MacOS 12.0
test: macos/12.0
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.5
test: rhel/8.5
- name: FreeBSD 12.3
test: freebsd/12.3
- name: FreeBSD 13.0
test: freebsd/13.0
- stage: Remote_2_13
displayName: Remote 2.13
- name: RHEL 9.3
test: rhel/9.3
- name: FreeBSD 13.2
test: freebsd/13.2
- stage: Remote_2_16
displayName: Remote 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/{0}/1
testFormat: 2.16/{0}/1
targets:
- name: MacOS 12.0
test: macos/12.0
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.5
test: rhel/8.5
- name: FreeBSD 12.3
test: freebsd/12.3
- name: FreeBSD 13.0
test: freebsd/13.0
- stage: Remote_2_12
displayName: Remote 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/{0}/1
targets:
- name: MacOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.4
test: rhel/8.4
- name: FreeBSD 12.2
test: freebsd/12.2
- name: FreeBSD 13.0
test: freebsd/13.0
- stage: Remote_2_11
displayName: Remote 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.11/{0}/1
targets:
- name: MacOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.3
test: rhel/8.3
- name: FreeBSD 11.4
test: freebsd/11.4
- name: FreeBSD 12.2
test: freebsd/12.2
- stage: Remote_2_10
displayName: Remote 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/{0}/1
targets:
- name: OS X 10.11
test: osx/10.11
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.2
test: rhel/8.2
- name: FreeBSD 11.1
test: freebsd/11.1
- name: FreeBSD 12.1
test: freebsd/12.1
- name: RHEL 8.8
test: rhel/8.8
- name: RHEL 9.2
test: rhel/9.2
- name: FreeBSD 13.2
test: freebsd/13.2
- stage: Remote_2_9
displayName: Remote 2.9
- stage: Remote_2_15
displayName: Remote 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/{0}/1
testFormat: 2.15/{0}/1
targets:
- name: OS X 10.11
test: osx/10.11
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.1
test: rhel/8.1
- name: FreeBSD 11.1
test: freebsd/11.1
- name: FreeBSD 12.0
test: freebsd/12.0
## Finally
- name: RHEL 8.7
test: rhel/8.7
- name: RHEL 9.1
test: rhel/9.1
- name: FreeBSD 13.2
test: freebsd/13.2
- stage: Remote_2_14
displayName: Remote 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.14/{0}/1
targets:
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.6
test: rhel/8.6
- name: FreeBSD 13.2
test: freebsd/13.2
## Finally
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Remote_2_9
- Docker_2_9
- Remote_2_10
- Docker_2_10
- Remote_2_11
- Docker_2_11
- Remote_2_12
- Docker_2_12
- Remote_2_13
- Docker_2_13
- Sanity_2_14
- Remote_2_14
- Docker_2_14
- Sanity_2_15
- Remote_2_15
- Docker_2_15
- Sanity_2_16
- Remote_2_16
- Docker_2_16
- Sanity_devel
- Remote_devel
- Docker_devel
jobs:

1
.github/BOTMETA.yml vendored
View file

@ -1,3 +1,4 @@
---
automerge: false
files:
$module_utils/mount.py:

View file

@ -5,6 +5,68 @@ ansible.posix Release Notes
.. contents:: Topics
v1.5.4
======
Minor Changes
-------------
- json and jsonl - Add the ``ANSIBLE_JSON_INDENT`` parameter
- json and jsonl - Add the ``path`` attribute into the play and task output
Bugfixes
--------
- Fix sysctl integration test failing on newer versions of core. Previously NoneType was allowable, now it fails to convert to a str type.
- Support new sanity test for the ansible-core devel branch CI test (https://github.com/ansible-collections/ansible.posix/issues/446).
- firewall - Fix issue where adding an interface to a zone would fail when the daemon is offline
- firewall - Fix issue where opening a specific port resulted in opening the whole protocol of the specified port
- firewalld - Consider value of masquerade and icmp_block_inversion parameters when a boolean like value is passed
v1.5.2
======
Release Summary
---------------
This is the minor release of the ``ansible.posix`` collection.
This changelog contains all changes to the modules and plugins
in this collection that have been added after the release of
``ansible.posix`` 1.5.1.
Minor Changes
-------------
- Add jsonl callback plugin to ansible.posix collection
- firewalld - add `protocol` parameter
Bugfixes
--------
- Fixed a bug where firewalld module fails to create/remove zones when the daemon is stopped
- rhel_facts - Call exit_json with all keyword arguments
v1.5.1
======
Minor Changes
-------------
- mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166).
- mount - Add ``ephemeral`` value for the ``state`` parameter, that allows to mount a filesystem without altering the ``fstab`` file (https://github.com/ansible-collections/ansible.posix/pull/267).
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
- rhel_facts - new facts module to handle RHEL specific facts
- rhel_rpm_ostree - new module to handle RHEL rpm-ostree specific package management functionality
- rpm_ostree_upgrade - new module to automate rpm-ostree upgrades
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems
Bugfixes
--------
- Removed contentious terminology to match reference documentation in profile_tasks.
- firewall - Fixed to output a more complete missing library message.
- synchronize - Fixed hosts involved in rsync require the same password
v1.4.0
======

View file

@ -11,13 +11,7 @@ An Ansible Collection of modules and plugins that target POSIX UNIX/Linux and de
<!--start requires_ansible-->
## Ansible version compatibility
This collection has been tested against following Ansible versions: **>=2.9**.
For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
fully qualified collection name (for example, `cisco.ios.ios`).
Plugins and modules within a collection may be tested with only specific Ansible versions.
A collection may contain metadata that identifies these versions.
PEP440 is the schema used to describe the versions of Ansible.
This collection has been tested against following Ansible versions: **>=2.14**.
<!--end requires_ansible-->
## Included content
@ -33,6 +27,9 @@ Name | Description
[ansible.posix.firewalld_info](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.firewalld_info_module.rst)|Gather information about firewalld
[ansible.posix.mount](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.mount_module.rst)|Control active and configured mount points
[ansible.posix.patch](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.patch_module.rst)|Apply patch files using the GNU patch tool
[ansible.posix.rhel_facts](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rhel_facts_module.rst)|Facts module to set or override RHEL specific facts.
[ansible.posix.rhel_rpm_ostree](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rhel_rpm_ostree_module.rst)|Ensure packages exist in a RHEL for Edge rpm-ostree based system
[ansible.posix.rpm_ostree_upgrade](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rpm_ostree_upgrade_module.rst)|Manage rpm-ostree upgrade transactions
[ansible.posix.seboolean](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.seboolean_module.rst)|Toggles SELinux booleans
[ansible.posix.selinux](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.selinux_module.rst)|Change policy and state of SELinux
[ansible.posix.synchronize](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.synchronize_module.rst)|A wrapper around rsync to make common tasks in your playbooks quick and easy
@ -60,8 +57,6 @@ collections:
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
**NOTE**: For Ansible 2.9, you may not see deprecation warnings when you run your playbooks with this collection. Use this documentation to track when a module is deprecated.
## Contributing to this collection
<!--Describe how the community can contribute to your collection. At a minimum, include how and where users can create issues to report problems or request features for this collection. List contribution requirements, including preferred workflows and necessary testing, so you can benefit from community PRs. If you are following general Ansible contributor guidelines, you can link to - [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html). -->
@ -88,12 +83,10 @@ None
<!-- List the versions of Ansible the collection has been tested with. Must match what is in galaxy.yml. -->
- ansible-core 2.14 (devel)
- ansible-core 2.13 (stable)
- ansible-core 2.12 (stable)
- ansible-core 2.11 (stable)
- ansible-base 2.10 (stable)
- ansible 2.9 (stable)
- ansible-core 2.17 (devel)
- ansible-core 2.16 (stable)
- ansible-core 2.15 (stable)
- ansible-core 2.14 (stable)
## Roadmap

View file

@ -1,4 +1,4 @@
# This is a cross-platform list tracking distribution packages needed by tests;
# see https://docs.openstack.org/infra/bindep/ for additional information.
rsync [platform:rhel-8 platform:rhel-9]
rsync [platform:redhat]

View file

@ -260,3 +260,90 @@ releases:
- sanity_fixes.yml
- shell_escape_full_path_for_rsync.yml
release_date: '2022-05-23'
1.5.1:
changes:
bugfixes:
- Removed contentious terminology to match reference documentation in profile_tasks.
- firewall - Fixed to output a more complete missing library message.
- synchronize - Fixed hosts involved in rsync require the same password
minor_changes:
- mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166).
- mount - Add ``ephemeral`` value for the ``state`` parameter, that allows to
mount a filesystem without altering the ``fstab`` file (https://github.com/ansible-collections/ansible.posix/pull/267).
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
- rhel_facts - new facts module to handle RHEL specific facts
- rhel_rpm_ostree - new module to handle RHEL rpm-ostree specific package management
functionality
- rpm_ostree_upgrade - new module to automate rpm-ostree upgrades
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems
fragments:
- 166_mount_absent_fstab.yml
- 267_mount_ephemeral.yml
- 366_update_version_number_for_galaxy.yml
- 371_refactoring_ci_process_202206.yml
- 373_firewall_fix_missing_library_message.yml
- 375_update_azp_container.yml
- 380_update_usage_profile_tasks.yml
- 386_follow_ci_testing_rules.yml
- 389_ci_add_stable_214.yml
- 390_hosts_involved_same_password.yml
- 393-rpm-ostree.yml
- 393_rhel_for_edge.yml
- 400-fix-boolean-values-in-docs.yml
- 401_document_module_default_values.yml
- 407_fix_firewalld_port_test.yml
- 409_update_azp_matrix.yml
release_date: '2023-01-20'
1.5.2:
changes:
bugfixes:
- Fixed a bug where firewalld module fails to create/remove zones when the daemon
is stopped
- rhel_facts - Call exit_json with all keyword arguments
minor_changes:
- Add jsonl callback plugin to ansible.posix collection
- firewalld - add `protocol` parameter
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
This changelog contains all changes to the modules and plugins
in this collection that have been added after the release of
``ansible.posix`` 1.5.1.'
fragments:
- 1.5.2.yml
- 399_firewalld_create_remove_zone_when_offline.yml
- 413-synchronize-seealso.yml
- 417-add-protocol-parameter.yml
- 419-fix-patch-doc.yml
- 425-support_test-sanity-docker-devel.yml
- 426-firewalld_info-doc-update.yml
- 434-fix-rhel_facts-exit_json.yml
- 535-add-jsonl-callback.yml
release_date: '2023-04-07'
1.5.4:
changes:
bugfixes:
- Fix sysctl integration test failing on newer versions of core. Previously
NoneType was allowable, now it fails to convert to a str type.
- Support new sanity test for the ansible-core devel branch CI test (https://github.com/ansible-collections/ansible.posix/issues/446).
- firewall - Fix issue where adding an interface to a zone would fail when the
daemon is offline
- firewall - Fix issue where opening a specific port resulted in opening the
whole protocol of the specified port
- firewalld - Consider value of masquerade and icmp_block_inversion parameters
when a boolean like value is passed
minor_changes:
- json and jsonl - Add the ``ANSIBLE_JSON_INDENT`` parameter
- json and jsonl - Add the ``path`` attribute into the play and task output
fragments:
- 343-fix-profile_tasks-callback-documentation.yml
- 402_firewall_fix_offline_interface_add.yml
- 404_firewalld_masquerade_icmp_block_inversion_bugfixes.yml
- 440-json-add-path-field.yaml
- 441-json-add-indent-parameter.yaml
- 445_ci_support_stable-215.yml
- 448_support_new_sanity_test.yml
- 451_firewall_fix_protocol_parameter.yml
- 456_sysctl_fix_nonetype.yml
release_date: '2023-05-10'

View file

@ -0,0 +1,10 @@
---
minor_changes:
- "seboolean - respawn module to use the system python interpreter when the ``selinux`` python module is not available for ``ansible_python_interpreter``
(https://github.com/ansible-collections/ansible.posix/pull/460)."
- "selinux - respawn module to use the system python interpreter when the ``selinux`` python module is not available for ``ansible_python_interpreter``
(https://github.com/ansible-collections/ansible.posix/pull/460)."
- "firewalld - respawn module to use the system python interpreter when the ``firewall`` python module is not available for ``ansible_python_interpreter``
(https://github.com/ansible-collections/ansible.posix/pull/460)."
- "firewalld_info - respawn module to use the system python interpreter when the ``firewall`` python module is not available for ``ansible_python_interpreter``
(https://github.com/ansible-collections/ansible.posix/pull/460)."

View file

@ -0,0 +1,2 @@
trivial:
- "Fix integration tests so they work with ansible-core devel / 2.16 (https://github.com/ansible-collections/ansible.posix/pull/466)."

View file

@ -0,0 +1,3 @@
---
trivial:
- "Drop Python3.9 and update versions of RHEL,Fedora and FreeBSD for ansible-core:devel test(https://github.com/ansible-collections/ansible.posix/issues/476)."

View file

@ -0,0 +1,2 @@
minor_changes:
- firewalld - added offline flag implementation (https://github.com/ansible-collections/ansible.posix/pull/484)

View file

@ -0,0 +1,3 @@
---
trivial:
- "Drop FreeBSD12.4 from CI for ansible-core:devel(https://github.com/ansible-collections/ansible.posix/issues/486)."

View file

@ -0,0 +1,2 @@
minor_changes:
- firewalld_info - Only warn about ignored zones, when there are zones ignored.

View file

@ -0,0 +1,3 @@
---
trivial:
- "Refactoring remote CI targets."

View file

@ -0,0 +1,3 @@
---
trivial:
- "Replace Fedora 38 with 39 for container test(https://github.com/ansible-collections/ansible.posix/issues/509)."

View file

@ -0,0 +1,2 @@
major_changes:
- "Dropping support for Ansible 2.9, ansible-core 2.14 will be minimum required version for this release"

View file

@ -0,0 +1,2 @@
trivial:
- "Move Galaxy test requirements from old transitional format in tests/requirements.yml to standard Ansible Galaxy requirements files in tests/integration/requirements.yml and tests/unit/requirements.yml."

View file

@ -1 +1,2 @@
---
comment: false

View file

@ -49,8 +49,8 @@ Parameters
</ul>
</td>
<td>
<div>If the target is a directory, setting this to <code>yes</code> will make it the default ACL for entities created inside the directory.</div>
<div>Setting <code>default</code> to <code>yes</code> causes an error if the path is a file.</div>
<div>If the target is a directory, setting this to <code>true</code> will make it the default ACL for entities created inside the directory.</div>
<div>Setting <code>default</code> to <code>true</code> causes an error if the path is a file.</div>
</td>
</tr>
<tr>
@ -63,6 +63,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">""</div>
</td>
<td>
<div>The actual user or group that the ACL applies to when matching entity types user or group are selected.</div>
@ -285,7 +286,7 @@ Examples
entity: joe
etype: user
permissions: rw
default: yes
default: true
state: present
- name: Same as previous but using entry shorthand

View file

@ -171,7 +171,7 @@ Examples
command: ls -d / >/dev/null
count: 20
units: minutes
unique: yes
unique: true

View file

@ -139,8 +139,8 @@ Parameters
</td>
<td>
<div>Whether this module should manage the directory of the authorized key file.</div>
<div>If set to <code>yes</code>, the module will create the directory, as well as set the owner and permissions of an existing directory.</div>
<div>Be sure to set <code>manage_dir=no</code> if you are using an alternate directory for authorized_keys, as set with <code>path</code>, since you could lock yourself out of SSH access.</div>
<div>If set to <code>true</code>, the module will create the directory, as well as set the owner and permissions of an existing directory.</div>
<div>Be sure to set <code>manage_dir=false</code> if you are using an alternate directory for authorized_keys, as set with <code>path</code>, since you could lock yourself out of SSH access.</div>
<div>See the example below.</div>
</td>
</tr>
@ -212,9 +212,9 @@ Parameters
</td>
<td>
<div>This only applies if using a https url as the source of the keys.</div>
<div>If set to <code>no</code>, the SSL certificates will not be validated.</div>
<div>This should only set to <code>no</code> used on personally controlled sites using self-signed certificates as it avoids verifying the source site.</div>
<div>Prior to 2.1 the code worked as if this was set to <code>yes</code>.</div>
<div>If set to <code>false</code>, the SSL certificates will not be validated.</div>
<div>This should only set to <code>false</code> used on personally controlled sites using self-signed certificates as it avoids verifying the source site.</div>
<div>Prior to 2.1 the code worked as if this was set to <code>true</code>.</div>
</td>
</tr>
</table>
@ -252,7 +252,7 @@ Examples
state: present
key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"
path: /etc/ssh/authorized_keys/charlie
manage_dir: False
manage_dir: false
- name: Set up multiple authorized keys
ansible.posix.authorized_key:
@ -275,14 +275,14 @@ Examples
user: charlie
state: present
key: https://github.com/user.keys
validate_certs: False
validate_certs: false
- name: Set authorized key, removing all the authorized keys already set
ansible.posix.authorized_key:
user: root
key: "{{ lookup('file', 'public_keys/doe-jane') }}"
state: present
exclusive: True
exclusive: true
- name: Set authorized key for user ubuntu copying it from current user
ansible.posix.authorized_key:
@ -460,7 +460,7 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
</td>
<td>success</td>
<td>
<div>This only applies if using a https url as the source of the keys. If set to <code>no</code>, the SSL certificates will not be validated.</div>
<div>This only applies if using a https url as the source of the keys. If set to <code>false</code>, the SSL certificates will not be validated.</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">True</div>

View file

@ -89,7 +89,12 @@ Examples
- name: Gather information about active zones
ansible.posix.firewalld_info:
active_zones: yes
active_zones: true
register: result
- name: Print default zone for debugging
ansible.builtin.debug:
var: result.firewalld_info.default_zone
- name: Gather information about specific zones
ansible.posix.firewalld_info:
@ -97,6 +102,7 @@ Examples
- public
- external
- internal
register: result
@ -163,7 +169,7 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="3">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>default_zones</b>
<b>default_zone</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>

View file

@ -155,7 +155,7 @@ Parameters
<td>
<div>Should this configuration be in the running firewalld configuration or persist across reboots.</div>
<div>As of Ansible 2.3, permanent operations can operate on firewalld configs when it is not running (requires firewalld &gt;= 0.3.9).</div>
<div>Note that if this is <code>no</code>, immediate is assumed <code>yes</code>.</div>
<div>Note that if this is <code>false</code>, immediate is assumed <code>true</code>.</div>
</td>
</tr>
<tr>
@ -262,6 +262,21 @@ Parameters
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>protocol</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Name of a protocol to add/remove to/from firewalld.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@ -414,29 +429,35 @@ Examples
- name: permit traffic in default zone for https service
ansible.posix.firewalld:
service: https
permanent: yes
permanent: true
state: enabled
- name: permit ospf traffic
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled
- name: do not permit traffic in default zone on port 8081/tcp
ansible.posix.firewalld:
port: 8081/tcp
permanent: yes
permanent: true
state: disabled
- ansible.posix.firewalld:
port: 161-162/udp
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
zone: dmz
service: http
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
rich_rule: rule service name="ftp" audit limit value="1/m" accept
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
@ -447,44 +468,44 @@ Examples
- ansible.posix.firewalld:
zone: trusted
interface: eth2
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
masquerade: yes
masquerade: true
state: enabled
permanent: yes
permanent: true
zone: dmz
- ansible.posix.firewalld:
zone: custom
state: present
permanent: yes
permanent: true
- ansible.posix.firewalld:
zone: drop
state: enabled
permanent: yes
icmp_block_inversion: yes
permanent: true
icmp_block_inversion: true
- ansible.posix.firewalld:
zone: drop
state: enabled
permanent: yes
permanent: true
icmp_block: echo-request
- ansible.posix.firewalld:
zone: internal
state: present
permanent: yes
permanent: true
target: ACCEPT
- name: Redirect port 443 to 8443 with Rich Rule
ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
zone: public
permanent: yes
immediate: yes
permanent: true
immediate: true
state: enabled

View file

@ -73,6 +73,7 @@ Parameters
<div>For Solaris systems, <code>true</code> will set <code>yes</code> as the value of mount at boot in <em>/etc/vfstab</em>.</div>
<div>For Linux, FreeBSD, NetBSD and OpenBSD systems, <code>false</code> will add <code>noauto</code> to mount options in <em>/etc/fstab</em>.</div>
<div>To avoid mount option conflicts, if <code>noauto</code> specified in <code>opts</code>, mount module will ignore <code>boot</code>.</div>
<div>This parameter is ignored when <em>state</em> is set to <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -90,7 +91,7 @@ Parameters
<td>
<div>Dump (see fstab(5)).</div>
<div>Note that if set to <code>null</code> and <em>state</em> set to <code>present</code>, it will cease to work and duplicate entries will be made with subsequent runs.</div>
<div>Has no effect on Solaris systems.</div>
<div>Has no effect on Solaris systems or when used with <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -110,6 +111,7 @@ Parameters
<div>This might be useful if you need to configure mountpoints in a chroot environment.</div>
<div>OpenBSD does not allow specifying alternate fstab files with mount so do not use this on OpenBSD with any state that operates on the live filesystem.</div>
<div>This parameter defaults to /etc/fstab or /etc/vfstab on Solaris.</div>
<div>This parameter is ignored when <em>state</em> is set to <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -125,7 +127,7 @@ Parameters
</td>
<td>
<div>Filesystem type.</div>
<div>Required when <em>state</em> is <code>present</code> or <code>mounted</code>.</div>
<div>Required when <em>state</em> is <code>present</code>, <code>mounted</code> or <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -158,7 +160,7 @@ Parameters
<td>
<div>Passno (see fstab(5)).</div>
<div>Note that if set to <code>null</code> and <em>state</em> set to <code>present</code>, it will cease to work and duplicate entries will be made with subsequent runs.</div>
<div>Deprecated on Solaris systems.</div>
<div>Deprecated on Solaris systems. Has no effect when used with <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -192,7 +194,7 @@ Parameters
</td>
<td>
<div>Device (or NFS volume, or something else) to be mounted on <em>path</em>.</div>
<div>Required when <em>state</em> set to <code>present</code> or <code>mounted</code>.</div>
<div>Required when <em>state</em> set to <code>present</code>, <code>mounted</code> or <code>ephemeral</code>.</div>
</td>
</tr>
<tr>
@ -208,18 +210,22 @@ Parameters
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>absent</li>
<li>absent_from_fstab</li>
<li>mounted</li>
<li>present</li>
<li>unmounted</li>
<li>remounted</li>
<li>ephemeral</li>
</ul>
</td>
<td>
<div>If <code>mounted</code>, the device will be actively mounted and appropriately configured in <em>fstab</em>. If the mount point is not present, the mount point will be created.</div>
<div>If <code>unmounted</code>, the device will be unmounted without changing <em>fstab</em>.</div>
<div><code>present</code> only specifies that the device is to be configured in <em>fstab</em> and does not trigger or require a mount.</div>
<div><code>ephemeral</code> only specifies that the device is to be mounted, without changing <em>fstab</em>. If it is already mounted, a remount will be triggered. This will always return changed=True. If the mount point <em>path</em> has already a device mounted on, and its source is different than <em>src</em>, the module will fail to avoid unexpected unmount or mount point override. If the mount point is not present, the mount point will be created. The <em>fstab</em> is completely ignored. This option is added in version 1.5.0.</div>
<div><code>absent</code> specifies that the device mount&#x27;s entry will be removed from <em>fstab</em> and will also unmount the device and remove the mount point.</div>
<div><code>remounted</code> specifies that the device will be remounted for when you want to force a refresh on the mount itself (added in 2.9). This will always return changed=true. If <em>opts</em> is set, the options will be applied to the remount, but will not change <em>fstab</em>. Additionally, if <em>opts</em> is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using <code>mounted</code> instead to work around this issue.</div>
<div><code>remounted</code> specifies that the device will be remounted for when you want to force a refresh on the mount itself (added in 2.9). This will always return changed=true. If <em>opts</em> is set, the options will be applied to the remount, but will not change <em>fstab</em>. Additionally, if <em>opts</em> is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using <code>mounted</code> instead to work around this issue. <code>remounted</code> expects the mount point to be present in the <em>fstab</em>. To remount a mount point not registered in <em>fstab</em>, use <code>ephemeral</code> instead, especially with BSD nodes.</div>
<div><code>absent_from_fstab</code> specifies that the device mount&#x27;s entry will be removed from <em>fstab</em>. This option does not unmount it or delete the mountpoint.</div>
</td>
</tr>
</table>
@ -304,10 +310,18 @@ Examples
src: 192.168.1.100:/nfs/ssd/shared_data
path: /mnt/shared_data
opts: rw,sync,hard
boot: no
boot: false
state: mounted
fstype: nfs
- name: Mount ephemeral SMB volume
ansible.posix.mount:
src: //192.168.1.200/share
path: /mnt/smb_share
opts: "rw,vers=3,file_mode=0600,dir_mode=0700,dom={{ ad_domain }},username={{ ad_username }},password={{ ad_password }}"
fstype: cifs
state: ephemeral

View file

@ -84,9 +84,9 @@ Parameters
</ul>
</td>
<td>
<div>Setting to <code>yes</code> will disable patch&#x27;s heuristic for transforming CRLF line endings into LF.</div>
<div>Setting to <code>true</code> will disable patch&#x27;s heuristic for transforming CRLF line endings into LF.</div>
<div>Line endings of src and dest must match.</div>
<div>If set to <code>no</code>, <code>patch</code> will replace CRLF in <code>src</code> files on POSIX.</div>
<div>If set to <code>false</code>, <code>patch</code> will replace CRLF in <code>src</code> files on POSIX.</div>
</td>
</tr>
<tr>
@ -122,7 +122,7 @@ Parameters
</ul>
</td>
<td>
<div>Setting to <code>yes</code> will ignore white space changes between patch and input..</div>
<div>Setting to <code>true</code> will ignore white space changes between patch and input.</div>
</td>
</tr>
<tr>
@ -141,7 +141,7 @@ Parameters
</ul>
</td>
<td>
<div>If <code>no</code>, it will search for src at originating/controller machine, if <code>yes</code> it will go to the remote/target machine for the <code>src</code>.</div>
<div>If <code>false</code>, it will search for src at originating/controller machine, if <code>true</code> it will go to the remote/target machine for the <code>src</code>.</div>
</td>
</tr>
<tr>
@ -157,7 +157,7 @@ Parameters
<td>
</td>
<td>
<div>Path of the patch file as accepted by the GNU patch tool. If <code>remote_src</code> is &#x27;no&#x27;, the patch source file is looked up from the module&#x27;s <em>files</em> directory.</div>
<div>Path of the patch file as accepted by the GNU patch tool. If <code>remote_src</code> is <code>false</code>, the patch source file is looked up from the module&#x27;s <em>files</em> directory.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: patchfile</div>
</td>
</tr>

View file

@ -0,0 +1,103 @@
.. _ansible.posix.rhel_facts_module:
************************
ansible.posix.rhel_facts
************************
**Facts module to set or override RHEL specific facts.**
Version added: 1.5.0
.. contents::
:local:
:depth: 1
Synopsis
--------
- Compatibility layer for using the "package" module for rpm-ostree based systems via setting the "pkg_mgr" fact correctly.
Requirements
------------
The below requirements are needed on the host that executes this module.
- rpm-ostree
See Also
--------
.. seealso::
:ref:`ansible.builtin.package_module`
The official documentation on the **ansible.builtin.package** module.
Examples
--------
.. code-block:: yaml
- name: Playbook to use the package module on all RHEL footprints
vars:
ansible_facts_modules:
- setup # REQUIRED to be run before all custom fact modules
- ansible.posix.rhel_facts
tasks:
- name: Ensure packages are installed
ansible.builtin.package:
name:
- htop
- ansible
state: present
Returned Facts
--------------
Facts returned by this module are added/updated in the ``hostvars`` host facts and can be referenced by name just like any other host fact. They do not need to be registered in order to use them.
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Fact</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="1" colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>pkg_mgr</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this fact"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>when needed</td>
<td>
<div>System-level package manager override
</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{&#x27;pkg_mgr&#x27;: &#x27;ansible.posix.rhel_facts&#x27;}</div>
</td>
</tr>
</table>
<br/><br/>
Status
------
Authors
~~~~~~~
- Adam Miller (@maxamillion)

View file

@ -0,0 +1,156 @@
.. _ansible.posix.rhel_rpm_ostree_module:
*****************************
ansible.posix.rhel_rpm_ostree
*****************************
**Ensure packages exist in a RHEL for Edge rpm-ostree based system**
Version added: 1.5.0
.. contents::
:local:
:depth: 1
Synopsis
--------
- Compatibility layer for using the "package" module for RHEL for Edge systems utilizing the RHEL System Roles.
Requirements
------------
The below requirements are needed on the host that executes this module.
- rpm-ostree
Parameters
----------
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>name</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=string</span>
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>A package name or package specifier with version, like <code>name-1.0</code>.</div>
<div>Comparison operators for package version are valid here <code>&gt;</code>, <code>&lt;</code>, <code>&gt;=</code>, <code>&lt;=</code>. Example - <code>name&gt;=1.0</code></div>
<div>If a previous version is specified, the task also needs to turn <code>allow_downgrade</code> on. See the <code>allow_downgrade</code> documentation for caveats with downgrading packages.</div>
<div>When using state=latest, this can be <code>&#x27;*&#x27;</code> which means run <code>yum -y update</code>.</div>
<div>You can also pass a url or a local path to a rpm file (using state=present). To operate on several packages this can accept a comma separated string of packages or (as of 2.0) a list of packages.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: pkg</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>state</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>absent</li>
<li>installed</li>
<li>latest</li>
<li>present</li>
<li>removed</li>
</ul>
</td>
<td>
<div>Whether to install (<code>present</code> or <code>installed</code>, <code>latest</code>), or remove (<code>absent</code> or <code>removed</code>) a package.</div>
<div><code>present</code> and <code>installed</code> will simply ensure that a desired package is installed.</div>
<div><code>latest</code> will update the specified package if it&#x27;s not of the latest available version.</div>
<div><code>absent</code> and <code>removed</code> will remove the specified package.</div>
<div>Default is <code>None</code>, however in effect the default action is <code>present</code> unless the <code>autoremove</code> option is enabled for this module, then <code>absent</code> is inferred.</div>
</td>
</tr>
</table>
<br/>
Notes
-----
.. note::
- This module does not support installing or removing packages to/from an overlay as this is not supported by RHEL for Edge, packages needed should be defined in the osbuild Blueprint and provided to Image Builder at build time. This module exists only for ``package`` module compatibility.
Examples
--------
.. code-block:: yaml
- name: Ensure htop and ansible are installed on rpm-ostree based RHEL
ansible.posix.rhel_rpm_ostree:
name:
- htop
- ansible
state: present
Return Values
-------------
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>msg</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>always</td>
<td>
<div>status of rpm transaction</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">No changes made.</div>
</td>
</tr>
</table>
<br/><br/>
Status
------
Authors
~~~~~~~
- Adam Miller (@maxamillion)

View file

@ -0,0 +1,175 @@
.. _ansible.posix.rpm_ostree_upgrade_module:
********************************
ansible.posix.rpm_ostree_upgrade
********************************
**Manage rpm-ostree upgrade transactions**
Version added: 1.5.0
.. contents::
:local:
:depth: 1
Synopsis
--------
- Manage an rpm-ostree upgrade transactions.
Requirements
------------
The below requirements are needed on the host that executes this module.
- rpm-ostree
Parameters
----------
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>allow_downgrade</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Allow for the upgrade to be a chronologically older tree.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>cache_only</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Perform the transaction using only pre-cached data, do not download.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>os</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">""</div>
</td>
<td>
<div>The OSNAME upon which to operate.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>peer</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Force peer-to-peer connection instead of using a system message bus.</div>
</td>
</tr>
</table>
<br/>
Examples
--------
.. code-block:: yaml
- name: Upgrade the rpm-ostree image without options, accept all defaults
ansible.posix.rpm_ostree_upgrade:
- name: Upgrade the rpm-ostree image allowing downgrades
ansible.posix.rpm_ostree_upgrade:
allow_downgrade: true
Return Values
-------------
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>msg</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>always</td>
<td>
<div>The command standard output</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">No upgrade available.</div>
</td>
</tr>
</table>
<br/><br/>
Status
------
Authors
~~~~~~~
- Adam Miller (@maxamillion)

View file

@ -92,7 +92,7 @@ Parameters
</ul>
</td>
<td>
<div>Set to <code>yes</code> if the boolean setting should survive a reboot.</div>
<div>Set to <code>true</code> if the boolean setting should survive a reboot.</div>
</td>
</tr>
<tr>
@ -135,8 +135,8 @@ Examples
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots
ansible.posix.seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
state: true
persistent: true

View file

@ -150,7 +150,7 @@ Parameters
</td>
<td>
<div>Delete files in <em>dest</em> that do not exist (after transfer, not before) in the <em>src</em> path.</div>
<div>This option requires <em>recursive=yes</em>.</div>
<div>This option requires <em>recursive=true</em>.</div>
<div>This option ignores excluded files and behaves like the rsync opt <code>--delete-after</code>.</div>
</td>
</tr>
@ -465,7 +465,7 @@ Parameters
</td>
<td>
<div>Put user@ for the remote paths.</div>
<div>If you have a custom ssh config to define the remote user for a host that does not match the inventory user, you should set this parameter to <code>no</code>.</div>
<div>If you have a custom ssh config to define the remote user for a host that does not match the inventory user, you should set this parameter to <code>false</code>.</div>
</td>
</tr>
<tr>
@ -502,8 +502,8 @@ Parameters
</td>
<td>
<div>SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections. This is accomplished by setting the SSH <code>ControlSocket</code> to <code>none</code>.</div>
<div>Set this option to <code>yes</code> to allow multiplexing and reduce SSH connection overhead.</div>
<div>Note that simply setting this option to <code>yes</code> is not enough; You must also configure SSH connection multiplexing in your SSH client config by setting values for <code>ControlMaster</code>, <code>ControlPersist</code> and <code>ControlPath</code>.</div>
<div>Set this option to <code>true</code> to allow multiplexing and reduce SSH connection overhead.</div>
<div>Note that simply setting this option to <code>true</code> is not enough; You must also configure SSH connection multiplexing in your SSH client config by setting values for <code>ControlMaster</code>, <code>ControlPersist</code> and <code>ControlPath</code>.</div>
</td>
</tr>
<tr>
@ -595,8 +595,8 @@ See Also
.. seealso::
:ref:`copy_module`
The official documentation on the **copy** module.
:ref:`ansible.builtin.copy_module`
The official documentation on the **ansible.builtin.copy** module.
:ref:`community.windows.win_robocopy_module`
The official documentation on the **community.windows.win_robocopy** module.
@ -639,27 +639,27 @@ Examples
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
archive: no
archive: false
- name: Synchronization with --archive options enabled except for --recursive
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
recursive: no
recursive: false
- name: Synchronization with --archive options enabled except for --times, with --checksum option enabled
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
checksum: yes
times: no
checksum: true
times: false
- name: Synchronization without --archive options enabled except use --links
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
archive: no
links: yes
archive: false
links: true
- name: Synchronization of two paths both on the control machine
ansible.posix.synchronize:
@ -689,8 +689,8 @@ Examples
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
delete: yes
recursive: yes
delete: true
recursive: true
# This specific command is granted su privileges on the destination
- name: Synchronize using an alternate rsync command

View file

@ -85,7 +85,7 @@ Parameters
</ul>
</td>
<td>
<div>If <code>yes</code>, performs a <em>/sbin/sysctl -p</em> if the <code>sysctl_file</code> is updated. If <code>no</code>, does not reload <em>sysctl</em> even if the <code>sysctl_file</code> is updated.</div>
<div>If <code>true</code>, performs a <em>/sbin/sysctl -p</em> if the <code>sysctl_file</code> is updated. If <code>false</code>, does not reload <em>sysctl</em> even if the <code>sysctl_file</code> is updated.</div>
</td>
</tr>
<tr>
@ -139,7 +139,7 @@ Parameters
</ul>
</td>
<td>
<div>Verify token value with the sysctl command and set with -w if necessary</div>
<div>Verify token value with the sysctl command and set with -w if necessary.</div>
</td>
</tr>
<tr>
@ -186,21 +186,21 @@ Examples
name: kernel.panic
value: '3'
sysctl_file: /tmp/test_sysctl.conf
reload: no
reload: false
# Set ip forwarding on in /proc and verify token value with the sysctl command
- ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: yes
sysctl_set: true
# Set ip forwarding on in /proc and in the sysctl file and reload if necessary
- ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: yes
sysctl_set: true
state: present
reload: yes
reload: true

View file

@ -1,6 +1,7 @@
---
namespace: ansible
name: posix
version: 1.4.0
version: 1.5.4
readme: README.md
authors:
- Ansible (github.com/ansible)

View file

@ -1,8 +1,8 @@
---
requires_ansible: '>=2.9'
requires_ansible: ">=2.14.0"
plugin_routing:
callback:
skippy:
deprecation:
removal_date: '2022-06-01'
removal_date: "2022-06-01"
warning_text: See the plugin documentation for more details

View file

@ -177,7 +177,7 @@ class ActionModule(ActionBase):
# Store remote connection type
self._remote_transport = self._connection.transport
use_ssh_args = _tmp_args.pop('use_ssh_args', None)
use_ssh_args = _tmp_args.pop('use_ssh_args', False)
if use_ssh_args and self._connection.transport == 'ssh':
ssh_args = [
@ -185,7 +185,7 @@ class ActionModule(ActionBase):
self._connection.get_option('ssh_common_args'),
self._connection.get_option('ssh_extra_args'),
]
_tmp_args['ssh_args'] = ' '.join([a for a in ssh_args if a])
_tmp_args['_ssh_args'] = ' '.join([a for a in ssh_args if a])
# Handle docker connection options
if self._remote_transport in DOCKER:
@ -225,7 +225,6 @@ class ActionModule(ActionBase):
# Parameter name needed by the ansible module
_tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync'
_tmp_args['_local_rsync_password'] = task_vars.get('ansible_ssh_pass') or task_vars.get('ansible_password')
# rsync thinks that one end of the connection is localhost and the
# other is the host we're running the task for (Note: We use
@ -333,8 +332,9 @@ class ActionModule(ActionBase):
if src is None or dest is None:
return dict(failed=True, msg="synchronize requires both src and dest parameters are set")
# Determine if we need a user@
# Determine if we need a user@ and a password
user = None
password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None)
if not dest_is_local:
# Src and dest rsync "path" handling
if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False):
@ -344,10 +344,12 @@ class ActionModule(ActionBase):
user = task_vars.get('ansible_user') or self._play_context.remote_user
if not user:
user = C.DEFAULT_REMOTE_USER
else:
user = task_vars.get('ansible_user') or self._play_context.remote_user
if self._templar is not None:
user = self._templar.template(user)
# Private key handling
# Use the private_key parameter if passed else use context private_key_file
_tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file)
@ -361,12 +363,17 @@ class ActionModule(ActionBase):
# src is a local path, dest is a remote path: <user>@<host>
src = self._process_origin(src_host, src, user)
dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports)
password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None)
if self._templar is not None:
password = self._templar.template(password)
else:
# Still need to munge paths (to account for roles) even if we aren't
# copying files between hosts
src = self._get_absolute_path(path=src)
dest = self._get_absolute_path(path=dest)
_tmp_args['_local_rsync_password'] = password
_tmp_args['src'] = src
_tmp_args['dest'] = dest

View file

@ -25,6 +25,16 @@ DOCUMENTATION = '''
- key: show_custom_stats
section: defaults
type: bool
json_indent:
name: Use indenting for the JSON output
description: 'If specified, use this many spaces for indenting in the JSON output. If <= 0, write to a single line.'
default: 4
env:
- name: ANSIBLE_JSON_INDENT
ini:
- key: json_indent
section: defaults
type: integer
notes:
- When using a strategy such as free, host_pinned, or a custom strategy, host results will
be added to new task results in ``.plays[].tasks[]``. As such, there will exist duplicate
@ -61,12 +71,19 @@ class CallbackModule(CallbackBase):
self._task_map = {}
self._is_lockstep = False
self.set_options()
self._json_indent = self.get_option('json_indent')
if self._json_indent <= 0:
self._json_indent = None
def _new_play(self, play):
self._is_lockstep = play.strategy in LOCKSTEP_CALLBACKS
return {
'play': {
'name': play.get_name(),
'id': to_text(play._uuid),
'path': to_text(play.get_path()),
'duration': {
'start': current_time()
}
@ -79,6 +96,7 @@ class CallbackModule(CallbackBase):
'task': {
'name': task.get_name(),
'id': to_text(task._uuid),
'path': to_text(task.get_path()),
'duration': {
'start': current_time()
}
@ -143,7 +161,7 @@ class CallbackModule(CallbackBase):
'global_custom_stats': global_custom_stats,
}
self._display.display(json.dumps(output, cls=AnsibleJSONEncoder, indent=4, sort_keys=True))
self._display.display(json.dumps(output, cls=AnsibleJSONEncoder, indent=self._json_indent, sort_keys=True))
def _record_task_result(self, on_info, result, **kwargs):
"""This function is used as a partial to add failed/skipped info in a single method"""

214
plugins/callback/jsonl.py Normal file
View file

@ -0,0 +1,214 @@
# (c) 2016, Matt Martz <matt@sivel.net>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
name: jsonl
short_description: Ansible screen output as JSONL (lines in json format)
description:
- This callback converts all events into JSON output to stdout
- This callback in contrast with ansible.posix.json uses less memory, because it doesn't store results.
type: stdout
requirements:
- Set as stdout in config
options:
show_custom_stats:
name: Show custom stats
description: 'This adds the custom stats set via the set_stats plugin to the play recap'
default: False
env:
- name: ANSIBLE_SHOW_CUSTOM_STATS
ini:
- key: show_custom_stats
section: defaults
type: bool
json_indent:
name: Use indenting for the JSON output
description: 'If specified, use this many spaces for indenting in the JSON output. If not specified or <= 0, write to a single line.'
default: 0
env:
- name: ANSIBLE_JSON_INDENT
ini:
- key: json_indent
section: defaults
type: integer
notes:
- When using a strategy such as free, host_pinned, or a custom strategy, host results will
be added to new task results in ``.plays[].tasks[]``. As such, there will exist duplicate
task objects indicated by duplicate task IDs at ``.plays[].tasks[].task.id``, each with an
individual host result for the task.
'''
import datetime
import json
import copy
from functools import partial
from ansible.inventory.host import Host
from ansible.module_utils._text import to_text
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
LOCKSTEP_CALLBACKS = frozenset(('linear', 'debug'))
def current_time():
return '%sZ' % datetime.datetime.utcnow().isoformat()
class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'stdout'
CALLBACK_NAME = 'ansible.posix.jsonl'
def __init__(self, display=None):
super(CallbackModule, self).__init__(display)
self.results = []
self._task_map = {}
self._is_lockstep = False
self.set_options()
self._json_indent = self.get_option('json_indent')
if self._json_indent <= 0:
self._json_indent = None
def _new_play(self, play):
self._is_lockstep = play.strategy in LOCKSTEP_CALLBACKS
return {
'play': {
'name': play.get_name(),
'id': to_text(play._uuid),
'path': to_text(play.get_path()),
'duration': {
'start': current_time()
}
},
'tasks': []
}
def _new_task(self, task):
return {
'task': {
'name': task.get_name(),
'id': to_text(task._uuid),
'path': to_text(task.get_path()),
'duration': {
'start': current_time()
}
},
'hosts': {}
}
def _find_result_task(self, host, task):
key = (host.get_name(), task._uuid)
return self._task_map.get(
key,
self.results[-1]['tasks'][-1]
)
def v2_playbook_on_play_start(self, play):
play_result = self._new_play(play)
self.results.append(play_result)
self._write_event('v2_playbook_on_play_start', play_result)
def v2_runner_on_start(self, host, task):
if self._is_lockstep:
return
key = (host.get_name(), task._uuid)
task_result = self._new_task(task)
self._task_map[key] = task_result
self.results[-1]['tasks'].append(task_result)
self._write_event('v2_runner_on_start', task_result)
def v2_playbook_on_task_start(self, task, is_conditional):
if not self._is_lockstep:
return
task_result = self._new_task(task)
self.results[-1]['tasks'].append(task_result)
self._write_event('v2_playbook_on_task_start', task_result)
def v2_playbook_on_handler_task_start(self, task):
if not self._is_lockstep:
return
task_result = self._new_task(task)
self.results[-1]['tasks'].append(task_result)
self._write_event('v2_playbook_on_handler_task_start', task_result)
def _convert_host_to_name(self, key):
if isinstance(key, (Host,)):
return key.get_name()
return key
def v2_playbook_on_stats(self, stats):
"""Display info about playbook statistics"""
hosts = sorted(stats.processed.keys())
summary = {}
for h in hosts:
s = stats.summarize(h)
summary[h] = s
custom_stats = {}
global_custom_stats = {}
if self.get_option('show_custom_stats') and stats.custom:
custom_stats.update(dict((self._convert_host_to_name(k), v) for k, v in stats.custom.items()))
global_custom_stats.update(custom_stats.pop('_run', {}))
output = {
'stats': summary,
'custom_stats': custom_stats,
'global_custom_stats': global_custom_stats,
}
self._write_event('v2_playbook_on_stats', output)
def _write_event(self, event_name, output):
output['_event'] = event_name
output['_timestamp'] = current_time()
self._display.display(json.dumps(output, cls=AnsibleJSONEncoder, indent=self._json_indent, separators=',:', sort_keys=True))
def _record_task_result(self, event_name, on_info, result, **kwargs):
"""This function is used as a partial to add failed/skipped info in a single method"""
host = result._host
task = result._task
result_copy = result._result.copy()
result_copy.update(on_info)
result_copy['action'] = task.action
task_result = self._find_result_task(host, task)
end_time = current_time()
task_result['task']['duration']['end'] = end_time
self.results[-1]['play']['duration']['end'] = end_time
task_result_copy = copy.deepcopy(task_result)
task_result_copy['hosts'][host.name] = result_copy
if not self._is_lockstep:
key = (host.get_name(), task._uuid)
del self._task_map[key]
self._write_event(event_name, task_result_copy)
def __getattribute__(self, name):
"""Return ``_record_task_result`` partial with a dict containing skipped/failed if necessary"""
if name not in ('v2_runner_on_ok', 'v2_runner_on_failed', 'v2_runner_on_unreachable', 'v2_runner_on_skipped'):
return object.__getattribute__(self, name)
on = name.rsplit('_', 1)[1]
on_info = {}
if on in ('failed', 'skipped'):
on_info[on] = True
return partial(self._record_task_result, name, on_info)

View file

@ -17,11 +17,11 @@ DOCUMENTATION = '''
- Ansible callback plugin for timing individual tasks and overall execution time.
- "Mashup of 2 excellent original works: https://github.com/jlafon/ansible-profile,
https://github.com/junaid18183/ansible_home/blob/master/ansible_plugins/callback_plugins/timestamp.py.old"
- "Format: C(<task start timestamp> (<length of previous task>) <current elapsed playbook execution time>)"
- "Format: C(<task start timestamp>) C(<length of previous task>) C(<current elapsed playbook execution time>)"
- It also lists the top/bottom time consuming tasks in the summary (configurable)
- Before 2.4 only the environment variables were available for configuration.
requirements:
- whitelisting in configuration - see examples section below for details.
- enable in configuration - see examples section below for details.
options:
output_limit:
description: Number of tasks to display in the summary
@ -46,7 +46,7 @@ EXAMPLES = '''
example: >
To enable, add this to your ansible.cfg file in the defaults block
[defaults]
callback_whitelist = ansible.posix.profile_tasks
callbacks_enabled=ansible.posix.profile_tasks
sample output: >
#
# TASK: [ensure messaging security group exists] ********************************

View file

@ -0,0 +1,45 @@
# Copyright (c) 2023 Maxwell G <maxwell@gtmx.me>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
Helpers to respawn a module to run using the system interpreter
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
try:
from ansible.module_utils.common import respawn
except ImportError:
HAS_RESPAWN_UTIL = False
else:
HAS_RESPAWN_UTIL = True
SYSTEM_PYTHON_INTERPRETERS = (
"/usr/bin/libexec/platform-python",
"/usr/bin/python3",
"/usr/bin/python2",
"/usr/bin/python",
)
def respawn_module(module):
"""
Respawn an ansible module to using the first interpreter in
SYSTEM_PYTHON_INTERPRETERS that contains `module`.
Args:
module (str): Name of python module to search for
Returns:
Returns None if the module cannot be respawned.
"""
if respawn.has_respawned():
return
interpreter = respawn.probe_interpreters_for_module(
SYSTEM_PYTHON_INTERPRETERS, module
)
if interpreter:
respawn.respawn_module(interpreter)

View file

@ -5,6 +5,8 @@
from __future__ import absolute_import, division, print_function
from ansible_collections.ansible.posix.plugins.module_utils.version import LooseVersion
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
from ansible.module_utils.basic import missing_required_lib
__metaclass__ = type
@ -313,7 +315,8 @@ class FirewallTransaction(object):
installed version (%s) likely too old. Requires firewalld >= 0.2.11" % FW_VERSION)
if import_failure:
if HAS_RESPAWN_UTIL:
respawn_module("firewall")
module.fail_json(
msg='Python Module not found: firewalld and its python module are required for this module, \
version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
msg=missing_required_lib('firewall') + '. Version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
)

View file

@ -16,3 +16,5 @@ __metaclass__ = type
# from ansible.module_utils.compat.version import LooseVersion
from ._version import LooseVersion, StrictVersion
__all__ = ['LooseVersion', 'StrictVersion']

View file

@ -20,7 +20,7 @@ options:
description:
- The full path of the file or object.
type: path
required: yes
required: true
aliases: [ name ]
state:
description:
@ -33,17 +33,18 @@ options:
description:
- Whether to follow symlinks on the path if a symlink is encountered.
type: bool
default: yes
default: true
default:
description:
- If the target is a directory, setting this to C(yes) will make it the default ACL for entities created inside the directory.
- Setting C(default) to C(yes) causes an error if the path is a file.
- If the target is a directory, setting this to C(true) will make it the default ACL for entities created inside the directory.
- Setting C(default) to C(true) causes an error if the path is a file.
type: bool
default: no
default: false
entity:
description:
- The actual user or group that the ACL applies to when matching entity types user or group are selected.
type: str
default: ""
etype:
description:
- The entity type of the ACL to apply, see C(setfacl) documentation for more info.
@ -69,13 +70,13 @@ options:
- Incompatible with C(state=query).
- Alias C(recurse) added in version 1.3.0.
type: bool
default: no
default: false
aliases: [ recurse ]
use_nfsv4_acls:
description:
- Use NFSv4 ACLs instead of POSIX ACLs.
type: bool
default: no
default: false
recalculate_mask:
description:
- Select if and when to recalculate the effective right masks of the files.
@ -115,7 +116,7 @@ EXAMPLES = r'''
entity: joe
etype: user
permissions: rw
default: yes
default: true
state: present
- name: Same as previous but using entry shorthand

View file

@ -44,7 +44,7 @@ options:
description:
- If a matching job is present a new job will not be added.
type: bool
default: no
default: false
requirements:
- at
author:
@ -68,7 +68,7 @@ EXAMPLES = r'''
command: ls -d / >/dev/null
count: 20
units: minutes
unique: yes
unique: true
'''
import os

View file

@ -34,13 +34,13 @@ options:
manage_dir:
description:
- Whether this module should manage the directory of the authorized key file.
- If set to C(yes), the module will create the directory, as well as set the owner and permissions
- If set to C(true), the module will create the directory, as well as set the owner and permissions
of an existing directory.
- Be sure to set C(manage_dir=no) if you are using an alternate directory for authorized_keys,
- Be sure to set C(manage_dir=false) if you are using an alternate directory for authorized_keys,
as set with C(path), since you could lock yourself out of SSH access.
- See the example below.
type: bool
default: yes
default: true
state:
description:
- Whether the given key (with the given key_options) should or should not be in the file.
@ -58,15 +58,15 @@ options:
- This option is not loop aware, so if you use C(with_) , it will be exclusive per iteration of the loop.
- If you want multiple keys in the file you need to pass them all to C(key) in a single batch as mentioned above.
type: bool
default: no
default: false
validate_certs:
description:
- This only applies if using a https url as the source of the keys.
- If set to C(no), the SSL certificates will not be validated.
- This should only set to C(no) used on personally controlled sites using self-signed certificates as it avoids verifying the source site.
- Prior to 2.1 the code worked as if this was set to C(yes).
- If set to C(false), the SSL certificates will not be validated.
- This should only set to C(false) used on personally controlled sites using self-signed certificates as it avoids verifying the source site.
- Prior to 2.1 the code worked as if this was set to C(true).
type: bool
default: yes
default: true
comment:
description:
- Change the comment on the public key.
@ -77,7 +77,7 @@ options:
description:
- Follow path symlink instead of replacing it.
type: bool
default: no
default: false
author: Ansible Core Team
'''
@ -106,7 +106,7 @@ EXAMPLES = r'''
state: present
key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"
path: /etc/ssh/authorized_keys/charlie
manage_dir: False
manage_dir: false
- name: Set up multiple authorized keys
ansible.posix.authorized_key:
@ -129,14 +129,14 @@ EXAMPLES = r'''
user: charlie
state: present
key: https://github.com/user.keys
validate_certs: False
validate_certs: false
- name: Set authorized key, removing all the authorized keys already set
ansible.posix.authorized_key:
user: root
key: "{{ lookup('file', 'public_keys/doe-jane') }}"
state: present
exclusive: True
exclusive: true
- name: Set authorized key for user ubuntu copying it from current user
ansible.posix.authorized_key:
@ -150,7 +150,7 @@ exclusive:
description: If the key has been forced to be exclusive or not.
returned: success
type: bool
sample: False
sample: false
key:
description: The key that the module was running against.
returned: success
@ -170,7 +170,7 @@ manage_dir:
description: Whether this module managed the directory of the authorized key file.
returned: success
type: bool
sample: True
sample: true
path:
description: Alternate path to the authorized_keys file
returned: success
@ -192,7 +192,7 @@ user:
type: str
sample: user
validate_certs:
description: This only applies if using a https url as the source of the keys. If set to C(no), the SSL certificates will not be validated.
description: This only applies if using a https url as the source of the keys. If set to C(false), the SSL certificates will not be validated.
returned: success
type: bool
sample: true
@ -347,6 +347,8 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
basedir = os.path.dirname(keysfile)
if not os.path.exists(basedir):
os.makedirs(basedir)
f = None
try:
f = open(keysfile, "w") # touches file so we can set ownership and perms
finally:

View file

@ -19,6 +19,10 @@ options:
- Name of a service to add/remove to/from firewalld.
- The service must be listed in output of firewall-cmd --get-services.
type: str
protocol:
description:
- Name of a protocol to add/remove to/from firewalld.
type: str
port:
description:
- Name of a port or port range to add/remove to/from firewalld.
@ -80,15 +84,17 @@ options:
type: str
permanent:
description:
- Should this configuration be in the running firewalld configuration or persist across reboots.
- Whether to apply this change to the permanent firewalld configuration.
- As of Ansible 2.3, permanent operations can operate on firewalld configs when it is not running (requires firewalld >= 0.3.9).
- Note that if this is C(no), immediate is assumed C(yes).
- Note that if this is C(false), I(immediate) defaults to C(true).
type: bool
default: false
immediate:
description:
- Should this configuration be applied immediately, if set as permanent.
- Whether to apply this change to the runtime firewalld configuration.
- Defaults to C(true) if I(permanent=false).
type: bool
default: no
default: false
state:
description:
- Enable or disable a setting.
@ -108,8 +114,9 @@ options:
type: str
offline:
description:
- Whether to run this module even when firewalld is offline.
- Ignores I(immediate) if I(permanent=true) and firewalld is not running.
type: bool
default: false
target:
description:
- firewalld Zone target
@ -138,32 +145,46 @@ author:
'''
EXAMPLES = r'''
- name: permanently enable https service, also enable it immediately if possible
ansible.posix.firewalld:
service: https
state: enabled
permanent: true
immediate: true
offline: true
- name: permit traffic in default zone for https service
ansible.posix.firewalld:
service: https
permanent: yes
permanent: true
state: enabled
- name: permit ospf traffic
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled
- name: do not permit traffic in default zone on port 8081/tcp
ansible.posix.firewalld:
port: 8081/tcp
permanent: yes
permanent: true
state: disabled
- ansible.posix.firewalld:
port: 161-162/udp
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
zone: dmz
service: http
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
rich_rule: rule service name="ftp" audit limit value="1/m" accept
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
@ -174,44 +195,44 @@ EXAMPLES = r'''
- ansible.posix.firewalld:
zone: trusted
interface: eth2
permanent: yes
permanent: true
state: enabled
- ansible.posix.firewalld:
masquerade: yes
masquerade: true
state: enabled
permanent: yes
permanent: true
zone: dmz
- ansible.posix.firewalld:
zone: custom
state: present
permanent: yes
permanent: true
- ansible.posix.firewalld:
zone: drop
state: enabled
permanent: yes
icmp_block_inversion: yes
permanent: true
icmp_block_inversion: true
- ansible.posix.firewalld:
zone: drop
state: enabled
permanent: yes
permanent: true
icmp_block: echo-request
- ansible.posix.firewalld:
zone: internal
state: present
permanent: yes
permanent: true
target: ACCEPT
- name: Redirect port 443 to 8443 with Rich Rule
ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
zone: public
permanent: yes
immediate: yes
permanent: true
immediate: true
state: enabled
'''
@ -343,6 +364,47 @@ class ServiceTransaction(FirewallTransaction):
self.update_fw_settings(fw_zone, fw_settings)
class ProtocolTransaction(FirewallTransaction):
"""
ProtocolTransaction
"""
def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(ProtocolTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)
def get_enabled_immediate(self, protocol, timeout):
if protocol in self.fw.getProtocols(self.zone):
return True
else:
return False
def get_enabled_permanent(self, protocol, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
if protocol in fw_settings.getProtocols():
return True
else:
return False
def set_enabled_immediate(self, protocol, timeout):
self.fw.addProtocol(self.zone, protocol, timeout)
def set_enabled_permanent(self, protocol, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.addProtocol(protocol)
self.update_fw_settings(fw_zone, fw_settings)
def set_disabled_immediate(self, protocol, timeout):
self.fw.removeProtocol(self.zone, protocol)
def set_disabled_permanent(self, protocol, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.removeProtocol(protocol)
self.update_fw_settings(fw_zone, fw_settings)
class MasqueradeTransaction(FirewallTransaction):
"""
MasqueradeTransaction
@ -469,6 +531,7 @@ class InterfaceTransaction(FirewallTransaction):
old_zone_obj = self.fw.config.get_zone(zone)
if interface in old_zone_obj.interfaces:
iface_zone_objs.append(old_zone_obj)
if len(iface_zone_objs) > 1:
# Even it shouldn't happen, it's actually possible that
# the same interface is in several zone XML files
@ -478,18 +541,17 @@ class InterfaceTransaction(FirewallTransaction):
len(iface_zone_objs)
)
)
old_zone_obj = iface_zone_objs[0]
if old_zone_obj.name != self.zone:
old_zone_settings = FirewallClientZoneSettings(
self.fw.config.get_zone_config(old_zone_obj)
)
elif len(iface_zone_objs) == 1 and iface_zone_objs[0].name != self.zone:
old_zone_obj = iface_zone_objs[0]
old_zone_config = self.fw.config.get_zone_config(old_zone_obj)
old_zone_settings = FirewallClientZoneSettings(list(old_zone_config))
old_zone_settings.removeInterface(interface) # remove from old
self.fw.config.set_zone_config(
old_zone_obj,
old_zone_settings.settings
)
fw_settings.addInterface(interface) # add to new
self.fw.config.set_zone_config(fw_zone, fw_settings.settings)
fw_settings.addInterface(interface) # add to new
self.fw.config.set_zone_config(fw_zone, fw_settings.settings)
else:
old_zone_name = self.fw.config().getZoneOfInterface(interface)
if old_zone_name != self.zone:
@ -675,25 +737,33 @@ class ZoneTransaction(FirewallTransaction):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def get_enabled_permanent(self):
zones = self.fw.config().listZones()
zone_names = [self.fw.config().getZone(z).get_property("name") for z in zones]
if self.zone in zone_names:
return True
if self.fw_offline:
zones = self.fw.config.get_zones()
zone_names = [self.fw.config.get_zone(z).name for z in zones]
else:
return False
zones = self.fw.config().listZones()
zone_names = [self.fw.config().getZone(z).get_property("name") for z in zones]
return self.zone in zone_names
def set_enabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_enabled_permanent(self):
self.fw.config().addZone(self.zone, FirewallClientZoneSettings())
if self.fw_offline:
self.fw.config.new_zone(self.zone, FirewallClientZoneSettings().settings)
else:
self.fw.config().addZone(self.zone, FirewallClientZoneSettings())
def set_disabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_disabled_permanent(self):
zone_obj = self.fw.config().getZoneByName(self.zone)
zone_obj.remove()
if self.fw_offline:
zone = self.fw.config.get_zone(self.zone)
self.fw.config.remove_zone(zone)
else:
zone_obj = self.fw.config().getZoneByName(self.zone)
zone_obj.remove()
class ForwardPortTransaction(FirewallTransaction):
@ -740,18 +810,19 @@ def main():
icmp_block=dict(type='str'),
icmp_block_inversion=dict(type='str'),
service=dict(type='str'),
protocol=dict(type='str'),
port=dict(type='str'),
port_forward=dict(type='list', elements='dict'),
rich_rule=dict(type='str'),
zone=dict(type='str'),
immediate=dict(type='bool', default=False),
source=dict(type='str'),
permanent=dict(type='bool'),
permanent=dict(type='bool', default=False),
state=dict(type='str', required=True, choices=['absent', 'disabled', 'enabled', 'present']),
timeout=dict(type='int', default=0),
interface=dict(type='str'),
masquerade=dict(type='str'),
offline=dict(type='bool'),
offline=dict(type='bool', default=False),
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', '%%REJECT%%']),
),
supports_check_mode=True,
@ -761,7 +832,7 @@ def main():
source=('permanent',),
),
mutually_exclusive=[
['icmp_block', 'icmp_block_inversion', 'service', 'port', 'port_forward', 'rich_rule',
['icmp_block', 'icmp_block_inversion', 'service', 'protocol', 'port', 'port_forward', 'rich_rule',
'interface', 'masquerade', 'source', 'target']
],
)
@ -772,38 +843,50 @@ def main():
timeout = module.params['timeout']
interface = module.params['interface']
masquerade = module.params['masquerade']
offline = module.params['offline']
# Sanity checks
FirewallTransaction.sanity_check(module)
# If neither permanent or immediate is provided, assume immediate (as
# written in the module's docs)
# `offline`, `immediate`, and `permanent` have a weird twisty relationship.
if offline:
# specifying offline without permanent makes no sense
if not permanent:
module.fail_json(msg='offline cannot be enabled unless permanent changes are allowed')
# offline overrides immediate to false if firewalld is offline
if fw_offline:
immediate = False
# immediate defaults to true if permanent is not enabled
if not permanent and not immediate:
immediate = True
# Verify required params are provided
if immediate and fw_offline:
module.fail_json(msg='firewall is not currently running, unable to perform immediate actions without a running firewall daemon')
# Verify required params are provided
changed = False
msgs = []
icmp_block = module.params['icmp_block']
icmp_block_inversion = module.params['icmp_block_inversion']
service = module.params['service']
protocol = module.params['protocol']
rich_rule = module.params['rich_rule']
source = module.params['source']
zone = module.params['zone']
target = module.params['target']
port = None
if module.params['port'] is not None:
if '/' in module.params['port']:
port, protocol = module.params['port'].strip().split('/')
port, port_protocol = module.params['port'].strip().split('/')
else:
protocol = None
if not protocol:
port_protocol = None
if not port_protocol:
module.fail_json(msg='improper port format (missing protocol?)')
else:
port = None
port_protocol = None
port_forward_toaddr = ''
port_forward = None
@ -821,7 +904,7 @@ def main():
port_forward_toaddr = port_forward['toaddr']
modification = False
if any([icmp_block, icmp_block_inversion, service, port, port_forward, rich_rule,
if any([icmp_block, icmp_block_inversion, service, protocol, port, port_forward, rich_rule,
interface, masquerade, source, target]):
modification = True
if modification and desired_state in ['absent', 'present'] and target is None:
@ -846,12 +929,21 @@ def main():
msgs.append("Changed icmp-block %s to %s" % (icmp_block, desired_state))
if icmp_block_inversion is not None:
# Type of icmp_block_inversion will be changed to boolean in a future release.
icmp_block_inversion_status = True
try:
icmp_block_inversion_status = boolean(icmp_block_inversion, True)
except TypeError:
module.warn('The value of the icmp_block_inversion option is "%s". '
'The type of the option will be changed from string to boolean in a future release. '
'To avoid unexpected behavior, please change the value to boolean.' % icmp_block_inversion)
expected_state = 'enabled' if (desired_state == 'enabled') == icmp_block_inversion_status else 'disabled'
transaction = IcmpBlockInversionTransaction(
module,
action_args=(),
zone=zone,
desired_state=desired_state,
desired_state=expected_state,
permanent=permanent,
immediate=immediate,
)
@ -861,14 +953,6 @@ def main():
if changed is True:
msgs.append("Changed icmp-block-inversion %s to %s" % (icmp_block_inversion, desired_state))
# Type of icmp_block_inversion will be changed to boolean in a future release.
try:
boolean(icmp_block_inversion, True)
except TypeError:
module.warn('The value of the icmp_block_inversion option is "%s". '
'The type of the option will be changed from string to boolean in a future release. '
'To avoid unexpected behavior, please change the value to boolean.' % icmp_block_inversion)
if service is not None:
transaction = ServiceTransaction(
@ -885,6 +969,22 @@ def main():
if changed is True:
msgs.append("Changed service %s to %s" % (service, desired_state))
if protocol is not None:
transaction = ProtocolTransaction(
module,
action_args=(protocol, timeout),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate,
)
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if changed is True:
msgs.append("Changed protocol %s to %s" % (protocol, desired_state))
if source is not None:
transaction = SourceTransaction(
@ -903,7 +1003,7 @@ def main():
transaction = PortTransaction(
module,
action_args=(port, protocol, timeout),
action_args=(port, port_protocol, timeout),
zone=zone,
desired_state=desired_state,
permanent=permanent,
@ -915,7 +1015,7 @@ def main():
if changed is True:
msgs.append(
"Changed port %s to %s" % (
"%s/%s" % (port, protocol), desired_state
"%s/%s" % (port, port_protocol), desired_state
)
)
@ -973,12 +1073,21 @@ def main():
msgs = msgs + transaction_msgs
if masquerade is not None:
# Type of masquerade will be changed to boolean in a future release.
masquerade_status = True
try:
masquerade_status = boolean(masquerade, True)
except TypeError:
module.warn('The value of the masquerade option is "%s". '
'The type of the option will be changed from string to boolean in a future release. '
'To avoid unexpected behavior, please change the value to boolean.' % masquerade)
expected_state = 'enabled' if (desired_state == 'enabled') == masquerade_status else 'disabled'
transaction = MasqueradeTransaction(
module,
action_args=(),
zone=zone,
desired_state=desired_state,
desired_state=expected_state,
permanent=permanent,
immediate=immediate,
)
@ -986,14 +1095,6 @@ def main():
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
# Type of masquerade will be changed to boolean in a future release.
try:
boolean(masquerade, True)
except TypeError:
module.warn('The value of the masquerade option is "%s". '
'The type of the option will be changed from string to boolean in a future release. '
'To avoid unexpected behavior, please change the value to boolean.' % masquerade)
if target is not None:
transaction = ZoneTargetTransaction(

View file

@ -17,7 +17,7 @@ options:
active_zones:
description: Gather information about active zones.
type: bool
default: no
default: false
zones:
description:
- Gather information about specific zones.
@ -36,7 +36,12 @@ author:
EXAMPLES = r'''
- name: Gather information about active zones
ansible.posix.firewalld_info:
active_zones: yes
active_zones: true
register: result
- name: Print default zone for debugging
ansible.builtin.debug:
var: result.firewalld_info.default_zone
- name: Gather information about specific zones
ansible.posix.firewalld_info:
@ -44,6 +49,7 @@ EXAMPLES = r'''
- public
- external
- internal
register: result
'''
RETURN = r'''
@ -78,7 +84,7 @@ firewalld_info:
returned: success
type: str
sample: 0.8.2
default_zones:
default_zone:
description:
- The zone name of default zone.
returned: success
@ -204,8 +210,8 @@ firewalld_info:
'''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.six import raise_from
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
@ -317,6 +323,12 @@ def main():
)
# Exit with failure message if requirements modules are not installed.
if not HAS_DBUS and not HAS_FIREWALLD and HAS_RESPAWN_UTIL:
# Only respawn the module if both libraries are missing.
# If only one is available, then usage of the "wrong" (i.e. not the system one)
# python interpreter is likely not the problem.
respawn_module("firewall")
if not HAS_DBUS:
module.fail_json(msg=missing_required_lib('python-dbus'))
if not HAS_FIREWALLD:
@ -344,8 +356,9 @@ def main():
specified_zones = module.params['zones']
collect_zones = list(set(specified_zones) & set(all_zones))
ignore_zones = list(set(specified_zones) - set(collect_zones))
warn.append(
'Please note: zone:(%s) have been ignored in the gathering process.' % ','.join(ignore_zones))
if 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)

View file

@ -31,12 +31,12 @@ options:
src:
description:
- Device (or NFS volume, or something else) to be mounted on I(path).
- Required when I(state) set to C(present) or C(mounted).
- Required when I(state) set to C(present), C(mounted) or C(ephemeral).
type: path
fstype:
description:
- Filesystem type.
- Required when I(state) is C(present) or C(mounted).
- Required when I(state) is C(present), C(mounted) or C(ephemeral).
type: str
opts:
description:
@ -48,7 +48,7 @@ options:
- Note that if set to C(null) and I(state) set to C(present),
it will cease to work and duplicate entries will be made
with subsequent runs.
- Has no effect on Solaris systems.
- Has no effect on Solaris systems or when used with C(ephemeral).
type: str
default: '0'
passno:
@ -57,7 +57,7 @@ options:
- Note that if set to C(null) and I(state) set to C(present),
it will cease to work and duplicate entries will be made
with subsequent runs.
- Deprecated on Solaris systems.
- Deprecated on Solaris systems. Has no effect when used with C(ephemeral).
type: str
default: '0'
state:
@ -68,6 +68,13 @@ options:
- If C(unmounted), the device will be unmounted without changing I(fstab).
- C(present) only specifies that the device is to be configured in
I(fstab) and does not trigger or require a mount.
- C(ephemeral) only specifies that the device is to be mounted, without changing
I(fstab). If it is already mounted, a remount will be triggered.
This will always return changed=True. If the mount point I(path)
has already a device mounted on, and its source is different than I(src),
the module will fail to avoid unexpected unmount or mount point override.
If the mount point is not present, the mount point will be created.
The I(fstab) is completely ignored. This option is added in version 1.5.0.
- C(absent) specifies that the device mount's entry will be removed from
I(fstab) and will also unmount the device and remove the mount
point.
@ -77,10 +84,15 @@ options:
applied to the remount, but will not change I(fstab). Additionally,
if I(opts) is set, and the remount command fails, the module will
error to prevent unexpected mount changes. Try using C(mounted)
instead to work around this issue.
instead to work around this issue. C(remounted) expects the mount point
to be present in the I(fstab). To remount a mount point not registered
in I(fstab), use C(ephemeral) instead, especially with BSD nodes.
- C(absent_from_fstab) specifies that the device mount's entry will be
removed from I(fstab). This option does not unmount it or delete the
mountpoint.
type: str
required: true
choices: [ absent, mounted, present, unmounted, remounted ]
choices: [ absent, absent_from_fstab, mounted, present, unmounted, remounted, ephemeral ]
fstab:
description:
- File to use instead of C(/etc/fstab).
@ -89,6 +101,7 @@ options:
- OpenBSD does not allow specifying alternate fstab files with mount so do not
use this on OpenBSD with any state that operates on the live filesystem.
- This parameter defaults to /etc/fstab or /etc/vfstab on Solaris.
- This parameter is ignored when I(state) is set to C(ephemeral).
type: str
boot:
description:
@ -100,14 +113,15 @@ options:
to mount options in I(/etc/fstab).
- To avoid mount option conflicts, if C(noauto) specified in C(opts),
mount module will ignore C(boot).
- This parameter is ignored when I(state) is set to C(ephemeral).
type: bool
default: yes
default: true
backup:
description:
- Create a backup file including the timestamp information so you can get
the original file back if you somehow clobbered it incorrectly.
type: bool
default: no
default: false
notes:
- As of Ansible 2.3, the I(name) option has been changed to I(path) as
default, but I(name) still works as well.
@ -181,9 +195,17 @@ EXAMPLES = r'''
src: 192.168.1.100:/nfs/ssd/shared_data
path: /mnt/shared_data
opts: rw,sync,hard
boot: no
boot: false
state: mounted
fstype: nfs
- name: Mount ephemeral SMB volume
ansible.posix.mount:
src: //192.168.1.200/share
path: /mnt/smb_share
opts: "rw,vers=3,file_mode=0600,dir_mode=0700,dom={{ ad_domain }},username={{ ad_username }},password={{ ad_password }}"
fstype: cifs
state: ephemeral
'''
import errno
@ -226,7 +248,7 @@ def _escape_fstab(v):
if isinstance(v, int):
return v
else:
return(
return (
v.
replace('\\', '\\134').
replace(' ', '\\040').
@ -430,6 +452,24 @@ def _set_fstab_args(fstab_file):
return result
def _set_ephemeral_args(args):
result = []
# Set fstype switch according to platform. SunOS/Solaris use -F
if platform.system().lower() == 'sunos':
result.append('-F')
else:
result.append('-t')
result.append(args['fstype'])
# Even if '-o remount' is already set, specifying multiple -o is valid
if args['opts'] != 'defaults':
result += ['-o', args['opts']]
result.append(args['src'])
return result
def mount(module, args):
"""Mount up a path or remount if needed."""
@ -446,7 +486,11 @@ def mount(module, args):
'OpenBSD does not support alternate fstab files. Do not '
'specify the fstab parameter for OpenBSD hosts'))
else:
cmd += _set_fstab_args(args['fstab'])
if module.params['state'] != 'ephemeral':
cmd += _set_fstab_args(args['fstab'])
if module.params['state'] == 'ephemeral':
cmd += _set_ephemeral_args(args)
cmd += [name]
@ -498,18 +542,24 @@ def remount(module, args):
'OpenBSD does not support alternate fstab files. Do not '
'specify the fstab parameter for OpenBSD hosts'))
else:
cmd += _set_fstab_args(args['fstab'])
if module.params['state'] != 'ephemeral':
cmd += _set_fstab_args(args['fstab'])
if module.params['state'] == 'ephemeral':
cmd += _set_ephemeral_args(args)
cmd += [args['name']]
out = err = ''
try:
if platform.system().lower().endswith('bsd'):
if module.params['state'] != 'ephemeral' and platform.system().lower().endswith('bsd'):
# Note: Forcing BSDs to do umount/mount due to BSD remount not
# working as expected (suspect bug in the BSD mount command)
# Interested contributor could rework this to use mount options on
# the CLI instead of relying on fstab
# https://github.com/ansible/ansible-modules-core/issues/5591
# Note: this does not affect ephemeral state as all options
# are set on the CLI and fstab is expected to be ignored.
rc = 1
else:
rc, out, err = module.run_command(cmd)
@ -663,6 +713,47 @@ def get_linux_mounts(module, mntinfo_file="/proc/self/mountinfo"):
return mounts
def _is_same_mount_src(module, src, mountpoint, linux_mounts):
"""Return True if the mounted fs on mountpoint is the same source than src. Return False if mountpoint is not a mountpoint"""
# If the provided mountpoint is not a mountpoint, don't waste time
if (
not ismount(mountpoint) and
not is_bind_mounted(module, linux_mounts, mountpoint)):
return False
# Treat Linux bind mounts
if platform.system() == 'Linux' and linux_mounts is not None:
# For Linux bind mounts only: the mount command does not return
# the actual source for bind mounts, but the device of the source.
# is_bind_mounted() called with the 'src' parameter will return True if
# the mountpoint is a bind mount AND the source FS is the same than 'src'.
# is_bind_mounted() is not reliable on Solaris, NetBSD and OpenBSD.
# But we can rely on 'mount -v' on all other platforms, and Linux non-bind mounts.
if is_bind_mounted(module, linux_mounts, mountpoint, src):
return True
# mount with parameter -v has a close behavior on Linux, *BSD, SunOS
# Requires -v with SunOS. Without -v, source and destination are reversed
# Output format differs from a system to another, but field[0:3] are consistent: [src, 'on', dest]
cmd = '%s -v' % module.get_bin_path('mount', required=True)
rc, out, err = module.run_command(cmd)
mounts = []
if len(out):
mounts = to_native(out).strip().split('\n')
else:
module.fail_json(msg="Unable to retrieve mount info with command '%s'" % cmd)
for mnt in mounts:
fields = mnt.split()
mp_src = fields[0]
mp_dst = fields[2]
if mp_src == src and mp_dst == mountpoint:
return True
return False
def main():
module = AnsibleModule(
argument_spec=dict(
@ -675,12 +766,13 @@ def main():
passno=dict(type='str', no_log=False, default='0'),
src=dict(type='path'),
backup=dict(type='bool', default=False),
state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted']),
state=dict(type='str', required=True, choices=['absent', 'absent_from_fstab', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']),
),
supports_check_mode=True,
required_if=(
['state', 'mounted', ['src', 'fstype']],
['state', 'present', ['src', 'fstype']],
['state', 'ephemeral', ['src', 'fstype']]
),
)
@ -739,7 +831,7 @@ def main():
# handle mount on boot. To avoid mount option conflicts, if 'noauto'
# specified in 'opts', mount module will ignore 'boot'.
opts = args['opts'].split(',')
if 'noauto' in opts:
if module.params['boot'] and 'noauto' in opts:
args['warnings'].append("Ignore the 'boot' due to 'opts' contains 'noauto'.")
elif not module.params['boot']:
args['boot'] = 'no'
@ -748,15 +840,17 @@ def main():
# If fstab file does not exist, we first need to create it. This mainly
# happens when fstab option is passed to the module.
if not os.path.exists(args['fstab']):
if not os.path.exists(os.path.dirname(args['fstab'])):
os.makedirs(os.path.dirname(args['fstab']))
try:
open(args['fstab'], 'a').close()
except PermissionError as e:
module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab'])
except Exception as e:
module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e)))
# If state is 'ephemeral', we do not need fstab file
if module.params['state'] != 'ephemeral':
if not os.path.exists(args['fstab']):
if not os.path.exists(os.path.dirname(args['fstab'])):
os.makedirs(os.path.dirname(args['fstab']))
try:
open(args['fstab'], 'a').close()
except PermissionError as e:
module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab'])
except Exception as e:
module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e)))
# absent:
# Remove from fstab and unmounted.
@ -767,12 +861,16 @@ def main():
# mounted:
# Add to fstab if not there and make sure it is mounted. If it has
# changed in fstab then remount it.
# ephemeral:
# Do not change fstab state, but mount.
state = module.params['state']
name = module.params['path']
changed = False
if state == 'absent':
if state == 'absent_from_fstab':
name, changed = unset_mount(module, args)
elif state == 'absent':
name, changed = unset_mount(module, args)
if changed and not module.check_mode:
@ -798,7 +896,7 @@ def main():
msg="Error unmounting %s: %s" % (name, msg))
changed = True
elif state == 'mounted':
elif state == 'mounted' or state == 'ephemeral':
dirs_created = []
if not os.path.exists(name) and not module.check_mode:
try:
@ -826,7 +924,11 @@ def main():
module.fail_json(
msg="Error making dir %s: %s" % (name, to_native(e)))
name, backup_lines, changed = _set_mount_save_old(module, args)
# ephemeral: completely ignore fstab
if state != 'ephemeral':
name, backup_lines, changed = _set_mount_save_old(module, args)
else:
name, backup_lines, changed = args['name'], [], False
res = 0
if (
@ -836,7 +938,26 @@ def main():
if changed and not module.check_mode:
res, msg = remount(module, args)
changed = True
# When 'state' == 'ephemeral', we don't know what is in fstab, and 'changed' is always False
if state == 'ephemeral':
# If state == 'ephemeral', check if the mountpoint src == module.params['src']
# If it doesn't, fail to prevent unwanted unmount or unwanted mountpoint override
if _is_same_mount_src(module, args['src'], args['name'], linux_mounts):
changed = True
if not module.check_mode:
res, msg = remount(module, args)
else:
module.fail_json(
msg=(
'Ephemeral mount point is already mounted with a different '
'source than the specified one. Failing in order to prevent an '
'unwanted unmount or override operation. Try replacing this command with '
'a "state: unmounted" followed by a "state: ephemeral", or use '
'a different destination path.'))
else:
# If not already mounted, mount it
changed = True
if not module.check_mode:
@ -848,7 +969,8 @@ def main():
# A non-working fstab entry may break the system at the reboot,
# so undo all the changes if possible.
try:
write_fstab(module, backup_lines, args['fstab'])
if state != 'ephemeral':
write_fstab(module, backup_lines, args['fstab'])
except Exception:
pass

View file

@ -37,7 +37,7 @@ options:
src:
description:
- Path of the patch file as accepted by the GNU patch tool. If
C(remote_src) is 'no', the patch source file is looked up from the
C(remote_src) is C(false), the patch source file is looked up from the
module's I(files) directory.
type: path
required: true
@ -50,10 +50,10 @@ options:
default: present
remote_src:
description:
- If C(no), it will search for src at originating/controller machine, if C(yes) it will
- If C(false), it will search for src at originating/controller machine, if C(true) it will
go to the remote/target machine for the C(src).
type: bool
default: no
default: false
strip:
description:
- Number that indicates the smallest prefix containing leading slashes
@ -65,20 +65,20 @@ options:
description:
- Passes C(--backup --version-control=numbered) to patch, producing numbered backup copies.
type: bool
default: no
default: false
binary:
description:
- Setting to C(yes) will disable patch's heuristic for transforming CRLF
- Setting to C(true) will disable patch's heuristic for transforming CRLF
line endings into LF.
- Line endings of src and dest must match.
- If set to C(no), C(patch) will replace CRLF in C(src) files on POSIX.
- If set to C(false), C(patch) will replace CRLF in C(src) files on POSIX.
type: bool
default: no
default: false
ignore_whitespace:
description:
- Setting to C(yes) will ignore white space changes between patch and input..
- Setting to C(true) will ignore white space changes between patch and input.
type: bool
default: no
default: false
notes:
- This module requires GNU I(patch) utility to be installed on the remote host.
'''

View file

@ -0,0 +1,76 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: Red Hat Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: rhel_facts
version_added: 1.5.0
short_description: Facts module to set or override RHEL specific facts.
description:
- Compatibility layer for using the "package" module for rpm-ostree based systems via setting the "pkg_mgr" fact correctly.
author:
- Adam Miller (@maxamillion)
requirements:
- rpm-ostree
seealso:
- module: ansible.builtin.package
options: {}
'''
EXAMPLES = '''
- name: Playbook to use the package module on all RHEL footprints
vars:
ansible_facts_modules:
- setup # REQUIRED to be run before all custom fact modules
- ansible.posix.rhel_facts
tasks:
- name: Ensure packages are installed
ansible.builtin.package:
name:
- htop
- ansible
state: present
'''
RETURN = """
ansible_facts:
description: Relevant Ansible Facts
returned: when needed
type: complex
contains:
pkg_mgr:
description: System-level package manager override
returned: when needed
type: str
sample: {'pkg_mgr': 'ansible.posix.rhel_facts'}
"""
import os
from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec=dict(),
supports_check_mode=True,
)
ansible_facts = {}
# Verify that the platform is an rpm-ostree based system
if os.path.exists("/run/ostree-booted"):
ansible_facts['pkg_mgr'] = 'ansible.posix.rhel_rpm_ostree'
module.exit_json(ansible_facts=ansible_facts, changed=False)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,124 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: Red Hat Inc.
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: rhel_rpm_ostree
version_added: 1.5.0
short_description: Ensure packages exist in a RHEL for Edge rpm-ostree based system
description:
- Compatibility layer for using the "package" module for RHEL for Edge systems utilizing the RHEL System Roles.
author:
- Adam Miller (@maxamillion)
requirements:
- rpm-ostree
options:
name:
description:
- A package name or package specifier with version, like C(name-1.0).
- Comparison operators for package version are valid here C(>), C(<), C(>=), C(<=). Example - C(name>=1.0)
- If a previous version is specified, the task also needs to turn C(allow_downgrade) on.
See the C(allow_downgrade) documentation for caveats with downgrading packages.
- When using state=latest, this can be C('*') which means run C(yum -y update).
- You can also pass a url or a local path to a rpm file (using state=present).
To operate on several packages this can accept a comma separated string of packages or (as of 2.0) a list of packages.
aliases: [ pkg ]
type: list
elements: str
default: []
state:
description:
- Whether to install (C(present) or C(installed), C(latest)), or remove (C(absent) or C(removed)) a package.
- C(present) and C(installed) will simply ensure that a desired package is installed.
- C(latest) will update the specified package if it's not of the latest available version.
- C(absent) and C(removed) will remove the specified package.
- Default is C(None), however in effect the default action is C(present) unless the C(autoremove) option is
enabled for this module, then C(absent) is inferred.
type: str
choices: [ absent, installed, latest, present, removed ]
notes:
- This module does not support installing or removing packages to/from an overlay as this is not supported
by RHEL for Edge, packages needed should be defined in the osbuild Blueprint and provided to Image Builder
at build time. This module exists only for C(package) module compatibility.
'''
EXAMPLES = '''
- name: Ensure htop and ansible are installed on rpm-ostree based RHEL
ansible.posix.rhel_rpm_ostree:
name:
- htop
- ansible
state: present
'''
RETURN = """
msg:
description: status of rpm transaction
returned: always
type: str
sample: "No changes made."
"""
import os
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_text
def locally_installed(module, pkgname):
(rc, out, err) = module.run_command('{0} -q {1}'.format(module.get_bin_path("rpm"), pkgname).split())
return (rc == 0)
def rpm_ostree_transaction(module):
pkgs = []
if module.params['state'] in ['present', 'installed', 'latest']:
for pkg in module.params['name']:
if not locally_installed(module, pkg):
pkgs.append(pkg)
elif module.params['state'] in ['absent', 'removed']:
for pkg in module.params['name']:
if locally_installed(module, pkg):
pkgs.append(pkg)
if not pkgs:
module.exit_json(msg="No changes made.")
else:
if module.params['state'] in ['present', 'installed', 'latest']:
module.fail_json(msg="The following packages are absent in the currently booted rpm-ostree commit: %s" ' '.join(pkgs))
else:
module.fail_json(msg="The following packages are present in the currently booted rpm-ostree commit: %s" ' '.join(pkgs))
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='list', elements='str', aliases=['pkg'], default=[]),
state=dict(type='str', default=None, choices=['absent', 'installed', 'latest', 'present', 'removed']),
),
)
# Verify that the platform is an rpm-ostree based system
if not os.path.exists("/run/ostree-booted"):
module.fail_json(msg="Module rpm_ostree is only applicable for rpm-ostree based systems.")
try:
rpm_ostree_transaction(module)
except Exception as e:
module.fail_json(msg=to_text(e), exception=traceback.format_exc())
if __name__ == '__main__':
main()

View file

@ -0,0 +1,125 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: Red Hat Inc.
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: rpm_ostree_upgrade
short_description: Manage rpm-ostree upgrade transactions
description:
- Manage an rpm-ostree upgrade transactions.
version_added: 1.5.0
author:
- Adam Miller (@maxamillion)
requirements:
- rpm-ostree
options:
os:
description:
- The OSNAME upon which to operate.
type: str
default: ""
required: false
cache_only:
description:
- Perform the transaction using only pre-cached data, do not download.
type: bool
default: false
required: false
allow_downgrade:
description:
- Allow for the upgrade to be a chronologically older tree.
type: bool
default: false
required: false
peer:
description:
- Force peer-to-peer connection instead of using a system message bus.
type: bool
default: false
required: false
'''
EXAMPLES = '''
- name: Upgrade the rpm-ostree image without options, accept all defaults
ansible.posix.rpm_ostree_upgrade:
- name: Upgrade the rpm-ostree image allowing downgrades
ansible.posix.rpm_ostree_upgrade:
allow_downgrade: true
'''
RETURN = '''
msg:
description: The command standard output
returned: always
type: str
sample: 'No upgrade available.'
'''
import os
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native, to_text
def rpm_ostree_transaction(module):
cmd = []
cmd.append(module.get_bin_path("rpm-ostree"))
cmd.append('upgrade')
if module.params['os']:
cmd += ['--os', module.params['os']]
if module.params['cache_only']:
cmd += ['--cache-only']
if module.params['allow_downgrade']:
cmd += ['--allow-downgrade']
if module.params['peer']:
cmd += ['--peer']
module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
rc, out, err = module.run_command(cmd)
if rc != 0:
module.fail_json(rc=rc, msg=err)
else:
if to_text("No upgrade available.") in to_text(out):
module.exit_json(msg=out, changed=False)
else:
module.exit_json(msg=out, changed=True)
def main():
module = AnsibleModule(
argument_spec=dict(
os=dict(type='str', default=''),
cache_only=dict(type='bool', default=False),
allow_downgrade=dict(type='bool', default=False),
peer=dict(type='bool', default=False),
),
)
# Verify that the platform is an rpm-ostree based system
if not os.path.exists("/run/ostree-booted"):
module.fail_json(msg="Module rpm_ostree_upgrade is only applicable for rpm-ostree based systems.")
try:
rpm_ostree_transaction(module)
except Exception as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
if __name__ == '__main__':
main()

View file

@ -22,9 +22,9 @@ options:
type: str
persistent:
description:
- Set to C(yes) if the boolean setting should survive a reboot.
- Set to C(true) if the boolean setting should survive a reboot.
type: bool
default: 'no'
default: false
state:
description:
- Desired boolean value
@ -49,8 +49,8 @@ EXAMPLES = r'''
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots
ansible.posix.seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
state: true
persistent: true
'''
import os
@ -75,6 +75,7 @@ except ImportError:
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.six import binary_type
from ansible.module_utils._text import to_bytes, to_text
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
def get_runtime_status(ignore_selinux_state=False):
@ -281,6 +282,12 @@ def main():
supports_check_mode=True,
)
if not HAVE_SELINUX and not HAVE_SEMANAGE and HAS_RESPAWN_UTIL:
# Only respawn the module if both libraries are missing.
# If only one is available, then usage of the "wrong" (i.e. not the system one)
# python interpreter is likely not the problem.
respawn_module("selinux")
if not HAVE_SELINUX:
module.fail_json(msg=missing_required_lib('libselinux-python'), exception=SELINUX_IMP_ERR)

View file

@ -32,7 +32,7 @@ options:
description:
- If set to I(true), will update also the kernel boot parameters when disabling/enabling SELinux.
- The C(grubby) tool must be present on the target system for this to work.
default: no
default: false
type: bool
version_added: '1.4.0'
configfile:
@ -107,6 +107,8 @@ from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.facts.utils import get_file_lines
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
# getter subroutines
def get_config_state(configfile):
@ -236,6 +238,8 @@ def main():
)
if not HAS_SELINUX:
if HAS_RESPAWN_UTIL:
respawn_module("selinux")
module.fail_json(msg=missing_required_lib('libselinux-python'), exception=SELINUX_IMP_ERR)
# global vars

View file

@ -26,13 +26,13 @@ options:
description:
- Path on the source host that will be synchronized to the destination.
- The path can be absolute or relative.
type: str
type: path
required: true
dest:
description:
- Path on the destination host that will be synchronized from the source.
- The path can be absolute or relative.
type: str
type: path
required: true
dest_port:
description:
@ -53,36 +53,36 @@ options:
description:
- Mirrors the rsync archive flag, enables recursive, links, perms, times, owner, group flags and -D.
type: bool
default: yes
default: true
checksum:
description:
- Skip based on checksum, rather than mod-time & size; Note that that "archive" option is still enabled by default - the "checksum" option will
not disable it.
type: bool
default: no
default: false
compress:
description:
- Compress file data during the transfer.
- In most cases, leave this enabled unless it causes problems.
type: bool
default: yes
default: true
existing_only:
description:
- Skip creating new files on receiver.
type: bool
default: no
default: false
delete:
description:
- Delete files in I(dest) that do not exist (after transfer, not before) in the I(src) path.
- This option requires I(recursive=yes).
- This option requires I(recursive=true).
- This option ignores excluded files and behaves like the rsync opt C(--delete-after).
type: bool
default: no
default: false
dirs:
description:
- Transfer directories without recursing.
type: bool
default: no
default: false
recursive:
description:
- Recurse into directories.
@ -97,7 +97,7 @@ options:
description:
- Copy symlinks as the item that they point to (the referent) is copied, rather than the symlink.
type: bool
default: no
default: false
perms:
description:
- Preserve permissions.
@ -132,43 +132,36 @@ options:
description:
- Put user@ for the remote paths.
- If you have a custom ssh config to define the remote user for a host
that does not match the inventory user, you should set this parameter to C(no).
that does not match the inventory user, you should set this parameter to C(false).
type: bool
default: yes
use_ssh_args:
description:
- In Ansible 2.10 and lower, it uses the ssh_args specified in C(ansible.cfg).
- In Ansible 2.11 and onwards, when set to C(true), it uses all SSH connection configurations like
C(ansible_ssh_args), C(ansible_ssh_common_args), and C(ansible_ssh_extra_args).
type: bool
default: no
default: true
ssh_connection_multiplexing:
description:
- SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections.
This is accomplished by setting the SSH C(ControlSocket) to C(none).
- Set this option to C(yes) to allow multiplexing and reduce SSH connection overhead.
- Note that simply setting this option to C(yes) is not enough;
- Set this option to C(true) to allow multiplexing and reduce SSH connection overhead.
- Note that simply setting this option to C(true) is not enough;
You must also configure SSH connection multiplexing in your SSH client config by setting values for
C(ControlMaster), C(ControlPersist) and C(ControlPath).
type: bool
default: no
default: false
rsync_opts:
description:
- Specify additional rsync options by passing in an array.
- Note that an empty string in C(rsync_opts) will end up transfer the current working directory.
type: list
default:
default: []
elements: str
partial:
description:
- Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.
type: bool
default: no
default: false
verify_host:
description:
- Verify destination host key.
type: bool
default: no
default: false
private_key:
description:
- Specify the private key to use for SSH-based rsync connections (e.g. C(~/.ssh/id_rsa)).
@ -178,14 +171,38 @@ options:
- Add a destination to hard link against during the rsync.
type: list
default:
elements: str
elements: path
delay_updates:
description:
- This option puts the temporary file from each updated file into a holding directory until the end of the transfer,
at which time all the files are renamed into place in rapid succession.
type: bool
default: yes
default: true
version_added: '1.3.0'
use_ssh_args:
description:
- In Ansible 2.10 and lower, it uses the ssh_args specified in C(ansible.cfg).
- In Ansible 2.11 and onwards, when set to C(true), it uses all SSH connection configurations like
C(ansible_ssh_args), C(ansible_ssh_common_args), and C(ansible_ssh_extra_args).
type: bool
default: false
_local_rsync_path:
description: Internal use only.
type: path
default: 'rsync'
required: false
_local_rsync_password:
description: Internal use only, never logged.
type: str
required: false
_substitute_controller:
description: Internal use only.
type: bool
default: false
_ssh_args:
description: Internal use only. See C(use_ssh_args) for ssh arg settings.
type: str
required: false
notes:
- rsync must be installed on both the local and remote host.
@ -212,7 +229,7 @@ notes:
- link_destination is subject to the same limitations as the underlying rsync daemon. Hard links are only preserved if the relative subtrees
of the source and destination are the same. Attempts to hardlink into a directory that is a subdirectory of the source will be prevented.
seealso:
- module: copy
- module: ansible.builtin.copy
- module: community.windows.win_robocopy
author:
- Timothy Appnel (@tima)
@ -235,7 +252,7 @@ EXAMPLES = r'''
src: rsync://somehost.com/path/
dest: /some/absolute/path/
- name: Synchronization using rsync protocol on delegate host (push)
- name: Synchronization using rsync protocol on delegate host (push)
ansible.posix.synchronize:
src: /some/absolute/path/
dest: rsync://somehost.com/path/
@ -252,27 +269,27 @@ EXAMPLES = r'''
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
archive: no
archive: false
- name: Synchronization with --archive options enabled except for --recursive
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
recursive: no
recursive: false
- name: Synchronization with --archive options enabled except for --times, with --checksum option enabled
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
checksum: yes
times: no
checksum: true
times: false
- name: Synchronization without --archive options enabled except use --links
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
archive: no
links: yes
archive: false
links: true
- name: Synchronization of two paths both on the control machine
ansible.posix.synchronize:
@ -302,8 +319,8 @@ EXAMPLES = r'''
ansible.posix.synchronize:
src: some/relative/path
dest: /some/absolute/path
delete: yes
recursive: yes
delete: true
recursive: true
# This specific command is granted su privileges on the destination
- name: Synchronize using an alternate rsync command
@ -362,11 +379,11 @@ def substitute_controller(path):
if not client_addr:
ssh_env_string = os.environ.get('SSH_CLIENT', None)
try:
client_addr, _ = ssh_env_string.split(None, 1)
client_addr, _ = ssh_env_string.split(None, 1) # pylint: disable=disallowed-name
except AttributeError:
ssh_env_string = os.environ.get('SSH_CONNECTION', None)
try:
client_addr, _ = ssh_env_string.split(None, 1)
client_addr, _ = ssh_env_string.split(None, 1) # pylint: disable=disallowed-name
except AttributeError:
pass
if not client_addr:
@ -388,8 +405,8 @@ def is_rsh_needed(source, dest):
def main():
module = AnsibleModule(
argument_spec=dict(
src=dict(type='str', required=True),
dest=dict(type='str', required=True),
src=dict(type='path', required=True),
dest=dict(type='path', required=True),
dest_port=dict(type='int'),
delete=dict(type='bool', default=False),
private_key=dict(type='path'),
@ -412,13 +429,14 @@ def main():
set_remote_user=dict(type='bool', default=True),
rsync_timeout=dict(type='int', default=0),
rsync_opts=dict(type='list', default=[], elements='str'),
ssh_args=dict(type='str'),
_ssh_args=dict(type='str'),
use_ssh_args=dict(type='bool', default=False),
ssh_connection_multiplexing=dict(type='bool', default=False),
partial=dict(type='bool', default=False),
verify_host=dict(type='bool', default=False),
delay_updates=dict(type='bool', default=True),
mode=dict(type='str', default='push', choices=['pull', 'push']),
link_dest=dict(type='list', elements='str'),
link_dest=dict(type='list', elements='path'),
),
supports_check_mode=True,
)
@ -454,7 +472,7 @@ def main():
owner = module.params['owner']
group = module.params['group']
rsync_opts = module.params['rsync_opts']
ssh_args = module.params['ssh_args']
ssh_args = module.params['_ssh_args']
ssh_connection_multiplexing = module.params['ssh_connection_multiplexing']
verify_host = module.params['verify_host']
link_dest = module.params['link_dest']
@ -572,7 +590,7 @@ def main():
# hardlink is actually a change
cmd.append('-vv')
for x in link_dest:
link_path = os.path.abspath(os.path.expanduser(x))
link_path = os.path.abspath(x)
destination_path = os.path.abspath(os.path.dirname(dest))
if destination_path.find(link_path) == 0:
module.fail_json(msg='Hardlinking into a subdirectory of the source would cause recursion. %s and %s' % (destination_path, dest))
@ -581,12 +599,6 @@ def main():
changed_marker = '<<CHANGED>>'
cmd.append('--out-format=%s' % shlex_quote(changed_marker + '%i %n%L'))
# expand the paths
if '@' not in source:
source = os.path.expanduser(source)
if '@' not in dest:
dest = os.path.expanduser(dest)
cmd.append(shlex_quote(source))
cmd.append(shlex_quote(dest))
cmdstr = ' '.join(cmd)

View file

@ -38,14 +38,14 @@ options:
description:
- Use this option to ignore errors about unknown keys.
type: bool
default: 'no'
default: false
reload:
description:
- If C(yes), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is
updated. If C(no), does not reload I(sysctl) even if the
- If C(true), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is
updated. If C(false), does not reload I(sysctl) even if the
C(sysctl_file) is updated.
type: bool
default: 'yes'
default: true
sysctl_file:
description:
- Specifies the absolute path to C(sysctl.conf), if not C(/etc/sysctl.conf).
@ -53,9 +53,9 @@ options:
type: path
sysctl_set:
description:
- Verify token value with the sysctl command and set with -w if necessary
- Verify token value with the sysctl command and set with -w if necessary.
type: bool
default: 'no'
default: false
author:
- David CHANIAL (@davixx)
'''
@ -78,21 +78,21 @@ EXAMPLES = r'''
name: kernel.panic
value: '3'
sysctl_file: /tmp/test_sysctl.conf
reload: no
reload: false
# Set ip forwarding on in /proc and verify token value with the sysctl command
- ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: yes
sysctl_set: true
# Set ip forwarding on in /proc and in the sysctl file and reload if necessary
- ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1'
sysctl_set: yes
sysctl_set: true
state: present
reload: yes
reload: true
'''
# ==============================================================

View file

@ -1,3 +1,4 @@
---
language: python
env:
@ -15,14 +16,14 @@ matrix:
- env: T=2.9/freebsd/12.0/1
- env: T=2.9/linux/centos6/1
- env: T=2.9/linux/centos7/1
# - env: T=2.9/linux/centos8/1
# - env: T=2.9/linux/centos8/1
- env: T=2.9/linux/fedora30/1
- env: T=2.9/linux/fedora31/1
- env: T=2.9/linux/opensuse15py2/1
- env: T=2.9/linux/opensuse15/1
- env: T=2.9/linux/ubuntu1604/1
- env: T=2.9/linux/ubuntu1804/1
# - env: T=2.10/aix/7.2/1
# - env: T=2.10/aix/7.2/1
- env: T=2.10/osx/10.11/1
- env: T=2.10/rhel/7.6/1
- env: T=2.10/rhel/8.2/1
@ -30,14 +31,14 @@ matrix:
- env: T=2.10/freebsd/12.1/1
- env: T=2.10/linux/centos6/1
- env: T=2.10/linux/centos7/1
# - env: T=2.10/linux/centos8/1
# - env: T=2.10/linux/centos8/1
- env: T=2.10/linux/fedora30/1
- env: T=2.10/linux/fedora31/1
- env: T=2.10/linux/opensuse15py2/1
- env: T=2.10/linux/opensuse15/1
- env: T=2.10/linux/ubuntu1604/1
- env: T=2.10/linux/ubuntu1804/1
# - env: T=devel/aix/7.2/1
# - env: T=devel/aix/7.2/1
- env: T=devel/osx/10.11/1
- env: T=devel/rhel/7.6/1
- env: T=devel/rhel/8.1/1
@ -45,7 +46,7 @@ matrix:
- env: T=devel/freebsd/12.1/1
- env: T=devel/linux/centos6/1
- env: T=devel/linux/centos7/1
# - env: T=devel/linux/centos8/1
# - env: T=devel/linux/centos8/1
- env: T=devel/linux/fedora30/1
- env: T=devel/linux/fedora31/1
- env: T=devel/linux/opensuse15py2/1
@ -56,7 +57,7 @@ matrix:
branches:
except:
- "*-patch-*"
- "revert-*-*"
- revert-*-*
build:
ci:

View file

@ -0,0 +1,3 @@
---
collections:
- community.general

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
# This file is part of Ansible
@ -16,35 +17,38 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: Create ansible user
user:
ansible.builtin.user:
name: "{{ test_user }}"
- name: Create ansible group
group:
ansible.builtin.group:
name: "{{ test_group }}"
- name: Clean up working directory and files
file:
ansible.builtin.file:
path: "{{ output_dir }}"
state: absent
- name: Create working directory
file:
ansible.builtin.file:
path: "{{ output_dir }}"
state: directory
mode: "0755"
- name: Create ansible file
file:
ansible.builtin.file:
path: "{{ test_file }}"
state: touch
mode: "0644"
- name: Create ansible dir
file:
ansible.builtin.file:
path: "{{ test_dir }}"
state: directory
mode: "0755"
##############################################################################
- name: Grant ansible user read access to a file
acl:
ansible.posix.acl:
path: "{{ test_file }}"
entity: "{{ test_user }}"
etype: user
@ -52,12 +56,21 @@
state: present
register: output
- name: get getfacl output
shell: "getfacl {{ test_file | quote }}"
- name: Debug ansible.posix.acl output
ansible.builtin.debug:
msg: "{{ output }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_file | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Debug getfacl output
ansible.builtin.debug:
msg: "{{ getfacl_output.stdout_lines }}"
- name: Verify Output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
@ -65,16 +78,25 @@
- "'user:{{ test_user }}:r--' in getfacl_output.stdout_lines"
##############################################################################
- name: Obtain the acl for a specific file
acl:
ansible.posix.acl:
path: "{{ test_file }}"
register: output
- name: get getfacl output
shell: "getfacl {{ test_file | quote }}"
- name: Debug ansible.posix.acl output
ansible.builtin.debug:
msg: "{{ output }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_file | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Debug getfacl output
ansible.builtin.debug:
msg: "{{ getfacl_output.stdout_lines }}"
- name: Verify output
ansible.builtin.assert:
that:
- output is not changed
- output is not failed
@ -89,20 +111,22 @@
- "'mask::r--' in getfacl_output.stdout_lines"
- "'other::r--' in getfacl_output.stdout_lines"
##############################################################################
#
- name: Removes the acl for ansible user on a specific file
acl:
ansible.posix.acl:
path: "{{ test_file }}"
entity: "{{ test_user }}"
etype: user
state: absent
register: output
- name: get getfacl output
shell: "getfacl {{ test_file | quote }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_file | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Verify output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
@ -110,21 +134,22 @@
- "'user:{{ test_user }}:r--' not in getfacl_output.stdout_lines"
##############################################################################
- name: Sets default acl for ansible user on ansible dir
acl:
ansible.posix.acl:
path: "{{ test_dir }}"
entity: "{{ test_user }}"
etype: user
permissions: rw
default: yes
default: true
state: present
register: output
- name: get getfacl output
shell: "getfacl {{ test_dir | quote }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_dir | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Verify output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
@ -132,22 +157,24 @@
- "'default:user:{{ test_user }}:rw-' in getfacl_output.stdout_lines"
##############################################################################
- name: Cleanup
shell: "setfacl -b {{ test_dir | quote }}"
ansible.builtin.command: setfacl -b {{ test_dir | quote }}
changed_when: false
##############################################################################
- name: Same as previous but using entry shorthand
acl:
ansible.posix.acl:
path: "{{ test_dir }}"
entry: "user:{{ test_user }}:rw-"
default: yes
entry: user:{{ test_user }}:rw-
default: true
state: present
register: output
- name: get getfacl output
shell: "getfacl {{ test_dir | quote }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_dir | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Verify output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
@ -155,19 +182,20 @@
- "'default:user:{{ test_user }}:rw-' in getfacl_output.stdout_lines"
##############################################################################
- name: Same as previous, to test idempotence
acl:
ansible.posix.acl:
path: "{{ test_dir }}"
entry: "user:{{ test_user }}:rw-"
default: yes
entry: user:{{ test_user }}:rw-
default: true
state: present
register: output
- name: get getfacl output
shell: "getfacl {{ test_dir | quote }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_dir | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Verify output
ansible.builtin.assert:
that:
- output is not changed
- output is not failed
@ -175,32 +203,34 @@
- "'default:user:{{ test_user }}:rw-' in getfacl_output.stdout_lines"
##############################################################################
- name: Cleanup
shell: "setfacl -b {{ test_dir | quote }}"
ansible.builtin.command: setfacl -b {{ test_dir | quote }}
changed_when: false
##############################################################################
- name: Set default acls
acl:
ansible.posix.acl:
path: "{{ test_dir }}"
entry: "{{ item }}"
default: yes
default: true
state: present
with_items:
- "user:{{ test_user }}:rw-"
- "group:{{ test_group }}:rw-"
- user:{{ test_user }}:rw-
- group:{{ test_group }}:rw-
- name: Remove default group test_user acl
acl:
ansible.posix.acl:
path: "{{ test_dir }}"
entry: "group:{{ test_group }}:rw-"
default: yes
entry: group:{{ test_group }}:rw-
default: true
state: absent
register: output
- name: get getfacl output
shell: "getfacl {{ test_dir | quote }}"
- name: Get getfacl output
ansible.builtin.command: getfacl {{ test_dir | quote }}
changed_when: false
register: getfacl_output
- name: verify output
assert:
- name: Verify output
ansible.builtin.assert:
that:
- output is changed
- output is not failed

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
# This file is part of Ansible
@ -15,22 +16,21 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- block:
- include: acl.yml
when: ansible_system == 'Linux' # TODO enable acls mount option on FreeBSD to test it there too
always:
- name: delete created directory and file
file:
path: '{{ item }}'
state: absent
with_items:
- '{{ test_dir }}'
- '{{ test_file }}'
- name: Test ACL
vars:
test_user: ansible_user
test_group: ansible_group
test_file: '{{ output_dir }}/ansible file'
test_file: "{{ output_dir }}/ansible file"
test_dir: "{{ output_dir }}/ansible_dir/with some space"
block:
- name: Include tests task file
ansible.builtin.include_tasks: acl.yml
when: ansible_system == 'Linux' # TODO enable acls mount option on FreeBSD to test it there too
always:
- name: Delete created directory and file
ansible.builtin.file:
path: "{{ item }}"
state: absent
with_items:
- "{{ test_dir }}"
- "{{ test_file }}"

View file

@ -1,2 +1,3 @@
---
dependencies:
- prepare_tests

View file

@ -1,3 +1,4 @@
---
# Test code for the at module.
# (c) 2017, James Tanner <tanner.jc@gmail.com>
@ -16,47 +17,56 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- set_fact: output_dir_test={{output_dir}}/at
- name: Set output_dir_test fast
ansible.builtin.set_fact:
output_dir_test: "{{ output_dir }}/at"
- name: make sure our testing sub-directory does not exist
file: path="{{ output_dir_test }}" state=absent
- name: Make sure our testing sub-directory does not exist
ansible.builtin.file:
path: "{{ output_dir_test }}"
state: absent
- name: create our testing sub-directory
file: path="{{ output_dir_test }}" state=directory
- name: Create our testing sub-directory
ansible.builtin.file:
path: "{{ output_dir_test }}"
state: directory
mode: "0755"
##
## at
##
- name: define distros to attempt installing at on
set_fact:
- name: Define distros to attempt installing at on
ansible.builtin.set_fact:
package_distros:
- RedHat
- CentOS
- ScientificLinux
- Fedora
- Ubuntu
- Debian
- openSUSE Leap
- RedHat
- CentOS
- ScientificLinux
- Fedora
- Ubuntu
- Debian
- openSUSE Leap
- name: ensure at is installed
package:
- name: Ensure at is installed
ansible.builtin.package:
name: at
state: present
when: ansible_distribution in package_distros
- name: run the first example
at:
command: "ls -d / > /dev/null"
- name: Run the first example
ansible.posix.at:
command: ls -d / > /dev/null
count: 20
units: minutes
register: at_test0
- debug: var=at_test0
- name: validate results
assert:
that:
- 'at_test0.changed is defined'
- 'at_test0.count is defined'
- 'at_test0.script_file is defined'
- 'at_test0.state is defined'
- 'at_test0.units is defined'
- name: Debug var=at_test0
ansible.builtin.debug:
var: at_test0
- name: Validate results
ansible.builtin.assert:
that:
- at_test0.changed is defined
- at_test0.count is defined
- at_test0.script_file is defined
- at_test0.state is defined
- at_test0.units is defined

View file

@ -1,3 +1,4 @@
---
dss_key_basic: ssh-dss DATA_BASIC root@testing
dss_key_unquoted_option: idle-timeout=5m ssh-dss DATA_UNQUOTED_OPTION root@testing
dss_key_command: command="/bin/true" ssh-dss DATA_COMMAND root@testing
@ -8,27 +9,27 @@ dss_key_trailing: ssh-dss DATA_TRAILING root@testing foo bar baz
rsa_key_basic: ssh-rsa DATA_BASIC root@testing
multiple_key_base: |
ssh-rsa DATA_BASIC 1@testing
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-dss DATA_TRAILING 3@testing foo bar baz
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
ssh-rsa DATA_BASIC 1@testing
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-dss DATA_TRAILING 3@testing foo bar baz
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
multiple_key_different_order: |
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-dss DATA_TRAILING 3@testing foo bar baz
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-dss DATA_TRAILING 3@testing foo bar baz
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
multiple_key_different_order_2: |
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-rsa WHATEVER 2.5@testing
ssh-dss DATA_TRAILING 3@testing foo bar baz
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
ssh-dss DATA_TRAILING 2@testing foo bar baz
ssh-rsa WHATEVER 2.5@testing
ssh-dss DATA_TRAILING 3@testing foo bar baz
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
multiple_key_exclusive: |
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
ssh-rsa DATA_BASIC 1@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
multiple_keys_comments: |
ssh-rsa DATA_BASIC 1@testing

View file

@ -1,2 +1,3 @@
---
dependencies:
- prepare_tests

View file

@ -1,34 +1,37 @@
---
# -------------------------------------------------------------
# check mode
- name: CHECK MODE | copy an existing file in place with comments
copy:
ansible.builtin.copy:
src: existing_authorized_keys
dest: "{{ output_dir | expanduser }}/authorized_keys"
mode: "0600"
- name: CHECK MODE | add key in check mode to validate return codes
authorized_key:
ansible.posix.authorized_key:
user: root
key: "{{ multiple_key_different_order_2 }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
check_mode: True
check_mode: true
register: result
- name: CHECK MODE | assert that authorized_keys return values are consistent
assert:
ansible.builtin.assert:
that:
- 'result.changed == True'
- result.changed == True
- '"user" in result'
- '"key" in result'
- name: CHECK MODE | recopy authorized_keys to ensure it was not changed
copy:
ansible.builtin.copy:
src: existing_authorized_keys
dest: "{{ output_dir | expanduser }}/authorized_keys"
mode: "0600"
register: result
- name: CHECK MODE | assert that the authorized_keys file was not changed
assert:
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False

View file

@ -1,8 +1,9 @@
---
# -------------------------------------------------------------
# comments
- name: Add rsa key with existing comment
authorized_key:
ansible.posix.authorized_key:
user: root
key: "{{ rsa_key_basic }}"
state: present
@ -10,7 +11,7 @@
register: result
- name: Change the comment on an existing key
authorized_key:
ansible.posix.authorized_key:
user: root
key: "{{ rsa_key_basic }}"
comment: user@acme.com
@ -18,18 +19,18 @@
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: get the file content
shell: cat "{{ output_dir | expanduser }}/authorized_keys" | fgrep DATA_BASIC
changed_when: no
- name: Get the file content
ansible.builtin.command: fgrep DATA_BASIC "{{ output_dir | expanduser }}/authorized_keys"
changed_when: false
register: content
- name: Assert that comment on an existing key was changed
assert:
ansible.builtin.assert:
that:
- "'user@acme.com' in content.stdout"
- name: Set the same key with comment to ensure no changes are reported
authorized_key:
ansible.posix.authorized_key:
user: root
key: "{{ rsa_key_basic }}"
comment: user@acme.com
@ -38,11 +39,12 @@
register: result
- name: Assert that no changes were made when running again
assert:
ansible.builtin.assert:
that:
- not result.changed
- debug:
- name: Debug the result and content
ansible.builtin.debug:
var: "{{ item }}"
verbosity: 1
with_items:

View file

@ -1,3 +1,4 @@
---
# test code for the authorized_key module
# - (c) 2014, James Cammarata <jcammarata@ansible.com>
# - (c) 2021, Hideki Saito <saito@fgrep.org>
@ -17,16 +18,16 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: Setup testing environment
import_tasks: setup_steps.yml
ansible.builtin.import_tasks: setup_steps.yml
- name: Test for multiple keys handling
import_tasks: multiple_keys.yml
ansible.builtin.import_tasks: multiple_keys.yml
- name: Test for ssh-dss key handling
import_tasks: ssh_dss.yml
ansible.builtin.import_tasks: ssh_dss.yml
- name: Test for check mode
import_tasks: check_mode.yml
ansible.builtin.import_tasks: check_mode.yml
- name: Test for the management of comments with key
import_tasks: comments.yml
ansible.builtin.import_tasks: comments.yml

View file

@ -1,38 +1,39 @@
---
# -------------------------------------------------------------
# multiple keys
- name: add multiple keys
authorized_key:
- name: Add multiple keys
ansible.posix.authorized_key:
user: root
key: "{{ multiple_key_base }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == multiple_key_base'
- 'result.key_options == None'
- result.changed == True
- result.key == multiple_key_base
- result.key_options == None
- name: add multiple keys different order
authorized_key:
- name: Add multiple keys different order
ansible.posix.authorized_key:
user: root
key: "{{ multiple_key_different_order }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == multiple_key_different_order'
- 'result.key_options == None'
- result.changed == True
- result.key == multiple_key_different_order
- result.key_options == None
- name: add multiple keys exclusive
authorized_key:
- name: Add multiple keys exclusive
ansible.posix.authorized_key:
user: root
key: "{{ multiple_key_exclusive }}"
state: present
@ -40,42 +41,42 @@
exclusive: true
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == multiple_key_exclusive'
- 'result.key_options == None'
- result.changed == True
- result.key == multiple_key_exclusive
- result.key_options == None
- name: add multiple keys in different calls
authorized_key:
- name: Add multiple keys in different calls
ansible.posix.authorized_key:
user: root
key: "ecdsa-sha2-nistp521 ECDSA_DATA 4@testing"
key: ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: add multiple keys in different calls
authorized_key:
- name: Add multiple keys in different calls
ansible.posix.authorized_key:
user: root
key: "ssh-rsa DATA_BASIC 1@testing"
key: ssh-rsa DATA_BASIC 1@testing
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: get the file content
shell: cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: no
- name: Get the file content
ansible.builtin.command: /bin/cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: false
register: multiple_keys_at_a_time
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == false'
- 'multiple_keys_at_a_time.stdout == multiple_key_exclusive.strip()'
- result.changed == false
- multiple_keys_at_a_time.stdout == multiple_key_exclusive.strip()
- name: add multiple keys comment
authorized_key:
- name: Add multiple keys comment
ansible.posix.authorized_key:
user: root
key: "{{ multiple_keys_comments }}"
state: present
@ -83,14 +84,14 @@
exclusive: true
register: result
- name: get the file content
shell: cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: no
- name: Get the file content
ansible.builtin.command: /bin/cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: false
register: multiple_keys_comments
- name: assert that the keys exist and comment only lines were not added
assert:
- name: Assert that the keys exist and comment only lines were not added
ansible.builtin.assert:
that:
- 'result.changed == False'
- 'multiple_keys_comments.stdout == multiple_key_exclusive.strip()'
- 'result.key_options == None'
- result.changed == False
- multiple_keys_comments.stdout == multiple_key_exclusive.strip()
- result.key_options == None

View file

@ -1,28 +1,40 @@
---
# -------------------------------------------------------------
# Setup steps
- name: Clean up the working directory and files
ansible.builtin.file:
path: "{{ output_dir }}"
state: absent
- name: copy an existing file in place with comments
copy:
- name: Create the working directory
ansible.builtin.file:
path: "{{ output_dir }}"
state: directory
mode: "0744"
- name: Copy an existing file in place with comments
ansible.builtin.copy:
src: existing_authorized_keys
dest: "{{ output_dir | expanduser }}/authorized_keys"
mode: "0600"
- name: add multiple keys different order
authorized_key:
- name: Add multiple keys different order
ansible.posix.authorized_key:
user: root
key: "{{ multiple_key_different_order_2 }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: get the file content
shell: cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: no
- name: Get the file content
ansible.builtin.command: /bin/cat "{{ output_dir | expanduser }}/authorized_keys"
changed_when: false
register: multiple_keys_existing
- name: assert that the key was added and comments and ordering preserved
assert:
- name: Assert that the key was added and comments and ordering preserved
ansible.builtin.assert:
that:
- 'result.changed == True'
- result.changed == True
- '"# I like candy" in multiple_keys_existing.stdout'
- '"# I like candy" in multiple_keys_existing.stdout_lines[0]'
- '"ssh-rsa DATA_BASIC 1@testing" in multiple_keys_existing.stdout'
@ -32,19 +44,20 @@
# start afresh
- name: remove file foo.txt
file:
- name: Remove file foo.txt
ansible.builtin.file:
path: "{{ output_dir | expanduser }}/authorized_keys"
state: absent
- name: touch the authorized_keys file
file:
- name: Touch the authorized_keys file
ansible.builtin.file:
dest: "{{ output_dir }}/authorized_keys"
state: touch
mode: "0600"
register: result
- name: assert that the authorized_keys file was created
assert:
- name: Assert that the authorized_keys file was created
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.state == "file"'
- result.changed == True
- result.state == "file"

View file

@ -1,241 +1,250 @@
---
# -------------------------------------------------------------
# basic ssh-dss key
- name: add basic ssh-dss key
authorized_key: user=root key="{{ dss_key_basic }}" state=present path="{{ output_dir | expanduser }}/authorized_keys"
- name: Add basic ssh-dss key
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_basic }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_basic'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_basic
- result.key_options == None
- name: re-add basic ssh-dss key
authorized_key: user=root key="{{ dss_key_basic }}" state=present path="{{ output_dir | expanduser }}/authorized_keys"
- name: Re-add basic ssh-dss key
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_basic }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with an unquoted option
- name: add ssh-dss key with an unquoted option
authorized_key:
- name: Add ssh-dss key with an unquoted option
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_unquoted_option }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_unquoted_option'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_unquoted_option
- result.key_options == None
- name: re-add ssh-dss key with an unquoted option
authorized_key:
- name: Re-add ssh-dss key with an unquoted option
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_unquoted_option }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with a leading command="/bin/foo"
- name: add ssh-dss key with a leading command
authorized_key:
- name: Add ssh-dss key with a leading command
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_command
- result.key_options == None
- name: re-add ssh-dss key with a leading command
authorized_key:
- name: Re-add ssh-dss key with a leading command
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with a complex quoted leading command
# ie. command="/bin/echo foo 'bar baz'"
- name: add ssh-dss key with a complex quoted leading command
authorized_key:
- name: Add ssh-dss key with a complex quoted leading command
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_complex_command }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_complex_command'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_complex_command
- result.key_options == None
- name: re-add ssh-dss key with a complex quoted leading command
authorized_key:
- name: Re-add ssh-dss key with a complex quoted leading command
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_complex_command }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with a command and a single option, which are
# in a comma-separated list
- name: add ssh-dss key with a command and a single option
authorized_key:
- name: Add ssh-dss key with a command and a single option
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command_single_option }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command_single_option'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_command_single_option
- result.key_options == None
- name: re-add ssh-dss key with a command and a single option
authorized_key:
- name: Re-add ssh-dss key with a command and a single option
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command_single_option }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with a command and multiple other options
- name: add ssh-dss key with a command and multiple options
authorized_key:
- name: Add ssh-dss key with a command and multiple options
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command_multiple_options }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_command_multiple_options'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_command_multiple_options
- result.key_options == None
- name: re-add ssh-dss key with a command and multiple options
authorized_key:
- name: Re-add ssh-dss key with a command and multiple options
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_command_multiple_options }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# ssh-dss key with multiple trailing parts, which are space-
# separated and not quoted in any way
- name: add ssh-dss key with trailing parts
authorized_key:
- name: Add ssh-dss key with trailing parts
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_trailing }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key was added
assert:
- name: Assert that the key was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_trailing'
- 'result.key_options == None'
- result.changed == True
- result.key == dss_key_trailing
- result.key_options == None
- name: re-add ssh-dss key with trailing parts
authorized_key:
- name: Re-add ssh-dss key with trailing parts
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_trailing }}"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that nothing changed
assert:
- name: Assert that nothing changed
ansible.builtin.assert:
that:
- 'result.changed == False'
- result.changed == False
# -------------------------------------------------------------
# basic ssh-dss key with mutliple permit-open options
# https://github.com/ansible/ansible-modules-core/issues/1715
- name: add basic ssh-dss key with multi-opts
authorized_key:
- name: Add basic ssh-dss key with multi-opts
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_basic }}"
key_options: 'no-agent-forwarding,no-X11-forwarding,permitopen="10.9.8.1:8080",permitopen="10.9.8.1:9001"'
key_options: no-agent-forwarding,no-X11-forwarding,permitopen="10.9.8.1:8080",permitopen="10.9.8.1:9001"
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result
- name: assert that the key with multi-opts was added
assert:
- name: Assert that the key with multi-opts was added
ansible.builtin.assert:
that:
- 'result.changed == True'
- 'result.key == dss_key_basic'
- 'result.key_options == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\""'
- result.changed == True
- result.key == dss_key_basic
- result.key_options == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\""
- name: get the file content
shell: cat "{{ output_dir | expanduser }}/authorized_keys" | fgrep DATA_BASIC
changed_when: no
- name: Get the file content
ansible.builtin.command: fgrep DATA_BASIC "{{ output_dir | expanduser }}/authorized_keys"
changed_when: false
register: content
- name: validate content
assert:
- name: Validate content
ansible.builtin.assert:
that:
- 'content.stdout == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\" ssh-dss DATA_BASIC root@testing"'
- content.stdout == "no-agent-forwarding,no-X11-forwarding,permitopen=\"10.9.8.1:8080\",permitopen=\"10.9.8.1:9001\" ssh-dss DATA_BASIC root@testing"

View file

@ -1,2 +1,3 @@
---
dependencies:
- setup_pkg_mgr

View file

@ -0,0 +1,173 @@
---
# Test playbook for the firewalld module - icmp block inversion operations
# (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Icmp block inversion enabled when icmp block inversion is truthy and state is enabled
block:
- name: Testing enable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: true
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: true
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Icmp block inversion disabled when icmp block inversion is falsy and state is enabled
block:
- name: Testing disable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: false
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: false
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Icmp block inversion enabled when icmp block inversion is falsy and state is disabled
block:
- name: Testing enable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: false
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: false
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Icmp block inversion disabled when icmp block inversion is truthy and state is disabled
block:
- name: Testing disable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: true
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: true
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
# Validate backwards compatible behavior until icmp block inversion is switched from string to boolean type
- name: Icmp block inversion enabled when icmp block inversion is non-boolean string and state is enabled
block:
- name: Testing enable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: some string
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: some string
permanent: true
state: enabled
register: result
- name: Assert icmp block inversion is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Icmp block inversion disabled when icmp block inversion is non-boolean string and state is disabled
block:
- name: Testing disable icmp block inversion
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: some string
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable icmp block inversion (verify not changed)
ansible.posix.firewalld:
zone: trusted
icmp_block_inversion: some string
permanent: true
state: disabled
register: result
- name: Assert icmp block inversion is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

View file

@ -0,0 +1,88 @@
---
# Test playbook for the firewalld module - interface operations
# (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Validate adding interface
block:
- name: Add lo interface to trusted zone
ansible.posix.firewalld:
interface: lo
zone: trusted
permanent: true
state: enabled
register: result
- name: Assert lo was added to trusted zone
ansible.builtin.assert:
that:
- result is changed
- name: Add lo interface to trusted zone (verify not changed)
ansible.posix.firewalld:
interface: lo
zone: trusted
permanent: true
state: enabled
register: result
- name: Assert lo was added to trusted zone (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Validate moving interfaces
block:
- name: Move lo interface from trusted zone to internal zone
ansible.posix.firewalld:
interface: lo
zone: internal
permanent: true
state: enabled
register: result
- name: Assert lo was moved from trusted zone to internal zone
ansible.builtin.assert:
that:
- result is changed
- name: Move lo interface from trusted zone to internal zone (verify not changed)
ansible.posix.firewalld:
interface: lo
zone: internal
permanent: true
state: enabled
register: result
- name: Assert lo was moved from trusted zone to internal zone (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Validate removing interface
block:
- name: Remove lo interface from internal zone
ansible.posix.firewalld:
interface: lo
zone: internal
permanent: true
state: disabled
register: result
- name: Assert lo interface was removed from internal zone
ansible.builtin.assert:
that:
- result is changed
- name: Remove lo interface from internal zone (verify not changed)
ansible.posix.firewalld:
interface: lo
zone: internal
permanent: true
state: disabled
register: result
- name: Assert lo interface was removed from internal zone (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

View file

@ -1,22 +1,24 @@
---
# Test playbook for the firewalld module
# (c) 2017, Adam Miller <admiller@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Run firewalld tests
when:
- ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('7', '>=')
- not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('14.04', '=='))
# Firewalld package on OpenSUSE (15+) require Python 3, so we skip on OpenSUSE running py2 on these newer distros
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
- not (ansible_facts.distribution == "CentOS" and ansible_distribution_major_version is version('7', '==')) # FIXME
block:
- name: Ensure firewalld is installed
package:
ansible.builtin.package:
name: firewalld
state: present
# This doesn't work for CentOS 6 because firewalld doesn't exist in CentOS6
- name: Check to make sure the firewalld python module is available.
shell: "{{ansible_python.executable}} -c 'import firewall'"
register: check_output
ignore_errors: true
# This doesn't work for CentOS 6 because firewalld doesn't exist in CentOS6
- name: Enable dbus-broker daemon
service:
ansible.builtin.service:
name: dbus-broker
enabled: true
state: started
@ -24,27 +26,20 @@
- name: Test Online Operations
block:
- name: start firewalld
service:
- name: Start firewalld
ansible.builtin.service:
name: firewalld
state: started
- import_tasks: run_all_tests.yml
when: check_output.rc == 0
- name: Import test tasks
ansible.builtin.import_tasks: run_all_tests.yml
- name: Test Offline Operations
block:
- name: stop firewalld
service:
- name: Stop firewalld
ansible.builtin.service:
name: firewalld
state: stopped
- import_tasks: run_all_tests.yml
when: check_output.rc == 0
when:
- ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('7', '>=')
- not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('14.04', '=='))
# Firewalld package on OpenSUSE (15+) require Python 3, so we skip on OpenSUSE running py2 on these newer distros
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
- not (ansible_facts.distribution == "CentOS" and ansible_distribution_major_version is version('7', '==')) # FIXME
- name: Import test tasks
ansible.builtin.import_tasks: run_all_tests.yml

View file

@ -0,0 +1,173 @@
---
# Test playbook for the firewalld module - masquerade operations
# (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Masquerade enabled when masquerade is truthy and state is enabled
block:
- name: Testing enable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: true
permanent: true
state: enabled
register: result
- name: Assert masquerade is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: true
permanent: true
state: enabled
register: result
- name: Assert masquerade is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Masquerade disabled when masquerade is falsy and state is enabled
block:
- name: Testing disable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: false
permanent: true
state: enabled
register: result
- name: Assert masquerade is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: false
permanent: true
state: enabled
register: result
- name: Assert masquerade is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Masquerade enabled when masquerade is falsy and state is disabled
block:
- name: Testing enable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: false
permanent: true
state: disabled
register: result
- name: Assert masquerade is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: false
permanent: true
state: disabled
register: result
- name: Assert masquerade is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Masquerade disabled when masquerade is truthy and state is disabled
block:
- name: Testing disable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: true
permanent: true
state: disabled
register: result
- name: Assert masquerade is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: true
permanent: true
state: disabled
register: result
- name: Assert masquerade is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
# Validate backwards compatible behavior until masquerade is switched from string to boolean type
- name: Masquerade enabled when masquerade is non-boolean string and state is enabled
block:
- name: Testing enable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: some string
permanent: true
state: enabled
register: result
- name: Assert masquerade is enabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing enable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: some string
permanent: true
state: enabled
register: result
- name: Assert masquerade is enabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Masquerade disabled when masquerade is non-boolean string and state is disabled
block:
- name: Testing disable masquerade
ansible.posix.firewalld:
zone: trusted
masquerade: some string
permanent: true
state: disabled
register: result
- name: Assert masquerade is disabled
ansible.builtin.assert:
that:
- result is changed
- name: Testing disable masquerade (verify not changed)
ansible.posix.firewalld:
zone: trusted
masquerade: some string
permanent: true
state: disabled
register: result
- name: Assert masquerade is disabled (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

View file

@ -1,9 +1,10 @@
---
# Test playbook for the firewalld module - port operations
# (c) 2017, Adam Miller <admiller@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: firewalld port forward test permanent enabled
firewalld:
- name: Firewalld port forward test permanent enabled
ansible.posix.firewalld:
port_forward:
- port: 8080
proto: tcp
@ -12,13 +13,13 @@
state: enabled
register: result
- name: assert firewalld port test permanent enabled worked
assert:
- name: Assert firewalld port test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port test permanent enabled rerun (verify not changed)
firewalld:
- name: Firewalld port test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
port_forward:
- port: 8080
proto: tcp
@ -27,13 +28,13 @@
state: enabled
register: result
- name: assert firewalld port test permanent enabled rerun worked (verify not changed)
assert:
- name: Assert firewalld port test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld port test permanent disabled
firewalld:
- name: Firewalld port test permanent disabled
ansible.posix.firewalld:
port_forward:
- port: 8080
proto: tcp
@ -42,13 +43,13 @@
state: disabled
register: result
- name: assert firewalld port test permanent disabled worked
assert:
- name: Assert firewalld port test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port test permanent disabled rerun (verify not changed)
firewalld:
- name: Firewalld port test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
port_forward:
- port: 8080
proto: tcp
@ -57,7 +58,7 @@
state: disabled
register: result
- name: assert firewalld port test permanent disabled rerun worked (verify not changed)
assert:
- name: Assert firewalld port test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed

View file

@ -1,108 +1,109 @@
---
# Test playbook for the firewalld module - port operations
# (c) 2017, Adam Miller <admiller@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: firewalld port range test permanent enabled
firewalld:
port: 5500-6950/tcp
- name: Firewalld port range test permanent enabled
ansible.posix.firewalld:
port: 5500-6850/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port range test permanent enabled worked
assert:
- name: Assert firewalld port range test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port range test permanent enabled rerun (verify not changed)
firewalld:
port: 5500-6950/tcp
- name: Firewalld port range test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
port: 5500-6850/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port range test permanent enabled rerun worked (verify not changed)
assert:
- name: Assert firewalld port range test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld port test permanent enabled
firewalld:
- name: Firewalld port test permanent enabled
ansible.posix.firewalld:
port: 6900/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled worked
assert:
- name: Assert firewalld port test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port test permanent enabled
firewalld:
- name: Firewalld port test permanent enabled
ansible.posix.firewalld:
port: 6900/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled worked
assert:
- name: Assert firewalld port test permanent enabled worked
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld port test disabled
firewalld:
- name: Firewalld port test disabled
ansible.posix.firewalld:
port: "{{ item }}"
permanent: true
state: disabled
loop:
- 6900/tcp
- 5500-6950/tcp
- 5500-6850/tcp
- name: firewalld port test permanent enabled
firewalld:
- name: Firewalld port test permanent enabled
ansible.posix.firewalld:
port: 8081/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled worked
assert:
- name: Assert firewalld port test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port test permanent enabled rerun (verify not changed)
firewalld:
- name: Firewalld port test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
port: 8081/tcp
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled rerun worked (verify not changed)
assert:
- name: Assert firewalld port test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld port test permanent disabled
firewalld:
- name: Firewalld port test permanent disabled
ansible.posix.firewalld:
port: 8081/tcp
permanent: true
state: disabled
register: result
- name: assert firewalld port test permanent disabled worked
assert:
- name: Assert firewalld port test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld port test permanent disabled rerun (verify not changed)
firewalld:
- name: Firewalld port test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
port: 8081/tcp
permanent: true
state: disabled
register: result
- name: assert firewalld port test permanent disabled rerun worked (verify not changed)
assert:
- name: Assert firewalld port test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed

View file

@ -0,0 +1,66 @@
---
# Test playbook for the firewalld module - protocol operations
# (c) 2022, Robért S. Guhr <rguhr@cronon.net>
# 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: Firewalld protocol test permanent enabled
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled
register: result
- name: Assert firewalld protocol test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- name: Firewalld protocol test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled
register: result
- name: Assert firewalld protocol test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Firewalld protocol test permanent disabled
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: disabled
register: result
- name: Assert firewalld protocol test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed
- name: Firewalld protocol test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: disabled
register: result
- name: Assert firewalld protocol test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

View file

@ -1,23 +1,50 @@
---
# Test playbook for the firewalld module
# (c) 2017, Adam Miller <admiller@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Ensure /run/firewalld exists
file:
ansible.builtin.file:
path: /run/firewalld
state: directory
mode: "0755"
# firewalld service operation test cases
- include_tasks: service_test_cases.yml
- name: Include service test cases for firewalld module
ansible.builtin.include_tasks: service_test_cases.yml
# firewalld protocol operation test cases
- name: Include protocol test cases for firewalld module
ansible.builtin.include_tasks: protocol_test_cases.yml
# firewalld port operation test cases
- include_tasks: port_test_cases.yml
- name: Include port test cases for firewalld module
ansible.builtin.include_tasks: port_test_cases.yml
# firewalld source operation test cases
- include_tasks: source_test_cases.yml
- name: Include source test cases for firewalld module
ansible.builtin.include_tasks: source_test_cases.yml
# firewalld zone operation test cases
- name: Include zone test cases for firewalld module
ansible.builtin.include_tasks: zone_test_cases.yml
# firewalld zone target operation test cases
- include_tasks: zone_target_test_cases.yml
- name: Include zone target test cases for firewalld module
ansible.builtin.include_tasks: zone_target_test_cases.yml
# firewalld port forwarding operation test cases
- include_tasks: port_forward_test_cases.yml
- name: Include port forward target test cases for firewalld module
ansible.builtin.include_tasks: port_forward_test_cases.yml
# firewalld masquerade operation test cases
- name: Include masquerade target test cases for firewalld module
ansible.builtin.include_tasks: masquerade_test_cases.yml
# firewalld icmp block inversion operation test cases
- name: Include icmp block inversion target test cases for firewalld module
ansible.builtin.include_tasks: icmp_block_inversion_test_cases.yml
# firewalld interface operation test cases
- name: Include interface target test cases for firewalld module
ansible.builtin.include_tasks: interface_test_cases.yml

View file

@ -1,3 +1,4 @@
---
# Test playbook for the firewalld module - service operations
# (c) 2017, Adam Miller <admiller@redhat.com>
@ -16,50 +17,58 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: firewalld service test permanent enabled
firewalld:
- name: Firewalld service test permanent enabled
ansible.posix.firewalld:
service: https
permanent: true
immediate: true
offline: true
state: enabled
register: result
- name: assert firewalld service test permanent enabled worked
assert:
- name: Assert firewalld service test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld service test permanent enabled rerun (verify not changed)
firewalld:
- name: Firewalld service test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
service: https
permanent: true
immediate: true
offline: true
state: enabled
register: result
- name: assert firewalld service test permanent enabled rerun worked (verify not changed)
assert:
- name: Assert firewalld service test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld service test permanent disabled
firewalld:
- name: Firewalld service test permanent disabled
ansible.posix.firewalld:
service: https
permanent: true
immediate: true
offline: true
state: disabled
register: result
- name: assert firewalld service test permanent disabled worked
assert:
- name: Assert firewalld service test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld service test permanent disabled rerun (verify not changed)
firewalld:
- name: Firewalld service test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
service: https
permanent: true
immediate: true
offline: true
state: disabled
register: result
- name: assert firewalld service test permanent disabled rerun worked (verify not changed)
assert:
- name: Assert firewalld service test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed

View file

@ -1,3 +1,4 @@
---
# Test playbook for the firewalld module - source operations
# (c) 2019, Hideki Saito <saito@fgrep.org>
@ -16,70 +17,71 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: firewalld source test permanent enabled
firewalld:
- name: Firewalld source test permanent enabled
ansible.posix.firewalld:
source: 192.0.2.0/24
zone: internal
permanent: True
permanent: true
state: enabled
register: result
- name: assert firewalld source test permanent enabled worked
assert:
- name: Assert firewalld source test permanent enabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld source test permanent enabled rerun (verify not changed)
firewalld:
- name: Firewalld source test permanent enabled rerun (verify not changed)
ansible.posix.firewalld:
source: 192.0.2.0/24
zone: internal
permanent: True
permanent: true
state: enabled
register: result
- name: assert firewalld source test permanent enabled rerun worked (verify not changed)
assert:
- name: Assert firewalld source test permanent enabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld source test permanent disabled
firewalld:
- name: Firewalld source test permanent disabled
ansible.posix.firewalld:
source: 192.0.2.0/24
zone: internal
permanent: True
permanent: true
state: disabled
register: result
- name: assert firewalld source test permanent disabled worked
assert:
- name: Assert firewalld source test permanent disabled worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld source test permanent disabled rerun (verify not changed)
firewalld:
- name: Firewalld source test permanent disabled rerun (verify not changed)
ansible.posix.firewalld:
source: 192.0.2.0/24
zone: internal
permanent: True
permanent: true
state: disabled
register: result
- name: assert firewalld source test permanent disabled rerun worked (verify not changed)
assert:
- name: Assert firewalld source test permanent disabled rerun worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld source test permanent enabled is exclusive (verify exclusive error)
firewalld:
- name: Firewalld source test permanent enabled is exclusive (verify exclusive error)
ansible.posix.firewalld:
source: 192.0.2.0/24
port: 8081/tcp
zone: internal
permanent: True
permanent: true
state: enabled
register: result
ignore_errors: true
- name: assert firewalld source test permanent enabled is exclusive (verify exclusive error)
assert:
- name: Assert firewalld source test permanent enabled is exclusive (verify exclusive error)
ansible.builtin.assert:
that:
- result is not changed
- "result.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|port|port_forward|rich_rule|interface|masquerade|source|target'"
- result is not changed
- "result.msg ==
'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|protocol|port|port_forward|rich_rule|interface|masquerade|source|target'"

View file

@ -1,3 +1,4 @@
---
# Test playbook for the firewalld module - source operations
# (c) 2020, Adam Miller <admiller@redhat.com>
@ -16,106 +17,106 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: firewalld dmz zone target DROP
firewalld:
- name: Firewalld dmz zone target DROP
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: present
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked
assert:
- name: Assert firewalld dmz zone target DROP present worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld dmz zone target DROP rerun (verify not changed)
firewalld:
- name: Firewalld dmz zone target DROP rerun (verify not changed)
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: present
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked (verify not changed)
assert:
- name: Assert firewalld dmz zone target DROP present worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld dmz zone target DROP absent
firewalld:
- name: Firewalld dmz zone target DROP absent
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: absent
target: DROP
register: result
- name: assert firewalld dmz zone target DROP absent worked
assert:
- name: Assert firewalld dmz zone target DROP absent worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld dmz zone target DROP rerun (verify not changed)
firewalld:
- name: Firewalld dmz zone target DROP rerun (verify not changed)
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: absent
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked (verify not changed)
assert:
- name: Assert firewalld dmz zone target DROP present worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld dmz zone target %%REJECT%%
firewalld:
- name: Firewalld dmz zone target %%REJECT%%
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: present
target: '%%REJECT%%'
target: "%%REJECT%%"
register: result
- name: assert firewalld dmz zone target %%REJECT%% present worked
assert:
- name: Assert firewalld dmz zone target %%REJECT%% present worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld dmz zone target %%REJECT%% rerun (verify not changed)
firewalld:
- name: Firewalld dmz zone target %%REJECT%% rerun (verify not changed)
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: present
target: '%%REJECT%%'
target: "%%REJECT%%"
register: result
- name: assert firewalld dmz zone target %%REJECT%% present worked (verify not changed)
assert:
- name: Assert firewalld dmz zone target %%REJECT%% present worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: firewalld dmz zone target %%REJECT%% absent
firewalld:
- name: Firewalld dmz zone target %%REJECT%% absent
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: absent
target: '%%REJECT%%'
target: "%%REJECT%%"
register: result
- name: assert firewalld dmz zone target %%REJECT%% absent worked
assert:
- name: Assert firewalld dmz zone target %%REJECT%% absent worked
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: firewalld dmz zone target %%REJECT%% rerun (verify not changed)
firewalld:
- name: Firewalld dmz zone target %%REJECT%% rerun (verify not changed)
ansible.posix.firewalld:
zone: dmz
permanent: True
permanent: true
state: absent
target: '%%REJECT%%'
target: "%%REJECT%%"
register: result
- name: assert firewalld dmz zone target %%REJECT%% present worked (verify not changed)
assert:
- name: Assert firewalld dmz zone target %%REJECT%% present worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- result is not changed

View file

@ -0,0 +1,48 @@
---
- name: Firewalld create zone custom
ansible.posix.firewalld:
zone: custom
permanent: true
state: present
register: result
- name: Assert firewalld custom zone created worked
ansible.builtin.assert:
that:
- result is changed
- name: Firewalld create zone custom rerun (verify not changed)
ansible.posix.firewalld:
zone: custom
permanent: true
state: present
register: result
- name: Assert firewalld custom zone created worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed
- name: Firewalld remove zone custom
ansible.posix.firewalld:
zone: custom
permanent: true
state: absent
register: result
- name: Assert firewalld custom zone removed worked
ansible.builtin.assert:
that:
- result is changed
- name: Firewalld remove custom zone rerun (verify not changed)
ansible.posix.firewalld:
zone: custom
permanent: true
state: absent
register: result
- name: Assert firewalld custom zone removed worked (verify not changed)
ansible.builtin.assert:
that:
- result is not changed

View file

@ -1,52 +1,53 @@
---
# Test playbook for the firewalld_info module
# (c) 2021, Hideki Saito <saito@fgrep.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# This test is based on the integration test playbook for firewalld module.
- name: Run firewalld tests
when:
- ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('7', '>=')
- not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('14.04', '=='))
# Firewalld package on OpenSUSE (15+) require Python 3, so we skip on OpenSUSE running py2 on these newer distros
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
block:
- name: Ensure firewalld is installed
package:
ansible.builtin.package:
name: firewalld
state: present
# This doesn't work for CentOS 6 because firewalld doesn't exist in CentOS6
# This doesn't work for CentOS 6 because firewalld doesn't exist in CentOS6
- name: Check to make sure the firewalld python module is available.
shell: "{{ansible_python.executable}} -c 'import firewall'"
ansible.builtin.command: "{{ ansible_python.executable }} -c 'import firewall'"
changed_when: false
register: check_output_firewall
ignore_errors: true
- name: Check to make sure the dbus python module is available.
shell: "{{ansible_python.executable}} -c 'import dbus'"
ansible.builtin.command: "{{ ansible_python.executable }} -c 'import dbus'"
changed_when: false
register: check_output_dbus
ignore_errors: true
- name: Test Online Operations
block:
- name: start firewalld
service:
- name: Start firewalld
ansible.builtin.service:
name: firewalld
state: started
- import_tasks: run_tests_in_started.yml
- name: Import test tasks from run_tests_in_started.yml
ansible.builtin.import_tasks: run_tests_in_started.yml
- name: Test Offline Operations
when:
- check_output_firewall.rc == 0
- check_output_dbus.rc == 0
- name: Test Offline Operations
block:
- name: stop firewalld
service:
- name: Stop firewalld
ansible.builtin.service:
name: firewalld
state: stopped
- import_tasks: run_tests_in_stopped.yml
when:
- check_output_firewall.rc == 0
- check_output_dbus.rc == 0
when:
- ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('7', '>=')
- not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('14.04', '=='))
# Firewalld package on OpenSUSE (15+) require Python 3, so we skip on OpenSUSE running py2 on these newer distros
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
- name: Import test tasks from run_tests_in_stopped.yml
ansible.builtin.import_tasks: run_tests_in_stopped.yml

View file

@ -1,32 +1,33 @@
---
# Test playbook for the firewalld_info module
# (c) 2021, Hideki Saito <saito@fgrep.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Ensure firewalld_info without options
firewalld_info:
ansible.posix.firewalld_info:
register: result
- name: Assert collected_zones and undefined_zones
assert:
ansible.builtin.assert:
that:
- 'result.collected_zones and not result.undefined_zones'
- result.collected_zones and not result.undefined_zones
- name: Ensure firewalld_info with active_zones
firewalld_info:
active_zones: yes
ansible.posix.firewalld_info:
active_zones: true
register: result
- name: Assert turn active_zones true
assert:
ansible.builtin.assert:
that:
- name: Ensure firewalld_zones with zone list
firewalld_info:
ansible.posix.firewalld_info:
zones:
- public
- invalid_zone
register: result
- name: Assert specified zones
assert:
ansible.builtin.assert:
that:

View file

@ -1,40 +1,41 @@
---
# Test playbook for the firewalld_info module
# (c) 2021, Hideki Saito <saito@fgrep.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Ensure firewalld_info without options
firewalld_info:
ansible.posix.firewalld_info:
register: result
ignore_errors: yes
ignore_errors: true
- name: Assert firewalld_info fails if firewalld is not running.
assert:
ansible.builtin.assert:
that:
- result.failed
- "'firewalld probably not be running,' in result.msg"
- name: Ensure firewalld_info with active_zones
firewalld_info:
active_zones: yes
ansible.posix.firewalld_info:
active_zones: true
register: result
ignore_errors: yes
ignore_errors: true
- name: Assert firewalld_info with active_zones fails if firewalld is not running.
assert:
ansible.builtin.assert:
that:
- result.failed
- "'firewalld probably not be running,' in result.msg"
- name: Ensure firewalld_zones with zone list
firewalld_info:
ansible.posix.firewalld_info:
zones:
- public
- invalid_zone
register: result
ignore_errors: yes
ignore_errors: true
- name: Assert firewalld_info with zones list fails if firewalld is not running.
assert:
ansible.builtin.assert:
that:
- result.failed
- "'firewalld probably not be running,' in result.msg"

File diff suppressed because it is too large Load diff

View file

@ -1,124 +1,147 @@
- name: ensure idempotency installed
package:
---
- name: Ensure idempotency installed
ansible.builtin.package:
name: patch
when: ansible_distribution != "MacOSX"
- name: create a directory for the result
file:
dest: '{{ output_dir }}/patch'
- name: Create a directory for the result
ansible.builtin.file:
dest: "{{ output_dir }}/patch"
state: directory
mode: "0755"
register: result
- name: assert the directory was created
assert:
- name: Assert the directory was created
ansible.builtin.assert:
that:
- result.state == 'directory'
- name: copy the origin file
copy:
- result.state == 'directory'
- name: Copy the origin file
ansible.builtin.copy:
src: ./origin.txt
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
mode: "0644"
register: result
- name: patch the origin file in check mode
- name: Patch the origin file in check mode
check_mode: true
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
- name: verify patch the origin file in check mode
assert:
dest: "{{ output_dir }}/patch/workfile.txt"
- name: Verify patch the origin file in check mode
ansible.builtin.assert:
that:
- result is changed
- name: patch the origin file
- result is changed
- name: Patch the origin file
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
- name: verify patch the origin file
assert:
dest: "{{ output_dir }}/patch/workfile.txt"
- name: Verify patch the origin file
ansible.builtin.assert:
that:
- result is changed
- name: test patch the origin file idempotency
- result is changed
- name: Test patch the origin file idempotency
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
- name: verify test patch the origin file idempotency
assert:
dest: "{{ output_dir }}/patch/workfile.txt"
- name: Verify test patch the origin file idempotency
ansible.builtin.assert:
that:
- result is not changed
- name: verify the resulted file matches expectations
copy:
- result is not changed
- name: Verify the resulted file matches expectations
ansible.builtin.copy:
src: ./result.txt
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
mode: "0644"
register: result
failed_when: result is changed
- name: patch the workfile file in check mode state absent
- name: Patch the workfile file in check mode state absent
check_mode: true
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
state: absent
- name: verify patch the workfile file in check mode state absent
assert:
- name: Verify patch the workfile file in check mode state absent
ansible.builtin.assert:
that:
- result is changed
- name: patch the workfile file state absent
- result is changed
- name: Patch the workfile file state absent
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
state: absent
- name: verify patch the workfile file state absent
assert:
- name: Verify patch the workfile file state absent
ansible.builtin.assert:
that:
- result is changed
- name: patch the workfile file state absent idempotency
- result is changed
- name: Patch the workfile file state absent idempotency
register: result
patch:
ansible.posix.patch:
src: result.patch
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
state: absent
- name: verify patch the workfile file state absent idempotency
assert:
- name: Verify patch the workfile file state absent idempotency
ansible.builtin.assert:
that:
- result is not changed
- name: verify the resulted file matches expectations
copy:
- result is not changed
- name: Verify the resulted file matches expectations
ansible.builtin.copy:
src: ./origin.txt
dest: '{{ output_dir }}/patch/workfile.txt'
dest: "{{ output_dir }}/patch/workfile.txt"
mode: "0644"
register: result
failed_when: result is changed
- name: copy the origin file whitespace
copy:
- name: Copy the origin file whitespace
ansible.builtin.copy:
src: ./origin.txt
dest: '{{ output_dir }}/patch/workfile_whitespace.txt'
dest: "{{ output_dir }}/patch/workfile_whitespace.txt"
mode: "0644"
register: result
- name: patch the origin file
- name: Patch the origin file
register: result
patch:
ansible.posix.patch:
src: result_whitespace.patch
dest: '{{ output_dir }}/patch/workfile_whitespace.txt'
ignore_whitespace: yes
- name: verify patch the origin file
assert:
dest: "{{ output_dir }}/patch/workfile_whitespace.txt"
ignore_whitespace: true
- name: Verify patch the origin file
ansible.builtin.assert:
that:
- result is changed
- result is changed
- name: test patch the origin file idempotency
- name: Test patch the origin file idempotency
register: result
patch:
ansible.posix.patch:
src: result_whitespace.patch
dest: '{{ output_dir }}/patch/workfile_whitespace.txt'
ignore_whitespace: yes
- name: verify test patch the origin file idempotency
assert:
dest: "{{ output_dir }}/patch/workfile_whitespace.txt"
ignore_whitespace: true
- name: Verify test patch the origin file idempotency
ansible.builtin.assert:
that:
- result is not changed
- result is not changed
- name: verify the resulted file matches expectations
copy:
- name: Verify the resulted file matches expectations
ansible.builtin.copy:
src: ./result_whitespace.txt
dest: '{{ output_dir }}/patch/workfile_whitespace.txt'
dest: "{{ output_dir }}/patch/workfile_whitespace.txt"
mode: "0644"
register: result
failed_when: result is changed

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
# This file is part of Ansible
@ -15,8 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- include: seboolean.yml
- name: Include_tasks for when SELinux is enabled
ansible.builtin.include_tasks: seboolean.yml
when:
- ansible_selinux is defined
- ansible_selinux != False
- ansible_selinux
- ansible_selinux.status == 'enabled'

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Martin Krizek <mkrizek@redhat.com>
# This file is part of Ansible
@ -15,69 +16,89 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: install requirements for RHEL 7 and earlier
package:
- name: Install requirements for RHEL 7 and earlier
ansible.builtin.package:
name: policycoreutils-python
when:
- ansible_distribution == 'RedHat' and ansible_distribution_major_version is version('7', '<=')
- name: install requirements for RHEL 8 and later
package:
- name: Install requirements for RHEL 8 and later
ansible.builtin.package:
name: policycoreutils-python-utils
when:
- ansible_distribution == 'RedHat' and ansible_distribution_major_version is version('8', '>=')
- name: Get getsebool output preflight
ansible.builtin.shell:
cmd: set -o pipefail && semanage boolean -l | grep 'httpd_can_network_connect\W'
executable: /bin/bash
changed_when: false
register: getsebool_output_preflight
- name: Cleanup
shell: setsebool -P httpd_can_network_connect 0
##########################################################################################
- name: set flag and don't keep it persistent
seboolean:
ansible.builtin.shell:
cmd: set -o pipefail && setsebool -P httpd_can_network_connect 0
executable: /bin/bash
changed_when: getsebool_output_preflight.stdout.startswith('httpd_can_network_connect --> on')
- name: Set flag and don't keep it persistent
ansible.posix.seboolean:
name: httpd_can_network_connect
state: yes
state: true
register: output
- name: get getsebool output
shell: semanage boolean -l | grep 'httpd_can_network_connect\W'
- name: Get getsebool output
ansible.builtin.shell:
cmd: set -o pipefail && semanage boolean -l | grep 'httpd_can_network_connect\W'
executable: /bin/bash
changed_when: false
register: getsebool_output
- name: check output
assert:
- name: Check output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
- output.name == 'httpd_can_network_connect'
- getsebool_output.stdout.startswith('httpd_can_network_connect (on , off)')
##########################################################################################
- name: unset flag
seboolean:
- name: Unset flag
ansible.posix.seboolean:
name: httpd_can_network_connect
state: no
state: false
- name: get getsebool output
shell: semanage boolean -l | grep 'httpd_can_network_connect\W'
- name: Get getsebool output
ansible.builtin.shell:
cmd: set -o pipefail && semanage boolean -l | grep 'httpd_can_network_connect\W'
executable: /bin/bash
changed_when: false
register: getsebool_output
- name: check output
assert:
- name: Check output
ansible.builtin.assert:
that:
- output is changed
- output is not failed
- output.name == 'httpd_can_network_connect'
- getsebool_output.stdout.startswith('httpd_can_network_connect (off , off)')
##########################################################################################
- name: set flag and keep it persistent
seboolean:
- name: Set flag and keep it persistent
ansible.posix.seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
state: true
persistent: true
register: output
- name: get getsebool output
shell: semanage boolean -l | grep 'httpd_can_network_connect\W'
- name: Get getsebool output
ansible.builtin.shell:
cmd: set -o pipefail && semanage boolean -l | grep 'httpd_can_network_connect\W'
executable: /bin/bash
changed_when: false
register: getsebool_output
- name: check output
assert:
- name: Check output
ansible.builtin.assert:
that:
- output is changed
- output is not failed

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Sam Doran <sdoran@redhat.com>
# This file is part of Ansible
@ -15,22 +16,26 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- debug:
- name: Debug message for when SELinux is disabled
ansible.builtin.debug:
msg: SELinux is disabled
when: ansible_selinux is defined and ansible_selinux == False
when: ansible_selinux is defined and not ansible_selinux
- debug:
- name: Debug message for when SELinux is enabled and not disabled
ansible.builtin.debug:
msg: SELinux is {{ ansible_selinux.status }}
when: ansible_selinux is defined and ansible_selinux != False
when: ansible_selinux is defined and ansible_selinux
- include: selinux.yml
- name: Include_tasks for when SELinux is enabled
ansible.builtin.include_tasks: selinux.yml
when:
- ansible_selinux is defined
- ansible_selinux != False
- ansible_selinux
- ansible_selinux.status == 'enabled'
- include: selogin.yml
- name: Include tasks for selogin when SELinux is enabled
ansible.builtin.include_tasks: selogin.yml
when:
- ansible_selinux is defined
- ansible_selinux != False
- ansible_selinux
- ansible_selinux.status == 'enabled'

View file

@ -1,3 +1,4 @@
---
# (c) 2017, Sam Doran <sdoran@redhat.com>
# This file is part of Ansible
@ -14,67 +15,67 @@
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# First Test
# ##############################################################################
# Test changing the state, which requires a reboot
- name: TEST 1 | Make sure grubby is present
package:
ansible.builtin.package:
name: grubby
state: present
- name: TEST 1 | Get current SELinux config file contents
slurp:
ansible.builtin.slurp:
src: /etc/sysconfig/selinux
register: selinux_config_original_base64
- name: TEST 1 | Register SELinux config and SELinux status
set_fact:
ansible.builtin.set_fact:
selinux_config_original_raw: "{{ selinux_config_original_base64.content | b64decode }}"
before_test_sestatus: "{{ ansible_selinux }}"
- name: TEST 1 | Split by line and register original config
set_fact:
ansible.builtin.set_fact:
selinux_config_original: "{{ selinux_config_original_raw.split('\n') }}"
- debug:
- name: TEST 1 | Debug selinux_config_original, before_test_sestatus, and ansible_selinux
ansible.builtin.debug:
var: "{{ item }}"
verbosity: 1
with_items:
loop:
- selinux_config_original
- before_test_sestatus
- ansible_selinux
- name: TEST 1 | Setup SELinux configuration for tests
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
- name: TEST 1 | Disable SELinux
selinux:
ansible.posix.selinux:
state: disabled
policy: targeted
register: _disable_test1
- debug:
- name: TEST 1 | Debug _disable_test1
ansible.builtin.debug:
var: _disable_test1
verbosity: 1
- name: Before gathering the fact
debug:
ansible.builtin.debug:
msg: "{{ ansible_selinux }}"
- name: TEST 1 | Re-gather facts
setup:
ansible.builtin.setup:
- name: After gathering the fact
debug:
ansible.builtin.debug:
msg: "{{ ansible_selinux }}"
- name: TEST 1 | Assert that status was changed, reboot_required is True, a warning was displayed, and SELinux is configured properly
assert:
ansible.builtin.assert:
that:
- _disable_test1 is changed
- _disable_test1.reboot_required
@ -82,53 +83,56 @@
- ansible_selinux.config_mode == 'disabled'
- ansible_selinux.type == 'targeted'
- debug:
- name: TEST 1 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
- name: TEST 1 | Disable SELinux again
selinux:
ansible.posix.selinux:
state: disabled
policy: targeted
register: _disable_test2
- debug:
- name: Test 1 | Debug _disable_test2
ansible.builtin.debug:
var: _disable_test2
verbosity: 1
- name: TEST 1 | Assert that no change is reported, a warning was displayed, and reboot_required is True
assert:
ansible.builtin.assert:
that:
- _disable_test2 is not changed
- (_disable_test1.warnings | length ) >= 1
- _disable_test2.reboot_required
- name: TEST 1 | Get modified config file
slurp:
ansible.builtin.slurp:
src: /etc/sysconfig/selinux
register: selinux_config_after_base64
- name: TEST 1 | Register modified config
set_fact:
ansible.builtin.set_fact:
selinux_config_after_raw: "{{ selinux_config_after_base64.content | b64decode }}"
- name: TEST 1 | Split by line and register modified config
set_fact:
ansible.builtin.set_fact:
selinux_config_after: "{{ selinux_config_after_raw.split('\n') }}"
- debug:
- name: TEST 1 | Debug selinux_config_after
ansible.builtin.debug:
var: selinux_config_after
verbosity: 1
- name: TEST 1 | Ensure SELinux config file is properly formatted
assert:
ansible.builtin.assert:
that:
- selinux_config_original | length == selinux_config_after | length
- selinux_config_after[selinux_config_after.index('SELINUX=disabled')] is search("^SELINUX=\w+$")
- selinux_config_after[selinux_config_after.index('SELINUXTYPE=targeted')] is search("^SELINUXTYPE=\w+$")
- name: TEST 1 | Disable SELinux again, with kernel arguments update
selinux:
ansible.posix.selinux:
state: disabled
policy: targeted
update_kernel_param: true
@ -136,72 +140,76 @@
- name: Check kernel command-line arguments
ansible.builtin.command: grubby --info=DEFAULT
changed_when: false
register: _grubby_test1
- name: TEST 1 | Assert that kernel cmdline contains selinux=0
assert:
ansible.builtin.assert:
that:
- "' selinux=0' in _grubby_test1.stdout"
- name: TEST 1 | Enable SELinux, without kernel arguments update
selinux:
ansible.posix.selinux:
state: disabled
policy: targeted
register: _disable_test2
- name: Check kernel command-line arguments
ansible.builtin.command: grubby --info=DEFAULT
changed_when: false
register: _grubby_test1
- name: TEST 1 | Assert that kernel cmdline still contains selinux=0
assert:
ansible.builtin.assert:
that:
- "' selinux=0' in _grubby_test1.stdout"
- name: TEST 1 | Reset SELinux configuration for next test (also kernel args)
selinux:
ansible.posix.selinux:
state: enforcing
update_kernel_param: true
policy: targeted
- name: Check kernel command-line arguments
ansible.builtin.command: grubby --info=DEFAULT
changed_when: false
register: _grubby_test2
- name: TEST 1 | Assert that kernel cmdline doesn't contain selinux=0
assert:
ansible.builtin.assert:
that:
- "' selinux=0' not in _grubby_test2.stdout"
# Second Test
# ##############################################################################
# Test changing only the policy, which does not require a reboot
- name: TEST 2 | Make sure the policy is present
package:
ansible.builtin.package:
name: selinux-policy-mls
state: present
- name: TEST 2 | Set SELinux policy
selinux:
ansible.posix.selinux:
state: enforcing
policy: mls
register: _state_test1
- debug:
- name: TEST 2 | Debug _state_test1
ansible.builtin.debug:
var: _state_test1
verbosity: 1
- name: TEST 2 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 2 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
tags: debug
- name: TEST 2 | Assert that status was changed, reboot_required is False, no warnings were displayed, and SELinux is configured properly
assert:
ansible.builtin.assert:
that:
- _state_test1 is changed
- not _state_test1.reboot_required
@ -210,76 +218,79 @@
- ansible_selinux.type == 'mls'
- name: TEST 2 | Set SELinux policy again
selinux:
ansible.posix.selinux:
state: enforcing
policy: mls
register: _state_test2
- debug:
- name: TEST 2 | Debug _state_test2
ansible.builtin.debug:
var: _state_test2
verbosity: 1
- name: TEST 2 | Assert that no change was reported, no warnings were displayed, and reboot_required is False
assert:
ansible.builtin.assert:
that:
- _state_test2 is not changed
- _state_test2.warnings is not defined
- not _state_test2.reboot_required
- name: TEST 2 | Get modified config file
slurp:
ansible.builtin.slurp:
src: /etc/sysconfig/selinux
register: selinux_config_after_base64
- name: TEST 2 | Register modified config
set_fact:
ansible.builtin.set_fact:
selinux_config_after_raw: "{{ selinux_config_after_base64.content | b64decode }}"
- name: TEST 2 | Split by line and register modified config
set_fact:
ansible.builtin.set_fact:
selinux_config_after: "{{ selinux_config_after_raw.split('\n') }}"
- debug:
- name: TEST 2 | Debug selinux_config_after
ansible.builtin.debug:
var: selinux_config_after
verbosity: 1
- name: TEST 2 | Ensure SELinux config file is properly formatted
assert:
ansible.builtin.assert:
that:
- selinux_config_original | length == selinux_config_after | length
- selinux_config_after[selinux_config_after.index('SELINUX=enforcing')] is search("^SELINUX=\w+$")
- selinux_config_after[selinux_config_after.index('SELINUXTYPE=mls')] is search("^SELINUXTYPE=\w+$")
- name: TEST 2 | Reset SELinux configuration for next test
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
# Third Test
# ##############################################################################
# Test changing non-existing policy
- name: TEST 3 | Set SELinux policy
selinux:
ansible.posix.selinux:
state: enforcing
policy: non-existing-selinux-policy
register: _state_test1
ignore_errors: yes
ignore_errors: true
- debug:
- name: TEST 3 | Debug _state_test1
ansible.builtin.debug:
var: _state_test1
verbosity: 1
- name: TEST 3 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST3 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
tags: debug
- name: TEST 3 | Assert that status was not changed, the task failed, the msg contains proper information and SELinux was not changed
assert:
ansible.builtin.assert:
that:
- _state_test1 is not changed
- _state_test1 is failed
@ -287,40 +298,40 @@
- ansible_selinux.config_mode == 'enforcing'
- ansible_selinux.type == 'targeted'
# Fourth Test
# ##############################################################################
# Test if check mode returns correct changed values and
# doesn't make any changes
- name: TEST 4 | Set SELinux to enforcing
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
register: _check_mode_test1
- debug:
- name: TEST 4 | Debug _check_mode_test1
ansible.builtin.debug:
var: _check_mode_test1
verbosity: 1
- name: TEST 4 | Set SELinux to enforcing in check mode
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
register: _check_mode_test1
check_mode: yes
check_mode: true
- name: TEST 4 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 4| Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
tags: debug
- name: TEST 4 | Assert that check mode is idempotent
assert:
ansible.builtin.assert:
that:
- _check_mode_test1 is success
- not _check_mode_test1.reboot_required
@ -328,22 +339,23 @@
- ansible_selinux.type == 'targeted'
- name: TEST 4 | Set SELinux to permissive in check mode
selinux:
ansible.posix.selinux:
state: permissive
policy: targeted
register: _check_mode_test2
check_mode: yes
check_mode: true
- name: TEST 4 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 4 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
tags: debug
- name: TEST 4 | Assert that check mode doesn't set state permissive and returns changed
assert:
ansible.builtin.assert:
that:
- _check_mode_test2 is changed
- not _check_mode_test2.reboot_required
@ -351,21 +363,22 @@
- ansible_selinux.type == 'targeted'
- name: TEST 4 | Disable SELinux in check mode
selinux:
ansible.posix.selinux:
state: disabled
register: _check_mode_test3
check_mode: yes
check_mode: true
- name: TEST 4 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 4 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
tags: debug
- name: TEST 4 | Assert that check mode didn't change anything, status is changed, reboot_required is True, a warning was displayed
assert:
ansible.builtin.assert:
that:
- _check_mode_test3 is changed
- _check_mode_test3.reboot_required
@ -374,31 +387,33 @@
- ansible_selinux.type == 'targeted'
- name: TEST 4 | Set SELinux to permissive
selinux:
ansible.posix.selinux:
state: permissive
policy: targeted
register: _check_mode_test4
- debug:
- name: TEST 4 | Debug _check_mode_test4
ansible.builtin.debug:
var: _check_mode_test4
verbosity: 1
- name: TEST 4 | Disable SELinux in check mode
selinux:
ansible.posix.selinux:
state: disabled
register: _check_mode_test4
check_mode: yes
check_mode: true
- name: TEST 4 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 4 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
tags: debug
- name: TEST 4 | Assert that check mode didn't change anything, status is changed, reboot_required is True, a warning was displayed
assert:
ansible.builtin.assert:
that:
- _check_mode_test4 is changed
- _check_mode_test4.reboot_required
@ -407,36 +422,38 @@
- ansible_selinux.type == 'targeted'
- name: TEST 4 | Set SELinux to enforcing
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
register: _check_mode_test5
- debug:
- name: TEST 4 | Debug _check_mode_test5
ansible.builtin.debug:
var: _check_mode_test5
verbosity: 1
- name: TEST 4 | Disable SELinux
selinux:
ansible.posix.selinux:
state: disabled
register: _check_mode_test5
- name: TEST 4 | Disable SELinux in check mode
selinux:
ansible.posix.selinux:
state: disabled
register: _check_mode_test5
check_mode: yes
check_mode: true
- name: TEST 4 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 4 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
tags: debug
- name: TEST 4 | Assert that in check mode status was not changed, reboot_required is True, a warning was displayed, and SELinux is configured properly
assert:
ansible.builtin.assert:
that:
- _check_mode_test5 is success
- _check_mode_test5.reboot_required
@ -450,32 +467,34 @@
# sure the module re-adds the expected lines
- name: TEST 5 | Remove SELINUX key from /etc/selinux/config
lineinfile:
ansible.builtin.lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
regexp: ^SELINUX=
state: absent
backup: yes
backup: true
register: _lineinfile_out1
- debug:
- name: TEST 5 | Debug _lineinfile_out1
ansible.builtin.debug:
var: _lineinfile_out1
verbosity: 1
- name: TEST 5 | Set SELinux to enforcing
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
register: _set_enforcing1
- name: TEST 5 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 5 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
- name: TEST 5 | Assert that SELINUX key is populated
assert:
ansible.builtin.assert:
that:
- _set_enforcing1 is success
- _set_enforcing1 is changed
@ -483,31 +502,33 @@
- ansible_selinux.config_mode == 'enforcing'
- name: TEST 5 | Remove SELINUXTYPE key from /etc/selinux/config
lineinfile:
ansible.builtin.lineinfile:
path: /etc/selinux/config
regexp: '^SELINUXTYPE='
regexp: ^SELINUXTYPE=
state: absent
register: _lineinfile_out2
- debug:
- name: TEST 5 | Debug _lineinfile_out2
ansible.builtin.debug:
var: _lineinfile_out2
verbosity: 1
- name: TEST 5 | Set SELinux Policy to targeted
selinux:
ansible.posix.selinux:
state: enforcing
policy: targeted
register: _set_policy2
- name: TEST 5 | Re-gather facts
setup:
ansible.builtin.setup:
- debug:
- name: TEST 5 | Debug ansible_selinux
ansible.builtin.debug:
var: ansible_selinux
verbosity: 1
- name: TEST 5 | Assert that SELINUXTYPE key is populated
assert:
ansible.builtin.assert:
that:
- _set_policy2 is success
- _set_policy2 is changed
@ -515,7 +536,8 @@
- ansible_selinux.type == 'targeted'
- name: TEST 5 | Restore original SELinux config file /etc/selinux/config
copy:
ansible.builtin.copy:
dest: /etc/selinux/config
src: "{{ _lineinfile_out1['backup'] }}"
remote_src: yes
remote_src: true
mode: "0644"

View file

@ -1,70 +1,71 @@
- name: create user for testing
user:
---
- name: Create user for testing
ansible.builtin.user:
name: seuser
- name: attempt to add mapping without 'seuser'
- name: Attempt to add mapping without 'seuser'
register: selogin_error
ignore_errors: true
community.general.system.selogin:
login: seuser
- name: verify failure
assert:
- name: Verify failure
ansible.builtin.assert:
that:
- selogin_error is failed
- name: map login to SELinux user
- selogin_error is failed
- name: Map login to SELinux user
register: selogin_new_mapping
check_mode: '{{ item }}'
check_mode: "{{ item }}"
with_items:
- true
- false
- true
- false
- true
- false
- true
- false
community.general.system.selogin:
login: seuser
seuser: staff_u
- name: new mapping- verify functionality and check_mode
assert:
- name: New mapping- verify functionality and check_mode
ansible.builtin.assert:
that:
- selogin_new_mapping.results[0] is changed
- selogin_new_mapping.results[1] is changed
- selogin_new_mapping.results[2] is not changed
- selogin_new_mapping.results[3] is not changed
- name: change SELinux user login mapping
- selogin_new_mapping.results[0] is changed
- selogin_new_mapping.results[1] is changed
- selogin_new_mapping.results[2] is not changed
- selogin_new_mapping.results[3] is not changed
- name: Change SELinux user login mapping
register: selogin_mod_mapping
check_mode: '{{ item }}'
check_mode: "{{ item }}"
with_items:
- true
- false
- true
- false
- true
- false
- true
- false
community.general.system.selogin:
login: seuser
seuser: user_u
- name: changed mapping- verify functionality and check_mode
assert:
- name: Changed mapping- verify functionality and check_mode
ansible.builtin.assert:
that:
- selogin_mod_mapping.results[0] is changed
- selogin_mod_mapping.results[1] is changed
- selogin_mod_mapping.results[2] is not changed
- selogin_mod_mapping.results[3] is not changed
- name: remove SELinux user mapping
- selogin_mod_mapping.results[0] is changed
- selogin_mod_mapping.results[1] is changed
- selogin_mod_mapping.results[2] is not changed
- selogin_mod_mapping.results[3] is not changed
- name: Remove SELinux user mapping
register: selogin_del_mapping
check_mode: '{{ item }}'
check_mode: "{{ item }}"
with_items:
- true
- false
- true
- false
- true
- false
- true
- false
community.general.system.selogin:
login: seuser
state: absent
- name: delete mapping- verify functionality and check_mode
assert:
- name: Delete mapping- verify functionality and check_mode
ansible.builtin.assert:
that:
- selogin_del_mapping.results[0] is changed
- selogin_del_mapping.results[1] is changed
- selogin_del_mapping.results[2] is not changed
- selogin_del_mapping.results[3] is not changed
- name: remove test user
user:
- selogin_del_mapping.results[0] is changed
- selogin_del_mapping.results[1] is changed
- selogin_del_mapping.results[2] is not changed
- selogin_del_mapping.results[3] is not changed
- name: Remove test user
ansible.builtin.user:
name: seuser
state: absent

View file

@ -4,14 +4,16 @@
# and should not be used as examples of how to write Ansible roles #
####################################################################
- set_fact:
- name: Set pkg_mgr and ansible_pkg_mgr on FreeBSD
ansible.builtin.set_fact:
pkg_mgr: community.general.pkgng
ansible_pkg_mgr: community.general.pkgng
cacheable: yes
cacheable: true
when: ansible_os_family == "FreeBSD"
- set_fact:
- name: Set pkg_mgr and ansible_pkg_mgr on Suse
ansible.builtin.set_fact:
pkg_mgr: community.general.zypper
ansible_pkg_mgr: community.general.zypper
cacheable: yes
cacheable: true
when: ansible_os_family == "Suse"

View file

@ -1,2 +1,3 @@
---
dependencies:
- prepare_tests

View file

@ -1,310 +1,350 @@
- name: install rsync
package:
---
- name: Install rsync
ansible.builtin.package:
name: rsync
when: ansible_distribution != "MacOSX"
- name: Clean up the working directory and files
file:
path: '{{ output_dir }}'
- name: Clean up the working disrectory and files
ansible.builtin.file:
path: "{{ output_dir }}"
state: absent
- name: Create the working directory
file:
path: '{{ output_dir }}'
ansible.builtin.file:
path: "{{ output_dir }}"
state: directory
- name: create test new files
copy:
dest: '{{output_dir}}/{{item}}'
mode: '0644'
content: 'hello world'
with_items:
- foo.txt
- bar.txt
mode: "0755"
- name: synchronize file to new filename
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
- name: Create test new files
ansible.builtin.copy:
dest: "{{ output_dir }}/{{ item }}"
mode: "0644"
content: hello world
loop:
- foo.txt
- bar.txt
- name: Synchronize file to new filename
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- '''changed'' in sync_result'
- sync_result.changed == true
- '''cmd'' in sync_result'
- '''rsync'' in sync_result.cmd'
- '''msg'' in sync_result'
- sync_result.msg.startswith('>f+')
- 'sync_result.msg.endswith(''+ foo.txt
delegate_to: "{{ inventory_hostname }}"
'')'
- name: test that the file was really copied over
stat:
path: '{{ output_dir }}/foo.result'
- name: Check that the file was copied over correctly
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- "'cmd' in sync_result"
- "'rsync' in sync_result.cmd"
- "'msg' in sync_result"
- sync_result.msg.startswith('>f+')
- "sync_result.msg.endswith('+ foo.txt\n')"
- name: Test that the file was really copied over
ansible.builtin.stat:
path: "{{ output_dir }}/foo.result"
register: stat_result
- assert:
that:
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: test that the file is not copied a second time
synchronize:
src='{{output_dir}}/foo.txt'
dest='{{output_dir}}/foo.result'
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
- name: Test that the file was really copied over
ansible.builtin.assert:
that:
- sync_result.changed == False
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: Test that the file is not copied a second time
ansible.posix.synchronize:
src: "'{{ output_dir }}/foo.txt'"
dest: "'{{ output_dir }}/foo.result'"
register: sync_result
delegate_to: "{{ inventory_hostname }}"
- name: Test that no change occurred
ansible.builtin.assert:
that:
- not sync_result.changed
- name: Cleanup
file:
ansible.builtin.file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- foo.result
- bar.result
path: "{{ output_dir }}/{{ item }}"
loop:
- foo.result
- bar.result
- name: Synchronize using the mode=push param
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
mode: push
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- '''changed'' in sync_result'
- sync_result.changed == true
- '''cmd'' in sync_result'
- '''rsync'' in sync_result.cmd'
- '''msg'' in sync_result'
- sync_result.msg.startswith('>f+')
- 'sync_result.msg.endswith(''+ foo.txt
delegate_to: "{{ inventory_hostname }}"
'')'
- name: test that the file was really copied over
stat:
path: '{{ output_dir }}/foo.result'
- name: Check that the file was copied over correctly mode=push
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- "'cmd' in sync_result"
- "'rsync' in sync_result.cmd"
- "'msg' in sync_result"
- sync_result.msg.startswith('>f+')
- "sync_result.msg.endswith('+ foo.txt\n')"
- name: Test that the file was really copied over
ansible.builtin.stat:
path: "{{ output_dir }}/foo.result"
register: stat_result
- assert:
that:
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: test that the file is not copied a second time
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
- name: Ensure file exists and checksum matches
ansible.builtin.assert:
that:
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: Test that the file is not copied a second time
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
mode: push
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
delegate_to: "{{ inventory_hostname }}"
- name: Ensure no change occorred
ansible.builtin.assert:
that:
- sync_result.changed == False
- sync_result.changed == False
- name: Cleanup
file:
ansible.builtin.file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- foo.result
- bar.result
path: "{{ output_dir }}/{{ item }}"
loop:
- foo.result
- bar.result
- name: Synchronize using the mode=pull param
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
mode: pull
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- '''changed'' in sync_result'
- sync_result.changed == true
- '''cmd'' in sync_result'
- '''rsync'' in sync_result.cmd'
- '''msg'' in sync_result'
- sync_result.msg.startswith('>f+')
- 'sync_result.msg.endswith(''+ foo.txt
delegate_to: "{{ inventory_hostname }}"
'')'
- name: test that the file was really copied over
stat:
path: '{{ output_dir }}/foo.result'
- name: Check that the file was copied over correctly mode=pull
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- "'cmd' in sync_result"
- "'rsync' in sync_result.cmd"
- "'msg' in sync_result"
- sync_result.msg.startswith('>f+')
- "sync_result.msg.endswith('+ foo.txt\n')"
- name: Test that the file was really copied over
ansible.builtin.stat:
path: "{{ output_dir }}/foo.result"
register: stat_result
- assert:
that:
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: test that the file is not copied a second time
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
- name: Ensure file exists and checksum matches
ansible.builtin.assert:
that:
- stat_result.stat.exists == True
- stat_result.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: Test that the file is not copied a second time
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
mode: pull
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
delegate_to: "{{ inventory_hostname }}"
- name: Ensure no change occorred
ansible.builtin.assert:
that:
- sync_result.changed == False
- sync_result.changed == False
- name: Cleanup
file:
ansible.builtin.file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- foo.result
- bar.result
path: "{{ output_dir }}/{{ item }}"
loop:
- foo.result
- bar.result
- name: synchronize files using with_items (issue#5965)
synchronize:
src: '{{output_dir}}/{{item}}'
dest: '{{output_dir}}/{{item}}.result'
with_items:
- foo.txt
- bar.txt
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- sync_result.changed
- sync_result.msg == 'All items completed'
- '''results'' in sync_result'
- sync_result.results|length == 2
- 'sync_result.results[0].msg.endswith(''+ foo.txt
'')'
- 'sync_result.results[1].msg.endswith(''+ bar.txt
'')'
- name: Cleanup
file:
state: absent
path: '{{output_dir}}/{{item}}.result'
with_items:
- foo.txt
- bar.txt
- name: synchronize files using rsync_path (issue#7182)
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.rsync_path'
rsync_path: 'sudo rsync'
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- '''changed'' in sync_result'
- sync_result.changed == true
- '''cmd'' in sync_result'
- '''rsync'' in sync_result.cmd'
- '''rsync_path'' in sync_result.cmd'
- '''msg'' in sync_result'
- sync_result.msg.startswith('>f+')
- 'sync_result.msg.endswith(''+ foo.txt
'')'
- name: Cleanup
file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- foo.rsync_path
- name: add subdirectories for link-dest test
file:
path: '{{output_dir}}/{{item}}/'
state: directory
mode: '0755'
with_items:
- directory_a
- directory_b
- name: copy foo.txt into the first directory
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/{{item}}/foo.txt'
with_items:
- directory_a
delegate_to: '{{ inventory_hostname }}'
- name: synchronize files using link_dest
synchronize:
src: '{{output_dir}}/directory_a/foo.txt'
dest: '{{output_dir}}/directory_b/foo.txt'
link_dest:
- '{{output_dir}}/directory_a'
register: sync_result
delegate_to: '{{ inventory_hostname }}'
- name: get stat information for directory_a
stat:
path: '{{ output_dir }}/directory_a/foo.txt'
register: stat_result_a
- name: get stat information for directory_b
stat:
path: '{{ output_dir }}/directory_b/foo.txt'
register: stat_result_b
- assert:
that:
- '''changed'' in sync_result'
- sync_result.changed == true
- stat_result_a.stat.inode == stat_result_b.stat.inode
- name: synchronize files using link_dest that would be recursive
synchronize:
src: '{{output_dir}}/foo.txt'
dest: '{{output_dir}}/foo.result'
link_dest:
- '{{output_dir}}'
register: sync_result
ignore_errors: true
delegate_to: '{{ inventory_hostname }}'
- assert:
that:
- sync_result is not changed
- sync_result is failed
- name: Cleanup
file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- directory_b/foo.txt
- directory_a/foo.txt
- directory_a
- directory_b
- name: setup - test for source with working dir with spaces in path
file:
state: directory
path: '{{output_dir}}/{{item}}'
delegate_to: '{{ inventory_hostname }}'
with_items:
- 'directory a'
- 'directory b'
- name: setup - create test new files
copy:
dest: '{{output_dir}}/directory a/{{item}}'
mode: '0644'
content: 'hello world'
- name: Synchronize files using with_items (issue#5965)
ansible.posix.synchronize:
src: "{{ output_dir }}/{{ item }}"
dest: "{{ output_dir }}/{{ item }}.result"
with_items:
- foo.txt
delegate_to: '{{ inventory_hostname }}'
- name: copy source with spaces in dir path
synchronize:
src: '{{output_dir}}/directory a/foo.txt'
dest: '{{output_dir}}/directory b/'
delegate_to: '{{ inventory_hostname }}'
- bar.txt
register: sync_result
delegate_to: "{{ inventory_hostname }}"
- name: Validate syncrhonize with_items
ansible.builtin.assert:
that:
- sync_result.changed
- sync_result.msg == 'All items completed'
- "'results' in sync_result"
- sync_result.results|length == 2
- "sync_result.results[0].msg.endswith('+ foo.txt\n')"
- "sync_result.results[1].msg.endswith('+ bar.txt\n')"
- name: Cleanup
ansible.builtin.file:
state: absent
path: "{{ output_dir }}/{{ item }}.result"
loop:
- foo.txt
- bar.txt
- name: Synchronize files using rsync_path (issue#7182)
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.rsync_path"
rsync_path: sudo rsync
register: sync_result
delegate_to: "{{ inventory_hostname }}"
- name: Validate syncrhonize using rsync_path (issue#7182)
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- "'cmd' in sync_result"
- "'rsync' in sync_result.cmd"
- "'rsync_path' in sync_result.cmd"
- "'msg' in sync_result"
- sync_result.msg.startswith('>f+')
- "sync_result.msg.endswith('+ foo.txt\n')"
- name: Cleanup
ansible.builtin.file:
state: absent
path: "{{ output_dir }}/{{ item }}"
loop:
- foo.rsync_path
- name: Add subdirectories for link-dest test
ansible.builtin.file:
path: "{{ output_dir }}/{{ item }}/"
state: directory
mode: "0755"
loop:
- directory_a
- directory_b
- name: Copy foo.txt into the first directory
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/{{ item }}/foo.txt"
loop:
- directory_a
delegate_to: "{{ inventory_hostname }}"
- name: Synchronize files using link_dest
ansible.posix.synchronize:
src: "{{ output_dir }}/directory_a/foo.txt"
dest: "{{ output_dir }}/directory_b/foo.txt"
link_dest:
- "{{ output_dir }}/directory_a"
register: sync_result
delegate_to: "{{ inventory_hostname }}"
- name: Get stat information for directory_a
ansible.builtin.stat:
path: "{{ output_dir }}/directory_a/foo.txt"
register: stat_result_a
- name: Get stat information for directory_b
ansible.builtin.stat:
path: "{{ output_dir }}/directory_b/foo.txt"
register: stat_result_b
- name: Ensure file exists and inode matches
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- stat_result_a.stat.inode == stat_result_b.stat.inode
- name: Synchronize files using link_dest that would be recursive
ansible.posix.synchronize:
src: "{{ output_dir }}/foo.txt"
dest: "{{ output_dir }}/foo.result"
link_dest:
- "{{ output_dir }}"
register: sync_result
ignore_errors: true
- name: get stat information for directory_b
stat:
path: '{{ output_dir }}/directory b/foo.txt'
register: stat_result_b
- assert:
delegate_to: "{{ inventory_hostname }}"
- name: Ensure no change occorred and failed
ansible.builtin.assert:
that:
- '''changed'' in sync_result'
- sync_result is not changed
- sync_result is failed
- name: Cleanup
ansible.builtin.file:
state: absent
path: "{{ output_dir }}/{{ item }}"
loop:
- directory_b/foo.txt
- directory_a/foo.txt
- directory_a
- directory_b
- name: Setup - test for source with working dir with spaces in path
ansible.builtin.file:
state: directory
path: "{{ output_dir }}/{{ item }}"
mode: "0755"
delegate_to: "{{ inventory_hostname }}"
loop:
- directory a
- directory b
- name: Setup - create test new files
ansible.builtin.copy:
dest: "{{ output_dir }}/directory a/{{ item }}"
mode: "0644"
content: hello world
loop:
- foo.txt
delegate_to: "{{ inventory_hostname }}"
- name: Copy source with spaces in dir path
ansible.posix.synchronize:
src: "{{ output_dir }}/directory a/foo.txt"
dest: "{{ output_dir }}/directory b/"
delegate_to: "{{ inventory_hostname }}"
register: sync_result
ignore_errors: true
- name: Get stat information for directory_b
ansible.builtin.stat:
path: "{{ output_dir }}/directory b/foo.txt"
register: stat_result_b
- name: Ensure file exists and checksum matches
ansible.builtin.assert:
that:
- "'changed' in sync_result"
- sync_result.changed == true
- stat_result_b.stat.exists == True
- stat_result_b.stat.checksum == '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
- name: Cleanup
file:
ansible.builtin.file:
state: absent
path: '{{output_dir}}/{{item}}'
with_items:
- 'directory b/foo.txt'
- 'directory a/foo.txt'
- 'directory a'
- 'directory b'
path: "{{ output_dir }}/{{ item }}"
loop:
- directory b/foo.txt
- directory a/foo.txt
- directory a
- directory b

View file

@ -1,2 +1,3 @@
---
dependencies:
- prepare_tests

View file

@ -1,3 +1,4 @@
---
# Test code for the sysctl module.
# (c) 2017, James Tanner <tanner.jc@gmail.com>
@ -24,79 +25,91 @@
when:
- ansible_facts.virtualization_type == 'docker' or ansible_facts.virtualization_type == 'container'
block:
- set_fact:
- name: Set output_dir_test fact
ansible.builtin.set_fact:
output_dir_test: "{{ output_dir }}/test_sysctl"
- name: make sure our testing sub-directory does not exist
file:
- name: Make sure our testing sub-directory does not exist
ansible.builtin.file:
path: "{{ output_dir_test }}"
state: absent
- name: create our testing sub-directory
file:
- name: Create our testing sub-directory
ansible.builtin.file:
path: "{{ output_dir_test }}"
state: directory
mode: "0755"
##
## sysctl - file manipulation
##
- name: copy the example conf to the test dir
copy:
- name: Copy the example conf to the test dir
ansible.builtin.copy:
src: sysctl.conf
dest: "{{ output_dir_test }}"
mode: "0644"
- name: Set vm.swappiness to 5
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: 5
state: present
reload: no
reload: false
sysctl_file: "{{ output_dir_test }}/sysctl.conf"
register: sysctl_test0
- debug:
- name: Debug sysctl_test0
ansible.builtin.debug:
var: sysctl_test0
verbosity: 1
- name: get file content
shell: "cat {{ output_dir_test }}/sysctl.conf | egrep -v ^\\#"
- name: Get file content
ansible.builtin.shell:
cmd: set -o pipefail && cat {{ output_dir_test }}/sysctl.conf | egrep -v ^\#
executable: /bin/bash
changed_when: false
register: sysctl_content0
- debug:
- name: Debug sysctl_content0
ansible.builtin.debug:
var: sysctl_content0
verbosity: 1
- name: Set vm.swappiness to 5 again
sysctl:
name: vm.swappiness
value: 5
state: present
reload: no
sysctl_file: "{{ output_dir_test }}/sysctl.conf"
ansible.posix.sysctl:
name: vm.swappiness
value: 5
state: present
reload: false
sysctl_file: "{{ output_dir_test }}/sysctl.conf"
register: sysctl_test1
- name: validate results
assert:
that:
- sysctl_test0 is changed
- sysctl_test1 is not changed
- 'sysctl_content0.stdout_lines[sysctl_content0.stdout_lines.index("vm.swappiness=5")] == "vm.swappiness=5"'
- name: Validate results
ansible.builtin.assert:
that:
- sysctl_test0 is changed
- sysctl_test1 is not changed
- sysctl_content0.stdout_lines[sysctl_content0.stdout_lines.index("vm.swappiness=5")] == "vm.swappiness=5"
- name: Remove kernel.panic
sysctl:
ansible.posix.sysctl:
name: kernel.panic
value: 2
reload: no
reload: false
state: absent
sysctl_file: "{{ output_dir_test }}/sysctl.conf"
register: sysctl_test2
- name: get file content
shell: "cat {{ output_dir_test }}/sysctl.conf | egrep -v ^\\#"
- name: Get file content
ansible.builtin.shell:
cmd: set -o pipefail && cat {{ output_dir_test }}/sysctl.conf | egrep -v ^\#
executable: /bin/bash
changed_when: false
register: sysctl_content2
- debug:
- name: Debug sysctl_test2 sysctl_content2
ansible.builtin.debug:
var: item
verbosity: 1
with_items:
@ -104,38 +117,39 @@
- "{{ sysctl_content2 }}"
- name: Validate results for key removal
assert:
ansible.builtin.assert:
that:
- sysctl_test2 is changed
- "'kernel.panic' not in sysctl_content2.stdout_lines"
- name: Test remove kernel.panic again
sysctl:
ansible.posix.sysctl:
name: kernel.panic
value: 2
state: absent
reload: no
reload: false
sysctl_file: "{{ output_dir_test }}/sysctl.conf"
register: sysctl_test2_change_test
- name: Assert that no change was made
assert:
ansible.builtin.assert:
that:
- sysctl_test2_change_test is not changed
- name: Try sysctl with an invalid name
sysctl:
ansible.posix.sysctl:
name: test.invalid
value: 1
register: sysctl_test3
ignore_errors: yes
ignore_errors: true
- debug:
- name: Debug sysctl_test3
ansible.builtin.debug:
var: sysctl_test3
verbosity: 1
- name: validate results for test 3
assert:
- name: Validate results for test 3
ansible.builtin.assert:
that:
- sysctl_test3 is failed
@ -143,77 +157,79 @@
## sysctl - sysctl_set
##
- name: set net.ipv4.ip_forward
sysctl:
- name: Set net.ipv4.ip_forward
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: 1
sysctl_set: yes
reload: no
sysctl_set: true
reload: false
register: sysctl_test3
- name: check with sysctl command
shell: sysctl net.ipv4.ip_forward
- name: Check with sysctl command
ansible.builtin.command: sysctl net.ipv4.ip_forward
changed_when: false
register: sysctl_check3
- debug:
- name: Debug sysctl_test3 sysctl_check3
ansible.builtin.debug:
var: item
verbosity: 1
with_items:
- "{{ sysctl_test3 }}"
- "{{ sysctl_check3 }}"
- name: validate results for test 3
assert:
- name: Validate results for test 3
ansible.builtin.assert:
that:
- sysctl_test3 is changed
- 'sysctl_check3.stdout_lines == ["net.ipv4.ip_forward = 1"]'
- sysctl_check3.stdout_lines == ["net.ipv4.ip_forward = 1"]
- name: Try sysctl with no name
sysctl:
name:
ansible.posix.sysctl:
name: ""
value: 1
sysctl_set: yes
ignore_errors: True
sysctl_set: true
ignore_errors: true
register: sysctl_no_name
- name: validate nameless results
assert:
- name: Validate nameless results
ansible.builtin.assert:
that:
- sysctl_no_name is failed
- "sysctl_no_name.msg == 'name cannot be None'"
- sysctl_no_name.msg == 'name cannot be blank'
- name: Try sysctl with no value
sysctl:
ansible.posix.sysctl:
name: Foo
value:
sysctl_set: yes
ignore_errors: True
sysctl_set: true
ignore_errors: true
register: sysctl_no_value
- name: validate nameless results
assert:
- name: Validate nameless results
ansible.builtin.assert:
that:
- sysctl_no_value is failed
- "sysctl_no_value.msg == 'value cannot be None'"
- sysctl_no_value.msg == 'value cannot be None'
- name: Try sysctl with an invalid name
sysctl:
ansible.posix.sysctl:
name: test.invalid
value: 1
sysctl_set: yes
sysctl_set: true
register: sysctl_test4
ignore_errors: yes
ignore_errors: true
- debug:
- name: Debug sysctl_test4
ansible.builtin.debug:
var: sysctl_test4
verbosity: 1
- name: validate results for test 4
assert:
- name: Validate results for test 4
ansible.builtin.assert:
that:
- sysctl_test4 is failed
- name: Test on RHEL VMs
when:
- ansible_facts.virtualization_type != 'docker'
@ -221,34 +237,37 @@
block:
# Test reload: yes
- name: Set sysctl property using module
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: '22'
value: "22"
state: present
reload: yes
reload: true
register: sysctl_set1
- name: Change sysctl property using command
command: sysctl vm.swappiness=33
ansible.builtin.command: sysctl vm.swappiness=33
changed_when: true
- name: Set sysctl property using module
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: '22'
value: "22"
state: present
reload: yes
reload: true
register: sysctl_set2
- name: Read /etc/sysctl.conf
command: 'egrep -v ^# /etc/sysctl.conf'
ansible.builtin.command: egrep -v ^# /etc/sysctl.conf
changed_when: false
register: sysctl_conf_content
- name: Get current value of vm.swappiness
command: sysctl -n vm.swappiness
ansible.builtin.command: sysctl -n vm.swappiness
changed_when: false
register: sysctl_current_vm_swappiness
- name: Ensure changes were made appropriately
assert:
ansible.builtin.assert:
that:
- sysctl_set1 is changed
- sysctl_set2 is changed
@ -257,33 +276,35 @@
# Test reload: yes in check mode
- name: Set the same value using module in check mode
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: '22'
value: "22"
state: present
reload: yes
check_mode: yes
reload: true
check_mode: true
register: sysctl_check_mode1
- name: Set a different value using module in check mode
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: '44'
value: "44"
state: present
reload: yes
check_mode: yes
reload: true
check_mode: true
register: sysctl_check_mode2
- name: Read /etc/sysctl.conf
command: 'egrep -v ^# /etc/sysctl.conf'
ansible.builtin.command: egrep -v ^# /etc/sysctl.conf
changed_when: false
register: sysctl_check_mode_conf_content
- name: Get current value of vm.swappiness
command: sysctl -n vm.swappiness
ansible.builtin.command: sysctl -n vm.swappiness
changed_when: false
register: sysctl_check_mode_current_vm_swappiness
- name: Ensure no changes were made in check mode
assert:
ansible.builtin.assert:
that:
- sysctl_check_mode1 is success
- sysctl_check_mode2 is changed
@ -292,21 +313,22 @@
# Test sysctl: invalid value
- name: Set invalid sysctl property using module
sysctl:
ansible.posix.sysctl:
name: vm.mmap_rnd_bits
value: '1024'
value: "1024"
state: present
reload: yes
sysctl_set: True
ignore_errors: True
reload: true
sysctl_set: true
ignore_errors: true
register: sysctl_invalid_set1
- name: Read /etc/sysctl.conf
command: 'cat /etc/sysctl.conf'
ansible.builtin.command: cat /etc/sysctl.conf
changed_when: false
register: sysctl_invalid_conf_content
- name: Ensure changes were not made
assert:
ansible.builtin.assert:
that:
- sysctl_invalid_set1 is failed
- "'vm.mmap_rnd_bits' not in sysctl_invalid_conf_content.stdout"

View file

@ -1,4 +0,0 @@
integration_tests_dependencies:
- community.general
unit_tests_dependencies:
- community.general

View file

@ -1,8 +0,0 @@
plugins/modules/synchronize.py pylint:blacklisted-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View file

@ -1,8 +0,0 @@
plugins/modules/synchronize.py pylint:blacklisted-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View file

@ -1,8 +0,0 @@
plugins/modules/synchronize.py pylint:disallowed-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View file

@ -1,8 +0,0 @@
plugins/modules/synchronize.py pylint:disallowed-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

Some files were not shown because too many files have changed in this diff Show more