puppet: Syntax error at 'target'; expected '}' - parsing error - puppet

Syntax error while parsing puppet resource.
class nagios::export {
##nagios_host { $::fqdn:
address => $::ipaddress,
use => "linux-server",
check_command => 'check-host-alive!3000.0,80%!5000.0,100%!10',
hostgroups => 'all-servers',
target => "/etc/nagios/resource.d/host_${::fqdn}.cfg"
}
##nagios_service { "check_ping_${hostname}":
check_command => "check-host-alive!100.0,20%!500.0,60%",
use => "generic-service",
host_name => "$fqdn",
notification_period => "24x7",
#target => "/etc/nagios/resource.d/service_${::fqdn}.cfg"
service_description => "${hostname}_check_ping"
target => "/etc/nagios/resource.d/service_${::fqdn}.cfg"
}
}
When I run puppet apply , following error is seen..
[root#ip-10-172-161-25 manifests]# puppet apply export.pp --noop
Could not parse for environment production: Syntax error at 'target'; expected '}' at /etc/puppet/modules/nagios/manifests/export.pp:28 on node ip-10-172-161-25.us-west-1.compute.internal

class nagios::export {
##nagios_host { $::fqdn:
address => $::ipaddress,
use => "linux-server",
check_command => 'check-host-alive!3000.0,80%!5000.0,100%!10',
hostgroups => 'all-servers',
target => "/etc/nagios/resource.d/host_${::fqdn}.cfg",
}
##nagios_service { "check_ping_${hostname}":
check_command => "check-host-alive!100.0,20%!500.0,60%",
use => "generic-service",
host_name => "$fqdn",
notification_period => "24x7",
#target => "/etc/nagios/resource.d/service_${::fqdn}.cfg",
service_description => "${hostname}_check_ping",
target => "/etc/nagios/resource.d/service_${::fqdn}.cfg",
}
}
Was just a few missing commas at the end.
I generally always finish with a comma on the last line. It's not needed, but catches gotcha's that happen when you add an extra line to the end.

Related

looping in Puppet 5 results in duplicate declaration error

Request some help please.
Requirement is to create a custom firewall service and then allow this custom firewall service only to a selected ips (trying to use firewalld_rich_rules here).
Here is the sample code:
class foo::fwall (
$sourceip = undef,
)
{
include firewalld
if $sourceip {
$sourceip.each |String $ipaddr| {
firewalld_rich_rule { "rich_rule_${ipaddr}":
ensure => enabled,
permanent => true,
zone => 'public',
family => ipv4,
source => $ipaddr,
element => service,
servicename => 'bar',
action => accept,
}
}
}
# this is defined in firewalld class and works good
firewalld::custom_service { 'bar':
short => 'bar custom service',
description => 'custom service ports',
ports => [
{
port => '7771',
protocol => 'tcp',
},
{
port => '8282',
protocol => 'tcp',
},
{
port => '8539',
protocol => 'tcp',
},
],
}
}
and while running it on a node, with couple of ip addresses (provided as an array for $sourceip), it results in duplicate declaration error
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: Firewalld_rich_rule[rich_rule_2] is already declared at (file: .../dev/modules/test/manifests/fwall.pp, line: 11); cannot redeclare (file: .../dev/modules/test/manifests/fwall.pp, line: 11) (file: .../dev/modules/test/manifests/fwall.pp, line: 11, column: 7) on node server.domain
Trying it in puppet v5.5 (from puppetlabs) for Redhat Enterprise Linux 7 servers
Note: tried defining a resource following this example from Puppet documentation but getting invalid address error.
define puppet::binary::symlink ($binary = $title) {
file {"/usr/bin/${binary}":
ensure => link,
target => "/opt/puppetlabs/bin/${binary}",
}
}
Use the defined type for the iteration somewhere ele in your manifest file:
$binaries = ['facter', 'hiera', 'mco', 'puppet', 'puppetserver']
puppet::binary::symlink { $binaries: }
I had to change the datatype for $sourceip to array in RH Satellite's smart class parameters which was String by default. Everything works good now.

Logstash multiline plugin not working for empty lines

I have these logs:
2019-04-01 12:45:33.207 ERROR [validator,,,] 1 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_VALIDATOR/e5d3dc665009:validator:8789 - was unable to send heartbeat!
com.netflix.discovery.shared.transport.TransportException: Retry limit reached; giving up on completing the request
at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:138) ~[eureka-client-1.4.12.jar!/:1.4.12]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.4.12.jar!/:1.4.12]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92) ~[eureka-client-1.4.12.jar!/:1.4.12]
at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.4.12.jar!/:1.4.12]
at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.4.12.jar!/:1.4.12]
...
I want to combine all these lines to the same line, so I used this input in logstash:
input {
tcp {
port => 5002
codec => json
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601}"
negate => true
what => previous
}
type => "logspout-logs-tcp"
}
}
But it is not working, I don't know if it's beacuase of the empty line on the second line, if so, how can I resolve this problem? I am using logstash version 5.6.14.
Please check the below code,
input {
tcp {
port => 5002
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601}"
negate => true
what => "previous"
}
type => "logspout-logs-tcp"
}
}

How to clean up files created by Exec resources?

I am trying to write a puppet class that will create a cirros image with OpenStacks Glance.
I have this puppet class. It downloads the image file and converts it to raw.
It then creates the glance image using the raw image format file.
I also want to remove the downloaded image file and the raw image file from
local disk.
Here is the manifest I tried:
class create_glance_cirros_image (
$cirrosver = '0.3.5',
$cirros_download_url = 'http://download.cirros-cloud.net',
$curl = '/usr/bin/curl',
$download_dir = '/root',
$qemu_img = '/usr/bin/qemu-img',
$qemu_img_args = 'convert -f qcow2 -O raw',
$image_name = 'cirros',
$is_public = 'no',
$container_format = 'bare',
$disk_format = 'raw',
$min_ram = '1024',
$min_disk = '1',
$properties = { 'img_key' => img_value },
$ensure = 'present',
) {
$cirros_image = "cirros-${cirrosver}-x86_64-disk.img"
$raw_cirros_image = "cirros-${cirrosver}-x86_64-disk.raw"
$image_url = "${cirros_download_url}/${cirrosver}/${cirros_image}"
$target_file = "${download_dir}/${cirros_image}"
$raw_target_file = "${download_dir}/${raw_cirros_image}"
$curl_args = "--output ${target_file}"
$download_command = "${curl} ${curl_args} ${image_url}"
$convert_command = "${qemu_img} ${qemu_img_args} ${target_file} ${raw_target_file}"
exec { $download_command:
creates => $target_file,
refreshonly => true,
}
exec { $convert_command:
creates => $raw_target_file,
refreshonly => true,
require => Exec[$download_command],
}
glance_image { $image_name:
ensure => $ensure,
name => $image_name,
is_public => $is_public,
container_format => $container_format,
disk_format => $disk_format,
source => $raw_target_file,
min_ram => $min_ram,
min_disk => $min_disk,
properties => $properties,
require => Exec[$convert_command],
}
file { $target_file:
ensure => 'absent',
}
file { $raw_target_file:
ensure => 'absent',
}
}
When I run it I get this error:
Error: Execution of '/usr/bin/openstack image create --format shell cirros --private --container-format=bare --disk-format=raw --min-disk=1 --min-ram=1024 --property img_key=img_value --file=/root/cirros-0.3.5-x86_64-disk.raw' returned 1: [Errno 2] No such file or directory: '/root/cirros-0.3.5-x86_64-disk.raw'
Error: /Stage[main]/Create_glance_cirros_image/Glance_image[cirros]/ensure: change from absent to present failed: Execution of '/usr/bin/openstack image create --format shell cirros --private --container-format=bare --disk-format=raw --min-disk=1 --min-ram=1024 --property img_key=img_value --file=/root/cirros-0.3.5-x86_64-disk.raw' returned 1: [Errno 2] No such file or directory: '/root/cirros-0.3.5-x86_64-disk.raw'
Why didn't the require cause the exec's to execute?
Update: Based on Matt's suggestions I modified my manifest to look like this:
exec { $download_command:
creates => $target_file,
unless => "/usr/bin/openstack image list --format=value | cut -d' ' -f2 | grep \"^${image_name}$\"",
notify => Exec[$convert_command],
}
exec { $convert_command:
creates => $raw_target_file,
refreshonly => true,
}
glance_image { $image_name:
ensure => present,
name => $image_name,
is_public => $is_public,
container_format => $container_format,
disk_format => $disk_format,
source => $raw_target_file,
min_ram => $min_ram,
min_disk => $min_disk,
properties => $properties,
}
exec { "/bin/rm -f ${target_file}":
subscribe => Exec[$convert_command],
refreshonly => true,
}
file { $raw_target_file:
ensure => 'absent',
require => Glance_image[$image_name],
}
Setting your exec resources to refreshonly means that they require a refresh signal to trigger and be applied. This can be done with a subscribe or a notify. Since your second exec depends upon the first, you can do this as:
exec { $download_command:
creates => $target_file,
refreshonly => true,
notify => Exec[$convert_command],
}
or:
exec { $convert_command:
creates => $raw_target_file,
refreshonly => true,
subscribe => Exec[$download_command],
}
The first one is trickier since it does not establish a relationship with anything. If you want the file download to be idempotent, I would recommend using a file resource instead.
file { $target_file:
source => $image_url,
}
This would cause both of your resources to be idempotent and apply when only when you want them to, thus achieving your goal.
You would need to modify your image file removal to be an exec though. Something like this would work:
exec { "/bin/rm -f ${target_file}":
subscribe => Exec[$convert_command]
refreshonly => true,
}
Your raw image file removal also needs to be applied after its creation and usage:
file { $raw_target_file:
ensure => 'absent',
require => Glance_image[$image_name],
}

Puppet. Using define with 2 variables

I have config file /home/ipeacocks/Dropbox/nscd/nscd.conf:
$ cat home/ipeacocks/Dropbox/nscd/nscd.conf
logfile /var/log/nscd.log
threads 4
max-threads 32
server-user nobody
stat-user somebody
debug-level 0
reload-count 5
paranoia no
restart-interval 3600
With puppet I want to change 2 lines:
server-user nobody
paranoia no
To these lines:
server-user nscd
paranoia yes
So for changing one first line I can use such manifest:
include nscd
class nscd {
define line_replace ($line, $match) {
file_line {'some useful info':
path => '/home/ipeacocks/Dropbox/nscd/nscd.conf',
line => $line,
match => $match
}
}
anchor{'nscd::begin':}
->
package { 'nscd':
ensure => installed,
}
->
line_replace {'test':
line => "server-user nscd",
match => "^\s*server-user.*$"
}
->
service { 'nscd':
ensure => running,
enable => "true",
}
->
anchor{'nscd::end':}
}
Puppet launch:
» sudo puppet apply /home/ipeacocks/Dropbox/nscd/nscd.pp
Notice: Compiled catalog for softserve-pc.ddns.softservecom.com in environment production in 0.37 seconds
Notice: /Stage[main]/Nscd/Nscd::Line_replace[test]/File_line[some useful info]/ensure: created
Notice: Finished catalog run in 0.22 seconds
But cant when 2 lines (using declared function twice):
include nscd
class nscd {
define line_replace ($line, $match) {
file_line {'some useful info':
path => '/home/ipeacocks/Dropbox/nscd/nscd.conf',
line => $line,
match => $match
}
}
anchor{'nscd::begin':}
->
package { 'nscd':
ensure => installed,
}
->
line_replace {'test':
line => "server-user nscd",
match => "^\s*server-user.*$"
}
->
line_replace {'test2':
line => "paranoia yes",
match => "^\s*paranoia.*$"
}
->
service { 'nscd':
ensure => running,
enable => "true",
}
->
anchor{'nscd::end':}
}
Launching again:
» sudo puppet apply /home/ipeacocks/Dropbox/nscd/nscd.pp 1 ↵
Error: Duplicate declaration: File_line[some useful info] is already declared in file /home/ipeacocks/Dropbox/nscd/nscd.pp:10; cannot redeclare at /home/ipeacocks/Dropbox/nscd/nscd.pp:10 on node softserve-pc.ddns.softservecom.com
Error: Duplicate declaration: File_line[some useful info] is already declared in file /home/ipeacocks/Dropbox/nscd/nscd.pp:10; cannot redeclare at /home/ipeacocks/Dropbox/nscd/nscd.pp:10 on node softserve-pc.ddns.softservecom.com
What can be wrong? Is it possible to pass two pairs of vars to declared function at once (with arrays or like that)?
I have tried this solution but it doesn't work for me:
https://stackoverflow.com/a/19034077/2971192
Change the 'some useful info' to $name in file_line -
define line_replace ($line, $match) {
file_line {$name:
path => '/home/ipeacocks/Dropbox/nscd/nscd.conf',
line => $line,
match => $match
}
}
The problem you are facing is because the second call to line_replace causes call to file_line with resource name 'some useful info' which is already declared.
Replace your define with this:
define line_replace ($line, $match) {
file_line {$name:
path => '/home/ipeacocks/Dropbox/nscd/nscd.conf',
line => $line,
match => $match
}
}
I changes the file_line resource name from a constant to the $name parameter of your define.

validate_cmd in Puppet: supporting older versions

I have the following Puppet code:
file { "/etc/sudoers.d/${name}":
content => template('sudo/sudoers.erb'),
owner => 'root',
group => 'root'
mode => '0440',
validate_cmd => '/usr/sbin/visudo -c -f %',
}
However, validate_cmd was only added in Puppet > 3.5, and I have to support some systems running 3.2 and older.
Is there some clever way of monkey-patching this into older versions of Puppet, or should I just resign to using the puppetlabs-stdlib validate_cmd statement?
Which does a similar thing, but won't revert the file if it does not validate correctly (the main benefit of the validate_cmd parameter on a fle).
EDIT: Using Felix's overwrite syntax, I ended up with the following code:
file { "/etc/sudoers.d/${name}":
content => template('sudo/sudoers.erb'),
owner => 'root',
group => 'root',
mode => '0440',
}
if versioncmp($::puppetversion, '3.5') >= 0 {
File["/etc/sudoers.d/${name}"] { validate_cmd => '/usr/sbin/visudo -c -f %' }
}
else {
validate_cmd(template('sudo/sudoers.erb'), '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content')
}
It's a bit fiddly to test in puppet-rspec, I ended up going with this:
if (Puppet.version >= '3.5.0')
context "validating content with puppet #{Puppet.version}" do
let(:params) { { :users => ['joe'] } }
let(:facts) {{ :puppetversion => Puppet.version }}
it { should contain_file('/etc/sudoers.d/worlddomination').with_validate_cmd('/usr/sbin/visudo -c -f %') }
end
else
context "validating content with puppet #{Puppet.version}" do
let(:params) { { :users => ['joe'] } }
let(:facts) {{ :puppetversion => Puppet.version }}
it { should contain_file('/etc/sudoers.d/worlddomination').with_validate_cmd(nil) }
end
end
Your manifest can adjust its behavior to the agent version.
file { "/etc/sudoers.d/${name}":
content => template('sudo/sudoers.erb'),
owner => 'root',
group => 'root'
mode => '0440',
}
if versioncmp($puppetversion, '3.5') >= 0 {
File["/etc/sudoers.d/${name}"] { validate_cmd => '/usr/sbin/visudo -c -f %' }
}
else {
# your workaround here
}
This will work courtesy of the puppetversion fact, of course.
The override syntax File[<name>] { ... } can be used like this because the actual resource declaration specifies no value for the validate_cmd attribute.

Resources