I'm trying to manage my hosts file on a Windows machine using Puppet and Hiera. My problem is that I have never really used Hiera and I'm struggling with parsing the data content into a proper format.
The relevant section in hieradata/hiera.yaml looks like this:
myhosts : [
'host1 1.2.3.4',
'host2 2.3.4.5',
'host3 3.4.5.6']
I have code that uses a host module, but it also depends on a class that I don't have, so naturally it doesn't work.
class hosts::module (
$myhosts = hiera('myhosts'),
)
{
define update_hosts {
$value = split($name,' ')
host {
"${value[0]}" : ip => "${value[1]}",
}
}
update_hosts { $myhosts :; }
}
I have tried using the file resource instead of the host resource, and also tried doing it without any class, but for some reason I am getting this 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: File[C:\Temp\tmp.txt] is already declared in file
/etc/puppetlabs/code/environments/production/manifests/site.pp:4; cannot redeclare
at /etc/puppetlabs/code/environments/production/manifests/site.pp:4
at /etc/puppetlabs/code/environments/production/manifests/site.pp:4:1
at /etc/puppetlabs/code/environments/production/manifests/site.pp:10 on node puppet-agent
As you can see, it claims that I have a duplicate declaration, but the weird thing is that it says it has a problem with the same line. It thinks it's declaring the same thing twice for some reason.
This is the code I have now (I know it won't work but the error doesn't really sound related)
define hosts_update($content) {
file { 'C:\Temp\tmp.txt' :
ensure => file,
content => $content,
}
}
hosts_update{ hiera('myhosts'):
content => split($name," "),
}
Any idea how to do this right?
fixed it.
site.pp
include update_hosts
init.pp
class update_hosts::host
(
$hosts = hiera('hosts_list'),
)
{
update_host { $hosts :; }
}
host.pp
define update_host {
$value = split($name,' ')
host {
"${value[0]}" : ip => "${value[1]}",
target => "C:/Windows/System32/drivers/etc/hosts"
}
}
Related
How to overwrite defined type in nodes.pp? I want to able to set custom domain using nodes.pp. Case Default isn't an option.
I'm using puppet 6.0..
The following method doesn't work. It says Could not find declared class resolv::resolv_config.
It looks like it used to work in 3.0 according to this answer.
nodes.pp
node "test001" {
class { 'resolv::resolv_config':
domain => "something.local",
}
}
modules/resolv/manifests/init.pp
class resolv {
case $hostname {
/^[Abc][Xyz]/: {
resolv:resolv_config { 'US':
domain => "mydomain.local",
}
}
}
}
define resolv::resolv_config($domain){
file { '/etc/resolv.conf':
content => template("resolv/resolv.conf.erb"),
}
}
resolv.conf.erb
domain <%= #domain %>
There are a couple of problems here, but the one causing the "could not find declared class" error is that you are using the wrong syntax for declaring a defined type. Your code should be something like this:
node "test001" {
resolv::resolv_config { 'something.local':
domain => "something.local",
}
}
There are examples of declaring defined types in the documentation, https://puppet.com/docs/puppet/latest/lang_defined_types.html.
Once you get that working, you'll find another problem, in that this definition
define resolv::resolv_config($domain){
file { '/etc/resolv.conf':
content => template("resolv/resolv.conf.erb"),
}
}
will cause a error if you try to declare more than one resolv::resolv_config, because they will both try to declare the /etc/resolv.conf file resource. You almost certainly wanted to use a file_line resource.
I want to use my own Jenkins plugin server to source plugins from. I'm using the puppet-jenkins module, but I can't seem to change the default plugin host value
The code on github has this in manifests/params:
class jenkins::params {
..
$default_plugins_host = 'https://updates.jenkins-ci.org'
..
}
So when I use this class, if I say:
class { 'jenkins':
default_plugins_host => "https://myhost.local"
}
I get Puppet (err): Invalid parameter
Or, if I try to define the value using capscase:
Jenkins::Params {
default_plugins_host => "https://specificallybrokenhost.com"
}
it isn't used by puppet. I tested this by giving it a plugin host that didn't exist, expecting the plugin installation to fail; but it was able to get plugins successfully (my assumption is that it still used jenkins-ci.org)
I was able to get this working by coping the entire module locally within library-jenkins/puppet-jenkins and changing the value, but i'd prefer not to have to resort to that
I'm using puppet-librarian and Puppet 3.3, if that helps.
the params.pp file stores private variables. This cannot be overridden.
Looking over the module is appears you can change the url from lines 67-82 of plugin.pp
if $version {
$plugins_host = $update_url ? {
undef => $::jenkins::default_plugins_host,
default => $update_url,
}
$base_url = "${plugins_host}/download/plugins/${name}/${version}/"
$search = "^${name} ${version}$"
}
else {
$plugins_host = $update_url ? {
undef => $::jenkins::default_plugins_host,
default => $update_url,
}
$base_url = "${plugins_host}/latest/"
$search = "${name} "
}
$plugins_host will use update_url if it's defined instead of default_plugins_host. if you make a default on the plugin define type you can change the default_plugins_host to update_url like so;
Jenkins::Plugin {
source_url => 'mycompany.jenkins.com',
}
I haven't tested this myself. So, let me know if it works.
I know it is something with the catalog that is the issue, I just can't figure out how to work around it.
I have the following code and I get the following error:
class test1 {
file { '/tmp/test.txt':
ensure => present,
content => 'name=joe',
}
}
class test2 {
$test = file('/tmp/test.txt')
notify { $test: }
}
class test3 {
class { 'test1': } ->
class { 'test2': }
}
puppet apply -e "include test3"
Error: Could not find any files from test.txt at ../modules/test2/manifests/init.pp
So essentially, I am trying to read a file before it exists, and the ordering doesn't appear to be working. Any ideas how I can work around this?
Based on the description of the function you are trying to utilize it will never operate in the fashion you are trying.
file:
Loads a file from a module and returns its contents as a string.
Affectively what this means is that the file would exist in
test1/files/test.txt
And would be loaded using:
file('test1/test.txt') i.e. file(<MODULENAME>/<FILENAME>)
I've been using hiera for several weeks now and all was working fine til few days ago when i started to get that kind of message:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not find data item nom in any Hiera data file and no default supplied on node d0puppetclient.victor-buck.com
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
So i tried to make a very simple test to check if the problem came from my last code changes and i'm still getting this message. I can't get hiera variable anymore.
Below the test i made:
hiera.yaml:
---
:backends:
- yaml
:yaml:
:datadir: /etc/puppet/hieradata
:hierarchy:
- common
site.pp:
# /etc/puppet/manifests/site.pp
case $operatingsystem {
'Solaris': { include role::solaris }
'RedHat', 'CentOS': { include redhat::roles::common }
/^(Debian|Ubuntu)$/: { include role::debian }
# default: { include role::generic }
}
case $hostname {
/^d0puppetclient/: { include test }
}
test.pp:
class test{
$nom = hiera('nom')
file {"/root/test.txt":
ensure => file,
source => "/etc/puppet/test.txt.erb",
}
}
test.txt.erb:
<%= nom %>
Any idea about to fix this? I thought this could be an file access right issue, so i tried to grante access on some files (755) and it's not working...
You need to define nom in your common.yaml in order for it to hold a value. You can set a default value and conditionally create the file if you don't plan on setting it.
class test {
$nom = hiera('nom', false)
if $nom {
file { '/root/test.txt':
ensure => file,
content => template('test/test.txt.erb')
}
}
}
Notice how i used content instead of source. When using erb templates you need to specify the content using the template() function.
Using Templates
If you use source it is expecting a file rather than an erb template.
Hope this helps.
I want to override parameters of base nodes. What I want to get is a pattern like this:
# File manifests/nodes.pp
node myDefault {
class { 'my::common::puppet_setup':
service => 'enable',
pushable => 'disable',
}
# Do lots of default things ...
}
node 'myFirstNode' inherits myDefault {
# Do something ...
}
node 'mySecondNode' inherits myDefault {
class { 'my::common::puppet_setup::params':
service => 'disable',
pushable => 'enable',
}
}
I understood the the puppet documentation, i could do this by writing my module like this:
# File modules/my/manifests/common/puppet_setup.pp
class my::common::puppet_setup (
$pushable = $my::common::puppet_setup::params::pushable,
$service = $my::common::puppet_setup::params::service,
) inherits my::common::puppet_setup::params {
# package that configures puppet node
# input value validation
validate_re($pushable, ['^enable$', '^disable$', '^ignore$', ])
validate_re($service, ['^enable$', '^disable$', '^ignore$', '^cron$', ])
# setup puppet, start or disable agent, put ssh keys for push ...
}
class my::common::puppet_setup::params {
$pushable = 'enable'
$service = 'enable'
$puppetserver = 'puppet.my.site.de'
case $::osfamily {
'Debian': {
}
default: {
fail("not implemented yet for {::operatingsystem}")
}
}
}
The Documentations on puppet website says:
When a derived class is declared, its base class is automatically declared first (if it wasn’t already declared elsewhere).
But i get this error (some indentation added):
mySecondNode# puppet agent --test --environment dev_my
Error: Could not retrieve catalog from remote server:
Error 400 on SERVER: Duplicate declaration:
Class[My::Common::Puppet_setup::Params] is already declared;
cannot redeclare at /.../puppet/manifests/nodes.pp:16 on node mySecondNode
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
I'm reading on this for a week and i guess my understanding ist totally wrong somewhere, although i used the puppetlabs ntp modules as an example.
what am i missing?
You should check Inheritance section from http://docs.puppetlabs.com/puppet/latest/reference/lang_node_definitions.html
Puppet treats node definitions like classes. It does not mash the two together and then compile the mix; instead, it compiles the base class, then compiles the derived class, which gets a parent scope and special permission to modify resource attributes from the base class.
One of the good solutions is to use roles and profiles, there's a great blog post about it:
http://garylarizza.com/blog/2014/02/17/puppet-workflow-part-2/
You can use virtual resources :
http://docs.puppetlabs.com/guides/virtual_resources.html