Merge branch 'main' into bugfix_masquerade_icmp_block_inversion

This commit is contained in:
Adam Miller 2023-04-12 17:09:22 -05:00 committed by GitHub
commit 9d1f67042e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 1706 additions and 267 deletions

View file

@ -53,8 +53,8 @@ stages:
targets: targets:
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: Fedora 36 - name: Fedora 37
test: fedora36 test: fedora37
- name: openSUSE 15 py3 - name: openSUSE 15 py3
test: opensuse15 test: opensuse15
- name: Ubuntu 20.04 - name: Ubuntu 20.04
@ -135,18 +135,12 @@ stages:
test: centos6 test: centos6
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: Fedora 32
test: fedora32
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py2 - name: openSUSE 15 py2
test: opensuse15py2 test: opensuse15py2
- name: openSUSE 15 py3 - name: openSUSE 15 py3
test: opensuse15 test: opensuse15
- name: Ubuntu 18.04 - name: Ubuntu 18.04
test: ubuntu1804 test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_10 - stage: Docker_2_10
displayName: Docker 2.10 displayName: Docker 2.10
dependsOn: [] dependsOn: []
@ -159,10 +153,6 @@ stages:
test: centos6 test: centos6
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2 - name: openSUSE 15 py2
test: opensuse15py2 test: opensuse15py2
- name: openSUSE 15 py3 - name: openSUSE 15 py3
@ -183,10 +173,6 @@ stages:
test: centos6 test: centos6
- name: CentOS 7 - name: CentOS 7
test: centos7 test: centos7
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2 - name: openSUSE 15 py2
test: opensuse15py2 test: opensuse15py2
- name: openSUSE 15 py3 - name: openSUSE 15 py3
@ -205,14 +191,16 @@ stages:
parameters: parameters:
testFormat: devel/{0}/1 testFormat: devel/{0}/1
targets: targets:
- name: MacOS 12.0 - name: MacOS 13.2
test: macos/12.0 test: macos/13.2
- name: RHEL 7.9 - name: RHEL 7.9
test: rhel/7.9 test: rhel/7.9
- name: RHEL 8.6 - name: RHEL 8.7
test: rhel/8.6 test: rhel/8.7
- name: RHEL 9.0 - name: RHEL 9.1
test: rhel/9.0 test: rhel/9.1
- name: FreeBSD 12.4
test: freebsd/12.4
- name: FreeBSD 13.1 - name: FreeBSD 13.1
test: freebsd/13.1 test: freebsd/13.1
- stage: Remote_2_14 - stage: Remote_2_14
@ -231,6 +219,8 @@ stages:
test: rhel/8.6 test: rhel/8.6
- name: RHEL 9.0 - name: RHEL 9.0
test: rhel/9.0 test: rhel/9.0
- name: FreeBSD 12.3
test: freebsd/12.3
- name: FreeBSD 13.1 - name: FreeBSD 13.1
test: freebsd/13.1 test: freebsd/13.1
- stage: Remote_2_13 - stage: Remote_2_13

View file

@ -5,6 +5,50 @@ ansible.posix Release Notes
.. contents:: Topics .. contents:: Topics
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 v1.4.0
====== ======

View file

@ -33,6 +33,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.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.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.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.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.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 [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

View file

@ -1,4 +1,4 @@
# This is a cross-platform list tracking distribution packages needed by tests; # This is a cross-platform list tracking distribution packages needed by tests;
# see https://docs.openstack.org/infra/bindep/ for additional information. # 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,64 @@ releases:
- sanity_fixes.yml - sanity_fixes.yml
- shell_escape_full_path_for_rsync.yml - shell_escape_full_path_for_rsync.yml
release_date: '2022-05-23' 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'

View file

@ -1,3 +0,0 @@
---
trivial:
- Update version number in galaxy.yml to 1.5.0.

View file

@ -1,3 +0,0 @@
---
trivial:
- CI - Refactor AZP to address new test infrastructure (https://github.com/ansible-collections/news-for-maintainers/issues/17).

View file

@ -1,3 +0,0 @@
---
bugfixes:
- firewall - Fixed to output a more complete missing library message.

View file

@ -1,3 +0,0 @@
---
trivial:
- CI - AZP test container to 3.0.0 (https://github.com/ansible-collections/news-for-maintainers/issues/18).

View file

@ -1,3 +0,0 @@
---
bugfixes:
- Removed contentious terminology to match reference documentation in profile_tasks.

View file

@ -1,3 +0,0 @@
---
trivial:
- CI - following the new CI testing rule ansible-test-sanity-docker-devel.

View file

@ -1,3 +0,0 @@
---
trivial:
- CI - Add stable-2.14 to AZP (https://github.com/ansible-collections/ansible.posix/issues/388).

View file

@ -1,5 +0,0 @@
---
minor_changes:
- 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

View file

@ -1,4 +0,0 @@
---
minor_changes:
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems

View file

@ -0,0 +1,3 @@
---
bugfixes:
- firewall - Fix issue where adding an interface to a zone would fail when the daemon is offline

View file

@ -49,8 +49,8 @@ Parameters
</ul> </ul>
</td> </td>
<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>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>yes</code> causes an error if the path is a file.</div> <div>Setting <code>default</code> to <code>true</code> causes an error if the path is a file.</div>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -63,6 +63,7 @@ Parameters
</div> </div>
</td> </td>
<td> <td>
<b>Default:</b><br/><div style="color: blue">""</div>
</td> </td>
<td> <td>
<div>The actual user or group that the ACL applies to when matching entity types user or group are selected.</div> <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 entity: joe
etype: user etype: user
permissions: rw permissions: rw
default: yes default: true
state: present state: present
- name: Same as previous but using entry shorthand - name: Same as previous but using entry shorthand

View file

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

View file

@ -139,8 +139,8 @@ Parameters
</td> </td>
<td> <td>
<div>Whether this module should manage the directory of the authorized key file.</div> <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>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=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>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> <div>See the example below.</div>
</td> </td>
</tr> </tr>
@ -212,9 +212,9 @@ Parameters
</td> </td>
<td> <td>
<div>This only applies if using a https url as the source of the keys.</div> <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>If set to <code>false</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>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>yes</code>.</div> <div>Prior to 2.1 the code worked as if this was set to <code>true</code>.</div>
</td> </td>
</tr> </tr>
</table> </table>
@ -252,7 +252,7 @@ Examples
state: present state: present
key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"
path: /etc/ssh/authorized_keys/charlie path: /etc/ssh/authorized_keys/charlie
manage_dir: False manage_dir: false
- name: Set up multiple authorized keys - name: Set up multiple authorized keys
ansible.posix.authorized_key: ansible.posix.authorized_key:
@ -275,14 +275,14 @@ Examples
user: charlie user: charlie
state: present state: present
key: https://github.com/user.keys key: https://github.com/user.keys
validate_certs: False validate_certs: false
- name: Set authorized key, removing all the authorized keys already set - name: Set authorized key, removing all the authorized keys already set
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: root user: root
key: "{{ lookup('file', 'public_keys/doe-jane') }}" key: "{{ lookup('file', 'public_keys/doe-jane') }}"
state: present state: present
exclusive: True exclusive: true
- name: Set authorized key for user ubuntu copying it from current user - name: Set authorized key for user ubuntu copying it from current user
ansible.posix.authorized_key: ansible.posix.authorized_key:
@ -460,7 +460,7 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
</td> </td>
<td>success</td> <td>success</td>
<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/> <br/>
<div style="font-size: smaller"><b>Sample:</b></div> <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> <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 - name: Gather information about active zones
ansible.posix.firewalld_info: 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 - name: Gather information about specific zones
ansible.posix.firewalld_info: ansible.posix.firewalld_info:
@ -97,6 +102,7 @@ Examples
- public - public
- external - external
- internal - 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 class="elbow-placeholder">&nbsp;</td>
<td colspan="3"> <td colspan="3">
<div class="ansibleOptionAnchor" id="return-"></div> <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> <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small"> <div style="font-size: small">
<span style="color: purple">string</span> <span style="color: purple">string</span>

View file

@ -155,7 +155,7 @@ Parameters
<td> <td>
<div>Should this configuration be in the running firewalld configuration or persist across reboots.</div> <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>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> </td>
</tr> </tr>
<tr> <tr>
@ -262,6 +262,21 @@ Parameters
</td> </td>
</tr> </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> <tr>
<td colspan="2"> <td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div> <div class="ansibleOptionAnchor" id="parameter-"></div>
@ -414,29 +429,35 @@ Examples
- name: permit traffic in default zone for https service - name: permit traffic in default zone for https service
ansible.posix.firewalld: ansible.posix.firewalld:
service: https service: https
permanent: yes permanent: true
state: enabled
- name: permit ospf traffic
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled state: enabled
- name: do not permit traffic in default zone on port 8081/tcp - name: do not permit traffic in default zone on port 8081/tcp
ansible.posix.firewalld: ansible.posix.firewalld:
port: 8081/tcp port: 8081/tcp
permanent: yes permanent: true
state: disabled state: disabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
port: 161-162/udp port: 161-162/udp
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: dmz zone: dmz
service: http service: http
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
rich_rule: rule service name="ftp" audit limit value="1/m" accept rich_rule: rule service name="ftp" audit limit value="1/m" accept
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
@ -447,44 +468,44 @@ Examples
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: trusted zone: trusted
interface: eth2 interface: eth2
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
masquerade: yes masquerade: true
state: enabled state: enabled
permanent: yes permanent: true
zone: dmz zone: dmz
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: custom zone: custom
state: present state: present
permanent: yes permanent: true
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: drop zone: drop
state: enabled state: enabled
permanent: yes permanent: true
icmp_block_inversion: yes icmp_block_inversion: true
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: drop zone: drop
state: enabled state: enabled
permanent: yes permanent: true
icmp_block: echo-request icmp_block: echo-request
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: internal zone: internal
state: present state: present
permanent: yes permanent: true
target: ACCEPT target: ACCEPT
- name: Redirect port 443 to 8443 with Rich Rule - name: Redirect port 443 to 8443 with Rich Rule
ansible.posix.firewalld: ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443 rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
zone: public zone: public
permanent: yes permanent: true
immediate: yes immediate: true
state: enabled 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 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>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>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> </td>
</tr> </tr>
<tr> <tr>
@ -90,7 +91,7 @@ Parameters
<td> <td>
<div>Dump (see fstab(5)).</div> <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>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> </td>
</tr> </tr>
<tr> <tr>
@ -110,6 +111,7 @@ Parameters
<div>This might be useful if you need to configure mountpoints in a chroot environment.</div> <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>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 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> </td>
</tr> </tr>
<tr> <tr>
@ -125,7 +127,7 @@ Parameters
</td> </td>
<td> <td>
<div>Filesystem type.</div> <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> </td>
</tr> </tr>
<tr> <tr>
@ -158,7 +160,7 @@ Parameters
<td> <td>
<div>Passno (see fstab(5)).</div> <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>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> </td>
</tr> </tr>
<tr> <tr>
@ -192,7 +194,7 @@ Parameters
</td> </td>
<td> <td>
<div>Device (or NFS volume, or something else) to be mounted on <em>path</em>.</div> <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> </td>
</tr> </tr>
<tr> <tr>
@ -208,18 +210,22 @@ Parameters
<td> <td>
<ul style="margin: 0; padding: 0"><b>Choices:</b> <ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>absent</li> <li>absent</li>
<li>absent_from_fstab</li>
<li>mounted</li> <li>mounted</li>
<li>present</li> <li>present</li>
<li>unmounted</li> <li>unmounted</li>
<li>remounted</li> <li>remounted</li>
<li>ephemeral</li>
</ul> </ul>
</td> </td>
<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>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>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>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>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> </td>
</tr> </tr>
</table> </table>
@ -304,10 +310,18 @@ Examples
src: 192.168.1.100:/nfs/ssd/shared_data src: 192.168.1.100:/nfs/ssd/shared_data
path: /mnt/shared_data path: /mnt/shared_data
opts: rw,sync,hard opts: rw,sync,hard
boot: no boot: false
state: mounted state: mounted
fstype: nfs 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> </ul>
</td> </td>
<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>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> </td>
</tr> </tr>
<tr> <tr>
@ -122,7 +122,7 @@ Parameters
</ul> </ul>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -141,7 +141,7 @@ Parameters
</ul> </ul>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -157,7 +157,7 @@ Parameters
<td> <td>
</td> </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> <div style="font-size: small; color: darkgreen"><br/>aliases: patchfile</div>
</td> </td>
</tr> </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> </ul>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -135,8 +135,8 @@ Examples
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots - name: Set httpd_can_network_connect flag on and keep it persistent across reboots
ansible.posix.seboolean: ansible.posix.seboolean:
name: httpd_can_network_connect name: httpd_can_network_connect
state: yes state: true
persistent: yes persistent: true

View file

@ -150,7 +150,7 @@ Parameters
</td> </td>
<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>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> <div>This option ignores excluded files and behaves like the rsync opt <code>--delete-after</code>.</div>
</td> </td>
</tr> </tr>
@ -465,7 +465,7 @@ Parameters
</td> </td>
<td> <td>
<div>Put user@ for the remote paths.</div> <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> </td>
</tr> </tr>
<tr> <tr>
@ -502,8 +502,8 @@ Parameters
</td> </td>
<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>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>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>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>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> </td>
</tr> </tr>
<tr> <tr>
@ -595,8 +595,8 @@ See Also
.. seealso:: .. seealso::
:ref:`copy_module` :ref:`ansible.builtin.copy_module`
The official documentation on the **copy** module. The official documentation on the **ansible.builtin.copy** module.
:ref:`community.windows.win_robocopy_module` :ref:`community.windows.win_robocopy_module`
The official documentation on the **community.windows.win_robocopy** module. The official documentation on the **community.windows.win_robocopy** module.
@ -639,27 +639,27 @@ Examples
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
archive: no archive: false
- name: Synchronization with --archive options enabled except for --recursive - name: Synchronization with --archive options enabled except for --recursive
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
recursive: no recursive: false
- name: Synchronization with --archive options enabled except for --times, with --checksum option enabled - name: Synchronization with --archive options enabled except for --times, with --checksum option enabled
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
checksum: yes checksum: true
times: no times: false
- name: Synchronization without --archive options enabled except use --links - name: Synchronization without --archive options enabled except use --links
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
archive: no archive: false
links: yes links: true
- name: Synchronization of two paths both on the control machine - name: Synchronization of two paths both on the control machine
ansible.posix.synchronize: ansible.posix.synchronize:
@ -689,8 +689,8 @@ Examples
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
delete: yes delete: true
recursive: yes recursive: true
# This specific command is granted su privileges on the destination # This specific command is granted su privileges on the destination
- name: Synchronize using an alternate rsync command - name: Synchronize using an alternate rsync command

View file

@ -85,7 +85,7 @@ Parameters
</ul> </ul>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -139,7 +139,7 @@ Parameters
</ul> </ul>
</td> </td>
<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> </td>
</tr> </tr>
<tr> <tr>
@ -186,21 +186,21 @@ Examples
name: kernel.panic name: kernel.panic
value: '3' value: '3'
sysctl_file: /tmp/test_sysctl.conf sysctl_file: /tmp/test_sysctl.conf
reload: no reload: false
# Set ip forwarding on in /proc and verify token value with the sysctl command # Set ip forwarding on in /proc and verify token value with the sysctl command
- ansible.posix.sysctl: - ansible.posix.sysctl:
name: net.ipv4.ip_forward name: net.ipv4.ip_forward
value: '1' value: '1'
sysctl_set: yes sysctl_set: true
# Set ip forwarding on in /proc and in the sysctl file and reload if necessary # Set ip forwarding on in /proc and in the sysctl file and reload if necessary
- ansible.posix.sysctl: - ansible.posix.sysctl:
name: net.ipv4.ip_forward name: net.ipv4.ip_forward
value: '1' value: '1'
sysctl_set: yes sysctl_set: true
state: present state: present
reload: yes reload: true

View file

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

View file

@ -225,7 +225,6 @@ class ActionModule(ActionBase):
# Parameter name needed by the ansible module # Parameter name needed by the ansible module
_tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync' _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 # 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 # 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: if src is None or dest is None:
return dict(failed=True, msg="synchronize requires both src and dest parameters are set") 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 user = None
password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None)
if not dest_is_local: if not dest_is_local:
# Src and dest rsync "path" handling # Src and dest rsync "path" handling
if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False): 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 user = task_vars.get('ansible_user') or self._play_context.remote_user
if not user: if not user:
user = C.DEFAULT_REMOTE_USER user = C.DEFAULT_REMOTE_USER
else: else:
user = task_vars.get('ansible_user') or self._play_context.remote_user 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 # Private key handling
# Use the private_key parameter if passed else use context private_key_file # 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) _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 is a local path, dest is a remote path: <user>@<host>
src = self._process_origin(src_host, src, user) src = self._process_origin(src_host, src, user)
dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports) 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: else:
# Still need to munge paths (to account for roles) even if we aren't # Still need to munge paths (to account for roles) even if we aren't
# copying files between hosts # copying files between hosts
src = self._get_absolute_path(path=src) src = self._get_absolute_path(path=src)
dest = self._get_absolute_path(path=dest) dest = self._get_absolute_path(path=dest)
_tmp_args['_local_rsync_password'] = password
_tmp_args['src'] = src _tmp_args['src'] = src
_tmp_args['dest'] = dest _tmp_args['dest'] = dest

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

@ -0,0 +1,196 @@
# (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
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
def _new_play(self, play):
self._is_lockstep = play.strategy in LOCKSTEP_CALLBACKS
return {
'play': {
'name': play.get_name(),
'id': to_text(play._uuid),
'duration': {
'start': current_time()
}
},
'tasks': []
}
def _new_task(self, task):
return {
'task': {
'name': task.get_name(),
'id': to_text(task._uuid),
'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, 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

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

View file

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

View file

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

View file

@ -34,13 +34,13 @@ options:
manage_dir: manage_dir:
description: description:
- Whether this module should manage the directory of the authorized key file. - 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. 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. as set with C(path), since you could lock yourself out of SSH access.
- See the example below. - See the example below.
type: bool type: bool
default: yes default: true
state: state:
description: description:
- Whether the given key (with the given key_options) should or should not be in the file. - 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. - 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. - 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 type: bool
default: no default: false
validate_certs: validate_certs:
description: description:
- This only applies if using a https url as the source of the keys. - 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. - If set to C(false), 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. - 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(yes). - Prior to 2.1 the code worked as if this was set to C(true).
type: bool type: bool
default: yes default: true
comment: comment:
description: description:
- Change the comment on the public key. - Change the comment on the public key.
@ -77,7 +77,7 @@ options:
description: description:
- Follow path symlink instead of replacing it. - Follow path symlink instead of replacing it.
type: bool type: bool
default: no default: false
author: Ansible Core Team author: Ansible Core Team
''' '''
@ -106,7 +106,7 @@ EXAMPLES = r'''
state: present state: present
key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"
path: /etc/ssh/authorized_keys/charlie path: /etc/ssh/authorized_keys/charlie
manage_dir: False manage_dir: false
- name: Set up multiple authorized keys - name: Set up multiple authorized keys
ansible.posix.authorized_key: ansible.posix.authorized_key:
@ -129,14 +129,14 @@ EXAMPLES = r'''
user: charlie user: charlie
state: present state: present
key: https://github.com/user.keys key: https://github.com/user.keys
validate_certs: False validate_certs: false
- name: Set authorized key, removing all the authorized keys already set - name: Set authorized key, removing all the authorized keys already set
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: root user: root
key: "{{ lookup('file', 'public_keys/doe-jane') }}" key: "{{ lookup('file', 'public_keys/doe-jane') }}"
state: present state: present
exclusive: True exclusive: true
- name: Set authorized key for user ubuntu copying it from current user - name: Set authorized key for user ubuntu copying it from current user
ansible.posix.authorized_key: ansible.posix.authorized_key:
@ -150,7 +150,7 @@ exclusive:
description: If the key has been forced to be exclusive or not. description: If the key has been forced to be exclusive or not.
returned: success returned: success
type: bool type: bool
sample: False sample: false
key: key:
description: The key that the module was running against. description: The key that the module was running against.
returned: success returned: success
@ -170,7 +170,7 @@ manage_dir:
description: Whether this module managed the directory of the authorized key file. description: Whether this module managed the directory of the authorized key file.
returned: success returned: success
type: bool type: bool
sample: True sample: true
path: path:
description: Alternate path to the authorized_keys file description: Alternate path to the authorized_keys file
returned: success returned: success
@ -192,7 +192,7 @@ user:
type: str type: str
sample: user sample: user
validate_certs: 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 returned: success
type: bool type: bool
sample: true sample: true

View file

@ -19,6 +19,10 @@ options:
- Name of a service to add/remove to/from firewalld. - Name of a service to add/remove to/from firewalld.
- The service must be listed in output of firewall-cmd --get-services. - The service must be listed in output of firewall-cmd --get-services.
type: str type: str
protocol:
description:
- Name of a protocol to add/remove to/from firewalld.
type: str
port: port:
description: description:
- Name of a port or port range to add/remove to/from firewalld. - Name of a port or port range to add/remove to/from firewalld.
@ -82,13 +86,13 @@ options:
description: description:
- Should this configuration be in the running firewalld configuration or persist across reboots. - Should this configuration be in the running firewalld configuration or persist across reboots.
- As of Ansible 2.3, permanent operations can operate on firewalld configs when it is not running (requires firewalld >= 0.3.9). - 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), immediate is assumed C(true).
type: bool type: bool
immediate: immediate:
description: description:
- Should this configuration be applied immediately, if set as permanent. - Should this configuration be applied immediately, if set as permanent.
type: bool type: bool
default: no default: false
state: state:
description: description:
- Enable or disable a setting. - Enable or disable a setting.
@ -141,29 +145,35 @@ EXAMPLES = r'''
- name: permit traffic in default zone for https service - name: permit traffic in default zone for https service
ansible.posix.firewalld: ansible.posix.firewalld:
service: https service: https
permanent: yes permanent: true
state: enabled
- name: permit ospf traffic
ansible.posix.firewalld:
protocol: ospf
permanent: true
state: enabled state: enabled
- name: do not permit traffic in default zone on port 8081/tcp - name: do not permit traffic in default zone on port 8081/tcp
ansible.posix.firewalld: ansible.posix.firewalld:
port: 8081/tcp port: 8081/tcp
permanent: yes permanent: true
state: disabled state: disabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
port: 161-162/udp port: 161-162/udp
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: dmz zone: dmz
service: http service: http
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
rich_rule: rule service name="ftp" audit limit value="1/m" accept rich_rule: rule service name="ftp" audit limit value="1/m" accept
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
@ -174,44 +184,44 @@ EXAMPLES = r'''
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: trusted zone: trusted
interface: eth2 interface: eth2
permanent: yes permanent: true
state: enabled state: enabled
- ansible.posix.firewalld: - ansible.posix.firewalld:
masquerade: yes masquerade: true
state: enabled state: enabled
permanent: yes permanent: true
zone: dmz zone: dmz
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: custom zone: custom
state: present state: present
permanent: yes permanent: true
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: drop zone: drop
state: enabled state: enabled
permanent: yes permanent: true
icmp_block_inversion: yes icmp_block_inversion: true
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: drop zone: drop
state: enabled state: enabled
permanent: yes permanent: true
icmp_block: echo-request icmp_block: echo-request
- ansible.posix.firewalld: - ansible.posix.firewalld:
zone: internal zone: internal
state: present state: present
permanent: yes permanent: true
target: ACCEPT target: ACCEPT
- name: Redirect port 443 to 8443 with Rich Rule - name: Redirect port 443 to 8443 with Rich Rule
ansible.posix.firewalld: ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443 rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
zone: public zone: public
permanent: yes permanent: true
immediate: yes immediate: true
state: enabled state: enabled
''' '''
@ -343,6 +353,47 @@ class ServiceTransaction(FirewallTransaction):
self.update_fw_settings(fw_zone, fw_settings) 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): class MasqueradeTransaction(FirewallTransaction):
""" """
MasqueradeTransaction MasqueradeTransaction
@ -469,6 +520,7 @@ class InterfaceTransaction(FirewallTransaction):
old_zone_obj = self.fw.config.get_zone(zone) old_zone_obj = self.fw.config.get_zone(zone)
if interface in old_zone_obj.interfaces: if interface in old_zone_obj.interfaces:
iface_zone_objs.append(old_zone_obj) iface_zone_objs.append(old_zone_obj)
if len(iface_zone_objs) > 1: if len(iface_zone_objs) > 1:
# Even it shouldn't happen, it's actually possible that # Even it shouldn't happen, it's actually possible that
# the same interface is in several zone XML files # the same interface is in several zone XML files
@ -478,18 +530,17 @@ class InterfaceTransaction(FirewallTransaction):
len(iface_zone_objs) len(iface_zone_objs)
) )
) )
old_zone_obj = iface_zone_objs[0] elif len(iface_zone_objs) == 1 and iface_zone_objs[0].name != self.zone:
if old_zone_obj.name != self.zone: old_zone_obj = iface_zone_objs[0]
old_zone_settings = FirewallClientZoneSettings( old_zone_config = self.fw.config.get_zone_config(old_zone_obj)
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 old_zone_settings.removeInterface(interface) # remove from old
self.fw.config.set_zone_config( self.fw.config.set_zone_config(
old_zone_obj, old_zone_obj,
old_zone_settings.settings old_zone_settings.settings
) )
fw_settings.addInterface(interface) # add to new fw_settings.addInterface(interface) # add to new
self.fw.config.set_zone_config(fw_zone, fw_settings.settings) self.fw.config.set_zone_config(fw_zone, fw_settings.settings)
else: else:
old_zone_name = self.fw.config().getZoneOfInterface(interface) old_zone_name = self.fw.config().getZoneOfInterface(interface)
if old_zone_name != self.zone: if old_zone_name != self.zone:
@ -675,25 +726,33 @@ class ZoneTransaction(FirewallTransaction):
self.module.fail_json(msg=self.tx_not_permanent_error_msg) self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def get_enabled_permanent(self): def get_enabled_permanent(self):
zones = self.fw.config().listZones() if self.fw_offline:
zone_names = [self.fw.config().getZone(z).get_property("name") for z in zones] zones = self.fw.config.get_zones()
if self.zone in zone_names: zone_names = [self.fw.config.get_zone(z).name for z in zones]
return True
else: 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): def set_enabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg) self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_enabled_permanent(self): 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): def set_disabled_immediate(self):
self.module.fail_json(msg=self.tx_not_permanent_error_msg) self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_disabled_permanent(self): def set_disabled_permanent(self):
zone_obj = self.fw.config().getZoneByName(self.zone) if self.fw_offline:
zone_obj.remove() 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): class ForwardPortTransaction(FirewallTransaction):
@ -740,6 +799,7 @@ def main():
icmp_block=dict(type='str'), icmp_block=dict(type='str'),
icmp_block_inversion=dict(type='str'), icmp_block_inversion=dict(type='str'),
service=dict(type='str'), service=dict(type='str'),
protocol=dict(type='str'),
port=dict(type='str'), port=dict(type='str'),
port_forward=dict(type='list', elements='dict'), port_forward=dict(type='list', elements='dict'),
rich_rule=dict(type='str'), rich_rule=dict(type='str'),
@ -761,7 +821,7 @@ def main():
source=('permanent',), source=('permanent',),
), ),
mutually_exclusive=[ 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'] 'interface', 'masquerade', 'source', 'target']
], ],
) )
@ -790,6 +850,7 @@ def main():
icmp_block = module.params['icmp_block'] icmp_block = module.params['icmp_block']
icmp_block_inversion = module.params['icmp_block_inversion'] icmp_block_inversion = module.params['icmp_block_inversion']
service = module.params['service'] service = module.params['service']
protocol = module.params['protocol']
rich_rule = module.params['rich_rule'] rich_rule = module.params['rich_rule']
source = module.params['source'] source = module.params['source']
zone = module.params['zone'] zone = module.params['zone']
@ -821,7 +882,7 @@ def main():
port_forward_toaddr = port_forward['toaddr'] port_forward_toaddr = port_forward['toaddr']
modification = False 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]): interface, masquerade, source, target]):
modification = True modification = True
if modification and desired_state in ['absent', 'present'] and target is None: if modification and desired_state in ['absent', 'present'] and target is None:
@ -886,6 +947,22 @@ def main():
if changed is True: if changed is True:
msgs.append("Changed service %s to %s" % (service, desired_state)) 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: if source is not None:
transaction = SourceTransaction( transaction = SourceTransaction(

View file

@ -17,7 +17,7 @@ options:
active_zones: active_zones:
description: Gather information about active zones. description: Gather information about active zones.
type: bool type: bool
default: no default: false
zones: zones:
description: description:
- Gather information about specific zones. - Gather information about specific zones.
@ -36,7 +36,12 @@ author:
EXAMPLES = r''' EXAMPLES = r'''
- name: Gather information about active zones - name: Gather information about active zones
ansible.posix.firewalld_info: 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 - name: Gather information about specific zones
ansible.posix.firewalld_info: ansible.posix.firewalld_info:
@ -44,6 +49,7 @@ EXAMPLES = r'''
- public - public
- external - external
- internal - internal
register: result
''' '''
RETURN = r''' RETURN = r'''
@ -78,7 +84,7 @@ firewalld_info:
returned: success returned: success
type: str type: str
sample: 0.8.2 sample: 0.8.2
default_zones: default_zone:
description: description:
- The zone name of default zone. - The zone name of default zone.
returned: success returned: success
@ -204,7 +210,6 @@ firewalld_info:
''' '''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib 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.module_utils._text import to_native
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion

View file

@ -31,12 +31,12 @@ options:
src: src:
description: description:
- Device (or NFS volume, or something else) to be mounted on I(path). - 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 type: path
fstype: fstype:
description: description:
- Filesystem type. - 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 type: str
opts: opts:
description: description:
@ -48,7 +48,7 @@ options:
- Note that if set to C(null) and I(state) set to C(present), - 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 it will cease to work and duplicate entries will be made
with subsequent runs. with subsequent runs.
- Has no effect on Solaris systems. - Has no effect on Solaris systems or when used with C(ephemeral).
type: str type: str
default: '0' default: '0'
passno: passno:
@ -57,7 +57,7 @@ options:
- Note that if set to C(null) and I(state) set to C(present), - 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 it will cease to work and duplicate entries will be made
with subsequent runs. with subsequent runs.
- Deprecated on Solaris systems. - Deprecated on Solaris systems. Has no effect when used with C(ephemeral).
type: str type: str
default: '0' default: '0'
state: state:
@ -68,6 +68,13 @@ options:
- If C(unmounted), the device will be unmounted without changing I(fstab). - If C(unmounted), the device will be unmounted without changing I(fstab).
- C(present) only specifies that the device is to be configured in - C(present) only specifies that the device is to be configured in
I(fstab) and does not trigger or require a mount. 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 - 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 I(fstab) and will also unmount the device and remove the mount
point. point.
@ -77,10 +84,15 @@ options:
applied to the remount, but will not change I(fstab). Additionally, applied to the remount, but will not change I(fstab). Additionally,
if I(opts) is set, and the remount command fails, the module will if I(opts) is set, and the remount command fails, the module will
error to prevent unexpected mount changes. Try using C(mounted) 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 type: str
required: true required: true
choices: [ absent, mounted, present, unmounted, remounted ] choices: [ absent, absent_from_fstab, mounted, present, unmounted, remounted, ephemeral ]
fstab: fstab:
description: description:
- File to use instead of C(/etc/fstab). - 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 - 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. 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 defaults to /etc/fstab or /etc/vfstab on Solaris.
- This parameter is ignored when I(state) is set to C(ephemeral).
type: str type: str
boot: boot:
description: description:
@ -100,14 +113,15 @@ options:
to mount options in I(/etc/fstab). to mount options in I(/etc/fstab).
- To avoid mount option conflicts, if C(noauto) specified in C(opts), - To avoid mount option conflicts, if C(noauto) specified in C(opts),
mount module will ignore C(boot). mount module will ignore C(boot).
- This parameter is ignored when I(state) is set to C(ephemeral).
type: bool type: bool
default: yes default: true
backup: backup:
description: description:
- Create a backup file including the timestamp information so you can get - Create a backup file including the timestamp information so you can get
the original file back if you somehow clobbered it incorrectly. the original file back if you somehow clobbered it incorrectly.
type: bool type: bool
default: no default: false
notes: notes:
- As of Ansible 2.3, the I(name) option has been changed to I(path) as - As of Ansible 2.3, the I(name) option has been changed to I(path) as
default, but I(name) still works as well. default, but I(name) still works as well.
@ -181,9 +195,17 @@ EXAMPLES = r'''
src: 192.168.1.100:/nfs/ssd/shared_data src: 192.168.1.100:/nfs/ssd/shared_data
path: /mnt/shared_data path: /mnt/shared_data
opts: rw,sync,hard opts: rw,sync,hard
boot: no boot: false
state: mounted state: mounted
fstype: nfs 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 import errno
@ -430,6 +452,24 @@ def _set_fstab_args(fstab_file):
return result 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): def mount(module, args):
"""Mount up a path or remount if needed.""" """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 ' 'OpenBSD does not support alternate fstab files. Do not '
'specify the fstab parameter for OpenBSD hosts')) 'specify the fstab parameter for OpenBSD hosts'))
else: 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] cmd += [name]
@ -498,18 +542,24 @@ def remount(module, args):
'OpenBSD does not support alternate fstab files. Do not ' 'OpenBSD does not support alternate fstab files. Do not '
'specify the fstab parameter for OpenBSD hosts')) 'specify the fstab parameter for OpenBSD hosts'))
else: 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']] cmd += [args['name']]
out = err = '' out = err = ''
try: 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 # Note: Forcing BSDs to do umount/mount due to BSD remount not
# working as expected (suspect bug in the BSD mount command) # working as expected (suspect bug in the BSD mount command)
# Interested contributor could rework this to use mount options on # Interested contributor could rework this to use mount options on
# the CLI instead of relying on fstab # the CLI instead of relying on fstab
# https://github.com/ansible/ansible-modules-core/issues/5591 # 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 rc = 1
else: else:
rc, out, err = module.run_command(cmd) rc, out, err = module.run_command(cmd)
@ -663,6 +713,47 @@ def get_linux_mounts(module, mntinfo_file="/proc/self/mountinfo"):
return mounts 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(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
@ -675,12 +766,13 @@ def main():
passno=dict(type='str', no_log=False, default='0'), passno=dict(type='str', no_log=False, default='0'),
src=dict(type='path'), src=dict(type='path'),
backup=dict(type='bool', default=False), 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, supports_check_mode=True,
required_if=( required_if=(
['state', 'mounted', ['src', 'fstype']], ['state', 'mounted', ['src', 'fstype']],
['state', 'present', ['src', 'fstype']], ['state', 'present', ['src', 'fstype']],
['state', 'ephemeral', ['src', 'fstype']]
), ),
) )
@ -751,15 +843,17 @@ def main():
# If fstab file does not exist, we first need to create it. This mainly # If fstab file does not exist, we first need to create it. This mainly
# happens when fstab option is passed to the module. # happens when fstab option is passed to the module.
if not os.path.exists(args['fstab']): # If state is 'ephemeral', we do not need fstab file
if not os.path.exists(os.path.dirname(args['fstab'])): if module.params['state'] != 'ephemeral':
os.makedirs(os.path.dirname(args['fstab'])) if not os.path.exists(args['fstab']):
try: if not os.path.exists(os.path.dirname(args['fstab'])):
open(args['fstab'], 'a').close() os.makedirs(os.path.dirname(args['fstab']))
except PermissionError as e: try:
module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab']) open(args['fstab'], 'a').close()
except Exception as e: except PermissionError as e:
module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(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: # absent:
# Remove from fstab and unmounted. # Remove from fstab and unmounted.
@ -770,12 +864,16 @@ def main():
# mounted: # mounted:
# Add to fstab if not there and make sure it is mounted. If it has # Add to fstab if not there and make sure it is mounted. If it has
# changed in fstab then remount it. # changed in fstab then remount it.
# ephemeral:
# Do not change fstab state, but mount.
state = module.params['state'] state = module.params['state']
name = module.params['path'] name = module.params['path']
changed = False 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) name, changed = unset_mount(module, args)
if changed and not module.check_mode: if changed and not module.check_mode:
@ -801,7 +899,7 @@ def main():
msg="Error unmounting %s: %s" % (name, msg)) msg="Error unmounting %s: %s" % (name, msg))
changed = True changed = True
elif state == 'mounted': elif state == 'mounted' or state == 'ephemeral':
dirs_created = [] dirs_created = []
if not os.path.exists(name) and not module.check_mode: if not os.path.exists(name) and not module.check_mode:
try: try:
@ -829,7 +927,11 @@ def main():
module.fail_json( module.fail_json(
msg="Error making dir %s: %s" % (name, to_native(e))) 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 res = 0
if ( if (
@ -839,7 +941,26 @@ def main():
if changed and not module.check_mode: if changed and not module.check_mode:
res, msg = remount(module, args) res, msg = remount(module, args)
changed = True 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: else:
# If not already mounted, mount it
changed = True changed = True
if not module.check_mode: if not module.check_mode:
@ -851,7 +972,8 @@ def main():
# A non-working fstab entry may break the system at the reboot, # A non-working fstab entry may break the system at the reboot,
# so undo all the changes if possible. # so undo all the changes if possible.
try: try:
write_fstab(module, backup_lines, args['fstab']) if state != 'ephemeral':
write_fstab(module, backup_lines, args['fstab'])
except Exception: except Exception:
pass pass

View file

@ -37,7 +37,7 @@ options:
src: src:
description: description:
- Path of the patch file as accepted by the GNU patch tool. If - 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. module's I(files) directory.
type: path type: path
required: true required: true
@ -50,10 +50,10 @@ options:
default: present default: present
remote_src: remote_src:
description: 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). go to the remote/target machine for the C(src).
type: bool type: bool
default: no default: false
strip: strip:
description: description:
- Number that indicates the smallest prefix containing leading slashes - Number that indicates the smallest prefix containing leading slashes
@ -65,20 +65,20 @@ options:
description: description:
- Passes C(--backup --version-control=numbered) to patch, producing numbered backup copies. - Passes C(--backup --version-control=numbered) to patch, producing numbered backup copies.
type: bool type: bool
default: no default: false
binary: binary:
description: 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 into LF.
- Line endings of src and dest must match. - 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 type: bool
default: no default: false
ignore_whitespace: ignore_whitespace:
description: 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 type: bool
default: no default: false
notes: notes:
- This module requires GNU I(patch) utility to be installed on the remote host. - This module requires GNU I(patch) utility to be installed on the remote host.
''' '''

View file

@ -69,7 +69,7 @@ def main():
if os.path.exists("/run/ostree-booted"): if os.path.exists("/run/ostree-booted"):
ansible_facts['pkg_mgr'] = 'ansible.posix.rhel_rpm_ostree' ansible_facts['pkg_mgr'] = 'ansible.posix.rhel_rpm_ostree'
module.exit_json(ansible_facts, changed=False) module.exit_json(ansible_facts=ansible_facts, changed=False)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -35,6 +35,7 @@ options:
aliases: [ pkg ] aliases: [ pkg ]
type: list type: list
elements: str elements: str
default: []
state: state:
description: description:
- Whether to install (C(present) or C(installed), C(latest)), or remove (C(absent) or C(removed)) a package. - Whether to install (C(present) or C(installed), C(latest)), or remove (C(absent) or C(removed)) a package.

View file

@ -22,9 +22,9 @@ options:
type: str type: str
persistent: persistent:
description: 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 type: bool
default: 'no' default: false
state: state:
description: description:
- Desired boolean value - Desired boolean value
@ -49,8 +49,8 @@ EXAMPLES = r'''
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots - name: Set httpd_can_network_connect flag on and keep it persistent across reboots
ansible.posix.seboolean: ansible.posix.seboolean:
name: httpd_can_network_connect name: httpd_can_network_connect
state: yes state: true
persistent: yes persistent: true
''' '''
import os import os

View file

@ -32,7 +32,7 @@ options:
description: description:
- If set to I(true), will update also the kernel boot parameters when disabling/enabling SELinux. - 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. - The C(grubby) tool must be present on the target system for this to work.
default: no default: false
type: bool type: bool
version_added: '1.4.0' version_added: '1.4.0'
configfile: configfile:

View file

@ -53,36 +53,36 @@ options:
description: description:
- Mirrors the rsync archive flag, enables recursive, links, perms, times, owner, group flags and -D. - Mirrors the rsync archive flag, enables recursive, links, perms, times, owner, group flags and -D.
type: bool type: bool
default: yes default: true
checksum: checksum:
description: description:
- Skip based on checksum, rather than mod-time & size; Note that that "archive" option is still enabled by default - the "checksum" option will - 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. not disable it.
type: bool type: bool
default: no default: false
compress: compress:
description: description:
- Compress file data during the transfer. - Compress file data during the transfer.
- In most cases, leave this enabled unless it causes problems. - In most cases, leave this enabled unless it causes problems.
type: bool type: bool
default: yes default: true
existing_only: existing_only:
description: description:
- Skip creating new files on receiver. - Skip creating new files on receiver.
type: bool type: bool
default: no default: false
delete: delete:
description: description:
- Delete files in I(dest) that do not exist (after transfer, not before) in the I(src) path. - 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). - This option ignores excluded files and behaves like the rsync opt C(--delete-after).
type: bool type: bool
default: no default: false
dirs: dirs:
description: description:
- Transfer directories without recursing. - Transfer directories without recursing.
type: bool type: bool
default: no default: false
recursive: recursive:
description: description:
- Recurse into directories. - Recurse into directories.
@ -97,7 +97,7 @@ options:
description: description:
- Copy symlinks as the item that they point to (the referent) is copied, rather than the symlink. - Copy symlinks as the item that they point to (the referent) is copied, rather than the symlink.
type: bool type: bool
default: no default: false
perms: perms:
description: description:
- Preserve permissions. - Preserve permissions.
@ -132,26 +132,26 @@ options:
description: description:
- Put user@ for the remote paths. - Put user@ for the remote paths.
- If you have a custom ssh config to define the remote user for a host - 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 type: bool
default: yes default: true
use_ssh_args: use_ssh_args:
description: description:
- In Ansible 2.10 and lower, it uses the ssh_args specified in C(ansible.cfg). - 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 - 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). C(ansible_ssh_args), C(ansible_ssh_common_args), and C(ansible_ssh_extra_args).
type: bool type: bool
default: no default: false
ssh_connection_multiplexing: ssh_connection_multiplexing:
description: description:
- SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections. - 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). 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. - Set this option to C(true) to allow multiplexing and reduce SSH connection overhead.
- Note that simply setting this option to C(yes) is not enough; - 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 You must also configure SSH connection multiplexing in your SSH client config by setting values for
C(ControlMaster), C(ControlPersist) and C(ControlPath). C(ControlMaster), C(ControlPersist) and C(ControlPath).
type: bool type: bool
default: no default: false
rsync_opts: rsync_opts:
description: description:
- Specify additional rsync options by passing in an array. - Specify additional rsync options by passing in an array.
@ -163,12 +163,12 @@ options:
description: description:
- Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster. - Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.
type: bool type: bool
default: no default: false
verify_host: verify_host:
description: description:
- Verify destination host key. - Verify destination host key.
type: bool type: bool
default: no default: false
private_key: private_key:
description: description:
- Specify the private key to use for SSH-based rsync connections (e.g. C(~/.ssh/id_rsa)). - Specify the private key to use for SSH-based rsync connections (e.g. C(~/.ssh/id_rsa)).
@ -184,7 +184,7 @@ options:
- This option puts the temporary file from each updated file into a holding directory until the end of the transfer, - 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. at which time all the files are renamed into place in rapid succession.
type: bool type: bool
default: yes default: true
version_added: '1.3.0' version_added: '1.3.0'
notes: notes:
@ -212,7 +212,7 @@ notes:
- link_destination is subject to the same limitations as the underlying rsync daemon. Hard links are only preserved if the relative subtrees - 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. 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: seealso:
- module: copy - module: ansible.builtin.copy
- module: community.windows.win_robocopy - module: community.windows.win_robocopy
author: author:
- Timothy Appnel (@tima) - Timothy Appnel (@tima)
@ -252,27 +252,27 @@ EXAMPLES = r'''
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
archive: no archive: false
- name: Synchronization with --archive options enabled except for --recursive - name: Synchronization with --archive options enabled except for --recursive
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
recursive: no recursive: false
- name: Synchronization with --archive options enabled except for --times, with --checksum option enabled - name: Synchronization with --archive options enabled except for --times, with --checksum option enabled
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
checksum: yes checksum: true
times: no times: false
- name: Synchronization without --archive options enabled except use --links - name: Synchronization without --archive options enabled except use --links
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
archive: no archive: false
links: yes links: true
- name: Synchronization of two paths both on the control machine - name: Synchronization of two paths both on the control machine
ansible.posix.synchronize: ansible.posix.synchronize:
@ -302,8 +302,8 @@ EXAMPLES = r'''
ansible.posix.synchronize: ansible.posix.synchronize:
src: some/relative/path src: some/relative/path
dest: /some/absolute/path dest: /some/absolute/path
delete: yes delete: true
recursive: yes recursive: true
# This specific command is granted su privileges on the destination # This specific command is granted su privileges on the destination
- name: Synchronize using an alternate rsync command - name: Synchronize using an alternate rsync command

View file

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

View file

@ -0,0 +1,87 @@
# 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: Yes
state: enabled
register: result
- name: assert lo was added to trusted zone
assert:
that:
- result is changed
- name: Add lo interface to trusted zone (verify not changed)
ansible.posix.firewalld:
interface: lo
zone: trusted
permanent: Yes
state: enabled
register: result
- name: assert lo was added to trusted zone (verify not changed)
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: Yes
state: enabled
register: result
- name: Assert lo was moved from trusted zone to internal zone
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: Yes
state: enabled
register: result
- name: assert lo was moved from trusted zone to internal zone (verify not changed)
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: Yes
state: disabled
register: result
- name: Assert lo interface was removed from internal zone
assert:
that:
- result is changed
- name: Remove lo interface from internal zone (verify not changed)
ansible.posix.firewalld:
interface: lo
zone: internal
permanent: Yes
state: disabled
register: result
- name: Assert lo interface was removed from internal zone (verify not changed)
assert:
that:
- result is not changed

View file

@ -4,7 +4,7 @@
- name: firewalld port range test permanent enabled - name: firewalld port range test permanent enabled
firewalld: firewalld:
port: 5500-6950/tcp port: 5500-6850/tcp
permanent: true permanent: true
state: enabled state: enabled
register: result register: result
@ -16,7 +16,7 @@
- name: firewalld port range test permanent enabled rerun (verify not changed) - name: firewalld port range test permanent enabled rerun (verify not changed)
firewalld: firewalld:
port: 5500-6950/tcp port: 5500-6850/tcp
permanent: true permanent: true
state: enabled state: enabled
register: result register: result
@ -57,7 +57,7 @@
state: disabled state: disabled
loop: loop:
- 6900/tcp - 6900/tcp
- 5500-6950/tcp - 5500-6850/tcp
- name: firewalld port test permanent enabled - name: firewalld port test permanent enabled
firewalld: firewalld:

View file

@ -0,0 +1,65 @@
# 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
firewalld:
protocol: ospf
permanent: true
state: enabled
register: result
- name: assert firewalld protocol test permanent enabled worked
assert:
that:
- result is changed
- name: firewalld protocol test permanent enabled rerun (verify not changed)
firewalld:
protocol: ospf
permanent: true
state: enabled
register: result
- name: assert firewalld protocol test permanent enabled rerun worked (verify not changed)
assert:
that:
- result is not changed
- name: firewalld protocol test permanent disabled
firewalld:
protocol: ospf
permanent: true
state: disabled
register: result
- name: assert firewalld protocol test permanent disabled worked
assert:
that:
- result is changed
- name: firewalld protocol test permanent disabled rerun (verify not changed)
firewalld:
protocol: ospf
permanent: true
state: disabled
register: result
- name: assert firewalld protocol test permanent disabled rerun worked (verify not changed)
assert:
that:
- result is not changed

View file

@ -10,12 +10,18 @@
# firewalld service operation test cases # firewalld service operation test cases
- include_tasks: service_test_cases.yml - include_tasks: service_test_cases.yml
# firewalld protocol operation test cases
- include_tasks: protocol_test_cases.yml
# firewalld port operation test cases # firewalld port operation test cases
- include_tasks: port_test_cases.yml - include_tasks: port_test_cases.yml
# firewalld source operation test cases # firewalld source operation test cases
- include_tasks: source_test_cases.yml - include_tasks: source_test_cases.yml
# firewalld zone operation test cases
- include_tasks: zone_test_cases.yml
# firewalld zone target operation test cases # firewalld zone target operation test cases
- include_tasks: zone_target_test_cases.yml - include_tasks: zone_target_test_cases.yml
@ -27,3 +33,6 @@
# firewalld icmp block inversion operation test cases # firewalld icmp block inversion operation test cases
- include_tasks: icmp_block_inversion_test_cases.yml - include_tasks: icmp_block_inversion_test_cases.yml
# firewalld interface operation test cases
- include_tasks: interface_test_cases.yml

View file

@ -82,4 +82,4 @@
assert: assert:
that: that:
- result is not changed - 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.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|protocol|port|port_forward|rich_rule|interface|masquerade|source|target'"

View file

@ -0,0 +1,47 @@
- name: firewalld create zone custom
firewalld:
zone: custom
permanent: True
state: present
register: result
- name: assert firewalld custom zone created worked
assert:
that:
- result is changed
- name: firewalld create zone custom rerun (verify not changed)
firewalld:
zone: custom
permanent: True
state: present
register: result
- name: assert firewalld custom zone created worked (verify not changed)
assert:
that:
- result is not changed
- name: firewalld remove zone custom
firewalld:
zone: custom
permanent: True
state: absent
register: result
- name: assert firewalld custom zone removed worked
assert:
that:
- result is changed
- name: firewalld remove custom zone rerun (verify not changed)
firewalld:
zone: custom
permanent: True
state: absent
register: result
- name: assert firewalld custom zone removed worked (verify not changed)
assert:
that:
- result is not changed

View file

@ -1,3 +1,9 @@
- name: Install dependencies
ansible.builtin.package:
name: e2fsprogs
state: present
when: ansible_system == 'Linux'
- name: Create the mount point - name: Create the mount point
file: file:
state: directory state: directory
@ -406,3 +412,270 @@
- /tmp/myfs1 - /tmp/myfs1
- /tmp/test_fstab - /tmp/test_fstab
when: ansible_system in ('Linux') when: ansible_system in ('Linux')
- name: Block to test ephemeral option
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
block:
- name: Create empty file A
community.general.filesize:
path: /tmp/myfs_A.img
size: 20M
- name: Create empty file B
community.general.filesize:
path: /tmp/myfs_B.img
size: 20M
- name: Register facts on Linux
ansible.builtin.set_fact:
ephemeral_device_A: /tmp/myfs_A.img
ephemeral_device_B: /tmp/myfs_B.img
ephemeral_fstype: ext3
ephemeral_fstab: /etc/fstab
when: ansible_system == 'Linux'
- name: Register facts on Solaris/SunOS
ansible.builtin.set_fact:
ephemeral_device_A: /dev/lofi/1
ephemeral_device_B: /dev/lofi/2
ephemeral_create_loop_dev_cmd: >
lofiadm -a /tmp/myfs_A.img /dev/lofi/1 &&
lofiadm -a /tmp/myfs_B.img /dev/lofi/2
ephemeral_remove_loop_dev_cmd: >
lofiadm -d /dev/lofi/1 &&
lofiadm -d /dev/lofi/2 || true
ephemeral_fstype: ufs
ephemeral_fstab: /etc/vfstab
when: ansible_system == 'SunOS'
- name: Register facts on FreeBSD
ansible.builtin.set_fact:
ephemeral_device_A: /dev/md1
ephemeral_device_B: /dev/md2
ephemeral_create_loop_dev_cmd: >
mdconfig -a -t vnode -f /tmp/myfs_A.img -u /dev/md1 &&
mdconfig -a -t vnode -f /tmp/myfs_B.img -u /dev/md2
ephemeral_remove_loop_dev_cmd: >
mdconfig -d -u /dev/md1 &&
mdconfig -d -u /dev/md2
ephemeral_fstype: ufs
ephemeral_fstab: /etc/fstab
when: ansible_system == 'FreeBSD'
- name: Register facts on NetBSD
ansible.builtin.set_fact:
ephemeral_device_A: /dev/vnd1
ephemeral_device_B: /dev/vnd2
ephemeral_create_loop_dev_cmd: >
vnconfig /dev/vnd1 /tmp/myfs_A.img &&
vnconfig /dev/vnd2 /tmp/myfs_B.img
ephemeral_remove_loop_dev_cmd: >
vnconfig -u /dev/vnd1 &&
vnconfig -u /dev/vnd2
ephemeral_fstype: ufs
ephemeral_fstab: /etc/fstab
when: ansible_system == 'NetBSD'
- name: Register format fs command on Non-Linux and Non-OpenBSD
ansible.builtin.set_fact:
ephemeral_format_fs_cmd: >
yes | newfs {{ ephemeral_device_A }} &&
yes | newfs {{ ephemeral_device_B }}
when: ansible_system in ('SunOS', 'FreeBSD', 'NetBSD')
- name: Register facts on OpenBSD
ansible.builtin.set_fact:
ephemeral_device_A: /dev/vnd1c
ephemeral_device_B: /dev/vnd2c
ephemeral_create_loop_dev_cmd: >
vnconfig vnd1 /tmp/myfs_A.img &&
vnconfig vnd2 /tmp/myfs_B.img
ephemeral_remove_loop_dev_cmd: >
vnconfig -u vnd1 &&
vnconfig -u vnd2
ephemeral_format_fs_cmd: >
yes | newfs /dev/rvnd1c &&
yes | newfs /dev/rvnd2c
ephemeral_fstype: ffs
ephemeral_fstab: /etc/fstab
when: ansible_system == 'OpenBSD'
##### FORMAT FS ON LINUX
- name: Block to format FS on Linux
block:
- name: Format FS A on Linux
community.general.filesystem:
fstype: ext3
dev: /tmp/myfs_A.img
- name: Format FS B on Linux
community.general.filesystem:
fstype: ext3
dev: /tmp/myfs_B.img
when: ansible_system == 'Linux'
##### FORMAT FS ON SOLARIS AND BSD
- name: Create loop devices on Solaris and BSD
ansible.builtin.shell: "{{ ephemeral_create_loop_dev_cmd }}"
when: ephemeral_create_loop_dev_cmd is defined
- name: Format FS A and B on Solaris and BSD
ansible.builtin.shell: "{{ ephemeral_format_fs_cmd }}"
when: ephemeral_format_fs_cmd is defined
##### TESTS
- name: Create fstab if it does not exist
ansible.builtin.file:
path: "{{ ephemeral_fstab }}"
state: touch
- name: Get checksum of /etc/fstab before mounting anything
stat:
path: '{{ ephemeral_fstab }}'
register: fstab_stat_before_mount
- name: Mount the FS A with ephemeral state
mount:
path: /tmp/myfs
src: '{{ ephemeral_device_A }}'
fstype: '{{ ephemeral_fstype }}'
opts: rw
state: ephemeral
register: ephemeral_mount_info
- name: Put something in the directory so we can do additional checks later on
copy:
content: 'Testing'
dest: /tmp/myfs/test_file
- name: Get checksum of /etc/fstab after an ephemeral mount
stat:
path: '{{ ephemeral_fstab }}'
register: fstab_stat_after_mount
- name: Get mountinfo
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
register: check_mountinfo
changed_when: no
- name: Assert the mount occured and the fstab is unchanged
assert:
that:
- check_mountinfo.stdout|int == 1
- ephemeral_mount_info['changed']
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
- name: Get first mount record
shell: mount -v | grep '/tmp/myfs'
register: ephemeral_mount_record_1
changed_when: no
- name: Try to mount FS A where FS A is already mounted (should trigger remount and changed)
mount:
path: /tmp/myfs
src: '{{ ephemeral_device_A }}'
fstype: '{{ ephemeral_fstype }}'
opts: ro
state: ephemeral
register: ephemeral_mount_info
- name: Get second mount record (should be different than the first)
shell: mount -v | grep '/tmp/myfs'
register: ephemeral_mount_record_2
changed_when: no
- name: Get mountinfo
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
register: check_mountinfo
changed_when: no
- name: Assert the FS A is still mounted, the options changed and the fstab unchanged
assert:
that:
- check_mountinfo.stdout|int == 1
- ephemeral_mount_record_1.stdout != ephemeral_mount_record_2.stdout
- ephemeral_mount_info['changed']
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
- name: Try to mount file B on file A mountpoint (should fail)
mount:
path: /tmp/myfs
src: '{{ ephemeral_device_B }}'
fstype: '{{ ephemeral_fstype }}'
state: ephemeral
register: ephemeral_mount_b_info
ignore_errors: true
- name: Get third mount record (should be the same than the second)
shell: mount -v | grep '/tmp/myfs'
register: ephemeral_mount_record_3
changed_when: no
- name: Get mountinfo
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
register: check_mountinfo
changed_when: no
- name: Try to stat our test file
stat:
path: /tmp/myfs/test_file
register: test_file_stat
- name: Assert that mounting FS B over FS A failed
assert:
that:
- check_mountinfo.stdout|int == 1
- ephemeral_mount_record_2.stdout == ephemeral_mount_record_3.stdout
- test_file_stat['stat']['exists']
- ephemeral_mount_b_info is failed
- name: Unmount FS with state = unmounted
mount:
path: /tmp/myfs
state: unmounted
- name: Get fstab checksum after unmounting an ephemeral mount with state = unmounted
stat:
path: '{{ ephemeral_fstab }}'
register: fstab_stat_after_unmount
- name: Get mountinfo
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
register: check_mountinfo
changed_when: no
- name: Try to stat our test file
stat:
path: /tmp/myfs/test_file
register: test_file_stat
- name: Assert that fstab is unchanged after unmounting an ephemeral mount with state = unmounted
assert:
that:
- check_mountinfo.stdout|int == 0
- not test_file_stat['stat']['exists']
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_unmount['stat']['checksum']
always:
- name: Unmount potential failure relicas
mount:
path: /tmp/myfs
state: unmounted
- name: Remove loop devices on Solaris and BSD
ansible.builtin.shell: "{{ ephemeral_remove_loop_dev_cmd }}"
when: ephemeral_remove_loop_dev_cmd is defined
- name: Remove the test FS
file:
path: '{{ item }}'
state: absent
loop:
- /tmp/myfs_A.img
- /tmp/myfs_B.img
- /tmp/myfs
when: ansible_system in ('Linux', 'SunOS', 'FreeBSD', 'NetBSD', 'OpenBSD')

View file

@ -31,3 +31,4 @@ except ImportError:
BUILTINS = 'builtins' BUILTINS = 'builtins'
else: else:
BUILTINS = '__builtin__' BUILTINS = '__builtin__'
__all__ = ['__builtin__']

View file

@ -19,7 +19,6 @@ import os
import unittest import unittest
import yaml import yaml
import ansible.plugins
from ansible_collections.ansible.posix.tests.unit.compat.mock import patch, MagicMock from ansible_collections.ansible.posix.tests.unit.compat.mock import patch, MagicMock
from ansible_collections.ansible.posix.plugins.action.synchronize import ActionModule from ansible_collections.ansible.posix.plugins.action.synchronize import ActionModule