Puppet data array - puppet

I got a module that creating some directories depending of server:
class linux_sftp::sftp_mount ($sftp_mount_ip, $sftp_mount_username, $sftp_mount_password, $sftp_mount_point) {
file { "/mnt/${sftp_mount_point}":
ensure => directory,
subscribe => Exec['sftp_remount'],
}
in data.yml
sftp_mount_point: "stcontent1"
I want to add to data more folders like: stcontent2, stcontent3. Is it a way to add this and loop thru data?
sftp_mount_point:
- "stcontent1"
- "stcontent2" ...

Yes you can use lambda method (can also be invoked as functions if desired) iteration to accomplish this task. The most common for your use case is each. It can be easily invoked on type Array[String] like you have in your question.
$sftp_mount_point.each |String $mount| {
file { "/mnt/${mount}":
ensure => directory,
}
}
Note that the file type does not have a subscribable property, so subscribe is not a valid attribute and I therefore removed it above.

Related

Puppet assign class parameters in multiple places

I'm learning puppet (v6), and trying to understand how to set class parameters when a specific node needs an additional parameter, but uses the same class. Maybe a little fuzzy on the terminology, but here's what I'm working on:
MyNode1 needs sshd configured to use a banner and timeout, so using ghoneycutt-ssh, I include the ssh class with parameters:
/modules/MyModule/manifests/MySSH.pp
# Configures SSH
class MyModule::MySSH {
# Using ssh module
class { '::ssh':
sshd_client_alive_count_max => 0,
sshd_client_alive_interval => 900,
sshd_config_banner => '/etc/MyBanner.txt',
}
}
Now I have a second node MyNode2, which requires MySSH above, and also needs to disable forwarding. I started with something like this, where I define only the additional parameter in its own class:
/modules/MyModule/manifests/MySSH_Node2.pp
class MyModule::MySSH_Node2 {
class { '::ssh':
sshd_allow_tcp_forwarding => 'no',
}
}
Then define MyNode2 to include both in my site definition, hoping that puppet merges my ::ssh definitions:
/manifests/site.pp
node MyNode1 {
include MyModule::MySSH
}
node MyNode2 {
include MyModule::MySSH
include MyModule::MySSH_Node2
}
I understand that the above example doesn't work due to error Duplicate declaration: Class[Ssh]. I also tried overriding the class with a new parameter:
class MyModule::MySSH_Node2 {
Class[ssh] {
sshd_allow_tcp_forwarding => 'no',
}
}
But it seems this is not allowed either: Error: Resource Override can only operate on resources, got: Class[ssh]-Type
I'm not sure what the best way to add parameters is. I know I can create a manifest that includes all the parameters needed for this node and apply that instead, but then I end up with duplicate code everywhere.
Is there a reasonable way in modern puppet to assign and merge class parameters like this in puppet?

Can verigy test methods' params, aliases and methods' be defined at different times?

I am importing all of my Verigy 93k test methods' parameters based on an ASCII file I received from Verigy. At the time of import, the test method attribute aliases and methods won't be known. Can they be created statically at a later time, by various developers? The code below is just a snippet of the test method param hash I am trying to auto-create.
thx
add_tml :my93k,
class_name: 'my93k',
Functional: {
class_name: 'Functional',
'ErrorMap.DutCyclesPerTesterCycles' => [:string, '1'],
'ErrorMap.EdgesPerTesterCycle' => [:string, '4'],
'ErrorMap.Location' => [:string, 'RAM'],
# Attribute aliases can be defined like this:
aliases: {
},
# Define any methods you want the test method to have
methods: {
}
},
my_other_test: {
# Define another test in exactly the same way...
}
end
There is no way to do that today, but I don't think it would be hard to add that capability if you want.
From your example above, test_methods.my93k.Functional will return an instance of OrigenTesters::SmartestBasedTester::Base::TestMethod, which is defined here: https://github.com/Origen-SDK/origen_testers/blob/5b89bf287b3d307bd6708c878666f3609a5fd3af/lib/origen_testers/smartest_based_tester/base/test_method.rb
The contents of the hash assigned to :Functional above are passed in as the initialization options when the TestMethod instance is instantiated.
If you look at the implementation of the initialize method, you will see where it defines the aliases and methods.
You could expose that same functionality via some new methods to provide an API for developers to add additional aliases and methods later in the process. e.g. test_methods.my93k.Functional.add_alias(:blah).

Puppet; Call another .pp

So I am using the https://forge.puppetlabs.com/pdxcat/nrpe module to try to figure out automation of NRPE across hosts.
One of the available usages is
nrpe::command {
'check_users':
ensure => present,
command => 'check_users -w 5 -c 10';
}
Is there anyway to make a "group" of these commands and have them called on specific nodes?
For example:
you have 5 different nrpe:command each defining a different check, and then call those specific checks?
I am basically trying to figure out if I could group certain checks/commands together instead of setting up a ton of text in the main sites.pp file. This would also allow for customized templates/configurations across numerous nodes.
Thanks!
EDIT:
This is the command and what it's supposed to do when called on with the 'check_users' portion. If I could have a class with a set of "nrpe:command" and just call on that class THROUGH the module, it should work. Sorry, though. Still new at puppet. Thanks again.
define nrpe::command (
$command,
$ensure = present,
$include_dir = $nrpe::params::nrpe_include_dir,
$libdir = $nrpe::params::libdir,
$package_name = $nrpe::params::nrpe_packages,
$service_name = $nrpe::params::nrpe_service,
$file_group = $nrpe::params::nrpe_files_group,
) {
file { "${include_dir}/${title}.cfg":
ensure => $ensure,
content => template('nrpe/command.cfg.erb'),
owner => root,
group => $file_group,
mode => '0644',
require => Package[$package_name],
notify => Service[$service_name],
}
}
What version are you talking about? In puppet latest versions, inheritance is deprecated, then you shouldn't use it.
The easiest way would be to use "baselines".
Assuming you are using a manifests directory (manifest = $confdir/manifests inside your puppet.conf), simply create a $confdir/manifests/minimal.pp (or $confdir/manifests/nrpe_config.pp or whatever class name you want to use) with the content below:
class minimal {
nrpe::command { 'check_users':
ensure => present,
command => 'check_users -w 5 -c 10',
}
}
Then just call this class inside your node definitions (let's say in $confdir/manifests/my_node.pp) :
node 'my_node.foo.bar' {
include minimal
}

Puppet: Multiple files based on templates

I have several files which I need to be created by Puppet, all based on templates. As an example:
/etc/my-project/a.ini
/etc/my-project/b.ini
/etc/my-project/c.ini
What I would like to do is to ensure all these files using one statement in Puppet. Something like this:
define myFile {
file { "/ect/init.d/$name.ini":
ensure => file,
content => template("myProject/myFiles/$name.erb"),
}
}
myFile { ['a', 'b', 'c']: }
However, this does not seem to work (inspired by How to iterate over an array in Puppet). What am I missing there? How can I access the file name and use it, if not as $name?
Your array declaration is fine, but you're actually trying to create multiple templates, all with a different filename $name.erb. You should change it to a fixed template name, like template.erb.
Another thing to make sure is that your template file is located correctly.
If your manifest is in a module, the template should be located at module_name/templates/template.erb and called as template("module_name/file_under_template_directory")
If it's a standalone manifest, you have to put the full path instead, template("fully_qualified_path_to_template_file").
Finally, if you're still encountering errors, you should update your question with the error message so we can narrow down the cause.
Did you try using ${name} instead of $name?
If it doesn't work, check that your template files (a.erb; b.erb; c.erb) are in the <module_name>/templates/myProject/myFiles directory.
If all of these don't work, post your error message.
Try this...it will serve your purpose in elegant way.
define myFile($file_name) {
file { "/ect/init.d/${file_name}.ini":
ensure => file,
content => template("myProject/myFiles/${file_name}.erb"),
}
}
$values = {
item_1 => {file_name => "a"},
item_2 => {file_name => "b"},
item_3 => {file_name => "c"}
}
create_resources(myFile,$values)
['a', 'b', 'c'].each |String $name| {
file { "/ect/init.d/$name.ini":
content => template("myProject/myFiles/$name.erb"),
}
}
See puppet docs on iteration.

puppet, getting the $name when instantiating a resource type with an array

using puppet, i need to create three files, with this content:
/tmp/f1.txt: hello /tmp/f1.txt
/tmp/f2.txt: hello /tmp/f2.txt
/tmp/f3.txt: hello /tmp/f3.txt
i try as follows:
$path="/tmp/"
$my_files = ["$path/f1.txt", "$path/f2.txt", "$path/f3.txt"]
file { $my_files:
ensure => file,
content => "hello $name\n",
}
however this does not work because $name is undefined.
is there a variable that gets instantiated for each 'iteration' and that i can use?
ps: i am aware that i could create a new resource type as follows:
define file_with_content {
file { $name:
ensure => file,
content => "hello $name\n",
}
}
$path="/tmp/"
$my_files = ["$path/f1.txt", "$path/f2.txt", "$path/f3.txt"]
file_with_content { $my_files: }
but this requires creating a new resource type,
and I cannot do this in my context (which is not explained here).
the question is, how to modify the first code to make it work, without defining a new resource type, nor executing shell code?
You only can access the namevar for defined types. For Puppet's resources, the results are unpredictable - for example, $name for File will give you main, or the current stage. Additionally, you cannot pass/utilize extra parameters to Puppet's resources as they have their own set of parameters already.
The standard solution has been to wrap the File declaration in a defined type like here, like your first. Perhaps you can explain why that cannot be used, so some other solution could be devised?

Resources