How to use multiple onlyif in Puppet Augeas resources?

118 views Asked by At

I am trying to use an Puppet Augeas resource to update the /etc/fstab file. The change should add a mount option, but ONLY if (a) the option is not already there, and (b) the filesystem is present in fstab.

To do this, I am trying to use an array of onlyif tests, as below:

    augeas { "fstab-${fsname}-${setting}":
      context => '/files',
      lens    => 'Fstab.lns',
      incl    => '/etc/fstab',
      onlyif  => [
        "values etc/fstab/*[file='${fsname}']/opt not_include ${setting}",
        "match etc/fstab/*[file='${fsname}'] size > 0",
      ],
      changes => [
        "insert opt after etc/fstab/*[file='${fsname}']/opt[last()]",
        "set etc/fstab/*[file='${fsname}']/opt[last()] ${setting}"
      ]
    }

If the filesystem exists, the this resource will correctly add the option if it does not exist, and will make no change if the option does exist.

However, if the filesystem does not exist in fstab, then I get an error, as it tries to apply the changes anyway which of course fail as there is no match for the insert.

It appears that the changes are being run even though the match size is returning 0. I can verify that by using augtool:

augtool> ls /files/etc/fstab/*[file='/var/tmp']
augtool> ls /files/etc/fstab/*[file='/tmp']
spec = /dev/mapper/vg_OS-lv_tmp
file = /tmp
vfstype = xfs
opt[1] = defaults
opt[2] = noexec
dump = 0
passno = 0
augtool>

Puppet debug logs do not appear to show the onlyif tests being run at all, but also do not show any syntax errors:

Debug: Augeas[fstab-/var/tmp-noexec](provider=augeas): Opening augeas with root /, lens path /opt/puppetlabs/puppet/cache/lib/augeas/lenses, flags 64
Debug: Augeas[fstab-/var/tmp-noexec](provider=augeas): Augeas version 1.12.0 is installed
Debug: Augeas[fstab-/var/tmp-noexec](provider=augeas): Will attempt to save and only run if files changed
Debug: Augeas[fstab-/var/tmp-noexec](provider=augeas): sending command 'insert' with params ["opt", "after", "/files/etc/fstab/*[file='/var/tmp']/opt[last()]"]
Debug: Augeas[fstab-/var/tmp-noexec](provider=augeas): Closed the augeas connection
Error: /Stage[main]/Smx_os_hardening::Filesystem/Augeas[fstab-/var/tmp-noexec]: Could not evaluate: Error sending command 'insert' with params ["opt", "after", "/files/etc/fstab/*[file='/var/tmp']/opt[last()]"]/Error sending command 'insert' with params ["opt", "after", "/files/etc/fstab/*[file='/var/tmp']/opt[last()]"]

The Puppet documentation appears to indicate that the onlyif can be a single test or an array; and, if an array, the tests must ALL be true (IE, use AND rather than OR). This does not appear to match the current behaviour, though.

[update] Note that, when using onlyif with the Exec resource type, multiple tests do work as expected. I am beginning to think that maybe the Augeas resource does not support an array for onlyif

Does anyone have any insight on what I may be doing wrong here?

Puppet server is v6.18 and so is the agent.

0

There are 0 answers