Tidy can’t use matches with recurse 0, false, or undef - puppet

I have the following Puppet resource.
tidy {
'beat_lock':
age => '8h',
path => '/var/lib/beat/',
alias => 'beat_lock',
matches => 'run.lock',
type => 'mtime'
}
I am getting an error stating the following:
Error: Failed to apply catalog: Parameter matches failed on Tidy[filebeat_lock]: Tidy can't use matches with recurse 0, false, or undef
The entity I want to cleanup is a file not a directory. So, why is the error showing up?

The entity I want to cleanup is a file not a directory. So, why is the error showing up?
You're telling Puppet that the entity you want to clean up is the directory /var/lib/beat. That's what the path parameter designates if you specify it, or what the the resource title designates if you don't explicitly specify the path parameter. At the same time, you have not provided a value for the recurse parameter, so the resource defaults to non-recursive, as if you had specified recurse => false. It doesn't make sense to use matches in this context, where you've already specified exactly which file is to be managed.
There is a variety of ways to spell it, but the simplest way to express what you seem actually to want would be this:
tidy { '/var/lib/beat/run.lock':
age => '8h',
type => 'mtime'
}
If you prefer to be able to refer to this resource elsewhere as Tidy['beat_lock'] then you might instead say
tidy { 'beat_lock':
path => '/var/lib/beat/run.lock',
age => '8h',
type => 'mtime'
}
I don't see much reason to introduce an alias, however, and you certainly don't need one that's the same as the resource title. I don't have any aliases declared anywhere in my own manifest set, and I don't recommend their use.

Related

Puppet: Could not find resource 'File[/etc/auditbeat/auditbeat.yml]' in parameter 'require'

I'm using Puppet to replace Spacewalk Configuration Channels.
I'm very new to puppet, and the class I'm writing should copy some files to the host system.
I have this in my class:
class main_configurations {
file { '/etc/auditbeat':
ensure => directory,
path => '/etc/auditbeat',
require => File['/etc/auditbeat/auditbeat.yml'],
source => 'puppet:///modules/main_configurations/auditbeat/auditbeat.yml',
recurse => true,
}
}
But when I run puppet agent -t I get the following error:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Could not find resource 'File[/etc/auditbeat/auditbeat.yml]' in parameter 'require' (file: /etc/puppetlabs/code/environments/production/modules/main_configurations/manifests/init.pp, line: 8) on node <servername>
For completeness, this is the folder structure on my puppet server:
/etc/puppetlabs/code/environments/production/modules/main_configurations/files/auditbeat
/etc/puppetlabs/code/environments/production/modules/main_configurations/files/auditbeat/auditbeat.yml
/etc/puppetlabs/code/environments/production/modules/main_configurations/files/auditbeat/audit.rules.d
/etc/puppetlabs/code/environments/production/modules/main_configurations/files/auditbeat/audit.rules.d/auditbeat-rules.conf
But when I run puppet agent -t I get the following error:
Error: Could not retrieve catalog from remote server: Error 500 on
SERVER: Server Error: Could not find resource
'File[/etc/auditbeat/auditbeat.yml]' in parameter 'require' (file:
/etc/puppetlabs/code/environments/production/modules/main_configurations/manifests/init.pp,
line: 8) on node
As #MattSchuchard explained in comments, that means exactly what it says: you have a require parameter that refers to resource File[/etc/auditbeat/auditbeat.yml], but that (Puppet) resource is not declared in any of the manifest files that were processed. This constitutes an inconsistency in your manifest set. It has nothing to do with which files are available for installation from your module or which are already present on the target, nor about what Puppet might do when given a manifest set free of such inconsistencies.
Considering the declaration that is presented:
file { '/etc/auditbeat':
ensure => directory,
path => '/etc/auditbeat',
require => File['/etc/auditbeat/auditbeat.yml'],
source => 'puppet:///modules/main_configurations/auditbeat/auditbeat.yml',
recurse => true,
}
I'm inclined to think that you misunderstand at least what the require metaparameter means. It is one of several that speak to the relative order in which various resources are applied. It says that application of the resource being declared requires the specified other resources to have successfully been applied before. That's surely not what you intend here.
Moreover, a resource reference such as you are assigning to that parameter does not serve as a resource declaration. It does not contain enough information to do so. As the name suggests, it is a reference to a resource declared elsewhere.
It looks like you are trying to manage a subdirectory tree rooted at /etc/auditbeat to match a tree in your module. In that case, you probably want something more like this:
file { '/etc/auditbeat':
# no path required if it is already given by the resource title
ensure => 'directory',
source => 'puppet:///modules/main_configurations/auditbeat',
recurse => true,
}
Mainly, that drops the require parameter.
Note that that combination will also enable purging for the destination subtree, so that unmanaged non-directories anywhere within are removed. If you don't want that then use recurse => 'remote' instead.
There is a variety of other attributes that you might want to add, mostly to do with ownership and mode for the installed files. If you just want to copy some or all of that from the files on the server then you will want to add source_permissions => 'use'. Alternatively, there are attributes for explicitly specifying ownership and mode in your manifest.

Puppet cron job -- ensure files exist

I'm trying to set up a Puppet cron job with the following structure:
file { '/usr/local/sbin/file.py':
mode => '0755',
source => 'puppet:///modules/file.py',
require => File['/usr/local/sbin']
}
cron { "cronjob":
require => "ALL_THE_FILES_ABOVE"
command => "...command_to_run_script..."
minute => '*/1'
}
All of the above is in one file run_script.pp. I'm wondering how I can code the require => "ALL_THE_FILES_ABOVE" part.
Thanks!
Based on the information provided in your question, I am going to make the assumption that the contents of run_script.pp is many file resources and the listed cron resource. You state that you want the cron resource there to require all of the file resources in that class. Based on this, here is a clean and efficient solution.
There are a few complicated/advanced ways to arrive at a clean and efficient solution, but the easiest to understand is to use a resource default: https://puppet.com/docs/puppet/5.3/lang_defaults.html
With this, we can establish attribute/value pair defaults for all file resources contained in that scope. This would make it easier to use the before metaparameter on the file resources instead: https://puppet.com/docs/puppet/5.3/metaparameter.html#before
This simplifies the solution to a one-liner in your class:
File { before => Cron['cronjob'] }
Note there will be a caveat to this method, which is that if you are declaring, requiring, or containing a class within this manifest, then this default could be expanded to that "area of effect" and cause a circular dependency. In that case, you should use a per-expression resource default attribute: https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#per-expression-default-attributes
You can use a multiple require
file{'path/foo':}
file{'path/bar':}
file{'~/foobar':
require => [ File['path/foo'], File['path/bar'] ]
}
or you can use the ordering arrow
-> (ordering arrow; a hyphen and a greater-than sign) — Applies the resource on the left before the resource on the right.
file{'path/foo':} ->
file{'path/bar':} ->
file{'~/foobar':}
Here is more information about relationships and ordering in Puppet

puppet class syntax clarification

Currently trying to understand the puppet manifests written by another person and met the following construction in the class:
postgres_helper::tablespace_grant { $tablespace_grants:
privilege => 'all',
require => [Postgresql::Server::Role[$rolename]]
}
what does $tablespace_grants: means in this case? First i suggested that is some kind of a title, however when i used notice to receive the value of it, it is hash:
Tablespace_grants value is [{name => TS_INDEX_01, role => developer},
{name => TS_DATA01_01, role => developer}]
what does $tablespace_grants: means in this case? First i suggested
that is some kind of a title,
It is a variable reference, used, yes, as the title of a postgres_helper::tablespace_grant resource declaration.
however when i used notice to receive
the value of it, it is hash:
Tablespace_grants value is [{name => TS_INDEX_01, role => developer},
{name => TS_DATA01_01, role => developer}]
Actually, it appears to be an array of hashes. An array may be used as the title of a resource declaration to compactly declare multiple resources, one for each array element. In Puppet 4, however, the elements are required to be strings. Earlier versions of Puppet would stringify hashes presented as resource titles; I am uncertain offhand whether Puppet 4 still falls back on this.
In any case, it is unlikely that the overall declaration means what its original author intended, in any version of Puppet. It looks like the intent is to declare multiple resources, each with properties specified by one of the hashes, but the given code doesn't accomplish that, and it's unclear exactly what the wanted code would be.

puppet resource command with title munge

I've created a puppet resource for interfaces. Most of the interface names on my switch are lowercase with the exception of Ethernet interfaces, so I munged the interface name to hopefully reduce errors in the manifest; e.g.:
manifest:
cisco_interface { 'Ethernet1/1': description => 'foo' }
type/cisco_interface.rb:
newparam(:name) do
munge { |value|
value.downcase
}
end
My provider code also downcases the interface names when I collect the list of interfaces with self.instances.
Okay, so this works great when I test with the manifest, but not so great with the puppet resource command which only works when I call it with the name already downcased:
switch# puppet resource cisco_interface 'Ethernet1/1'
cisco_interface { 'Ethernet1/1':
ensure => 'absent',
}
switch# puppet resource cisco_interface 'ethernet1/1'
cisco_interface { 'ethernet1/1':
ensure => 'present',
description => 'foo',
}
The puppet resource command name field seems to just be a simple filter so I think I'm stuck, but I thought I'd seen other resource types munging title values like this.
Is it possible to munge the title values in a way that works for both scenarios?
If not then I'm not sure whether it would be better to leave it case-sensitive since that is what users will see in the switch config, or to "help" them avoid errors in the manifest.
You are correct about what is happening here, puppet currently requires that the name passed into the command line exactly matches the name according to the type. It's buried a couple levels deep, but look at the find and resource_name methods of the RAL.
It doesn't seem to me like this would be a major change, so you might want to log a defect or make the change yourself!

Do puppet conditionals ensure order, or do I still need to add metaparameters

I have code similar to the following:
class someclass($ensure = installed)
{
if($ensure == installed)
{
$installValue = installed
file { "someprogram.msi":
ensure => file,
source => 'somewhere',
path => 'C:/puppet-files/someprogram.msi',
}
}
else
{
$installValue = absent
}
package{ "someprogram":
ensure => $installValue,
source => 'C:/puppet-files/someprogram.msi',
}
}
Does the if statement containing the file resource ensure that the file resource will get applied before the package resource? Or do I need to explicitly state this in the metaparameters? Also, I am assuming that the $installValue will always be set before the package is installed, is that correct?
Thank you,
Derongan
You should specify the ordering explicitly, however the variable will be initialised correctly.
The ordering of resources in Puppet 3 is deterministic, but essentially random as it's based on hashes of the resource titles. In Puppet 3.3, this behaviour can be changed to the manifest order (release notes), but I wouldn't recommend relying on this - certainly if you're sharing the module, there's no guarantee that others use the same setting.
Since the file resource may not exist (if ensure => absent), you can't specify the relationship on the package resource. Instead, add before => Package['someprogram'], to the file resource.

Resources