2

I have two classes in puppet.

Here is the first one:

class nagios::is_production {

  file { '/etc/puppetlabs/facter/':
    ensure  => directory,
  }
  file { '/etc/puppetlabs/facter/facts.d/':
    ensure => directory,
  }
  file { '/etc/puppetlabs/facter/facts.d/production.txt':
    ensure  =>  file,
    content =>  epp('nagios/production.epp')
  }

}

This creates a custom fact (production=yes/no based on the node name) This class on its own assigns the fact correctly.

The second class:

class nagios::client {

  if $facts[production] =~ yes {
    @@nagios_host {"${::hostname}":
      ensure                => present,
      address               => $::ipaddress,
      hostgroups            => "production, all-servers",
      notifications_enabled => $notifications_enabled,
      use                   => 'generic-server',
    }
  } else {
    @@nagios_host {"${::hostname}":
      ensure                => present,
      address               => $::ipaddress,
      hostgroups            => "non-production, all-servers",
      notifications_enabled => $notifications_enabled,
      owner                 => root,
      use                   => 'generic-server',
    } 
  }
}

This creates the exported resource for the host and adds it to either the production/non-production hostgroup.

If the custom fact exists, the host gets created with the hostgroup correctly.

I created a 3rd class to pull in these 2 just to keep track of it a little easier for myself:

class nagios::agent {

  Class['nagios::is_production']->Class['nagios::client']

  include nagios::is_production
  include nagios::client

}

This seems like it should make ::is_production run before ::client. When I include this class on the node for the puppet run, I get this error:

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Left match operand must result in a String value. Got an Undef Value. at /etc/puppetlabs/code/environments/production/modules/nagios/manifests/client.pp:3:6 on node

So the fact seems like it's not getting set causing the export of the host to fail.

What am I missing?

Followup to answer

I am trying to do this: if domain name contains 'something' production=yes else production=no

Then in the nagios module, if $facts[production] =~ yes Assign to production host group.

Bash:

#!/bin/bash
if  [[ $(hostname) =~ '512' ]] ; then
echo production=yes
else
echo production=no
fi

Id like to be able to use $facts[something] in here to make create other facts based off things like OS and IP.

I read here: Custom Facts Walkthrough

But I wasn't able to understand the custom facts load path as I didn't have that directory. I'm very new to puppet...

Also new to stack overflow... did I do this right?

Thanks

1 Answers1

1

Facts are generated during pluginsync. Since you are trying to place the external fact during catalog execution, it is not available earlier during catalog compilation, which occurs after pluginsync.

You need to remove your nagios::production class and place your external fact directly in the module to take advantage of pluginsync. It should be located in your module structure like this:

nagios
|__facts.d
  |__production.txt

The external fact will then be copied over during pluginsync and the fact will be generated. It will then be available later during catalog compilation. Facter will expect your production.txt to be key:value pairs too.

Check here for more information on properly using external facts: https://docs.puppet.com/facter/3.5/custom_facts.html#external-facts

Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
  • This is actually what I did the first time around, but ran into an issue. Say I create that fact in nagios/facts.d/production.txt - production=yes and it will get ran the agent runs. Won't it always have production=yes on every node that runs the agent? – Jesse Hammil Dec 28 '16 at 00:45
  • @JesseHammil Yes, so you should use a custom fact instead of an external fact, or you can use a dynamic external fact, such as with a script. Feel free to do a followup question about that if you need more information. – Matthew Schuchard Dec 28 '16 at 01:29
  • Thanks a lot. I did a bash script to determine host name and and set the fact accordingly. Thanks so much for the help! – Jesse Hammil Dec 28 '16 at 18:21
  • I do have a folloup... Having trouble accessing facts in my bash script. In the .epp files I can just do $facts[fqdn] for example. In my bash script this doesn't work. Is it possible to access facts with the bash script? – Jesse Hammil Dec 28 '16 at 19:03
  • @JesseHammil I would have recommended you do a hostname --> fact logic with a custom fact instead of a bash script in an external fact. If you need to access a fact (e.g. fqdn or hostname) to help with your fact, then I definitely think you should use a custom fact. Please do a followup question with what specifically you are trying to achieve, including posting your bash script, and I and others can help. – Matthew Schuchard Dec 28 '16 at 19:26