puppet and inline_epp and using hiera deliver content - puppet

It's possible to use inline_epp's using string variable like this ?
"htaccess": {
"content": [
"<% include stdlib -%>",
"AuthType Basic ",
"AuthUserFile <%= $auth_file %>",
"Require valid-use"
],
"params": {
"auth_name": "Bootstrap content for provisioning",
"auth_file": "file_path"
}
}
and (some.pp):
$htacces = $sub_attrs['htaccess']
$content = $htacces['content']
$data = join($content, "\n")
$auth_file = "sgsdgsdfgsdfg"
notice inline_epp($data)
This is result in the notice line : Invalid EPP: This Name has no
effect. A value was produced and then forgotten (one or more preceding
expressions may have the wrong form)
Idea is use hiera data to deliver content to epp .
Using puppet 5.5.2 and Ubuntu 16.04

There looks like there are a few things going on here.
For one thing, is the syntax of that notice function correct? The Puppet Cookbook shows notice with either brackets notice("message") or in Puppet's class syntax notify { "message": }).
Also, inline_epp takes a hash of the parameters used to fill in the EPP. See the Puppet documentation on inline_epp. In your case, that'd be something like inline_epp($data, { auth_file => $auth_file }).
And lastly, EPP needs a line at the top listing its parameters. In your case it should be something like <%- | String $auth_file | -%>. See the Puppet documentation on EPP files.

Related

How to add multiline painless code in nodejs

So in my js-code I have this line:
var _script = {
_script: {
script: {
lang: 'painless',
source: `
"""
if(1>2){
params._source.id;
}
else{
params._source.id;
}
"""
`
},
type: 'string',
order: params._source.id
}
}
This will fail. I see in the log this error message:
,\"reason\":\"unexpected token ['\\\"\\\\n if(1>2){\\\\n params._source.id;\\\\n }\\\\n else{\\\\n params._source.id;\\\\n }\\\\n \\\"'] was expecting one of [{<EOF>, ';'}].\"}}}]},
I have tried first to have without tilde-character. And then it also fails.
I then tried to have tilde at the beginning, something like:
var _script = `{
Thing is that the final json that will be sent to elastic is not shown in the code above. So "_script" is only a little part of all the json.
I was wondering if I added the tilde at the very beginning and end of the whole json. Maybe it could work? I need to work it out where it is.
But just in theory: do you think the problem is there? Putting the tilde around all the json? Or is it something else?
The triple " is not valid JSON, it only works internally to the Elastic stack (i.e. from Kibana Dev Tools to ES).
The way I usually do it from Node.js is to add each line to an array and then I join that array, like this:
const code = [];
code.push("if(1>2){");
code.push("params._source.id;");
code.push("} else {");
code.push("params._source.id;");
code.push("}");
source = code.join(" ");
It's not super legible, I admit. Another way is to use stored scripts so you can simple reference your script by ID in Node.js.

Puppet: How to gather selected node names in manifest?

I am trying to set up a set of nodes running various parts of the ELK stack. In particular, I've got a set of systems running Elasticsearch and I'd like to fill out my logstash config file so that it knows which systems have ES on them.
I can see something like this in the logstash config (obviously untested):
output {
elasticsearch {
hosts => [
<%
#es_hosts.each do |host|
"#{host}",
end
-%>
]
}
}
But what I can't figure out is how to collect the hostnames for systems which are running elasticsearch. I've got a modules which apply RabbitMQ and ES, and it already exports some resources, but this one looks like it just needs nodenames for merging into a list.
--------EDIT BELOW--------
I stumbled across datacat after examing some of the PF modules I use, and thought it might be a candidate. Here's what I've done, posted here because it's not working the way I would have expected.
On my elasticsearch nodes (there are several):
##datacat_fragment { "${::hostname} in hosts":
tag => ['elasticsearch_cluster'],
target => '/etc/logstash/conf.d/master.conf',
data => {
host => ["${::hostname}" ],
}
}
Then, on the logstash node that needs to output to these ES nodes:
Datacat_fragment<| tag == 'elasticsearch_cluster' |>
datacat { '/etc/lostash/conf.d/master.conf':
template => "${module_name}/logstash-master.conf.erb",
}
Finally, the template itself:
input { [...snip...] }
filter {}
output {
elasticsearch {
<% #data.keys.sort.each do |host| %>
hosts = [
<%= #data[host.sort.join(',') %>
]
}
}
Sadly, the result of all this is
input { [...snip...] }
filter {}
output {
elasticsearch {
}
}
So at present, it looks like the exported resources aren't being instantiated as expected and I can't see why. If I add a datacat_fragment defined the same way but local to the logstash manifest, the data gets inserted into the .conf file just fine. It's just the ones from the ES nodes that are being ignored.
To further complicate matters, the input section needs to have a value inserted into it that's based on the system receiving the file. So there's one part that needs to behave like a traditional template, and another section that needs to have data inserted from multiple sources. Datacat looks promising, but is there another way to do this? Concat with an inline template somehow?

Puppet: configuring with augeas a set of [keys:values] via create_resources from hiera

I am trying to create an interface to pseudo-loop over a set of keys:values from my hiera yaml to update a config file with augeas
define augeas_config (
$key,
$value
)
{
augeas{ "/var/MYCONF/MYCONF.def":
lens => "/var/lib/puppet/lib/augeas/lenses/MYCONF.aug",
incl => "/var/MYCONF/MYCONF.def",
context => "/var/MYCONF/MYCONF.def",
changes => [ "set $key $val" ],
}
}
$augeas_files = hiera_hash('lib_BOX::MYCONF::config', {} )
validate_hash($augeas_files)
create_resources('augeas_config', $augeas_files)
where in my yaml keys:values to be updated are supposed to be in a hash like
lib_BOX::MYCONF::config:
SITE_NAME: "TEST-SITE"
OTHER_STUFF: "DEBUG"
So, the idea is to apply my augeas lense (not sure, if I really need 'context', when 'incl' has to be used with 'lens') for the pairs from my yaml.
However, puppet fails currently complaining about a string instead of an expected hash
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash at /etc/puppet/environments/development/modules/lib_BOX/manifests/config.pp:28:3 on node MY.NODE.FOO
where line 28 is the one with "create_resources('augeas_config'...". Since I get a hash from hiera, I suppose something in my resource definition is broken, but I do not see what??
Maybe somebody has an idea for me?
Cheers and thanks,
Thomas
Data in your yaml file is invalid. Change it to something like:
lib_BOX::MYCONF::config:
first_aug:
key: SITE_NAME
value: "TEST-SITE"
second_aug:
key: OTHER_STUFF
value : "DEBUG"
In addition you do not have to use hiera_hash. You can use just hiera.
Please read about differences between hiera lookup functions and follow examples about lookup types.
Probably you will also have to remove line validate_hash($augeas_files).

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?

Puppet Can't Find Variable for Template

Just getting started with Puppet, and I'm having trouble with my first template. It should be very easy, but I can't figure it out.
I have a module "base" at
/etc/puppet/modules/base/
./manifests
./manifests/service.pp
./manifests/init.pp
./manifests/params.pp
./manifests/config.pp
./manifests/install.pp
./templates
./templates/puppet.conf.erb
There's other stuff, but it's not necessary.
base/manifests/init.pp:
class base {
include base::install, base::service, base::config, base::params
}
base/manifests/config.pp
class base::config {
include base::params
File {
require => Class["base::install"],
ensure => present,
owner => root,
group => root,
}
file { "/etc/puppet/puppet.conf":
mode => 0644,
content => template("base/puppet.conf.erb"),
require => Class["base::install"],
nofity => Service["puppet"],
}
...
base/manifests/params.pp
class base::params {
$puppetserver = "pup01.sdirect.lab"
}
Finally the interesting part of the template at base/templates/puppet.conf.erb
...
server=<% puppetserver %>
The error message:
err: Failed to parse template base/puppet.conf.erb: Could not find
value for 'puppetserver' at
/etc/puppet/modules/base/manifests/config.pp:13 on node ...
I don't get what the problem is. I've copied this part straight out of the Pro Puppet book.
Could someone show me where $puppetserver should be defined and how?
The issue is that the name "puppetserver" needs to be fully qualified so Puppet can find the value, since it's defined in a different scope to the one the template is evaluated in.
The variable is defined in base::params so can only be referred to simply as "puppetserver" in that scope. When you're evaluating the template from within base::config, you're in a different scope and so you can't refer to the variable simply by its short name. The "include" adds the other class to the catalog, but doesn't change these rules.
This means to access it, you fully qualify it with the class name: base::params::puppetserver. If you were using it in the manifest itself, this would be $base::params::puppetserver. You'll see similar examples in Pro Puppet in the ssh::config and ssh::service classes where it refers to "ssh_service_name" in the params class (pages 43-45).
To access the variable in a template it's a bit different, use scope.lookupvar("base::params::puppetserver"). Taking your full example and adding a missing equals sign (to output the value) in the template:
...
server=<%= scope.lookupvar("base::params::puppetserver") %>
There's a bit more information about scoping on the Scope and Puppet as of 2.7 page.
(Edit: looks like it's listed on the confirmed errata page too with the same solution.)
Answer #1 is technically correct, but results in very verbose templates.
You can shorten them by bringing variable values from other classes into your own class scope:
class base::config {
include base::params
$puppetserver = $base::params::puppetserver
...
}
And then use them in your template as expected:
server=<% puppetserver %>
You could also use inherits:
class puppet::config inherits puppet::params {
....
In this way you don't have to define $puppetserver again in this class.

Resources