From 18469dbb3e3bf92492c141e8f685fc495f05111a Mon Sep 17 00:00:00 2001 From: dkjii Date: Fri, 2 Apr 2021 09:50:36 -0400 Subject: [PATCH 01/40] ansible.posix.mount: add absent_from_fstab option --- plugins/modules/mount.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index e7ce7ee..31ea269 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -78,9 +78,12 @@ options: if I(opts) is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using C(mounted) instead to work around this issue. + - C(absent_from_fstab) specifies that the device mount's entry will be + removed from I(fstab). This option does not unmount it or delete the + mountpoint. type: str required: true - choices: [ absent, mounted, present, unmounted, remounted ] + choices: [ absent, absent_from_fstab, mounted, present, unmounted, remounted ] fstab: description: - File to use instead of C(/etc/fstab). @@ -651,7 +654,7 @@ def main(): passno=dict(type='str', no_log=False), src=dict(type='path'), backup=dict(type='bool', default=False), - state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted']), + state=dict(type='str', required=True, choices=['absent', 'absent_from_fstab', 'mounted', 'present', 'unmounted', 'remounted']), ), supports_check_mode=True, required_if=( @@ -734,7 +737,9 @@ def main(): name = module.params['path'] changed = False - if state == 'absent': + if state == 'absent_from_fstab': + name, changed = unset_mount(module, args) + elif state == 'absent': name, changed = unset_mount(module, args) if changed and not module.check_mode: From 20e294e0264647f4aa2078ad0eaf320ba2ee1879 Mon Sep 17 00:00:00 2001 From: dkjii Date: Fri, 2 Apr 2021 12:33:58 -0400 Subject: [PATCH 02/40] add changelog --- changelogs/fragments/166_mount_absent_fstab.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/166_mount_absent_fstab.yml diff --git a/changelogs/fragments/166_mount_absent_fstab.yml b/changelogs/fragments/166_mount_absent_fstab.yml new file mode 100644 index 0000000..2f7400c --- /dev/null +++ b/changelogs/fragments/166_mount_absent_fstab.yml @@ -0,0 +1,2 @@ +minor_changes: +- mount - Add absent_from_fstab state From 553b0ea4f74c2c4e0d0d3252bc57b1dabed54913 Mon Sep 17 00:00:00 2001 From: dkjii-g <41760646+dkjii-g@users.noreply.github.com> Date: Fri, 2 Apr 2021 21:00:51 -0400 Subject: [PATCH 03/40] Update changelogs/fragments/166_mount_absent_fstab.yml Co-authored-by: Amin Vakil --- changelogs/fragments/166_mount_absent_fstab.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/166_mount_absent_fstab.yml b/changelogs/fragments/166_mount_absent_fstab.yml index 2f7400c..be11324 100644 --- a/changelogs/fragments/166_mount_absent_fstab.yml +++ b/changelogs/fragments/166_mount_absent_fstab.yml @@ -1,2 +1,2 @@ minor_changes: -- mount - Add absent_from_fstab state + - mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166). From 04089e80fbfd969f2b0fd43a80e42639d25c1f8e Mon Sep 17 00:00:00 2001 From: NdFeB Date: Tue, 14 Sep 2021 18:57:39 +0200 Subject: [PATCH 04/40] Add ephemeral state to mount fs without altering fstab --- changelogs/fragments/267_mount_ephemeral.yml | 4 + plugins/modules/mount.py | 161 +++++++++-- .../integration/targets/mount/tasks/main.yml | 273 ++++++++++++++++++ 3 files changed, 416 insertions(+), 22 deletions(-) create mode 100644 changelogs/fragments/267_mount_ephemeral.yml diff --git a/changelogs/fragments/267_mount_ephemeral.yml b/changelogs/fragments/267_mount_ephemeral.yml new file mode 100644 index 0000000..5671916 --- /dev/null +++ b/changelogs/fragments/267_mount_ephemeral.yml @@ -0,0 +1,4 @@ +--- +minor_changes: +- 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). diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 2021464..7c4cc3d 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -31,12 +31,12 @@ options: src: description: - Device (or NFS volume, or something else) to be mounted on I(path). - - Required when I(state) set to C(present) or C(mounted). + - Required when I(state) set to C(present), C(mounted) or C(ephemeral). type: path fstype: description: - Filesystem type. - - Required when I(state) is C(present) or C(mounted). + - Required when I(state) is C(present), C(mounted) or C(ephemeral). type: str opts: description: @@ -48,7 +48,7 @@ options: - Note that if set to C(null) and I(state) set to C(present), it will cease to work and duplicate entries will be made with subsequent runs. - - Has no effect on Solaris systems. + - Has no effect on Solaris systems or when used with C(ephemeral). type: str default: '0' passno: @@ -57,7 +57,7 @@ options: - Note that if set to C(null) and I(state) set to C(present), it will cease to work and duplicate entries will be made with subsequent runs. - - Deprecated on Solaris systems. + - Deprecated on Solaris systems. Has no effect when used with C(ephemeral). type: str default: '0' state: @@ -68,6 +68,13 @@ options: - If C(unmounted), the device will be unmounted without changing I(fstab). - C(present) only specifies that the device is to be configured in I(fstab) and does not trigger or require a mount. + - C(ephemeral) only specifies that the device is to be mounted, without changing + I(fstab). If it is already mounted, a remount will be triggered. + This will always return changed=True. If the mount point I(path) + has already a device mounted on, and its source is different than I(src), + the module will fail to avoid unexpected unmount or mount point override. + If the mount point is not present, the mount point will be created. + The I(fstab) is completely ignored. - C(absent) specifies that the device mount's entry will be removed from I(fstab) and will also unmount the device and remove the mount point. @@ -77,10 +84,12 @@ options: applied to the remount, but will not change I(fstab). Additionally, if I(opts) is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using C(mounted) - instead to work around this issue. + instead to work around this issue. C(remounted) expects the mount point + to be present in the I(fstab). To remount a mount point not registered + in I(fstab), use C(ephemeral) instead, especially with BSD nodes. type: str required: true - choices: [ absent, mounted, present, unmounted, remounted ] + choices: [ absent, mounted, present, unmounted, remounted, ephemeral ] fstab: description: - File to use instead of C(/etc/fstab). @@ -89,6 +98,7 @@ options: - OpenBSD does not allow specifying alternate fstab files with mount so do not use this on OpenBSD with any state that operates on the live filesystem. - This parameter defaults to /etc/fstab or /etc/vfstab on Solaris. + - This parameter is ignored when I(state) is set to C(ephemeral). type: str boot: description: @@ -100,6 +110,7 @@ options: to mount options in I(/etc/fstab). - To avoid mount option conflicts, if C(noauto) specified in C(opts), mount module will ignore C(boot). + - This parameter is ignored when I(state) is set to C(ephemeral). type: bool default: yes backup: @@ -184,6 +195,14 @@ EXAMPLES = r''' boot: no state: mounted fstype: nfs + +- name: Mount ephemeral SMB volume + ansible.posix.mount: + src: //192.168.1.200/share + path: /mnt/smb_share + opts: "rw,vers=3,file_mode=0600,dir_mode=0700,dom={{ ad_domain }},username={{ ad_username }},password={{ ad_password }}" + fstype: cifs + state: ephemeral ''' import errno @@ -430,6 +449,24 @@ def _set_fstab_args(fstab_file): return result +def _set_ephemeral_args(args): + result = [] + # Set fstype switch according to platform. SunOS/Solaris use -F + if platform.system().lower() == 'sunos': + result.append('-F') + else: + result.append('-t') + result.append(args['fstype']) + + # Even if '-o remount' is already set, specifying multiple -o is valid + if args['opts'] != 'defaults': + result += ['-o', args['opts']] + + result.append(args['src']) + + return result + + def mount(module, args): """Mount up a path or remount if needed.""" @@ -446,7 +483,11 @@ def mount(module, args): 'OpenBSD does not support alternate fstab files. Do not ' 'specify the fstab parameter for OpenBSD hosts')) else: - cmd += _set_fstab_args(args['fstab']) + if module.params['state'] != 'ephemeral': + cmd += _set_fstab_args(args['fstab']) + + if module.params['state'] == 'ephemeral': + cmd += _set_ephemeral_args(args) cmd += [name] @@ -498,18 +539,24 @@ def remount(module, args): 'OpenBSD does not support alternate fstab files. Do not ' 'specify the fstab parameter for OpenBSD hosts')) else: - cmd += _set_fstab_args(args['fstab']) + if module.params['state'] != 'ephemeral': + cmd += _set_fstab_args(args['fstab']) + + if module.params['state'] == 'ephemeral': + cmd += _set_ephemeral_args(args) cmd += [args['name']] out = err = '' try: - if platform.system().lower().endswith('bsd'): + if module.params['state'] != 'ephemeral' and platform.system().lower().endswith('bsd'): # Note: Forcing BSDs to do umount/mount due to BSD remount not # working as expected (suspect bug in the BSD mount command) # Interested contributor could rework this to use mount options on # the CLI instead of relying on fstab # https://github.com/ansible/ansible-modules-core/issues/5591 + # Note: this does not affect ephemeral state as all options + # are set on the CLI and fstab is expected to be ignored. rc = 1 else: rc, out, err = module.run_command(cmd) @@ -663,6 +710,47 @@ def get_linux_mounts(module, mntinfo_file="/proc/self/mountinfo"): return mounts +def _is_same_mount_src(module, src, mountpoint, linux_mounts): + """Return True if the mounted fs on mountpoint is the same source than src. Return False if mountpoint is not a mountpoint""" + # If the provided mountpoint is not a mountpoint, don't waste time + if ( + not ismount(mountpoint) and + not is_bind_mounted(module, linux_mounts, mountpoint)): + return False + + # Treat Linux bind mounts + if platform.system() == 'Linux' and linux_mounts is not None: + # For Linux bind mounts only: the mount command does not return + # the actual source for bind mounts, but the device of the source. + # is_bind_mounted() called with the 'src' parameter will return True if + # the mountpoint is a bind mount AND the source FS is the same than 'src'. + # is_bind_mounted() is not reliable on Solaris, NetBSD and OpenBSD. + # But we can rely on 'mount -v' on all other platforms, and Linux non-bind mounts. + if (is_bind_mounted(module, linux_mounts, mountpoint, src)): + return True + + # mount with parameter -v has a close behavior on Linux, *BSD, SunOS + # Requires -v with SunOS. Without -v, source and destination are reversed + # Output format differs from a system to another, but field[0:3] are consistent: [src, 'on', dest] + cmd = '%s -v' % module.get_bin_path('mount', required=True) + rc, out, err = module.run_command(cmd) + mounts = [] + + if len(out): + mounts = to_native(out).strip().split('\n') + else: + module.fail_json(msg="Unable to retrieve mount info with command '%s'" % cmd) + + for mnt in mounts: + fields = mnt.split() + mp_src = fields[0] + mp_dst = fields[2] + if mp_src == src and mp_dst == mountpoint: + return True + + return False + + def main(): module = AnsibleModule( argument_spec=dict( @@ -675,12 +763,13 @@ def main(): passno=dict(type='str', no_log=False, default='0'), src=dict(type='path'), backup=dict(type='bool', default=False), - state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted']), + state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']), ), supports_check_mode=True, required_if=( ['state', 'mounted', ['src', 'fstype']], ['state', 'present', ['src', 'fstype']], + ['state', 'ephemeral', ['src', 'fstype']] ), ) @@ -751,15 +840,17 @@ def main(): # If fstab file does not exist, we first need to create it. This mainly # happens when fstab option is passed to the module. - if not os.path.exists(args['fstab']): - if not os.path.exists(os.path.dirname(args['fstab'])): - os.makedirs(os.path.dirname(args['fstab'])) - try: - open(args['fstab'], 'a').close() - except PermissionError as e: - module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab']) - except Exception as e: - module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e))) + # If state is 'ephemeral', we do not need fstab file + if module.params['state'] != 'ephemeral': + if not os.path.exists(args['fstab']): + if not os.path.exists(os.path.dirname(args['fstab'])): + os.makedirs(os.path.dirname(args['fstab'])) + try: + open(args['fstab'], 'a').close() + except PermissionError as e: + module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab']) + except Exception as e: + module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e))) # absent: # Remove from fstab and unmounted. @@ -770,6 +861,8 @@ def main(): # mounted: # Add to fstab if not there and make sure it is mounted. If it has # changed in fstab then remount it. + # ephemeral: + # Do not change fstab state, but mount. state = module.params['state'] name = module.params['path'] @@ -801,7 +894,7 @@ def main(): msg="Error unmounting %s: %s" % (name, msg)) changed = True - elif state == 'mounted': + elif state == 'mounted' or state == 'ephemeral': dirs_created = [] if not os.path.exists(name) and not module.check_mode: try: @@ -829,7 +922,11 @@ def main(): module.fail_json( msg="Error making dir %s: %s" % (name, to_native(e))) - name, backup_lines, changed = _set_mount_save_old(module, args) + # ephemeral: completely ignore fstab + if state != 'ephemeral': + name, backup_lines, changed = _set_mount_save_old(module, args) + else: + name, backup_lines, changed = args['name'], [], False res = 0 if ( @@ -839,7 +936,26 @@ def main(): if changed and not module.check_mode: res, msg = remount(module, args) changed = True + + # When 'state' == 'ephemeral', we don't know what is in fstab, and 'changed' is always False + if state == 'ephemeral': + # If state == 'ephemeral', check if the mountpoint src == module.params['src'] + # If it doesn't, fail to prevent unwanted unmount or unwanted mountpoint override + if _is_same_mount_src(module, args['src'], args['name'], linux_mounts): + changed = True + if not module.check_mode: + res, msg = remount(module, args) + else: + module.fail_json( + msg=( + 'Ephemeral mount point is already mounted with a different ' + 'source than the specified one. Failing in order to prevent an ' + 'unwanted unmount or override operation. Try replacing this command with ' + 'a "state: unmounted" followed by a "state: ephemeral", or use ' + 'a different destination path.')) + else: + # If not already mounted, mount it changed = True if not module.check_mode: @@ -851,7 +967,8 @@ def main(): # A non-working fstab entry may break the system at the reboot, # so undo all the changes if possible. try: - write_fstab(module, backup_lines, args['fstab']) + if state != 'ephemeral': + write_fstab(module, backup_lines, args['fstab']) except Exception: pass diff --git a/tests/integration/targets/mount/tasks/main.yml b/tests/integration/targets/mount/tasks/main.yml index be1850f..7b0d141 100644 --- a/tests/integration/targets/mount/tasks/main.yml +++ b/tests/integration/targets/mount/tasks/main.yml @@ -1,3 +1,9 @@ +- name: Install dependencies + ansible.builtin.package: + name: e2fsprogs + state: present + when: ansible_system == 'Linux' + - name: Create the mount point file: state: directory @@ -406,3 +412,270 @@ - /tmp/myfs1 - /tmp/test_fstab 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') From b8ed9190116ff924c8e9431f090f35c07bc92943 Mon Sep 17 00:00:00 2001 From: NeodymiumFerBore <32781483+NeodymiumFerBore@users.noreply.github.com> Date: Wed, 18 May 2022 18:55:10 +0200 Subject: [PATCH 05/40] Apply suggestions from code review Co-authored-by: Abhijeet Kasurde --- plugins/modules/mount.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 7c4cc3d..36ceb98 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -74,7 +74,7 @@ options: 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. + The I(fstab) is completely ignored. This option is added in version 1.5.0. - C(absent) specifies that the device mount's entry will be removed from I(fstab) and will also unmount the device and remove the mount point. @@ -726,7 +726,7 @@ def _is_same_mount_src(module, src, mountpoint, linux_mounts): # 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)): + if is_bind_mounted(module, linux_mounts, mountpoint, src): return True # mount with parameter -v has a close behavior on Linux, *BSD, SunOS From 139e103b0f2f211bcf73b0bdff4307ff3ce9d2dc Mon Sep 17 00:00:00 2001 From: Juan Antonio Valino Garcia Date: Fri, 7 Oct 2022 17:20:20 +0200 Subject: [PATCH 06/40] Fixes ##390. Hosts involved must have same password --- plugins/action/synchronize.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/action/synchronize.py b/plugins/action/synchronize.py index a5752b9..7a330ac 100644 --- a/plugins/action/synchronize.py +++ b/plugins/action/synchronize.py @@ -225,7 +225,6 @@ class ActionModule(ActionBase): # Parameter name needed by the ansible module _tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync' - _tmp_args['_local_rsync_password'] = task_vars.get('ansible_ssh_pass') or task_vars.get('ansible_password') # rsync thinks that one end of the connection is localhost and the # other is the host we're running the task for (Note: We use @@ -333,8 +332,9 @@ class ActionModule(ActionBase): if src is None or dest is None: return dict(failed=True, msg="synchronize requires both src and dest parameters are set") - # Determine if we need a user@ + # Determine if we need a user@ and a password user = None + password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None) if not dest_is_local: # Src and dest rsync "path" handling if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False): @@ -344,10 +344,11 @@ class ActionModule(ActionBase): user = task_vars.get('ansible_user') or self._play_context.remote_user if not user: user = C.DEFAULT_REMOTE_USER - else: user = task_vars.get('ansible_user') or self._play_context.remote_user + user = self._templar.template(user) + # Private key handling # Use the private_key parameter if passed else use context private_key_file _tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file) @@ -361,12 +362,15 @@ class ActionModule(ActionBase): # src is a local path, dest is a remote path: @ src = self._process_origin(src_host, src, user) dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports) + + password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None) else: # Still need to munge paths (to account for roles) even if we aren't # copying files between hosts src = self._get_absolute_path(path=src) dest = self._get_absolute_path(path=dest) + _tmp_args['_local_rsync_password'] = self._templar.template(password) _tmp_args['src'] = src _tmp_args['dest'] = dest From 297a10fec7eb431c95584eb7317f90434e22dbe3 Mon Sep 17 00:00:00 2001 From: Juan Antonio Valino Garcia Date: Fri, 7 Oct 2022 18:04:09 +0200 Subject: [PATCH 07/40] handle missing templar --- synchronize.py | 434 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 synchronize.py diff --git a/synchronize.py b/synchronize.py new file mode 100644 index 0000000..c70db5f --- /dev/null +++ b/synchronize.py @@ -0,0 +1,434 @@ +# -*- coding: utf-8 -*- + +# (c) 2012-2013, Timothy Appnel +# +# 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 . +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os.path + +from ansible import constants as C +from ansible.module_utils.six import string_types +from ansible.module_utils.six.moves import shlex_quote +from ansible.module_utils._text import to_text +from ansible.module_utils.common._collections_compat import MutableSequence +from ansible.module_utils.parsing.convert_bool import boolean +from ansible.plugins.action import ActionBase +from ansible.plugins.loader import connection_loader + + +DOCKER = ['docker', 'community.general.docker', 'community.docker.docker'] +PODMAN = ['podman', 'ansible.builtin.podman', 'containers.podman.podman'] +BUILDAH = ['buildah', 'containers.podman.buildah'] + + +class ActionModule(ActionBase): + + def _get_absolute_path(self, path): + original_path = path + + # + # Check if we have a local relative path and do not process + # * remote paths (some.server.domain:/some/remote/path/...) + # * URLs (rsync://...) + # * local absolute paths (/some/local/path/...) + # + if ':' in path or path.startswith('/'): + return path + + if self._task._role is not None: + path = self._loader.path_dwim_relative(self._task._role._role_path, 'files', path) + else: + path = self._loader.path_dwim_relative(self._loader.get_basedir(), 'files', path) + + if original_path and original_path[-1] == '/' and path[-1] != '/': + # make sure the dwim'd path ends in a trailing "/" + # if the original path did + path += '/' + + return path + + def _host_is_ipv6_address(self, host): + return ':' in to_text(host, errors='surrogate_or_strict') + + def _format_rsync_rsh_target(self, host, path, user): + ''' formats rsync rsh target, escaping ipv6 addresses if needed ''' + + user_prefix = '' + + if path.startswith('rsync://'): + return path + + # If using docker or buildah, do not add user information + if self._remote_transport not in DOCKER + PODMAN + BUILDAH and user: + user_prefix = '%s@' % (user, ) + + if self._host_is_ipv6_address(host): + return '[%s%s]:%s' % (user_prefix, host, path) + return '%s%s:%s' % (user_prefix, host, path) + + def _process_origin(self, host, path, user): + + if host not in C.LOCALHOST: + return self._format_rsync_rsh_target(host, path, user) + + path = self._get_absolute_path(path=path) + return path + + def _process_remote(self, task_args, host, path, user, port_matches_localhost_port): + """ + :arg host: hostname for the path + :arg path: file path + :arg user: username for the transfer + :arg port_matches_localhost_port: boolean whether the remote port + matches the port used by localhost's sshd. This is used in + conjunction with seeing whether the host is localhost to know + if we need to have the module substitute the pathname or if it + is a different host (for instance, an ssh tunnelled port or an + alternative ssh port to a vagrant host.) + """ + transport = self._connection.transport + # If we're connecting to a remote host or we're delegating to another + # host or we're connecting to a different ssh instance on the + # localhost then we have to format the path as a remote rsync path + if host not in C.LOCALHOST or transport != "local" or \ + (host in C.LOCALHOST and not port_matches_localhost_port): + # If we're delegating to non-localhost and but the + # inventory_hostname host is localhost then we need the module to + # fix up the rsync path to use the controller's public DNS/IP + # instead of "localhost" + if port_matches_localhost_port and host in C.LOCALHOST: + task_args['_substitute_controller'] = True + return self._format_rsync_rsh_target(host, path, user) + + path = self._get_absolute_path(path=path) + return path + + def _override_module_replaced_vars(self, task_vars): + """ Some vars are substituted into the modules. Have to make sure + that those are correct for localhost when synchronize creates its own + connection to localhost.""" + + # Clear the current definition of these variables as they came from the + # connection to the remote host + if 'ansible_syslog_facility' in task_vars: + del task_vars['ansible_syslog_facility'] + for key in list(task_vars.keys()): + if key.startswith("ansible_") and key.endswith("_interpreter"): + del task_vars[key] + + # Add the definitions from localhost + for host in C.LOCALHOST: + if host in task_vars['hostvars']: + localhost = task_vars['hostvars'][host] + break + if 'ansible_syslog_facility' in localhost: + task_vars['ansible_syslog_facility'] = localhost['ansible_syslog_facility'] + for key in localhost: + if key.startswith("ansible_") and key.endswith("_interpreter"): + task_vars[key] = localhost[key] + + def run(self, tmp=None, task_vars=None): + ''' generates params and passes them on to the rsync module ''' + # When modifying this function be aware of the tricky convolutions + # your thoughts have to go through: + # + # In normal ansible, we connect from controller to inventory_hostname + # (playbook's hosts: field) or controller to delegate_to host and run + # a module on one of those hosts. + # + # So things that are directly related to the core of ansible are in + # terms of that sort of connection that always originate on the + # controller. + # + # In synchronize we use ansible to connect to either the controller or + # to the delegate_to host and then run rsync which makes its own + # connection from controller to inventory_hostname or delegate_to to + # inventory_hostname. + # + # That means synchronize needs to have some knowledge of the + # controller to inventory_host/delegate host that ansible typically + # establishes and use those to construct a command line for rsync to + # connect from the inventory_host to the controller/delegate. The + # challenge for coders is remembering which leg of the trip is + # associated with the conditions that you're checking at any one time. + if task_vars is None: + task_vars = dict() + + # We make a copy of the args here because we may fail and be asked to + # retry. If that happens we don't want to pass the munged args through + # to our next invocation. Munged args are single use only. + _tmp_args = self._task.args.copy() + + result = super(ActionModule, self).run(tmp, task_vars) + del tmp # tmp no longer has any effect + + # Store remote connection type + self._remote_transport = self._connection.transport + use_ssh_args = _tmp_args.pop('use_ssh_args', None) + + if use_ssh_args and self._connection.transport == 'ssh': + ssh_args = [ + self._connection.get_option('ssh_args'), + self._connection.get_option('ssh_common_args'), + self._connection.get_option('ssh_extra_args'), + ] + _tmp_args['ssh_args'] = ' '.join([a for a in ssh_args if a]) + + # Handle docker connection options + if self._remote_transport in DOCKER: + self._docker_cmd = self._connection.docker_cmd + if self._play_context.docker_extra_args: + self._docker_cmd = "%s %s" % (self._docker_cmd, self._play_context.docker_extra_args) + elif self._remote_transport in PODMAN: + self._docker_cmd = self._connection._options['podman_executable'] + if self._connection._options.get('podman_extra_args'): + self._docker_cmd = "%s %s" % (self._docker_cmd, self._connection._options['podman_extra_args']) + + # self._connection accounts for delegate_to so + # remote_transport is the transport ansible thought it would need + # between the controller and the delegate_to host or the controller + # and the remote_host if delegate_to isn't set. + + remote_transport = False + if self._connection.transport != 'local': + remote_transport = True + + try: + delegate_to = self._task.delegate_to + except (AttributeError, KeyError): + delegate_to = None + + # ssh paramiko docker buildah and local are fully supported transports. Anything + # else only works with delegate_to + if delegate_to is None and self._connection.transport not in [ + 'ssh', 'paramiko', 'local'] + DOCKER + PODMAN + BUILDAH: + result['failed'] = True + result['msg'] = ( + "synchronize uses rsync to function. rsync needs to connect to the remote " + "host via ssh, docker client or a direct filesystem " + "copy. This remote host is being accessed via %s instead " + "so it cannot work." % self._connection.transport) + return result + + # Parameter name needed by the ansible module + _tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync' + + # 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 + # ansible's delegate_to mechanism to determine which host rsync is + # running on so localhost could be a non-controller machine if + # delegate_to is used) + src_host = '127.0.0.1' + inventory_hostname = task_vars.get('inventory_hostname') + dest_host_inventory_vars = task_vars['hostvars'].get(inventory_hostname) + dest_host = dest_host_inventory_vars.get('ansible_host', inventory_hostname) + + dest_host_ids = [hostid for hostid in (dest_host_inventory_vars.get('inventory_hostname'), + dest_host_inventory_vars.get('ansible_host')) + if hostid is not None] + + localhost_ports = set() + for host in C.LOCALHOST: + localhost_vars = task_vars['hostvars'].get(host, {}) + for port_var in C.MAGIC_VARIABLE_MAPPING['port']: + port = localhost_vars.get(port_var, None) + if port: + break + else: + port = C.DEFAULT_REMOTE_PORT + localhost_ports.add(port) + + # dest_is_local tells us if the host rsync runs on is the same as the + # host rsync puts the files on. This is about *rsync's connection*, + # not about the ansible connection to run the module. + dest_is_local = False + if delegate_to is None and remote_transport is False: + dest_is_local = True + elif delegate_to is not None and delegate_to in dest_host_ids: + dest_is_local = True + + # CHECK FOR NON-DEFAULT SSH PORT + inv_port = task_vars.get('ansible_port', None) or C.DEFAULT_REMOTE_PORT + if _tmp_args.get('dest_port', None) is None: + if inv_port is not None: + _tmp_args['dest_port'] = inv_port + + # Set use_delegate if we are going to run rsync on a delegated host + # instead of localhost + use_delegate = False + if delegate_to is not None and delegate_to in dest_host_ids: + # edge case: explicit delegate and dest_host are the same + # so we run rsync on the remote machine targeting its localhost + # (itself) + dest_host = '127.0.0.1' + use_delegate = True + elif delegate_to is not None and remote_transport: + # If we're delegating to a remote host then we need to use the + # delegate_to settings + use_delegate = True + + # Delegate to localhost as the source of the rsync unless we've been + # told (via delegate_to) that a different host is the source of the + # rsync + if not use_delegate and remote_transport: + # Create a connection to localhost to run rsync on + new_stdin = self._connection._new_stdin + + # Unlike port, there can be only one shell + localhost_shell = None + for host in C.LOCALHOST: + localhost_vars = task_vars['hostvars'].get(host, {}) + for shell_var in C.MAGIC_VARIABLE_MAPPING['shell']: + localhost_shell = localhost_vars.get(shell_var, None) + if localhost_shell: + break + if localhost_shell: + break + else: + localhost_shell = os.path.basename(C.DEFAULT_EXECUTABLE) + self._play_context.shell = localhost_shell + + # Unlike port, there can be only one executable + localhost_executable = None + for host in C.LOCALHOST: + localhost_vars = task_vars['hostvars'].get(host, {}) + for executable_var in C.MAGIC_VARIABLE_MAPPING['executable']: + localhost_executable = localhost_vars.get(executable_var, None) + if localhost_executable: + break + if localhost_executable: + break + else: + localhost_executable = C.DEFAULT_EXECUTABLE + self._play_context.executable = localhost_executable + + new_connection = connection_loader.get('local', self._play_context, new_stdin) + self._connection = new_connection + # Override _remote_is_local as an instance attribute specifically for the synchronize use case + # ensuring we set local tmpdir correctly + self._connection._remote_is_local = True + self._override_module_replaced_vars(task_vars) + + # SWITCH SRC AND DEST HOST PER MODE + if _tmp_args.get('mode', 'push') == 'pull': + (dest_host, src_host) = (src_host, dest_host) + + # MUNGE SRC AND DEST PER REMOTE_HOST INFO + src = _tmp_args.get('src', None) + dest = _tmp_args.get('dest', None) + if src is None or dest is None: + return dict(failed=True, msg="synchronize requires both src and dest parameters are set") + + # Determine if we need a user@ and a password + user = None + password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None) + if not dest_is_local: + # Src and dest rsync "path" handling + if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False): + if use_delegate: + user = task_vars.get('ansible_delegated_vars', dict()).get('ansible_user', None) + if not user: + user = task_vars.get('ansible_user') or self._play_context.remote_user + if not user: + user = C.DEFAULT_REMOTE_USER + else: + user = task_vars.get('ansible_user') or self._play_context.remote_user + + if self._templar is not None: + user = self._templar.template(user) + + # Private key handling + # Use the private_key parameter if passed else use context private_key_file + _tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file) + + # use the mode to define src and dest's url + if _tmp_args.get('mode', 'push') == 'pull': + # src is a remote path: @, dest is a local path + src = self._process_remote(_tmp_args, src_host, src, user, inv_port in localhost_ports) + dest = self._process_origin(dest_host, dest, user) + else: + # src is a local path, dest is a remote path: @ + src = self._process_origin(src_host, src, user) + dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports) + + password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None) + if self._templar is not None: + password = self._templar.template(password) + else: + # Still need to munge paths (to account for roles) even if we aren't + # copying files between hosts + src = self._get_absolute_path(path=src) + dest = self._get_absolute_path(path=dest) + + _tmp_args['_local_rsync_password'] = password + _tmp_args['src'] = src + _tmp_args['dest'] = dest + + # Allow custom rsync path argument + rsync_path = _tmp_args.get('rsync_path', None) + + # backup original become as we are probably about to unset it + become = self._play_context.become + + if not dest_is_local: + # don't escalate for docker. doing --rsync-path with docker exec fails + # and we can switch directly to the user via docker arguments + if self._play_context.become and not rsync_path and self._remote_transport not in DOCKER + PODMAN: + # If no rsync_path is set, become was originally set, and dest is + # remote then add privilege escalation here. + if self._play_context.become_method == 'sudo': + if self._play_context.become_user: + rsync_path = 'sudo -u %s rsync' % self._play_context.become_user + else: + rsync_path = 'sudo rsync' + # TODO: have to add in the rest of the become methods here + + # We cannot use privilege escalation on the machine running the + # module. Instead we run it on the machine rsync is connecting + # to. + self._play_context.become = False + + _tmp_args['rsync_path'] = rsync_path + + # If launching synchronize against docker container + # use rsync_opts to support container to override rsh options + if self._remote_transport in DOCKER + BUILDAH + PODMAN and not use_delegate: + # Replicate what we do in the module argumentspec handling for lists + if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence): + tmp_rsync_opts = _tmp_args.get('rsync_opts', []) + if isinstance(tmp_rsync_opts, string_types): + tmp_rsync_opts = tmp_rsync_opts.split(',') + elif isinstance(tmp_rsync_opts, (int, float)): + tmp_rsync_opts = [to_text(tmp_rsync_opts)] + _tmp_args['rsync_opts'] = tmp_rsync_opts + + if '--blocking-io' not in _tmp_args['rsync_opts']: + _tmp_args['rsync_opts'].append('--blocking-io') + + if self._remote_transport in DOCKER + PODMAN: + if become and self._play_context.become_user: + _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -u %s -i' % (self._docker_cmd, self._play_context.become_user))) + elif user is not None: + _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -u %s -i' % (self._docker_cmd, user))) + else: + _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -i' % self._docker_cmd)) + elif self._remote_transport in BUILDAH: + _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('buildah run --')) + + # run the module and store the result + result.update(self._execute_module('ansible.posix.synchronize', module_args=_tmp_args, task_vars=task_vars)) + + return result From 4512e7b1e9d195bd30a535f09f207b322da53177 Mon Sep 17 00:00:00 2001 From: Juan Antonio Valino Garcia Date: Fri, 7 Oct 2022 18:10:45 +0200 Subject: [PATCH 08/40] add changelog fragment --- changelogs/fragments/390_hosts_involved_same_password.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/390_hosts_involved_same_password.yml diff --git a/changelogs/fragments/390_hosts_involved_same_password.yml b/changelogs/fragments/390_hosts_involved_same_password.yml new file mode 100644 index 0000000..1169a31 --- /dev/null +++ b/changelogs/fragments/390_hosts_involved_same_password.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - synchronize - Fixed hosts involved in rsync require the same password From 50f87b0d15903cfc3f7cd700d550b1e633310a0b Mon Sep 17 00:00:00 2001 From: Juan Antonio Valino Garcia Date: Fri, 7 Oct 2022 18:30:49 +0200 Subject: [PATCH 09/40] move plugin to correct dir --- plugins/action/synchronize.py | 7 +- synchronize.py | 434 ---------------------------------- 2 files changed, 5 insertions(+), 436 deletions(-) delete mode 100644 synchronize.py diff --git a/plugins/action/synchronize.py b/plugins/action/synchronize.py index 7a330ac..c70db5f 100644 --- a/plugins/action/synchronize.py +++ b/plugins/action/synchronize.py @@ -347,7 +347,8 @@ class ActionModule(ActionBase): else: user = task_vars.get('ansible_user') or self._play_context.remote_user - user = self._templar.template(user) + if self._templar is not None: + user = self._templar.template(user) # Private key handling # Use the private_key parameter if passed else use context private_key_file @@ -364,13 +365,15 @@ class ActionModule(ActionBase): dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports) password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None) + if self._templar is not None: + password = self._templar.template(password) else: # Still need to munge paths (to account for roles) even if we aren't # copying files between hosts src = self._get_absolute_path(path=src) dest = self._get_absolute_path(path=dest) - _tmp_args['_local_rsync_password'] = self._templar.template(password) + _tmp_args['_local_rsync_password'] = password _tmp_args['src'] = src _tmp_args['dest'] = dest diff --git a/synchronize.py b/synchronize.py deleted file mode 100644 index c70db5f..0000000 --- a/synchronize.py +++ /dev/null @@ -1,434 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2012-2013, Timothy Appnel -# -# 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 . -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os.path - -from ansible import constants as C -from ansible.module_utils.six import string_types -from ansible.module_utils.six.moves import shlex_quote -from ansible.module_utils._text import to_text -from ansible.module_utils.common._collections_compat import MutableSequence -from ansible.module_utils.parsing.convert_bool import boolean -from ansible.plugins.action import ActionBase -from ansible.plugins.loader import connection_loader - - -DOCKER = ['docker', 'community.general.docker', 'community.docker.docker'] -PODMAN = ['podman', 'ansible.builtin.podman', 'containers.podman.podman'] -BUILDAH = ['buildah', 'containers.podman.buildah'] - - -class ActionModule(ActionBase): - - def _get_absolute_path(self, path): - original_path = path - - # - # Check if we have a local relative path and do not process - # * remote paths (some.server.domain:/some/remote/path/...) - # * URLs (rsync://...) - # * local absolute paths (/some/local/path/...) - # - if ':' in path or path.startswith('/'): - return path - - if self._task._role is not None: - path = self._loader.path_dwim_relative(self._task._role._role_path, 'files', path) - else: - path = self._loader.path_dwim_relative(self._loader.get_basedir(), 'files', path) - - if original_path and original_path[-1] == '/' and path[-1] != '/': - # make sure the dwim'd path ends in a trailing "/" - # if the original path did - path += '/' - - return path - - def _host_is_ipv6_address(self, host): - return ':' in to_text(host, errors='surrogate_or_strict') - - def _format_rsync_rsh_target(self, host, path, user): - ''' formats rsync rsh target, escaping ipv6 addresses if needed ''' - - user_prefix = '' - - if path.startswith('rsync://'): - return path - - # If using docker or buildah, do not add user information - if self._remote_transport not in DOCKER + PODMAN + BUILDAH and user: - user_prefix = '%s@' % (user, ) - - if self._host_is_ipv6_address(host): - return '[%s%s]:%s' % (user_prefix, host, path) - return '%s%s:%s' % (user_prefix, host, path) - - def _process_origin(self, host, path, user): - - if host not in C.LOCALHOST: - return self._format_rsync_rsh_target(host, path, user) - - path = self._get_absolute_path(path=path) - return path - - def _process_remote(self, task_args, host, path, user, port_matches_localhost_port): - """ - :arg host: hostname for the path - :arg path: file path - :arg user: username for the transfer - :arg port_matches_localhost_port: boolean whether the remote port - matches the port used by localhost's sshd. This is used in - conjunction with seeing whether the host is localhost to know - if we need to have the module substitute the pathname or if it - is a different host (for instance, an ssh tunnelled port or an - alternative ssh port to a vagrant host.) - """ - transport = self._connection.transport - # If we're connecting to a remote host or we're delegating to another - # host or we're connecting to a different ssh instance on the - # localhost then we have to format the path as a remote rsync path - if host not in C.LOCALHOST or transport != "local" or \ - (host in C.LOCALHOST and not port_matches_localhost_port): - # If we're delegating to non-localhost and but the - # inventory_hostname host is localhost then we need the module to - # fix up the rsync path to use the controller's public DNS/IP - # instead of "localhost" - if port_matches_localhost_port and host in C.LOCALHOST: - task_args['_substitute_controller'] = True - return self._format_rsync_rsh_target(host, path, user) - - path = self._get_absolute_path(path=path) - return path - - def _override_module_replaced_vars(self, task_vars): - """ Some vars are substituted into the modules. Have to make sure - that those are correct for localhost when synchronize creates its own - connection to localhost.""" - - # Clear the current definition of these variables as they came from the - # connection to the remote host - if 'ansible_syslog_facility' in task_vars: - del task_vars['ansible_syslog_facility'] - for key in list(task_vars.keys()): - if key.startswith("ansible_") and key.endswith("_interpreter"): - del task_vars[key] - - # Add the definitions from localhost - for host in C.LOCALHOST: - if host in task_vars['hostvars']: - localhost = task_vars['hostvars'][host] - break - if 'ansible_syslog_facility' in localhost: - task_vars['ansible_syslog_facility'] = localhost['ansible_syslog_facility'] - for key in localhost: - if key.startswith("ansible_") and key.endswith("_interpreter"): - task_vars[key] = localhost[key] - - def run(self, tmp=None, task_vars=None): - ''' generates params and passes them on to the rsync module ''' - # When modifying this function be aware of the tricky convolutions - # your thoughts have to go through: - # - # In normal ansible, we connect from controller to inventory_hostname - # (playbook's hosts: field) or controller to delegate_to host and run - # a module on one of those hosts. - # - # So things that are directly related to the core of ansible are in - # terms of that sort of connection that always originate on the - # controller. - # - # In synchronize we use ansible to connect to either the controller or - # to the delegate_to host and then run rsync which makes its own - # connection from controller to inventory_hostname or delegate_to to - # inventory_hostname. - # - # That means synchronize needs to have some knowledge of the - # controller to inventory_host/delegate host that ansible typically - # establishes and use those to construct a command line for rsync to - # connect from the inventory_host to the controller/delegate. The - # challenge for coders is remembering which leg of the trip is - # associated with the conditions that you're checking at any one time. - if task_vars is None: - task_vars = dict() - - # We make a copy of the args here because we may fail and be asked to - # retry. If that happens we don't want to pass the munged args through - # to our next invocation. Munged args are single use only. - _tmp_args = self._task.args.copy() - - result = super(ActionModule, self).run(tmp, task_vars) - del tmp # tmp no longer has any effect - - # Store remote connection type - self._remote_transport = self._connection.transport - use_ssh_args = _tmp_args.pop('use_ssh_args', None) - - if use_ssh_args and self._connection.transport == 'ssh': - ssh_args = [ - self._connection.get_option('ssh_args'), - self._connection.get_option('ssh_common_args'), - self._connection.get_option('ssh_extra_args'), - ] - _tmp_args['ssh_args'] = ' '.join([a for a in ssh_args if a]) - - # Handle docker connection options - if self._remote_transport in DOCKER: - self._docker_cmd = self._connection.docker_cmd - if self._play_context.docker_extra_args: - self._docker_cmd = "%s %s" % (self._docker_cmd, self._play_context.docker_extra_args) - elif self._remote_transport in PODMAN: - self._docker_cmd = self._connection._options['podman_executable'] - if self._connection._options.get('podman_extra_args'): - self._docker_cmd = "%s %s" % (self._docker_cmd, self._connection._options['podman_extra_args']) - - # self._connection accounts for delegate_to so - # remote_transport is the transport ansible thought it would need - # between the controller and the delegate_to host or the controller - # and the remote_host if delegate_to isn't set. - - remote_transport = False - if self._connection.transport != 'local': - remote_transport = True - - try: - delegate_to = self._task.delegate_to - except (AttributeError, KeyError): - delegate_to = None - - # ssh paramiko docker buildah and local are fully supported transports. Anything - # else only works with delegate_to - if delegate_to is None and self._connection.transport not in [ - 'ssh', 'paramiko', 'local'] + DOCKER + PODMAN + BUILDAH: - result['failed'] = True - result['msg'] = ( - "synchronize uses rsync to function. rsync needs to connect to the remote " - "host via ssh, docker client or a direct filesystem " - "copy. This remote host is being accessed via %s instead " - "so it cannot work." % self._connection.transport) - return result - - # Parameter name needed by the ansible module - _tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync' - - # 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 - # ansible's delegate_to mechanism to determine which host rsync is - # running on so localhost could be a non-controller machine if - # delegate_to is used) - src_host = '127.0.0.1' - inventory_hostname = task_vars.get('inventory_hostname') - dest_host_inventory_vars = task_vars['hostvars'].get(inventory_hostname) - dest_host = dest_host_inventory_vars.get('ansible_host', inventory_hostname) - - dest_host_ids = [hostid for hostid in (dest_host_inventory_vars.get('inventory_hostname'), - dest_host_inventory_vars.get('ansible_host')) - if hostid is not None] - - localhost_ports = set() - for host in C.LOCALHOST: - localhost_vars = task_vars['hostvars'].get(host, {}) - for port_var in C.MAGIC_VARIABLE_MAPPING['port']: - port = localhost_vars.get(port_var, None) - if port: - break - else: - port = C.DEFAULT_REMOTE_PORT - localhost_ports.add(port) - - # dest_is_local tells us if the host rsync runs on is the same as the - # host rsync puts the files on. This is about *rsync's connection*, - # not about the ansible connection to run the module. - dest_is_local = False - if delegate_to is None and remote_transport is False: - dest_is_local = True - elif delegate_to is not None and delegate_to in dest_host_ids: - dest_is_local = True - - # CHECK FOR NON-DEFAULT SSH PORT - inv_port = task_vars.get('ansible_port', None) or C.DEFAULT_REMOTE_PORT - if _tmp_args.get('dest_port', None) is None: - if inv_port is not None: - _tmp_args['dest_port'] = inv_port - - # Set use_delegate if we are going to run rsync on a delegated host - # instead of localhost - use_delegate = False - if delegate_to is not None and delegate_to in dest_host_ids: - # edge case: explicit delegate and dest_host are the same - # so we run rsync on the remote machine targeting its localhost - # (itself) - dest_host = '127.0.0.1' - use_delegate = True - elif delegate_to is not None and remote_transport: - # If we're delegating to a remote host then we need to use the - # delegate_to settings - use_delegate = True - - # Delegate to localhost as the source of the rsync unless we've been - # told (via delegate_to) that a different host is the source of the - # rsync - if not use_delegate and remote_transport: - # Create a connection to localhost to run rsync on - new_stdin = self._connection._new_stdin - - # Unlike port, there can be only one shell - localhost_shell = None - for host in C.LOCALHOST: - localhost_vars = task_vars['hostvars'].get(host, {}) - for shell_var in C.MAGIC_VARIABLE_MAPPING['shell']: - localhost_shell = localhost_vars.get(shell_var, None) - if localhost_shell: - break - if localhost_shell: - break - else: - localhost_shell = os.path.basename(C.DEFAULT_EXECUTABLE) - self._play_context.shell = localhost_shell - - # Unlike port, there can be only one executable - localhost_executable = None - for host in C.LOCALHOST: - localhost_vars = task_vars['hostvars'].get(host, {}) - for executable_var in C.MAGIC_VARIABLE_MAPPING['executable']: - localhost_executable = localhost_vars.get(executable_var, None) - if localhost_executable: - break - if localhost_executable: - break - else: - localhost_executable = C.DEFAULT_EXECUTABLE - self._play_context.executable = localhost_executable - - new_connection = connection_loader.get('local', self._play_context, new_stdin) - self._connection = new_connection - # Override _remote_is_local as an instance attribute specifically for the synchronize use case - # ensuring we set local tmpdir correctly - self._connection._remote_is_local = True - self._override_module_replaced_vars(task_vars) - - # SWITCH SRC AND DEST HOST PER MODE - if _tmp_args.get('mode', 'push') == 'pull': - (dest_host, src_host) = (src_host, dest_host) - - # MUNGE SRC AND DEST PER REMOTE_HOST INFO - src = _tmp_args.get('src', None) - dest = _tmp_args.get('dest', None) - if src is None or dest is None: - return dict(failed=True, msg="synchronize requires both src and dest parameters are set") - - # Determine if we need a user@ and a password - user = None - password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None) - if not dest_is_local: - # Src and dest rsync "path" handling - if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False): - if use_delegate: - user = task_vars.get('ansible_delegated_vars', dict()).get('ansible_user', None) - if not user: - user = task_vars.get('ansible_user') or self._play_context.remote_user - if not user: - user = C.DEFAULT_REMOTE_USER - else: - user = task_vars.get('ansible_user') or self._play_context.remote_user - - if self._templar is not None: - user = self._templar.template(user) - - # Private key handling - # Use the private_key parameter if passed else use context private_key_file - _tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file) - - # use the mode to define src and dest's url - if _tmp_args.get('mode', 'push') == 'pull': - # src is a remote path: @, dest is a local path - src = self._process_remote(_tmp_args, src_host, src, user, inv_port in localhost_ports) - dest = self._process_origin(dest_host, dest, user) - else: - # src is a local path, dest is a remote path: @ - src = self._process_origin(src_host, src, user) - dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports) - - password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None) - if self._templar is not None: - password = self._templar.template(password) - else: - # Still need to munge paths (to account for roles) even if we aren't - # copying files between hosts - src = self._get_absolute_path(path=src) - dest = self._get_absolute_path(path=dest) - - _tmp_args['_local_rsync_password'] = password - _tmp_args['src'] = src - _tmp_args['dest'] = dest - - # Allow custom rsync path argument - rsync_path = _tmp_args.get('rsync_path', None) - - # backup original become as we are probably about to unset it - become = self._play_context.become - - if not dest_is_local: - # don't escalate for docker. doing --rsync-path with docker exec fails - # and we can switch directly to the user via docker arguments - if self._play_context.become and not rsync_path and self._remote_transport not in DOCKER + PODMAN: - # If no rsync_path is set, become was originally set, and dest is - # remote then add privilege escalation here. - if self._play_context.become_method == 'sudo': - if self._play_context.become_user: - rsync_path = 'sudo -u %s rsync' % self._play_context.become_user - else: - rsync_path = 'sudo rsync' - # TODO: have to add in the rest of the become methods here - - # We cannot use privilege escalation on the machine running the - # module. Instead we run it on the machine rsync is connecting - # to. - self._play_context.become = False - - _tmp_args['rsync_path'] = rsync_path - - # If launching synchronize against docker container - # use rsync_opts to support container to override rsh options - if self._remote_transport in DOCKER + BUILDAH + PODMAN and not use_delegate: - # Replicate what we do in the module argumentspec handling for lists - if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence): - tmp_rsync_opts = _tmp_args.get('rsync_opts', []) - if isinstance(tmp_rsync_opts, string_types): - tmp_rsync_opts = tmp_rsync_opts.split(',') - elif isinstance(tmp_rsync_opts, (int, float)): - tmp_rsync_opts = [to_text(tmp_rsync_opts)] - _tmp_args['rsync_opts'] = tmp_rsync_opts - - if '--blocking-io' not in _tmp_args['rsync_opts']: - _tmp_args['rsync_opts'].append('--blocking-io') - - if self._remote_transport in DOCKER + PODMAN: - if become and self._play_context.become_user: - _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -u %s -i' % (self._docker_cmd, self._play_context.become_user))) - elif user is not None: - _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -u %s -i' % (self._docker_cmd, user))) - else: - _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('%s exec -i' % self._docker_cmd)) - elif self._remote_transport in BUILDAH: - _tmp_args['rsync_opts'].append('--rsh=' + shlex_quote('buildah run --')) - - # run the module and store the result - result.update(self._execute_module('ansible.posix.synchronize', module_args=_tmp_args, task_vars=task_vars)) - - return result From d0e1504f8a74f666bad417c69f3b48b9b8d141b3 Mon Sep 17 00:00:00 2001 From: Vladislav Sharapov Date: Fri, 9 Dec 2022 00:36:29 +0400 Subject: [PATCH 10/40] Fix boolean values in docs --- plugins/modules/acl.py | 16 +++++----- plugins/modules/at.py | 4 +-- plugins/modules/authorized_key.py | 30 +++++++++---------- plugins/modules/firewalld.py | 34 ++++++++++----------- plugins/modules/firewalld_info.py | 4 +-- plugins/modules/mount.py | 6 ++-- plugins/modules/patch.py | 16 +++++----- plugins/modules/seboolean.py | 8 ++--- plugins/modules/selinux.py | 2 +- plugins/modules/synchronize.py | 50 +++++++++++++++---------------- plugins/modules/sysctl.py | 20 ++++++------- 11 files changed, 95 insertions(+), 95 deletions(-) diff --git a/plugins/modules/acl.py b/plugins/modules/acl.py index a2e3d6d..37efc44 100644 --- a/plugins/modules/acl.py +++ b/plugins/modules/acl.py @@ -20,7 +20,7 @@ options: description: - The full path of the file or object. type: path - required: yes + required: true aliases: [ name ] state: description: @@ -33,13 +33,13 @@ options: description: - Whether to follow symlinks on the path if a symlink is encountered. type: bool - default: yes + default: true default: description: - - If the target is a directory, setting this to C(yes) will make it the default ACL for entities created inside the directory. - - Setting C(default) to C(yes) causes an error if the path is a file. + - If the target is a directory, setting this to C(true) will make it the default ACL for entities created inside the directory. + - Setting C(default) to C(true) causes an error if the path is a file. type: bool - default: no + default: false entity: description: - The actual user or group that the ACL applies to when matching entity types user or group are selected. @@ -69,13 +69,13 @@ options: - Incompatible with C(state=query). - Alias C(recurse) added in version 1.3.0. type: bool - default: no + default: false aliases: [ recurse ] use_nfsv4_acls: description: - Use NFSv4 ACLs instead of POSIX ACLs. type: bool - default: no + default: false recalculate_mask: description: - Select if and when to recalculate the effective right masks of the files. @@ -115,7 +115,7 @@ EXAMPLES = r''' entity: joe etype: user permissions: rw - default: yes + default: true state: present - name: Same as previous but using entry shorthand diff --git a/plugins/modules/at.py b/plugins/modules/at.py index a35ec4e..3db953e 100644 --- a/plugins/modules/at.py +++ b/plugins/modules/at.py @@ -44,7 +44,7 @@ options: description: - If a matching job is present a new job will not be added. type: bool - default: no + default: false requirements: - at author: @@ -68,7 +68,7 @@ EXAMPLES = r''' command: ls -d / >/dev/null count: 20 units: minutes - unique: yes + unique: true ''' import os diff --git a/plugins/modules/authorized_key.py b/plugins/modules/authorized_key.py index 5e37c28..424ee4a 100644 --- a/plugins/modules/authorized_key.py +++ b/plugins/modules/authorized_key.py @@ -34,13 +34,13 @@ options: manage_dir: description: - Whether this module should manage the directory of the authorized key file. - - If set to C(yes), the module will create the directory, as well as set the owner and permissions + - If set to C(true), the module will create the directory, as well as set the owner and permissions of an existing directory. - - Be sure to set C(manage_dir=no) if you are using an alternate directory for authorized_keys, + - Be sure to set C(manage_dir=false) if you are using an alternate directory for authorized_keys, as set with C(path), since you could lock yourself out of SSH access. - See the example below. type: bool - default: yes + default: true state: description: - Whether the given key (with the given key_options) should or should not be in the file. @@ -58,15 +58,15 @@ options: - This option is not loop aware, so if you use C(with_) , it will be exclusive per iteration of the loop. - If you want multiple keys in the file you need to pass them all to C(key) in a single batch as mentioned above. type: bool - default: no + default: false validate_certs: description: - This only applies if using a https url as the source of the keys. - - If set to C(no), the SSL certificates will not be validated. - - This should only set to C(no) used on personally controlled sites using self-signed certificates as it avoids verifying the source site. - - Prior to 2.1 the code worked as if this was set to C(yes). + - If set to C(false), the SSL certificates will not be validated. + - This should only set to C(false) used on personally controlled sites using self-signed certificates as it avoids verifying the source site. + - Prior to 2.1 the code worked as if this was set to C(true). type: bool - default: yes + default: true comment: description: - Change the comment on the public key. @@ -77,7 +77,7 @@ options: description: - Follow path symlink instead of replacing it. type: bool - default: no + default: false author: Ansible Core Team ''' @@ -106,7 +106,7 @@ EXAMPLES = r''' state: present key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" path: /etc/ssh/authorized_keys/charlie - manage_dir: False + manage_dir: false - name: Set up multiple authorized keys ansible.posix.authorized_key: @@ -129,14 +129,14 @@ EXAMPLES = r''' user: charlie state: present key: https://github.com/user.keys - validate_certs: False + validate_certs: false - name: Set authorized key, removing all the authorized keys already set ansible.posix.authorized_key: user: root key: "{{ lookup('file', 'public_keys/doe-jane') }}" state: present - exclusive: True + exclusive: true - name: Set authorized key for user ubuntu copying it from current user ansible.posix.authorized_key: @@ -150,7 +150,7 @@ exclusive: description: If the key has been forced to be exclusive or not. returned: success type: bool - sample: False + sample: false key: description: The key that the module was running against. returned: success @@ -170,7 +170,7 @@ manage_dir: description: Whether this module managed the directory of the authorized key file. returned: success type: bool - sample: True + sample: true path: description: Alternate path to the authorized_keys file returned: success @@ -192,7 +192,7 @@ user: type: str sample: user validate_certs: - description: This only applies if using a https url as the source of the keys. If set to C(no), the SSL certificates will not be validated. + description: This only applies if using a https url as the source of the keys. If set to C(false), the SSL certificates will not be validated. returned: success type: bool sample: true diff --git a/plugins/modules/firewalld.py b/plugins/modules/firewalld.py index 39a3b18..dba16aa 100644 --- a/plugins/modules/firewalld.py +++ b/plugins/modules/firewalld.py @@ -82,13 +82,13 @@ options: description: - 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). - - 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 immediate: description: - Should this configuration be applied immediately, if set as permanent. type: bool - default: no + default: false state: description: - Enable or disable a setting. @@ -141,29 +141,29 @@ EXAMPLES = r''' - name: permit traffic in default zone for https service ansible.posix.firewalld: service: https - permanent: yes + permanent: true state: enabled - name: do not permit traffic in default zone on port 8081/tcp ansible.posix.firewalld: port: 8081/tcp - permanent: yes + permanent: true state: disabled - ansible.posix.firewalld: port: 161-162/udp - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: zone: dmz service: http - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: rich_rule: rule service name="ftp" audit limit value="1/m" accept - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: @@ -174,44 +174,44 @@ EXAMPLES = r''' - ansible.posix.firewalld: zone: trusted interface: eth2 - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: - masquerade: yes + masquerade: true state: enabled - permanent: yes + permanent: true zone: dmz - ansible.posix.firewalld: zone: custom state: present - permanent: yes + permanent: true - ansible.posix.firewalld: zone: drop state: enabled - permanent: yes - icmp_block_inversion: yes + permanent: true + icmp_block_inversion: true - ansible.posix.firewalld: zone: drop state: enabled - permanent: yes + permanent: true icmp_block: echo-request - ansible.posix.firewalld: zone: internal state: present - permanent: yes + permanent: true target: ACCEPT - name: Redirect port 443 to 8443 with Rich Rule ansible.posix.firewalld: rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443 zone: public - permanent: yes - immediate: yes + permanent: true + immediate: true state: enabled ''' diff --git a/plugins/modules/firewalld_info.py b/plugins/modules/firewalld_info.py index 6b1535b..29257bc 100644 --- a/plugins/modules/firewalld_info.py +++ b/plugins/modules/firewalld_info.py @@ -17,7 +17,7 @@ options: active_zones: description: Gather information about active zones. type: bool - default: no + default: false zones: description: - Gather information about specific zones. @@ -36,7 +36,7 @@ author: EXAMPLES = r''' - name: Gather information about active zones ansible.posix.firewalld_info: - active_zones: yes + active_zones: true - name: Gather information about specific zones ansible.posix.firewalld_info: diff --git a/plugins/modules/mount.py b/plugins/modules/mount.py index 58b49bc..d8e1359 100644 --- a/plugins/modules/mount.py +++ b/plugins/modules/mount.py @@ -101,13 +101,13 @@ options: - To avoid mount option conflicts, if C(noauto) specified in C(opts), mount module will ignore C(boot). type: bool - default: yes + default: true backup: description: - Create a backup file including the timestamp information so you can get the original file back if you somehow clobbered it incorrectly. type: bool - default: no + default: false notes: - As of Ansible 2.3, the I(name) option has been changed to I(path) as default, but I(name) still works as well. @@ -181,7 +181,7 @@ EXAMPLES = r''' src: 192.168.1.100:/nfs/ssd/shared_data path: /mnt/shared_data opts: rw,sync,hard - boot: no + boot: false state: mounted fstype: nfs ''' diff --git a/plugins/modules/patch.py b/plugins/modules/patch.py index ea2c618..0c6fe47 100644 --- a/plugins/modules/patch.py +++ b/plugins/modules/patch.py @@ -50,10 +50,10 @@ options: default: present remote_src: description: - - If C(no), it will search for src at originating/controller machine, if C(yes) it will + - If C(false), it will search for src at originating/controller machine, if C(true) it will go to the remote/target machine for the C(src). type: bool - default: no + default: false strip: description: - Number that indicates the smallest prefix containing leading slashes @@ -65,20 +65,20 @@ options: description: - Passes C(--backup --version-control=numbered) to patch, producing numbered backup copies. type: bool - default: no + default: false binary: description: - - Setting to C(yes) will disable patch's heuristic for transforming CRLF + - Setting to C(true) will disable patch's heuristic for transforming CRLF line endings into LF. - Line endings of src and dest must match. - - If set to C(no), C(patch) will replace CRLF in C(src) files on POSIX. + - If set to C(false), C(patch) will replace CRLF in C(src) files on POSIX. type: bool - default: no + default: false ignore_whitespace: description: - - Setting to C(yes) will ignore white space changes between patch and input.. + - Setting to C(true) will ignore white space changes between patch and input. type: bool - default: no + default: false notes: - This module requires GNU I(patch) utility to be installed on the remote host. ''' diff --git a/plugins/modules/seboolean.py b/plugins/modules/seboolean.py index f4d8cf4..657b7fa 100644 --- a/plugins/modules/seboolean.py +++ b/plugins/modules/seboolean.py @@ -22,9 +22,9 @@ options: type: str persistent: description: - - Set to C(yes) if the boolean setting should survive a reboot. + - Set to C(true) if the boolean setting should survive a reboot. type: bool - default: 'no' + default: false state: description: - Desired boolean value @@ -49,8 +49,8 @@ EXAMPLES = r''' - name: Set httpd_can_network_connect flag on and keep it persistent across reboots ansible.posix.seboolean: name: httpd_can_network_connect - state: yes - persistent: yes + state: true + persistent: true ''' import os diff --git a/plugins/modules/selinux.py b/plugins/modules/selinux.py index 89e6b63..14110fe 100644 --- a/plugins/modules/selinux.py +++ b/plugins/modules/selinux.py @@ -32,7 +32,7 @@ options: description: - If set to I(true), will update also the kernel boot parameters when disabling/enabling SELinux. - The C(grubby) tool must be present on the target system for this to work. - default: no + default: false type: bool version_added: '1.4.0' configfile: diff --git a/plugins/modules/synchronize.py b/plugins/modules/synchronize.py index 86cf360..260fac8 100644 --- a/plugins/modules/synchronize.py +++ b/plugins/modules/synchronize.py @@ -53,36 +53,36 @@ options: description: - Mirrors the rsync archive flag, enables recursive, links, perms, times, owner, group flags and -D. type: bool - default: yes + default: true checksum: description: - Skip based on checksum, rather than mod-time & size; Note that that "archive" option is still enabled by default - the "checksum" option will not disable it. type: bool - default: no + default: false compress: description: - Compress file data during the transfer. - In most cases, leave this enabled unless it causes problems. type: bool - default: yes + default: true existing_only: description: - Skip creating new files on receiver. type: bool - default: no + default: false delete: description: - Delete files in I(dest) that do not exist (after transfer, not before) in the I(src) path. - - This option requires I(recursive=yes). + - This option requires I(recursive=true). - This option ignores excluded files and behaves like the rsync opt C(--delete-after). type: bool - default: no + default: false dirs: description: - Transfer directories without recursing. type: bool - default: no + default: false recursive: description: - Recurse into directories. @@ -97,7 +97,7 @@ options: description: - Copy symlinks as the item that they point to (the referent) is copied, rather than the symlink. type: bool - default: no + default: false perms: description: - Preserve permissions. @@ -132,26 +132,26 @@ options: description: - Put user@ for the remote paths. - If you have a custom ssh config to define the remote user for a host - that does not match the inventory user, you should set this parameter to C(no). + that does not match the inventory user, you should set this parameter to C(false). type: bool - default: yes + default: true use_ssh_args: description: - In Ansible 2.10 and lower, it uses the ssh_args specified in C(ansible.cfg). - In Ansible 2.11 and onwards, when set to C(true), it uses all SSH connection configurations like C(ansible_ssh_args), C(ansible_ssh_common_args), and C(ansible_ssh_extra_args). type: bool - default: no + default: false ssh_connection_multiplexing: description: - SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections. This is accomplished by setting the SSH C(ControlSocket) to C(none). - - Set this option to C(yes) to allow multiplexing and reduce SSH connection overhead. - - Note that simply setting this option to C(yes) is not enough; + - Set this option to C(true) to allow multiplexing and reduce SSH connection overhead. + - Note that simply setting this option to C(true) is not enough; You must also configure SSH connection multiplexing in your SSH client config by setting values for C(ControlMaster), C(ControlPersist) and C(ControlPath). type: bool - default: no + default: false rsync_opts: description: - Specify additional rsync options by passing in an array. @@ -163,12 +163,12 @@ options: description: - Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster. type: bool - default: no + default: false verify_host: description: - Verify destination host key. type: bool - default: no + default: false private_key: description: - Specify the private key to use for SSH-based rsync connections (e.g. C(~/.ssh/id_rsa)). @@ -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, at which time all the files are renamed into place in rapid succession. type: bool - default: yes + default: true version_added: '1.3.0' notes: @@ -252,27 +252,27 @@ EXAMPLES = r''' ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - archive: no + archive: false - name: Synchronization with --archive options enabled except for --recursive ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - recursive: no + recursive: false - name: Synchronization with --archive options enabled except for --times, with --checksum option enabled ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - checksum: yes - times: no + checksum: true + times: false - name: Synchronization without --archive options enabled except use --links ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - archive: no - links: yes + archive: false + links: true - name: Synchronization of two paths both on the control machine ansible.posix.synchronize: @@ -302,8 +302,8 @@ EXAMPLES = r''' ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - delete: yes - recursive: yes + delete: true + recursive: true # This specific command is granted su privileges on the destination - name: Synchronize using an alternate rsync command diff --git a/plugins/modules/sysctl.py b/plugins/modules/sysctl.py index b82b2e4..542b3c5 100644 --- a/plugins/modules/sysctl.py +++ b/plugins/modules/sysctl.py @@ -38,14 +38,14 @@ options: description: - Use this option to ignore errors about unknown keys. type: bool - default: 'no' + default: false reload: description: - - If C(yes), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is - updated. If C(no), does not reload I(sysctl) even if the + - If C(true), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is + updated. If C(false), does not reload I(sysctl) even if the C(sysctl_file) is updated. type: bool - default: 'yes' + default: true sysctl_file: description: - Specifies the absolute path to C(sysctl.conf), if not C(/etc/sysctl.conf). @@ -53,9 +53,9 @@ options: type: path sysctl_set: description: - - Verify token value with the sysctl command and set with -w if necessary + - Verify token value with the sysctl command and set with -w if necessary. type: bool - default: 'no' + default: false author: - David CHANIAL (@davixx) ''' @@ -78,21 +78,21 @@ EXAMPLES = r''' name: kernel.panic value: '3' sysctl_file: /tmp/test_sysctl.conf - reload: no + reload: false # Set ip forwarding on in /proc and verify token value with the sysctl command - ansible.posix.sysctl: name: net.ipv4.ip_forward value: '1' - sysctl_set: yes + sysctl_set: true # Set ip forwarding on in /proc and in the sysctl file and reload if necessary - ansible.posix.sysctl: name: net.ipv4.ip_forward value: '1' - sysctl_set: yes + sysctl_set: true state: present - reload: yes + reload: true ''' # ============================================================== From adcb28f8069f33d0d93628ec106e3b19a7f9ee4e Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 13 Dec 2022 10:40:51 -0500 Subject: [PATCH 11/40] Update documented default value for acl's entry parameter to match implementation. --- plugins/modules/acl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/acl.py b/plugins/modules/acl.py index a2e3d6d..119520e 100644 --- a/plugins/modules/acl.py +++ b/plugins/modules/acl.py @@ -44,6 +44,7 @@ options: description: - The actual user or group that the ACL applies to when matching entity types user or group are selected. type: str + default: "" etype: description: - The entity type of the ACL to apply, see C(setfacl) documentation for more info. From 0fff8fde30b8daee3ab66699bce082839576dd28 Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 13 Dec 2022 11:48:39 -0500 Subject: [PATCH 12/40] Update documented default value for rhel_rpm_ostree's name parameter to match implementation. --- plugins/modules/rhel_rpm_ostree.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/rhel_rpm_ostree.py b/plugins/modules/rhel_rpm_ostree.py index e5e8f2b..0976e02 100644 --- a/plugins/modules/rhel_rpm_ostree.py +++ b/plugins/modules/rhel_rpm_ostree.py @@ -35,6 +35,7 @@ options: aliases: [ pkg ] type: list elements: str + default: [] state: description: - Whether to install (C(present) or C(installed), C(latest)), or remove (C(absent) or C(removed)) a package. From bf0ad4aad236ba719a41caf812d8f8e03ae966bf Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 13 Dec 2022 12:46:39 -0500 Subject: [PATCH 13/40] Document pr #401 as a changelog fragment. --- changelogs/fragments/401_document_module_default_values.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/fragments/401_document_module_default_values.yml diff --git a/changelogs/fragments/401_document_module_default_values.yml b/changelogs/fragments/401_document_module_default_values.yml new file mode 100644 index 0000000..8a631dc --- /dev/null +++ b/changelogs/fragments/401_document_module_default_values.yml @@ -0,0 +1,4 @@ +--- +trivial: +- acl - document default value for the ``entry`` parameter +- rhel_rpm_ostree - document default value for the ``name`` parameter From 4229db1bbec16f7a8401acf296f97763d3f55c35 Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 13 Dec 2022 17:27:59 -0500 Subject: [PATCH 14/40] Fix issue where interfaces could not be added to a zone when firewalld is offline. Resolves issue #357. --- plugins/modules/firewalld.py | 14 +-- .../firewalld/tasks/interface_test_cases.yml | 87 +++++++++++++++++++ .../targets/firewalld/tasks/run_all_tests.yml | 3 + 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 tests/integration/targets/firewalld/tasks/interface_test_cases.yml diff --git a/plugins/modules/firewalld.py b/plugins/modules/firewalld.py index 39a3b18..960a42d 100644 --- a/plugins/modules/firewalld.py +++ b/plugins/modules/firewalld.py @@ -469,6 +469,7 @@ class InterfaceTransaction(FirewallTransaction): old_zone_obj = self.fw.config.get_zone(zone) if interface in old_zone_obj.interfaces: iface_zone_objs.append(old_zone_obj) + if len(iface_zone_objs) > 1: # Even it shouldn't happen, it's actually possible that # the same interface is in several zone XML files @@ -478,18 +479,17 @@ class InterfaceTransaction(FirewallTransaction): len(iface_zone_objs) ) ) - old_zone_obj = iface_zone_objs[0] - if old_zone_obj.name != self.zone: - old_zone_settings = FirewallClientZoneSettings( - self.fw.config.get_zone_config(old_zone_obj) - ) + elif len(iface_zone_objs) == 1 and iface_zone_objs[0].name != self.zone: + old_zone_obj = iface_zone_objs[0] + old_zone_config = self.fw.config.get_zone_config(old_zone_obj) + old_zone_settings = FirewallClientZoneSettings(list(old_zone_config)) old_zone_settings.removeInterface(interface) # remove from old self.fw.config.set_zone_config( old_zone_obj, old_zone_settings.settings ) - fw_settings.addInterface(interface) # add to new - self.fw.config.set_zone_config(fw_zone, fw_settings.settings) + fw_settings.addInterface(interface) # add to new + self.fw.config.set_zone_config(fw_zone, fw_settings.settings) else: old_zone_name = self.fw.config().getZoneOfInterface(interface) if old_zone_name != self.zone: diff --git a/tests/integration/targets/firewalld/tasks/interface_test_cases.yml b/tests/integration/targets/firewalld/tasks/interface_test_cases.yml new file mode 100644 index 0000000..e7130f7 --- /dev/null +++ b/tests/integration/targets/firewalld/tasks/interface_test_cases.yml @@ -0,0 +1,87 @@ +# Test playbook for the firewalld module - interface operations +# (c) 2022, Gregory Furlong +# 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 diff --git a/tests/integration/targets/firewalld/tasks/run_all_tests.yml b/tests/integration/targets/firewalld/tasks/run_all_tests.yml index 4270e89..b7540f3 100644 --- a/tests/integration/targets/firewalld/tasks/run_all_tests.yml +++ b/tests/integration/targets/firewalld/tasks/run_all_tests.yml @@ -21,3 +21,6 @@ # firewalld port forwarding operation test cases - include_tasks: port_forward_test_cases.yml + +# firewalld interface operation test cases +- include_tasks: interface_test_cases.yml From 9575b9be6429f17f22a091f796d2f6fd2dff1e22 Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 13 Dec 2022 18:02:56 -0500 Subject: [PATCH 15/40] Add changelog fragment documenting PR #402 --- .../fragments/402_firewall_fix_offline_interface_add.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/402_firewall_fix_offline_interface_add.yml diff --git a/changelogs/fragments/402_firewall_fix_offline_interface_add.yml b/changelogs/fragments/402_firewall_fix_offline_interface_add.yml new file mode 100644 index 0000000..e59a45d --- /dev/null +++ b/changelogs/fragments/402_firewall_fix_offline_interface_add.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - firewall - Fix issue where adding an interface to a zone would fail when the daemon is offline From c4742cfa810742c305d90b5461285f38810f7abc Mon Sep 17 00:00:00 2001 From: Vladislav Sharapov Date: Wed, 14 Dec 2022 20:44:50 +0400 Subject: [PATCH 16/40] Add changelog fragment --- changelogs/fragments/400-fix-boolean-values-in-docs.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/400-fix-boolean-values-in-docs.yml diff --git a/changelogs/fragments/400-fix-boolean-values-in-docs.yml b/changelogs/fragments/400-fix-boolean-values-in-docs.yml new file mode 100644 index 0000000..8ea04a7 --- /dev/null +++ b/changelogs/fragments/400-fix-boolean-values-in-docs.yml @@ -0,0 +1,3 @@ +--- +trivial: + - Change boolean values in documentation to ``true/false`` (https://github.com/ansible-collections/ansible.posix/pull/400). From d6a997b37d4c19c48f336a9415aa72658ec4cc92 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Thu, 22 Dec 2022 15:42:38 +0900 Subject: [PATCH 17/40] Modify firewalld port test cases to avoid port duplication. Signed-off-by: Hideki Saito --- changelogs/fragments/407_fix_firewalld_port_test.yml | 3 +++ .../integration/targets/firewalld/tasks/port_test_cases.yml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/407_fix_firewalld_port_test.yml diff --git a/changelogs/fragments/407_fix_firewalld_port_test.yml b/changelogs/fragments/407_fix_firewalld_port_test.yml new file mode 100644 index 0000000..0b82489 --- /dev/null +++ b/changelogs/fragments/407_fix_firewalld_port_test.yml @@ -0,0 +1,3 @@ +--- +trivial: +- Fix firewalld port test cases to avoid port duplicatation. diff --git a/tests/integration/targets/firewalld/tasks/port_test_cases.yml b/tests/integration/targets/firewalld/tasks/port_test_cases.yml index 2beb8ca..c62c242 100644 --- a/tests/integration/targets/firewalld/tasks/port_test_cases.yml +++ b/tests/integration/targets/firewalld/tasks/port_test_cases.yml @@ -4,7 +4,7 @@ - name: firewalld port range test permanent enabled firewalld: - port: 5500-6950/tcp + port: 5500-6850/tcp permanent: true state: enabled register: result @@ -16,7 +16,7 @@ - name: firewalld port range test permanent enabled rerun (verify not changed) firewalld: - port: 5500-6950/tcp + port: 5500-6850/tcp permanent: true state: enabled register: result @@ -57,7 +57,7 @@ state: disabled loop: - 6900/tcp - - 5500-6950/tcp + - 5500-6850/tcp - name: firewalld port test permanent enabled firewalld: From f109c162b002feb02562c3502a880bea43e408c3 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Wed, 11 Jan 2023 19:21:27 +0900 Subject: [PATCH 18/40] Update AZP CI matrix - Addresses https://github.com/ansible-collections/news-for-maintainers/issues/31 Signed-off-by: Hideki Saito --- .azure-pipelines/azure-pipelines.yml | 16 ++++++++++------ changelogs/fragments/409_update_azp_matrix.yml | 3 +++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/409_update_azp_matrix.yml diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 9aef200..9fb818b 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -53,8 +53,8 @@ stages: targets: - name: CentOS 7 test: centos7 - - name: Fedora 36 - test: fedora36 + - name: Fedora 37 + test: fedora37 - name: openSUSE 15 py3 test: opensuse15 - name: Ubuntu 20.04 @@ -209,10 +209,12 @@ stages: test: macos/12.0 - name: RHEL 7.9 test: rhel/7.9 - - name: RHEL 8.6 - test: rhel/8.6 - - name: RHEL 9.0 - test: rhel/9.0 + - name: RHEL 8.7 + test: rhel/8.7 + - name: RHEL 9.1 + test: rhel/9.1 + - name: FreeBSD 12.4 + test: freebsd/12.4 - name: FreeBSD 13.1 test: freebsd/13.1 - stage: Remote_2_14 @@ -231,6 +233,8 @@ stages: test: rhel/8.6 - name: RHEL 9.0 test: rhel/9.0 + - name: FreeBSD 12.3 + test: freebsd/12.3 - name: FreeBSD 13.1 test: freebsd/13.1 - stage: Remote_2_13 diff --git a/changelogs/fragments/409_update_azp_matrix.yml b/changelogs/fragments/409_update_azp_matrix.yml new file mode 100644 index 0000000..23d7a86 --- /dev/null +++ b/changelogs/fragments/409_update_azp_matrix.yml @@ -0,0 +1,3 @@ +--- +trivial: + - CI - Update AZP CI matrix (https://github.com/ansible-collections/ansible.posix/issues/408). From 6695394af67a2b988d522f603794542a2e9a1bca Mon Sep 17 00:00:00 2001 From: Gregory Furlong Date: Tue, 29 Nov 2022 14:57:04 -0500 Subject: [PATCH 19/40] Update ZoneTransaction to support adding/removing zones when firewalld is offline. Add integration test cases for adding/removing a custom zone with the firewalld module. --- ...ewalld_create_remove_zone_when_offline.yml | 3 ++ plugins/modules/firewalld.py | 24 ++++++---- .../targets/firewalld/tasks/run_all_tests.yml | 3 ++ .../firewalld/tasks/zone_test_cases.yml | 47 +++++++++++++++++++ 4 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml create mode 100644 tests/integration/targets/firewalld/tasks/zone_test_cases.yml diff --git a/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml b/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml new file mode 100644 index 0000000..691fc65 --- /dev/null +++ b/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - Fixed a bug where firewalld module fails to create/remove zones when the daemon is stopped diff --git a/plugins/modules/firewalld.py b/plugins/modules/firewalld.py index dba16aa..52a2a5a 100644 --- a/plugins/modules/firewalld.py +++ b/plugins/modules/firewalld.py @@ -675,25 +675,33 @@ class ZoneTransaction(FirewallTransaction): self.module.fail_json(msg=self.tx_not_permanent_error_msg) def get_enabled_permanent(self): - zones = self.fw.config().listZones() - zone_names = [self.fw.config().getZone(z).get_property("name") for z in zones] - if self.zone in zone_names: - return True + if self.fw_offline: + zones = self.fw.config.get_zones() + zone_names = [self.fw.config.get_zone(z).name for z in zones] else: - return False + zones = self.fw.config().listZones() + zone_names = [self.fw.config().getZone(z).get_property("name") for z in zones] + return self.zone in zone_names def set_enabled_immediate(self): self.module.fail_json(msg=self.tx_not_permanent_error_msg) def set_enabled_permanent(self): - self.fw.config().addZone(self.zone, FirewallClientZoneSettings()) + if self.fw_offline: + self.fw.config.new_zone(self.zone, FirewallClientZoneSettings().settings) + else: + self.fw.config().addZone(self.zone, FirewallClientZoneSettings()) def set_disabled_immediate(self): self.module.fail_json(msg=self.tx_not_permanent_error_msg) def set_disabled_permanent(self): - zone_obj = self.fw.config().getZoneByName(self.zone) - zone_obj.remove() + if self.fw_offline: + zone = self.fw.config.get_zone(self.zone) + self.fw.config.remove_zone(zone) + else: + zone_obj = self.fw.config().getZoneByName(self.zone) + zone_obj.remove() class ForwardPortTransaction(FirewallTransaction): diff --git a/tests/integration/targets/firewalld/tasks/run_all_tests.yml b/tests/integration/targets/firewalld/tasks/run_all_tests.yml index 4270e89..5027c1c 100644 --- a/tests/integration/targets/firewalld/tasks/run_all_tests.yml +++ b/tests/integration/targets/firewalld/tasks/run_all_tests.yml @@ -16,6 +16,9 @@ # firewalld source operation test cases - include_tasks: source_test_cases.yml +# firewalld zone operation test cases +- include_tasks: zone_test_cases.yml + # firewalld zone target operation test cases - include_tasks: zone_target_test_cases.yml diff --git a/tests/integration/targets/firewalld/tasks/zone_test_cases.yml b/tests/integration/targets/firewalld/tasks/zone_test_cases.yml new file mode 100644 index 0000000..c9d54c6 --- /dev/null +++ b/tests/integration/targets/firewalld/tasks/zone_test_cases.yml @@ -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 From bbc511dbc811cc684c60eb3d1361b91540938647 Mon Sep 17 00:00:00 2001 From: Adam Miller Date: Fri, 20 Jan 2023 11:52:10 -0600 Subject: [PATCH 20/40] v1.5.1 changelog Signed-off-by: Adam Miller --- CHANGELOG.rst | 21 ++++++++++++ changelogs/changelog.yaml | 34 +++++++++++++++++++ .../fragments/166_mount_absent_fstab.yml | 2 -- changelogs/fragments/267_mount_ephemeral.yml | 4 --- .../366_update_version_number_for_galaxy.yml | 3 -- .../371_refactoring_ci_process_202206.yml | 3 -- ...3_firewall_fix_missing_library_message.yml | 3 -- .../fragments/375_update_azp_container.yml | 3 -- .../380_update_usage_profile_tasks.yml | 3 -- .../fragments/386_follow_ci_testing_rules.yml | 3 -- .../fragments/389_ci_add_stable_214.yml | 3 -- .../390_hosts_involved_same_password.yml | 3 -- changelogs/fragments/393-rpm-ostree.yml | 5 --- changelogs/fragments/393_rhel_for_edge.yml | 4 --- .../400-fix-boolean-values-in-docs.yml | 3 -- .../401_document_module_default_values.yml | 4 --- .../fragments/407_fix_firewalld_port_test.yml | 3 -- .../fragments/409_update_azp_matrix.yml | 3 -- 18 files changed, 55 insertions(+), 52 deletions(-) delete mode 100644 changelogs/fragments/166_mount_absent_fstab.yml delete mode 100644 changelogs/fragments/267_mount_ephemeral.yml delete mode 100644 changelogs/fragments/366_update_version_number_for_galaxy.yml delete mode 100644 changelogs/fragments/371_refactoring_ci_process_202206.yml delete mode 100644 changelogs/fragments/373_firewall_fix_missing_library_message.yml delete mode 100644 changelogs/fragments/375_update_azp_container.yml delete mode 100644 changelogs/fragments/380_update_usage_profile_tasks.yml delete mode 100644 changelogs/fragments/386_follow_ci_testing_rules.yml delete mode 100644 changelogs/fragments/389_ci_add_stable_214.yml delete mode 100644 changelogs/fragments/390_hosts_involved_same_password.yml delete mode 100644 changelogs/fragments/393-rpm-ostree.yml delete mode 100644 changelogs/fragments/393_rhel_for_edge.yml delete mode 100644 changelogs/fragments/400-fix-boolean-values-in-docs.yml delete mode 100644 changelogs/fragments/401_document_module_default_values.yml delete mode 100644 changelogs/fragments/407_fix_firewalld_port_test.yml delete mode 100644 changelogs/fragments/409_update_azp_matrix.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9d1d855..45421b2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,27 @@ ansible.posix Release Notes .. contents:: Topics +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 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 382141c..d313a88 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -260,3 +260,37 @@ releases: - sanity_fixes.yml - shell_escape_full_path_for_rsync.yml release_date: '2022-05-23' + 1.5.1: + changes: + bugfixes: + - Removed contentious terminology to match reference documentation in profile_tasks. + - firewall - Fixed to output a more complete missing library message. + - synchronize - Fixed hosts involved in rsync require the same password + minor_changes: + - mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166). + - mount - Add ``ephemeral`` value for the ``state`` parameter, that allows to + mount a filesystem without altering the ``fstab`` file (https://github.com/ansible-collections/ansible.posix/pull/267). + - r4e_rpm_ostree - new module for validating package state on RHEL for Edge + - rhel_facts - new facts module to handle RHEL specific facts + - rhel_rpm_ostree - new module to handle RHEL rpm-ostree specific package management + functionality + - rpm_ostree_upgrade - new module to automate rpm-ostree upgrades + - rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems + fragments: + - 166_mount_absent_fstab.yml + - 267_mount_ephemeral.yml + - 366_update_version_number_for_galaxy.yml + - 371_refactoring_ci_process_202206.yml + - 373_firewall_fix_missing_library_message.yml + - 375_update_azp_container.yml + - 380_update_usage_profile_tasks.yml + - 386_follow_ci_testing_rules.yml + - 389_ci_add_stable_214.yml + - 390_hosts_involved_same_password.yml + - 393-rpm-ostree.yml + - 393_rhel_for_edge.yml + - 400-fix-boolean-values-in-docs.yml + - 401_document_module_default_values.yml + - 407_fix_firewalld_port_test.yml + - 409_update_azp_matrix.yml + release_date: '2023-01-20' diff --git a/changelogs/fragments/166_mount_absent_fstab.yml b/changelogs/fragments/166_mount_absent_fstab.yml deleted file mode 100644 index be11324..0000000 --- a/changelogs/fragments/166_mount_absent_fstab.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166). diff --git a/changelogs/fragments/267_mount_ephemeral.yml b/changelogs/fragments/267_mount_ephemeral.yml deleted file mode 100644 index 5671916..0000000 --- a/changelogs/fragments/267_mount_ephemeral.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -minor_changes: -- 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). diff --git a/changelogs/fragments/366_update_version_number_for_galaxy.yml b/changelogs/fragments/366_update_version_number_for_galaxy.yml deleted file mode 100644 index a905b39..0000000 --- a/changelogs/fragments/366_update_version_number_for_galaxy.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: -- Update version number in galaxy.yml to 1.5.0. diff --git a/changelogs/fragments/371_refactoring_ci_process_202206.yml b/changelogs/fragments/371_refactoring_ci_process_202206.yml deleted file mode 100644 index 26325d4..0000000 --- a/changelogs/fragments/371_refactoring_ci_process_202206.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: -- CI - Refactor AZP to address new test infrastructure (https://github.com/ansible-collections/news-for-maintainers/issues/17). diff --git a/changelogs/fragments/373_firewall_fix_missing_library_message.yml b/changelogs/fragments/373_firewall_fix_missing_library_message.yml deleted file mode 100644 index a5faea8..0000000 --- a/changelogs/fragments/373_firewall_fix_missing_library_message.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - firewall - Fixed to output a more complete missing library message. diff --git a/changelogs/fragments/375_update_azp_container.yml b/changelogs/fragments/375_update_azp_container.yml deleted file mode 100644 index 6d02987..0000000 --- a/changelogs/fragments/375_update_azp_container.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: - - CI - AZP test container to 3.0.0 (https://github.com/ansible-collections/news-for-maintainers/issues/18). diff --git a/changelogs/fragments/380_update_usage_profile_tasks.yml b/changelogs/fragments/380_update_usage_profile_tasks.yml deleted file mode 100644 index 5b23d40..0000000 --- a/changelogs/fragments/380_update_usage_profile_tasks.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - Removed contentious terminology to match reference documentation in profile_tasks. diff --git a/changelogs/fragments/386_follow_ci_testing_rules.yml b/changelogs/fragments/386_follow_ci_testing_rules.yml deleted file mode 100644 index f59e82a..0000000 --- a/changelogs/fragments/386_follow_ci_testing_rules.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: - - CI - following the new CI testing rule ansible-test-sanity-docker-devel. diff --git a/changelogs/fragments/389_ci_add_stable_214.yml b/changelogs/fragments/389_ci_add_stable_214.yml deleted file mode 100644 index 6a174fd..0000000 --- a/changelogs/fragments/389_ci_add_stable_214.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: -- CI - Add stable-2.14 to AZP (https://github.com/ansible-collections/ansible.posix/issues/388). diff --git a/changelogs/fragments/390_hosts_involved_same_password.yml b/changelogs/fragments/390_hosts_involved_same_password.yml deleted file mode 100644 index 1169a31..0000000 --- a/changelogs/fragments/390_hosts_involved_same_password.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - synchronize - Fixed hosts involved in rsync require the same password diff --git a/changelogs/fragments/393-rpm-ostree.yml b/changelogs/fragments/393-rpm-ostree.yml deleted file mode 100644 index e473b39..0000000 --- a/changelogs/fragments/393-rpm-ostree.yml +++ /dev/null @@ -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 diff --git a/changelogs/fragments/393_rhel_for_edge.yml b/changelogs/fragments/393_rhel_for_edge.yml deleted file mode 100644 index 118d377..0000000 --- a/changelogs/fragments/393_rhel_for_edge.yml +++ /dev/null @@ -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 diff --git a/changelogs/fragments/400-fix-boolean-values-in-docs.yml b/changelogs/fragments/400-fix-boolean-values-in-docs.yml deleted file mode 100644 index 8ea04a7..0000000 --- a/changelogs/fragments/400-fix-boolean-values-in-docs.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: - - Change boolean values in documentation to ``true/false`` (https://github.com/ansible-collections/ansible.posix/pull/400). diff --git a/changelogs/fragments/401_document_module_default_values.yml b/changelogs/fragments/401_document_module_default_values.yml deleted file mode 100644 index 8a631dc..0000000 --- a/changelogs/fragments/401_document_module_default_values.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -trivial: -- acl - document default value for the ``entry`` parameter -- rhel_rpm_ostree - document default value for the ``name`` parameter diff --git a/changelogs/fragments/407_fix_firewalld_port_test.yml b/changelogs/fragments/407_fix_firewalld_port_test.yml deleted file mode 100644 index 0b82489..0000000 --- a/changelogs/fragments/407_fix_firewalld_port_test.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: -- Fix firewalld port test cases to avoid port duplicatation. diff --git a/changelogs/fragments/409_update_azp_matrix.yml b/changelogs/fragments/409_update_azp_matrix.yml deleted file mode 100644 index 23d7a86..0000000 --- a/changelogs/fragments/409_update_azp_matrix.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -trivial: - - CI - Update AZP CI matrix (https://github.com/ansible-collections/ansible.posix/issues/408). From 8ccd0b800bf563fa9689fe403c26bdf265072f0f Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 30 Jan 2023 22:07:10 +0100 Subject: [PATCH 21/40] Fix broken seealso in synchronize module Module references must always have FQCN. --- plugins/modules/synchronize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/synchronize.py b/plugins/modules/synchronize.py index 260fac8..40fae71 100644 --- a/plugins/modules/synchronize.py +++ b/plugins/modules/synchronize.py @@ -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 of the source and destination are the same. Attempts to hardlink into a directory that is a subdirectory of the source will be prevented. seealso: -- module: copy +- module: ansible.builtin.copy - module: community.windows.win_robocopy author: - Timothy Appnel (@tima) From 42af89d019b959a4af4632ee9e74036040e21de2 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 30 Jan 2023 22:30:26 +0100 Subject: [PATCH 22/40] Add changelog fragment --- changelogs/fragments/413-synchronize-seealso.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/413-synchronize-seealso.yml diff --git a/changelogs/fragments/413-synchronize-seealso.yml b/changelogs/fragments/413-synchronize-seealso.yml new file mode 100644 index 0000000..ac680af --- /dev/null +++ b/changelogs/fragments/413-synchronize-seealso.yml @@ -0,0 +1,2 @@ +trivial: + - "synchronize - fix broken ``seealso`` module reference (https://github.com/ansible-collections/ansible.posix/pull/413)." From ee9df947629c1e7f644e403aa0a556d3b679cf93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rob=C3=A9rt=20S=2E=20Guhr?= <20595746+rsguhr@users.noreply.github.com> Date: Tue, 14 Feb 2023 23:20:47 +0100 Subject: [PATCH 23/40] Add support for protocol parameter --- .../fragments/xxx-add-protocol-parameter.yml | 2 + plugins/modules/firewalld.py | 73 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/xxx-add-protocol-parameter.yml diff --git a/changelogs/fragments/xxx-add-protocol-parameter.yml b/changelogs/fragments/xxx-add-protocol-parameter.yml new file mode 100644 index 0000000..ad78cea --- /dev/null +++ b/changelogs/fragments/xxx-add-protocol-parameter.yml @@ -0,0 +1,2 @@ +minor_changes: +- firewalld - add `protocol` parameter diff --git a/plugins/modules/firewalld.py b/plugins/modules/firewalld.py index 52a2a5a..765e575 100644 --- a/plugins/modules/firewalld.py +++ b/plugins/modules/firewalld.py @@ -19,6 +19,10 @@ options: - Name of a service to add/remove to/from firewalld. - The service must be listed in output of firewall-cmd --get-services. type: str + protocol: + description: + - Name of a protocol to add/remove to/from firewalld. + type: str port: description: - Name of a port or port range to add/remove to/from firewalld. @@ -144,6 +148,12 @@ EXAMPLES = r''' permanent: true state: enabled +- name: permit ospf traffic + ansible.posix.firewalld: + protocol: ospf + permanent: true + state: enabled + - name: do not permit traffic in default zone on port 8081/tcp ansible.posix.firewalld: port: 8081/tcp @@ -343,6 +353,47 @@ class ServiceTransaction(FirewallTransaction): self.update_fw_settings(fw_zone, fw_settings) +class ProtocolTransaction(FirewallTransaction): + """ + ProtocolTransaction + """ + + def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False): + super(ProtocolTransaction, self).__init__( + module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate + ) + + def get_enabled_immediate(self, protocol, timeout): + if protocol in self.fw.getProtocols(self.zone): + return True + else: + return False + + def get_enabled_permanent(self, protocol, timeout): + fw_zone, fw_settings = self.get_fw_zone_settings() + + if protocol in fw_settings.getProtocols(): + return True + else: + return False + + def set_enabled_immediate(self, protocol, timeout): + self.fw.addProtocol(self.zone, protocol, timeout) + + def set_enabled_permanent(self, protocol, timeout): + fw_zone, fw_settings = self.get_fw_zone_settings() + fw_settings.addProtocol(protocol) + self.update_fw_settings(fw_zone, fw_settings) + + def set_disabled_immediate(self, protocol, timeout): + self.fw.removeProtocol(self.zone, protocol) + + def set_disabled_permanent(self, protocol, timeout): + fw_zone, fw_settings = self.get_fw_zone_settings() + fw_settings.removeProtocol(protocol) + self.update_fw_settings(fw_zone, fw_settings) + + class MasqueradeTransaction(FirewallTransaction): """ MasqueradeTransaction @@ -748,6 +799,7 @@ def main(): icmp_block=dict(type='str'), icmp_block_inversion=dict(type='str'), service=dict(type='str'), + protocol=dict(type='str'), port=dict(type='str'), port_forward=dict(type='list', elements='dict'), rich_rule=dict(type='str'), @@ -769,7 +821,7 @@ def main(): source=('permanent',), ), mutually_exclusive=[ - ['icmp_block', 'icmp_block_inversion', 'service', 'port', 'port_forward', 'rich_rule', + ['icmp_block', 'icmp_block_inversion', 'service', 'protocol' 'port', 'port_forward', 'rich_rule', 'interface', 'masquerade', 'source', 'target'] ], ) @@ -798,6 +850,7 @@ def main(): icmp_block = module.params['icmp_block'] icmp_block_inversion = module.params['icmp_block_inversion'] service = module.params['service'] + protocol = module.params['protocol'] rich_rule = module.params['rich_rule'] source = module.params['source'] zone = module.params['zone'] @@ -829,7 +882,7 @@ def main(): port_forward_toaddr = port_forward['toaddr'] modification = False - if any([icmp_block, icmp_block_inversion, service, port, port_forward, rich_rule, + if any([icmp_block, icmp_block_inversion, service, protocol, port, port_forward, rich_rule, interface, masquerade, source, target]): modification = True if modification and desired_state in ['absent', 'present'] and target is None: @@ -893,6 +946,22 @@ def main(): if changed is True: msgs.append("Changed service %s to %s" % (service, desired_state)) + if protocol is not None: + + transaction = ProtocolTransaction( + module, + action_args=(protocol, timeout), + zone=zone, + desired_state=desired_state, + permanent=permanent, + immediate=immediate, + ) + + changed, transaction_msgs = transaction.run() + msgs = msgs + transaction_msgs + if changed is True: + msgs.append("Changed protocol %s to %s" % (protocol, desired_state)) + if source is not None: transaction = SourceTransaction( From a9920ae1898f134d4f6fb4187e086a155c0abcbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rob=C3=A9rt=20S=2E=20Guhr?= <20595746+rsguhr@users.noreply.github.com> Date: Tue, 14 Feb 2023 23:26:44 +0100 Subject: [PATCH 24/40] Changed changelog file name --- ...-add-protocol-parameter.yml => 417-add-protocol-parameter.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/fragments/{xxx-add-protocol-parameter.yml => 417-add-protocol-parameter.yml} (100%) diff --git a/changelogs/fragments/xxx-add-protocol-parameter.yml b/changelogs/fragments/417-add-protocol-parameter.yml similarity index 100% rename from changelogs/fragments/xxx-add-protocol-parameter.yml rename to changelogs/fragments/417-add-protocol-parameter.yml From b2f053a856dc4dddddad45a1d16e320726593c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rob=C3=A9rt=20S=2E=20Guhr?= <20595746+rsguhr@users.noreply.github.com> Date: Tue, 14 Feb 2023 23:39:17 +0100 Subject: [PATCH 25/40] Adjust assert for firewalld source test permanent --- tests/integration/targets/firewalld/tasks/source_test_cases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/firewalld/tasks/source_test_cases.yml b/tests/integration/targets/firewalld/tasks/source_test_cases.yml index 172a47e..4bc8b65 100644 --- a/tests/integration/targets/firewalld/tasks/source_test_cases.yml +++ b/tests/integration/targets/firewalld/tasks/source_test_cases.yml @@ -82,4 +82,4 @@ assert: that: - result is not changed - - "result.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|port|port_forward|rich_rule|interface|masquerade|source|target'" + - "result.msg == 'parameters are mutually exclusive: icmp_block|icmp_block_inversion|service|protocol|port|port_forward|rich_rule|interface|masquerade|source|target'" From 2ac6fbb84bcf85333786ae1c389c227a17174b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rob=C3=A9rt=20S=2E=20Guhr?= <20595746+rsguhr@users.noreply.github.com> Date: Wed, 15 Feb 2023 00:26:57 +0100 Subject: [PATCH 26/40] added forgotten comma --- plugins/modules/firewalld.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/firewalld.py b/plugins/modules/firewalld.py index 765e575..79c1440 100644 --- a/plugins/modules/firewalld.py +++ b/plugins/modules/firewalld.py @@ -821,7 +821,7 @@ def main(): source=('permanent',), ), mutually_exclusive=[ - ['icmp_block', 'icmp_block_inversion', 'service', 'protocol' 'port', 'port_forward', 'rich_rule', + ['icmp_block', 'icmp_block_inversion', 'service', 'protocol', 'port', 'port_forward', 'rich_rule', 'interface', 'masquerade', 'source', 'target'] ], ) From 0d2ff1d2d8bc62c428507330f50449054e2f204b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rob=C3=A9rt=20S=2E=20Guhr?= <20595746+rsguhr@users.noreply.github.com> Date: Wed, 15 Feb 2023 00:41:57 +0100 Subject: [PATCH 27/40] added integrations tests for protocol parameter --- .../firewalld/tasks/protocol_test_cases.yml | 65 +++++++++++++++++++ .../targets/firewalld/tasks/run_all_tests.yml | 3 + 2 files changed, 68 insertions(+) create mode 100644 tests/integration/targets/firewalld/tasks/protocol_test_cases.yml diff --git a/tests/integration/targets/firewalld/tasks/protocol_test_cases.yml b/tests/integration/targets/firewalld/tasks/protocol_test_cases.yml new file mode 100644 index 0000000..2af8921 --- /dev/null +++ b/tests/integration/targets/firewalld/tasks/protocol_test_cases.yml @@ -0,0 +1,65 @@ +# Test playbook for the firewalld module - protocol operations +# (c) 2022, Robért S. Guhr + +# 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 . + +- 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 diff --git a/tests/integration/targets/firewalld/tasks/run_all_tests.yml b/tests/integration/targets/firewalld/tasks/run_all_tests.yml index 5027c1c..ff25847 100644 --- a/tests/integration/targets/firewalld/tasks/run_all_tests.yml +++ b/tests/integration/targets/firewalld/tasks/run_all_tests.yml @@ -10,6 +10,9 @@ # firewalld service operation test cases - include_tasks: service_test_cases.yml +# firewalld protocol operation test cases +- include_tasks: protocol_test_cases.yml + # firewalld port operation test cases - include_tasks: port_test_cases.yml From fd32da0e99b2e84c284e307cac6c90e2f7ac8f8d Mon Sep 17 00:00:00 2001 From: Akira Yokochi Date: Tue, 21 Feb 2023 12:06:22 +0000 Subject: [PATCH 28/40] fix document syntax --- plugins/modules/patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/patch.py b/plugins/modules/patch.py index 0c6fe47..ecedbf6 100644 --- a/plugins/modules/patch.py +++ b/plugins/modules/patch.py @@ -37,7 +37,7 @@ options: src: description: - Path of the patch file as accepted by the GNU patch tool. If - C(remote_src) is 'no', the patch source file is looked up from the + C(remote_src) is C(false), the patch source file is looked up from the module's I(files) directory. type: path required: true From d64db13643f0ffee2a5012049922a955ab3bae26 Mon Sep 17 00:00:00 2001 From: Akira Yokochi Date: Tue, 21 Feb 2023 12:08:02 +0000 Subject: [PATCH 29/40] collection_prep for patch module --- docs/ansible.posix.patch_module.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ansible.posix.patch_module.rst b/docs/ansible.posix.patch_module.rst index 60c30cf..07f672a 100644 --- a/docs/ansible.posix.patch_module.rst +++ b/docs/ansible.posix.patch_module.rst @@ -84,9 +84,9 @@ Parameters -
Setting to yes will disable patch's heuristic for transforming CRLF line endings into LF.
+
Setting to true will disable patch's heuristic for transforming CRLF line endings into LF.
Line endings of src and dest must match.
-
If set to no, patch will replace CRLF in src files on POSIX.
+
If set to false, patch will replace CRLF in src files on POSIX.
@@ -122,7 +122,7 @@ Parameters -
Setting to yes will ignore white space changes between patch and input..
+
Setting to true will ignore white space changes between patch and input.
@@ -141,7 +141,7 @@ Parameters -
If no, it will search for src at originating/controller machine, if yes it will go to the remote/target machine for the src.
+
If false, it will search for src at originating/controller machine, if true it will go to the remote/target machine for the src.
@@ -157,7 +157,7 @@ Parameters -
Path of the patch file as accepted by the GNU patch tool. If remote_src is 'no', the patch source file is looked up from the module's files directory.
+
Path of the patch file as accepted by the GNU patch tool. If remote_src is false, the patch source file is looked up from the module's files directory.

aliases: patchfile
From 14accca52f5ebc7dbd8d037e51385752db122b48 Mon Sep 17 00:00:00 2001 From: Akira Yokochi Date: Tue, 21 Feb 2023 12:46:54 +0000 Subject: [PATCH 30/40] add changelog fragment --- changelogs/fragments/419-fix-patch-doc.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/419-fix-patch-doc.yml diff --git a/changelogs/fragments/419-fix-patch-doc.yml b/changelogs/fragments/419-fix-patch-doc.yml new file mode 100644 index 0000000..7a39a27 --- /dev/null +++ b/changelogs/fragments/419-fix-patch-doc.yml @@ -0,0 +1,2 @@ +trivial: + - patch - fix format syntax and boolean values on document (https://github.com/ansible-collections/ansible.posix/pull/419). From 94523978d227838ce2e5a17ac6f5119f0678680f Mon Sep 17 00:00:00 2001 From: austlane Date: Wed, 22 Feb 2023 20:07:25 -0500 Subject: [PATCH 31/40] bindep - install rsync on all EL variants Adds support for installing rsync for centos and related EL variants (AlmaLinux, Rocky, Oracle, etc) rsync is an extremely common package, available in the base repos of all EL distros This is necessary to properly support AWX-EE and other community-built EL Execution Environments. --- bindep.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindep.txt b/bindep.txt index fc5997d..f589f51 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,4 +1,4 @@ # This is a cross-platform list tracking distribution packages needed by tests; # see https://docs.openstack.org/infra/bindep/ for additional information. -rsync [platform:rhel-8 platform:rhel-9] +rsync [platform:redhat] From 5eb019b2c1f38bec7940e29d302cd3eb70605b1a Mon Sep 17 00:00:00 2001 From: Akira Yokochi Date: Sun, 26 Feb 2023 02:47:41 +0000 Subject: [PATCH 32/40] Revert "collection_prep for patch module" This reverts commit d64db13643f0ffee2a5012049922a955ab3bae26. --- docs/ansible.posix.patch_module.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ansible.posix.patch_module.rst b/docs/ansible.posix.patch_module.rst index 07f672a..60c30cf 100644 --- a/docs/ansible.posix.patch_module.rst +++ b/docs/ansible.posix.patch_module.rst @@ -84,9 +84,9 @@ Parameters -
Setting to true will disable patch's heuristic for transforming CRLF line endings into LF.
+
Setting to yes will disable patch's heuristic for transforming CRLF line endings into LF.
Line endings of src and dest must match.
-
If set to false, patch will replace CRLF in src files on POSIX.
+
If set to no, patch will replace CRLF in src files on POSIX.
@@ -122,7 +122,7 @@ Parameters -
Setting to true will ignore white space changes between patch and input.
+
Setting to yes will ignore white space changes between patch and input..
@@ -141,7 +141,7 @@ Parameters -
If false, it will search for src at originating/controller machine, if true it will go to the remote/target machine for the src.
+
If no, it will search for src at originating/controller machine, if yes it will go to the remote/target machine for the src.
@@ -157,7 +157,7 @@ Parameters -
Path of the patch file as accepted by the GNU patch tool. If remote_src is false, the patch source file is looked up from the module's files directory.
+
Path of the patch file as accepted by the GNU patch tool. If remote_src is 'no', the patch source file is looked up from the module's files directory.

aliases: patchfile
From 553b49245f6e78743717258b1fbaa29c15c942c9 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Mon, 13 Mar 2023 17:13:26 +0900 Subject: [PATCH 33/40] Support new test-sanity-docker-devel test * Remove unused module import Signed-off-by: Hideki Saito --- changelogs/fragments/425-support_test-sanity-docker-devel.yml | 2 ++ plugins/module_utils/version.py | 2 ++ plugins/modules/firewalld_info.py | 1 - tests/unit/compat/builtins.py | 1 + tests/unit/plugins/action/test_synchronize.py | 1 - 5 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/425-support_test-sanity-docker-devel.yml diff --git a/changelogs/fragments/425-support_test-sanity-docker-devel.yml b/changelogs/fragments/425-support_test-sanity-docker-devel.yml new file mode 100644 index 0000000..e66622c --- /dev/null +++ b/changelogs/fragments/425-support_test-sanity-docker-devel.yml @@ -0,0 +1,2 @@ +trivial: + - ansible.posix - removed unused module import from the code. diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py index 26d8c30..c6a5f68 100644 --- a/plugins/module_utils/version.py +++ b/plugins/module_utils/version.py @@ -16,3 +16,5 @@ __metaclass__ = type # from ansible.module_utils.compat.version import LooseVersion from ._version import LooseVersion, StrictVersion + +__all__ = ['LooseVersion', 'StrictVersion'] diff --git a/plugins/modules/firewalld_info.py b/plugins/modules/firewalld_info.py index 29257bc..024dd39 100644 --- a/plugins/modules/firewalld_info.py +++ b/plugins/modules/firewalld_info.py @@ -204,7 +204,6 @@ firewalld_info: ''' from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils.six import raise_from from ansible.module_utils._text import to_native from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion diff --git a/tests/unit/compat/builtins.py b/tests/unit/compat/builtins.py index f60ee67..f8e6c3d 100644 --- a/tests/unit/compat/builtins.py +++ b/tests/unit/compat/builtins.py @@ -31,3 +31,4 @@ except ImportError: BUILTINS = 'builtins' else: BUILTINS = '__builtin__' + __all__ = ['__builtin__'] diff --git a/tests/unit/plugins/action/test_synchronize.py b/tests/unit/plugins/action/test_synchronize.py index 40e489d..1c4a241 100644 --- a/tests/unit/plugins/action/test_synchronize.py +++ b/tests/unit/plugins/action/test_synchronize.py @@ -19,7 +19,6 @@ import os import unittest import yaml -import ansible.plugins from ansible_collections.ansible.posix.tests.unit.compat.mock import patch, MagicMock from ansible_collections.ansible.posix.plugins.action.synchronize import ActionModule From 01f19cde258cf316dac75a275c9a4d8070c5fb75 Mon Sep 17 00:00:00 2001 From: exploide Date: Tue, 14 Mar 2023 18:53:36 +0100 Subject: [PATCH 34/40] firewalld_info: fixed typo in default_zone and improved examples --- changelogs/fragments/426-firewalld_info-doc-update.yml | 4 ++++ plugins/modules/firewalld_info.py | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/426-firewalld_info-doc-update.yml diff --git a/changelogs/fragments/426-firewalld_info-doc-update.yml b/changelogs/fragments/426-firewalld_info-doc-update.yml new file mode 100644 index 0000000..71037f5 --- /dev/null +++ b/changelogs/fragments/426-firewalld_info-doc-update.yml @@ -0,0 +1,4 @@ +--- + +trivial: + - firewalld_info - fixed typo in return value and improved examples in documentation diff --git a/plugins/modules/firewalld_info.py b/plugins/modules/firewalld_info.py index 024dd39..334518d 100644 --- a/plugins/modules/firewalld_info.py +++ b/plugins/modules/firewalld_info.py @@ -37,6 +37,11 @@ EXAMPLES = r''' - name: Gather information about active zones ansible.posix.firewalld_info: active_zones: true + register: result + +- name: Print default zone for debugging + ansible.builtin.debug: + var: result.firewalld_info.default_zone - name: Gather information about specific zones ansible.posix.firewalld_info: @@ -44,6 +49,7 @@ EXAMPLES = r''' - public - external - internal + register: result ''' RETURN = r''' @@ -78,7 +84,7 @@ firewalld_info: returned: success type: str sample: 0.8.2 - default_zones: + default_zone: description: - The zone name of default zone. returned: success From a62acdfc5ad1564e9f4dbf79dd7ffb3158ce2983 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Tue, 21 Mar 2023 17:56:23 +0900 Subject: [PATCH 35/40] Added macOS 13.2 and remove macOS 12.0 - This commit fixes issue #431 Signed-off-by: Hideki Saito --- .azure-pipelines/azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 9fb818b..e403638 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -205,8 +205,8 @@ stages: parameters: testFormat: devel/{0}/1 targets: - - name: MacOS 12.0 - test: macos/12.0 + - name: MacOS 13.2 + test: macos/13.2 - name: RHEL 7.9 test: rhel/7.9 - name: RHEL 8.7 From 583e4a6d6b4643f81bc4e86c9a468d7340039d1f Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Thu, 23 Mar 2023 15:52:16 -0600 Subject: [PATCH 36/40] rhel_facts module must use keyword arguments The rhel_facts module must use keyword arguments. The current code gives this error: ``` Traceback (most recent call last): ... File "/tmp/ansible_ansible.posix.rhel_facts_payload_y10oy_4m/.../rhel_facts.py", line 72, in main TypeError: exit_json() takes 1 positional argument but 2 were given ``` The fix is to use all keyword arguments like other facts plugins. --- plugins/modules/rhel_facts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/rhel_facts.py b/plugins/modules/rhel_facts.py index 57c15f7..a30622a 100644 --- a/plugins/modules/rhel_facts.py +++ b/plugins/modules/rhel_facts.py @@ -69,7 +69,7 @@ def main(): if os.path.exists("/run/ostree-booted"): 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__': From 0e92d30fd3904ab89a90a24c69636fa56e01006e Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Thu, 23 Mar 2023 17:31:31 -0600 Subject: [PATCH 37/40] add changelog fragment --- changelogs/fragments/434-fix-rhel_facts-exit_json.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/434-fix-rhel_facts-exit_json.yml diff --git a/changelogs/fragments/434-fix-rhel_facts-exit_json.yml b/changelogs/fragments/434-fix-rhel_facts-exit_json.yml new file mode 100644 index 0000000..dcf16d9 --- /dev/null +++ b/changelogs/fragments/434-fix-rhel_facts-exit_json.yml @@ -0,0 +1,2 @@ +bugfixes: + - rhel_facts - Call exit_json with all keyword arguments From a417ac80f07a8d5536e918ab6d2425d65658c4cc Mon Sep 17 00:00:00 2001 From: Michael Dubner Date: Wed, 29 Mar 2023 09:57:29 +0300 Subject: [PATCH 38/40] Add jsonl callback plugin to ansible.posix collection --- .../fragments/535-add-jsonl-callback.yml | 2 + plugins/callback/jsonl.py | 196 ++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 changelogs/fragments/535-add-jsonl-callback.yml create mode 100644 plugins/callback/jsonl.py diff --git a/changelogs/fragments/535-add-jsonl-callback.yml b/changelogs/fragments/535-add-jsonl-callback.yml new file mode 100644 index 0000000..64eb192 --- /dev/null +++ b/changelogs/fragments/535-add-jsonl-callback.yml @@ -0,0 +1,2 @@ +minor_changes: +- Add jsonl callback plugin to ansible.posix collection diff --git a/plugins/callback/jsonl.py b/plugins/callback/jsonl.py new file mode 100644 index 0000000..2403dba --- /dev/null +++ b/plugins/callback/jsonl.py @@ -0,0 +1,196 @@ +# (c) 2016, Matt Martz +# (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) From 26c182c8ef6b1c41b2dacd32789b8439533ba004 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Fri, 7 Apr 2023 13:57:13 +0900 Subject: [PATCH 39/40] Release 1.5.2 commit Signed-off-by: Hideki Saito --- .azure-pipelines/azure-pipelines.yml | 14 -- CHANGELOG.rst | 23 +++ README.md | 3 + changelogs/changelog.yaml | 27 +++ ...ewalld_create_remove_zone_when_offline.yml | 3 - .../fragments/413-synchronize-seealso.yml | 2 - .../fragments/417-add-protocol-parameter.yml | 2 - changelogs/fragments/419-fix-patch-doc.yml | 2 - .../425-support_test-sanity-docker-devel.yml | 2 - .../426-firewalld_info-doc-update.yml | 4 - .../434-fix-rhel_facts-exit_json.yml | 2 - .../fragments/535-add-jsonl-callback.yml | 2 - docs/ansible.posix.acl_module.rst | 7 +- docs/ansible.posix.at_module.rst | 2 +- docs/ansible.posix.authorized_key_module.rst | 18 +- docs/ansible.posix.firewalld_info_module.rst | 10 +- docs/ansible.posix.firewalld_module.rst | 53 ++++-- docs/ansible.posix.mount_module.rst | 26 ++- docs/ansible.posix.patch_module.rst | 10 +- docs/ansible.posix.rhel_facts_module.rst | 103 +++++++++++ docs/ansible.posix.rhel_rpm_ostree_module.rst | 156 ++++++++++++++++ ...nsible.posix.rpm_ostree_upgrade_module.rst | 175 ++++++++++++++++++ docs/ansible.posix.seboolean_module.rst | 6 +- docs/ansible.posix.synchronize_module.rst | 28 +-- docs/ansible.posix.sysctl_module.rst | 12 +- galaxy.yml | 2 +- 26 files changed, 595 insertions(+), 99 deletions(-) delete mode 100644 changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml delete mode 100644 changelogs/fragments/413-synchronize-seealso.yml delete mode 100644 changelogs/fragments/417-add-protocol-parameter.yml delete mode 100644 changelogs/fragments/419-fix-patch-doc.yml delete mode 100644 changelogs/fragments/425-support_test-sanity-docker-devel.yml delete mode 100644 changelogs/fragments/426-firewalld_info-doc-update.yml delete mode 100644 changelogs/fragments/434-fix-rhel_facts-exit_json.yml delete mode 100644 changelogs/fragments/535-add-jsonl-callback.yml create mode 100644 docs/ansible.posix.rhel_facts_module.rst create mode 100644 docs/ansible.posix.rhel_rpm_ostree_module.rst create mode 100644 docs/ansible.posix.rpm_ostree_upgrade_module.rst diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index e403638..728ef40 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -135,18 +135,12 @@ stages: test: centos6 - name: CentOS 7 test: centos7 - - name: Fedora 32 - test: fedora32 - - name: Fedora 33 - test: fedora33 - name: openSUSE 15 py2 test: opensuse15py2 - name: openSUSE 15 py3 test: opensuse15 - name: Ubuntu 18.04 test: ubuntu1804 - - name: Ubuntu 20.04 - test: ubuntu2004 - stage: Docker_2_10 displayName: Docker 2.10 dependsOn: [] @@ -159,10 +153,6 @@ stages: test: centos6 - name: CentOS 7 test: centos7 - - name: Fedora 30 - test: fedora30 - - name: Fedora 31 - test: fedora31 - name: openSUSE 15 py2 test: opensuse15py2 - name: openSUSE 15 py3 @@ -183,10 +173,6 @@ stages: test: centos6 - name: CentOS 7 test: centos7 - - name: Fedora 30 - test: fedora30 - - name: Fedora 31 - test: fedora31 - name: openSUSE 15 py2 test: opensuse15py2 - name: openSUSE 15 py3 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 45421b2..06cdf22 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,29 @@ ansible.posix Release Notes .. 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 ====== diff --git a/README.md b/README.md index c0ee2b4..b0cd705 100644 --- a/README.md +++ b/README.md @@ -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.mount](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.mount_module.rst)|Control active and configured mount points [ansible.posix.patch](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.patch_module.rst)|Apply patch files using the GNU patch tool +[ansible.posix.rhel_facts](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rhel_facts_module.rst)|Facts module to set or override RHEL specific facts. +[ansible.posix.rhel_rpm_ostree](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rhel_rpm_ostree_module.rst)|Ensure packages exist in a RHEL for Edge rpm-ostree based system +[ansible.posix.rpm_ostree_upgrade](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.rpm_ostree_upgrade_module.rst)|Manage rpm-ostree upgrade transactions [ansible.posix.seboolean](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.seboolean_module.rst)|Toggles SELinux booleans [ansible.posix.selinux](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.selinux_module.rst)|Change policy and state of SELinux [ansible.posix.synchronize](https://github.com/ansible-collections/ansible.posix/blob/main/docs/ansible.posix.synchronize_module.rst)|A wrapper around rsync to make common tasks in your playbooks quick and easy diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index d313a88..0b59c25 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -294,3 +294,30 @@ releases: - 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' diff --git a/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml b/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml deleted file mode 100644 index 691fc65..0000000 --- a/changelogs/fragments/399_firewalld_create_remove_zone_when_offline.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - Fixed a bug where firewalld module fails to create/remove zones when the daemon is stopped diff --git a/changelogs/fragments/413-synchronize-seealso.yml b/changelogs/fragments/413-synchronize-seealso.yml deleted file mode 100644 index ac680af..0000000 --- a/changelogs/fragments/413-synchronize-seealso.yml +++ /dev/null @@ -1,2 +0,0 @@ -trivial: - - "synchronize - fix broken ``seealso`` module reference (https://github.com/ansible-collections/ansible.posix/pull/413)." diff --git a/changelogs/fragments/417-add-protocol-parameter.yml b/changelogs/fragments/417-add-protocol-parameter.yml deleted file mode 100644 index ad78cea..0000000 --- a/changelogs/fragments/417-add-protocol-parameter.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- firewalld - add `protocol` parameter diff --git a/changelogs/fragments/419-fix-patch-doc.yml b/changelogs/fragments/419-fix-patch-doc.yml deleted file mode 100644 index 7a39a27..0000000 --- a/changelogs/fragments/419-fix-patch-doc.yml +++ /dev/null @@ -1,2 +0,0 @@ -trivial: - - patch - fix format syntax and boolean values on document (https://github.com/ansible-collections/ansible.posix/pull/419). diff --git a/changelogs/fragments/425-support_test-sanity-docker-devel.yml b/changelogs/fragments/425-support_test-sanity-docker-devel.yml deleted file mode 100644 index e66622c..0000000 --- a/changelogs/fragments/425-support_test-sanity-docker-devel.yml +++ /dev/null @@ -1,2 +0,0 @@ -trivial: - - ansible.posix - removed unused module import from the code. diff --git a/changelogs/fragments/426-firewalld_info-doc-update.yml b/changelogs/fragments/426-firewalld_info-doc-update.yml deleted file mode 100644 index 71037f5..0000000 --- a/changelogs/fragments/426-firewalld_info-doc-update.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- - -trivial: - - firewalld_info - fixed typo in return value and improved examples in documentation diff --git a/changelogs/fragments/434-fix-rhel_facts-exit_json.yml b/changelogs/fragments/434-fix-rhel_facts-exit_json.yml deleted file mode 100644 index dcf16d9..0000000 --- a/changelogs/fragments/434-fix-rhel_facts-exit_json.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - rhel_facts - Call exit_json with all keyword arguments diff --git a/changelogs/fragments/535-add-jsonl-callback.yml b/changelogs/fragments/535-add-jsonl-callback.yml deleted file mode 100644 index 64eb192..0000000 --- a/changelogs/fragments/535-add-jsonl-callback.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- Add jsonl callback plugin to ansible.posix collection diff --git a/docs/ansible.posix.acl_module.rst b/docs/ansible.posix.acl_module.rst index aab5a37..6a13d89 100644 --- a/docs/ansible.posix.acl_module.rst +++ b/docs/ansible.posix.acl_module.rst @@ -49,8 +49,8 @@ Parameters -
If the target is a directory, setting this to yes will make it the default ACL for entities created inside the directory.
-
Setting default to yes causes an error if the path is a file.
+
If the target is a directory, setting this to true will make it the default ACL for entities created inside the directory.
+
Setting default to true causes an error if the path is a file.
@@ -63,6 +63,7 @@ Parameters + Default:
""
The actual user or group that the ACL applies to when matching entity types user or group are selected.
@@ -285,7 +286,7 @@ Examples entity: joe etype: user permissions: rw - default: yes + default: true state: present - name: Same as previous but using entry shorthand diff --git a/docs/ansible.posix.at_module.rst b/docs/ansible.posix.at_module.rst index d9f3cc8..3d731a2 100644 --- a/docs/ansible.posix.at_module.rst +++ b/docs/ansible.posix.at_module.rst @@ -171,7 +171,7 @@ Examples command: ls -d / >/dev/null count: 20 units: minutes - unique: yes + unique: true diff --git a/docs/ansible.posix.authorized_key_module.rst b/docs/ansible.posix.authorized_key_module.rst index bfbb444..53efe25 100644 --- a/docs/ansible.posix.authorized_key_module.rst +++ b/docs/ansible.posix.authorized_key_module.rst @@ -139,8 +139,8 @@ Parameters
Whether this module should manage the directory of the authorized key file.
-
If set to yes, the module will create the directory, as well as set the owner and permissions of an existing directory.
-
Be sure to set manage_dir=no if you are using an alternate directory for authorized_keys, as set with path, since you could lock yourself out of SSH access.
+
If set to true, the module will create the directory, as well as set the owner and permissions of an existing directory.
+
Be sure to set manage_dir=false if you are using an alternate directory for authorized_keys, as set with path, since you could lock yourself out of SSH access.
See the example below.
@@ -212,9 +212,9 @@ Parameters
This only applies if using a https url as the source of the keys.
-
If set to no, the SSL certificates will not be validated.
-
This should only set to no used on personally controlled sites using self-signed certificates as it avoids verifying the source site.
-
Prior to 2.1 the code worked as if this was set to yes.
+
If set to false, the SSL certificates will not be validated.
+
This should only set to 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 true.
@@ -252,7 +252,7 @@ Examples state: present key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" path: /etc/ssh/authorized_keys/charlie - manage_dir: False + manage_dir: false - name: Set up multiple authorized keys ansible.posix.authorized_key: @@ -275,14 +275,14 @@ Examples user: charlie state: present key: https://github.com/user.keys - validate_certs: False + validate_certs: false - name: Set authorized key, removing all the authorized keys already set ansible.posix.authorized_key: user: root key: "{{ lookup('file', 'public_keys/doe-jane') }}" state: present - exclusive: True + exclusive: true - name: Set authorized key for user ubuntu copying it from current user ansible.posix.authorized_key: @@ -460,7 +460,7 @@ Common return values are documented `here success -
This only applies if using a https url as the source of the keys. If set to no, the SSL certificates will not be validated.
+
This only applies if using a https url as the source of the keys. If set to false, the SSL certificates will not be validated.

Sample:
True
diff --git a/docs/ansible.posix.firewalld_info_module.rst b/docs/ansible.posix.firewalld_info_module.rst index 8bb6508..911acce 100644 --- a/docs/ansible.posix.firewalld_info_module.rst +++ b/docs/ansible.posix.firewalld_info_module.rst @@ -89,7 +89,12 @@ Examples - name: Gather information about active zones ansible.posix.firewalld_info: - active_zones: yes + active_zones: true + register: result + + - name: Print default zone for debugging + ansible.builtin.debug: + var: result.firewalld_info.default_zone - name: Gather information about specific zones ansible.posix.firewalld_info: @@ -97,6 +102,7 @@ Examples - public - external - internal + register: result @@ -163,7 +169,7 @@ Common return values are documented `here  
- default_zones + default_zone
string diff --git a/docs/ansible.posix.firewalld_module.rst b/docs/ansible.posix.firewalld_module.rst index ea58ff2..0932ac2 100644 --- a/docs/ansible.posix.firewalld_module.rst +++ b/docs/ansible.posix.firewalld_module.rst @@ -155,7 +155,7 @@ Parameters
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).
-
Note that if this is no, immediate is assumed yes.
+
Note that if this is false, immediate is assumed true.
@@ -262,6 +262,21 @@ Parameters + + +
+ protocol + +
+ string +
+ + + + +
Name of a protocol to add/remove to/from firewalld.
+ +
@@ -414,29 +429,35 @@ Examples - name: permit traffic in default zone for https service ansible.posix.firewalld: service: https - permanent: yes + permanent: true + state: enabled + + - name: permit ospf traffic + ansible.posix.firewalld: + protocol: ospf + permanent: true state: enabled - name: do not permit traffic in default zone on port 8081/tcp ansible.posix.firewalld: port: 8081/tcp - permanent: yes + permanent: true state: disabled - ansible.posix.firewalld: port: 161-162/udp - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: zone: dmz service: http - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: rich_rule: rule service name="ftp" audit limit value="1/m" accept - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: @@ -447,44 +468,44 @@ Examples - ansible.posix.firewalld: zone: trusted interface: eth2 - permanent: yes + permanent: true state: enabled - ansible.posix.firewalld: - masquerade: yes + masquerade: true state: enabled - permanent: yes + permanent: true zone: dmz - ansible.posix.firewalld: zone: custom state: present - permanent: yes + permanent: true - ansible.posix.firewalld: zone: drop state: enabled - permanent: yes - icmp_block_inversion: yes + permanent: true + icmp_block_inversion: true - ansible.posix.firewalld: zone: drop state: enabled - permanent: yes + permanent: true icmp_block: echo-request - ansible.posix.firewalld: zone: internal state: present - permanent: yes + permanent: true target: ACCEPT - name: Redirect port 443 to 8443 with Rich Rule ansible.posix.firewalld: rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443 zone: public - permanent: yes - immediate: yes + permanent: true + immediate: true state: enabled diff --git a/docs/ansible.posix.mount_module.rst b/docs/ansible.posix.mount_module.rst index 3ec3ce9..f38621f 100644 --- a/docs/ansible.posix.mount_module.rst +++ b/docs/ansible.posix.mount_module.rst @@ -73,6 +73,7 @@ Parameters
For Solaris systems, true will set yes as the value of mount at boot in /etc/vfstab.
For Linux, FreeBSD, NetBSD and OpenBSD systems, false will add noauto to mount options in /etc/fstab.
To avoid mount option conflicts, if noauto specified in opts, mount module will ignore boot.
+
This parameter is ignored when state is set to ephemeral.
@@ -90,7 +91,7 @@ Parameters
Dump (see fstab(5)).
Note that if set to null and state set to present, it will cease to work and duplicate entries will be made with subsequent runs.
-
Has no effect on Solaris systems.
+
Has no effect on Solaris systems or when used with ephemeral.
@@ -110,6 +111,7 @@ Parameters
This might be useful if you need to configure mountpoints in a chroot environment.
OpenBSD does not allow specifying alternate fstab files with mount so do not use this on OpenBSD with any state that operates on the live filesystem.
This parameter defaults to /etc/fstab or /etc/vfstab on Solaris.
+
This parameter is ignored when state is set to ephemeral.
@@ -125,7 +127,7 @@ Parameters
Filesystem type.
-
Required when state is present or mounted.
+
Required when state is present, mounted or ephemeral.
@@ -158,7 +160,7 @@ Parameters
Passno (see fstab(5)).
Note that if set to null and state set to present, it will cease to work and duplicate entries will be made with subsequent runs.
-
Deprecated on Solaris systems.
+
Deprecated on Solaris systems. Has no effect when used with ephemeral.
@@ -192,7 +194,7 @@ Parameters
Device (or NFS volume, or something else) to be mounted on path.
-
Required when state set to present or mounted.
+
Required when state set to present, mounted or ephemeral.
@@ -208,18 +210,22 @@ Parameters
    Choices:
  • absent
  • +
  • absent_from_fstab
  • mounted
  • present
  • unmounted
  • remounted
  • +
  • ephemeral
If mounted, the device will be actively mounted and appropriately configured in fstab. If the mount point is not present, the mount point will be created.
If unmounted, the device will be unmounted without changing fstab.
present only specifies that the device is to be configured in fstab and does not trigger or require a mount.
+
ephemeral only specifies that the device is to be mounted, without changing fstab. If it is already mounted, a remount will be triggered. This will always return changed=True. If the mount point path has already a device mounted on, and its source is different than 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 fstab is completely ignored. This option is added in version 1.5.0.
absent specifies that the device mount's entry will be removed from fstab and will also unmount the device and remove the mount point.
-
remounted 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 opts is set, the options will be applied to the remount, but will not change fstab. Additionally, if opts is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using mounted instead to work around this issue.
+
remounted 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 opts is set, the options will be applied to the remount, but will not change fstab. Additionally, if opts is set, and the remount command fails, the module will error to prevent unexpected mount changes. Try using mounted instead to work around this issue. remounted expects the mount point to be present in the fstab. To remount a mount point not registered in fstab, use ephemeral instead, especially with BSD nodes.
+
absent_from_fstab specifies that the device mount's entry will be removed from fstab. This option does not unmount it or delete the mountpoint.
@@ -304,10 +310,18 @@ Examples src: 192.168.1.100:/nfs/ssd/shared_data path: /mnt/shared_data opts: rw,sync,hard - boot: no + boot: false state: mounted fstype: nfs + - name: Mount ephemeral SMB volume + ansible.posix.mount: + src: //192.168.1.200/share + path: /mnt/smb_share + opts: "rw,vers=3,file_mode=0600,dir_mode=0700,dom={{ ad_domain }},username={{ ad_username }},password={{ ad_password }}" + fstype: cifs + state: ephemeral + diff --git a/docs/ansible.posix.patch_module.rst b/docs/ansible.posix.patch_module.rst index 60c30cf..07f672a 100644 --- a/docs/ansible.posix.patch_module.rst +++ b/docs/ansible.posix.patch_module.rst @@ -84,9 +84,9 @@ Parameters -
Setting to yes will disable patch's heuristic for transforming CRLF line endings into LF.
+
Setting to true will disable patch's heuristic for transforming CRLF line endings into LF.
Line endings of src and dest must match.
-
If set to no, patch will replace CRLF in src files on POSIX.
+
If set to false, patch will replace CRLF in src files on POSIX.
@@ -122,7 +122,7 @@ Parameters -
Setting to yes will ignore white space changes between patch and input..
+
Setting to true will ignore white space changes between patch and input.
@@ -141,7 +141,7 @@ Parameters -
If no, it will search for src at originating/controller machine, if yes it will go to the remote/target machine for the src.
+
If false, it will search for src at originating/controller machine, if true it will go to the remote/target machine for the src.
@@ -157,7 +157,7 @@ Parameters -
Path of the patch file as accepted by the GNU patch tool. If remote_src is 'no', the patch source file is looked up from the module's files directory.
+
Path of the patch file as accepted by the GNU patch tool. If remote_src is false, the patch source file is looked up from the module's files directory.

aliases: patchfile
diff --git a/docs/ansible.posix.rhel_facts_module.rst b/docs/ansible.posix.rhel_facts_module.rst new file mode 100644 index 0000000..d4c8fb6 --- /dev/null +++ b/docs/ansible.posix.rhel_facts_module.rst @@ -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 + + + + + + + + + + + + +
FactReturnedDescription
+
+ pkg_mgr + +
+ string +
+
when needed +
System-level package manager override +
+
+
Sample:
+
{'pkg_mgr': 'ansible.posix.rhel_facts'}
+
+

+ + + +Status +------ + + +Authors +~~~~~~~ + +- Adam Miller (@maxamillion) diff --git a/docs/ansible.posix.rhel_rpm_ostree_module.rst b/docs/ansible.posix.rhel_rpm_ostree_module.rst new file mode 100644 index 0000000..b170b15 --- /dev/null +++ b/docs/ansible.posix.rhel_rpm_ostree_module.rst @@ -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 + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ name + +
+ list + / elements=string +
+
+ Default:
[]
+
+
A package name or package specifier with version, like name-1.0.
+
Comparison operators for package version are valid here >, <, >=, <=. Example - name>=1.0
+
If a previous version is specified, the task also needs to turn allow_downgrade on. See the allow_downgrade documentation for caveats with downgrading packages.
+
When using state=latest, this can be '*' which means run yum -y update.
+
You can also pass a url or a local path to a rpm file (using state=present). To operate on several packages this can accept a comma separated string of packages or (as of 2.0) a list of packages.
+

aliases: pkg
+
+
+ state + +
+ string +
+
+
    Choices: +
  • absent
  • +
  • installed
  • +
  • latest
  • +
  • present
  • +
  • removed
  • +
+
+
Whether to install (present or installed, latest), or remove (absent or removed) a package.
+
present and installed will simply ensure that a desired package is installed.
+
latest will update the specified package if it's not of the latest available version.
+
absent and removed will remove the specified package.
+
Default is None, however in effect the default action is present unless the autoremove option is enabled for this module, then absent is inferred.
+
+
+ + +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 `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ msg + +
+ string +
+
always +
status of rpm transaction
+
+
Sample:
+
No changes made.
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Adam Miller (@maxamillion) diff --git a/docs/ansible.posix.rpm_ostree_upgrade_module.rst b/docs/ansible.posix.rpm_ostree_upgrade_module.rst new file mode 100644 index 0000000..d683166 --- /dev/null +++ b/docs/ansible.posix.rpm_ostree_upgrade_module.rst @@ -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 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ allow_downgrade + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Allow for the upgrade to be a chronologically older tree.
+
+
+ cache_only + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Perform the transaction using only pre-cached data, do not download.
+
+
+ os + +
+ string +
+
+ Default:
""
+
+
The OSNAME upon which to operate.
+
+
+ peer + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Force peer-to-peer connection instead of using a system message bus.
+
+
+ + + + +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 `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ msg + +
+ string +
+
always +
The command standard output
+
+
Sample:
+
No upgrade available.
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Adam Miller (@maxamillion) diff --git a/docs/ansible.posix.seboolean_module.rst b/docs/ansible.posix.seboolean_module.rst index 03a9b33..330d091 100644 --- a/docs/ansible.posix.seboolean_module.rst +++ b/docs/ansible.posix.seboolean_module.rst @@ -92,7 +92,7 @@ Parameters -
Set to yes if the boolean setting should survive a reboot.
+
Set to true if the boolean setting should survive a reboot.
@@ -135,8 +135,8 @@ Examples - name: Set httpd_can_network_connect flag on and keep it persistent across reboots ansible.posix.seboolean: name: httpd_can_network_connect - state: yes - persistent: yes + state: true + persistent: true diff --git a/docs/ansible.posix.synchronize_module.rst b/docs/ansible.posix.synchronize_module.rst index 82458df..7cb3059 100644 --- a/docs/ansible.posix.synchronize_module.rst +++ b/docs/ansible.posix.synchronize_module.rst @@ -150,7 +150,7 @@ Parameters
Delete files in dest that do not exist (after transfer, not before) in the src path.
-
This option requires recursive=yes.
+
This option requires recursive=true.
This option ignores excluded files and behaves like the rsync opt --delete-after.
@@ -465,7 +465,7 @@ Parameters
Put user@ for the remote paths.
-
If you have a custom ssh config to define the remote user for a host that does not match the inventory user, you should set this parameter to no.
+
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 false.
@@ -502,8 +502,8 @@ Parameters
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 ControlSocket to none.
-
Set this option to yes to allow multiplexing and reduce SSH connection overhead.
-
Note that simply setting this option to yes is not enough; You must also configure SSH connection multiplexing in your SSH client config by setting values for ControlMaster, ControlPersist and ControlPath.
+
Set this option to true to allow multiplexing and reduce SSH connection overhead.
+
Note that simply setting this option to true is not enough; You must also configure SSH connection multiplexing in your SSH client config by setting values for ControlMaster, ControlPersist and ControlPath.
@@ -595,8 +595,8 @@ See Also .. seealso:: - :ref:`copy_module` - The official documentation on the **copy** module. + :ref:`ansible.builtin.copy_module` + The official documentation on the **ansible.builtin.copy** module. :ref:`community.windows.win_robocopy_module` The official documentation on the **community.windows.win_robocopy** module. @@ -639,27 +639,27 @@ Examples ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - archive: no + archive: false - name: Synchronization with --archive options enabled except for --recursive ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - recursive: no + recursive: false - name: Synchronization with --archive options enabled except for --times, with --checksum option enabled ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - checksum: yes - times: no + checksum: true + times: false - name: Synchronization without --archive options enabled except use --links ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - archive: no - links: yes + archive: false + links: true - name: Synchronization of two paths both on the control machine ansible.posix.synchronize: @@ -689,8 +689,8 @@ Examples ansible.posix.synchronize: src: some/relative/path dest: /some/absolute/path - delete: yes - recursive: yes + delete: true + recursive: true # This specific command is granted su privileges on the destination - name: Synchronize using an alternate rsync command diff --git a/docs/ansible.posix.sysctl_module.rst b/docs/ansible.posix.sysctl_module.rst index 1f49cf6..1a3b111 100644 --- a/docs/ansible.posix.sysctl_module.rst +++ b/docs/ansible.posix.sysctl_module.rst @@ -85,7 +85,7 @@ Parameters -
If yes, performs a /sbin/sysctl -p if the sysctl_file is updated. If no, does not reload sysctl even if the sysctl_file is updated.
+
If true, performs a /sbin/sysctl -p if the sysctl_file is updated. If false, does not reload sysctl even if the sysctl_file is updated.
@@ -139,7 +139,7 @@ Parameters -
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.
@@ -186,21 +186,21 @@ Examples name: kernel.panic value: '3' sysctl_file: /tmp/test_sysctl.conf - reload: no + reload: false # Set ip forwarding on in /proc and verify token value with the sysctl command - ansible.posix.sysctl: name: net.ipv4.ip_forward value: '1' - sysctl_set: yes + sysctl_set: true # Set ip forwarding on in /proc and in the sysctl file and reload if necessary - ansible.posix.sysctl: name: net.ipv4.ip_forward value: '1' - sysctl_set: yes + sysctl_set: true state: present - reload: yes + reload: true diff --git a/galaxy.yml b/galaxy.yml index 9520636..e31ae2e 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: ansible name: posix -version: 1.5.0 +version: 1.5.2 readme: README.md authors: - Ansible (github.com/ansible) From 38dd009615e27a1b81e695ef8f071dcdefdba446 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Mon, 10 Apr 2023 17:45:13 +0900 Subject: [PATCH 40/40] Bump release version in galaxy.yml for the next release number. Signed-off-by: Hideki Saito --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index e31ae2e..5eec30c 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: ansible name: posix -version: 1.5.2 +version: 1.5.3 readme: README.md authors: - Ansible (github.com/ansible)