Why can't puppet find my class? - puppet

I'm trying to implement the recipe found here https://github.com/puppetlabs/puppetlabs-firewall#readme and I appear to be making a rookie puppet mistake I can't see. I have a module called mwsettings which itself can be found okay (the mwsettings/init.pp stores a helper for loading some templates and that works), but the following code in my site.pp
Firewall {
notify => Exec['persist-firewall'],
before => Class['mwsettings::postfirewall'],
require => Class['mwsettings::prefirewall'],
}
Blows up with
Error: Failed to apply catalog: Could not find dependency Class[Mwsettings::Prefirewall] for Firewall[100 accept mysql - XXXXXXXX]
when my code later in site.pp invokes
firewall { "100 accept mysql - $name":
proto => 'tcp',
action => 'accept',
dport => 3306,
source => $name,
}
But, it appears I have the manifest set up properly for prefirewall:
# cat modules/mwsettings/manifests/prefirewall.pp
class mwsettings::prefirewall {
Firewall {
require => undef,
}
<snip>
Am I missing something incredibly trivial here? Since it's my first rodeo with puppet, I'm not even entirely sure how to debug this.
Thanks!

You are referring to a class that you haven't declared.
If you add this it should work :
include mwsettings::prefirewall
include mwsettings::postfirewall

Related

Can not find class during Puppet apply

My puppet structure is as follows
/puppet
/manifests
/nodes
redis.pp
site.pp
/modules
The site.pp resembles
class base {
include ml-basefw
include ml-users
include ml-filelimits
include repoforge
include epel
class { 'ml-yumrepo':
base_url => "http://${puppet_server}/yumrepo"
}
}
import 'nodes/*.pp'
node default {
include base
}
When I run
puppet apply --modulepath=/puppet/modules:/puppet/manifests --noop --debug /puppet/manifests/nodes/redis.pp
I receive
Error: Could not find class base for redis-1.test.ml.com on node redis-1.test.ml.com
Is there something non-standard about my file layout that precludes me from using apply?
I am not the maintainer of the puppet module so I am not able to alter the file structure or layout.
There are numerous related questions but I wasn't able to relate them to the problem that I am having.
Edit1 : Adding redis.pp
node /^redis-\d+(.stage)?(.test)?(.aws)?.ml.com$/ {
include base
include epel
class { 'redis':
package_ensure => '2.8.15-1.el6.remi',
service_ensure => 'running',
conf_bind => '0.0.0.0',
conf_port => '6379',
}
firewall { '176 allow port 6379 for redis traffic':
chain => 'INPUT',
state => ['NEW'],
dport => '6379',
proto => 'tcp',
action => 'accept'
}
}
What happens when you run puppet apply against your site.pp file instead? You probably don't have a node definition in your redis.pp file (nor should you).
This does in fact look a little messy and convoluted.
What you want is
an actual base module
defining class base in /puppet/modules/base/manifests/init.pp
You should also loose the import statement by arranging your manifests better. If your version of Puppet is recent enough (I think 3.6+), just see the docs.
fist of all, puppet have the entry manifest file.
in master mode, the entry is site.pp and puppet deprated deprecated it from version 3.5, it started auto imported all manifest files in specified directory.
in apply mode, the entry is specified file in your command.
so it works fine in your production environment, puppet master read site.pp(contains class base) and import nodes/*.pp(redis.pp, contains node definition). but when you use "puppet apply /puppet/manifests/nodes/redis.pp", puppet just read redis.pp, no anyone tell puppet where the base class is.

Puppet Could not find dependency Class

I am trying to pull things out into roles and profiles and am having an issue. I am using puppet apply for all of this as I am using it to finish setting up my Puppet Master. If I define my node in site.pp as shown here:
[root#puppet puppetdbsetup]# cat manifests/site.pp
node 'puppet' {
include ::roles::puppetmaster
}
I get this error:
[root#puppet puppetdbsetup]# puppet apply manifests/site.pp --environmentpath /etc/puppet/environments --environment puppetdbsetup --noop
Notice: Compiled catalog for puppet.belkin in environment puppetdbsetup in 1.29 seconds
Error: Could not find dependency Class[Puppet::Install] for File[/etc/puppet/hiera.yaml] at /etc/puppet/environments/puppetdbsetup/modules/p
uppet/manifests/master.pp:31
If I run puppetmaster.pp (shown below) with puppet apply directly it doesn't throw the same error.
[root#puppet puppetdbsetup]# cat modules/roles/manifests/puppetmaster.pp
class roles::puppetmaster {
#include profiles::base
include profiles::puppet::master
}
Can anyone tell me why this is and how to fix it? As a side note, all three modules referenced here are hand written... none are Forge modules.
Update 1
Here is my puppet::install class:
[root#puppet puppetdbsetup]# cat modules/puppet/manifests/install.pp
class puppet::install {
package { 'puppet':
ensure => present,
}
}
Somewhere in your manifest, you are declaring a File[/etc/puppet/hiera.yaml] that depends on Class[Puppet::Install], like
file { '/etc/puppet/hiera.yaml': require => Class['puppet::install'] }
or so
Class['puppet::install'] -> file { '/etc/puppet/hiera.yaml': ... }
or something in that vein.
What you are lacking is the actual declaration of the class either via
include puppet::install # nice!
or
class { 'puppet::install': } # please don't
If in doubt, add the include line near the file declaration. It is usually safe to include a class multiple times.
If you apply puppetmaster.pp directly, you're just defining the class not applying it.
You need to do puppet apply -e 'include ::roles::puppetmaster' to be comparible.
The other error is probably caused by modules/puppet/manifests/install.pp not existing, or the class definition in the file not starting with
class puppet::install (
....
....
) {

Including a definition by variable

I'm working on putting together some puppet scripts - I've got a list of services (probably about 20 or so) that need to be deployed in very similar fashions.
Stop existing service
Get package out of nexus
Unzip it into directory
Set configuration variables
Start service
The problem is #4. Each service has a slightly different configuration. I'd like to use augeas to set the configurations for each service, and it seemed to make sense to make a definition for each service's config, and then that definition loaded in the main service definition.
So, I've got something like the following:
definition service ($serviceName) {
//stopping, wget, unzip
config[downcase($serviceName)] { "${servicename}_config":
serviceName => $serviceName
}
//start
}
Then, I've got (for example) in the config module's manifest folder "foo.pp"
definition config::foo {
//set some stuff
}
This isn't working due to various rules that I'm sure I've broken but are unaware of. Is there a 'standard' way of doing what I'm trying to do?
You could try the code below. You can put all these in a define type with variables for service name myserv. I would suggest of using templates to set the configuration rather than augeas... easier to control.
exec { "stop_myserv" :
command => "service stop myserv",
path => "/path/to/command/service",
refreshonly => true,
}
exec { "get_pkg_from_nexus" :
command => "/command/to/do/the/above && unzip to/dirctory",
path => "/path/to/command",
require => Exec["stop_myserv"],
}
file { "set_configuration" :
path => "/etc/somewhere/file",
content => template("modulename/file.erb"),
mode => "999",
group => "jiut",
owner => "muit",
require => Exec["get_pkg_from_nexus"],
}
service { "myserv" :
ensure => running,
subscribe => File["set_configuration"],
}

execute puppet class if file is modified by some package

I'm using puppet to deploy standardized ubuntu installs as well as configuration files.
I'm facing a problem where installing a certain package (through a dependency), will overwrite a critical config file. Is there a way to monitor whether this file changes (get's overwritten by some package) and restore it's original content?
what would be the best way of achieving this?
This is the class which takes care of configuring /etc/nsswitch.conf:
class nsswitchconfig {
# roll out nsswitch
class { 'nsswitch':
passwd => ['compat'],
group => ['compat'],
hosts => ['files'],
automount => ['files'],
}
notify { "hate #8040": message => "work around bug #8040" }
}
this is the class which overwrites /etc/nsswitch.conf
class desktop {
include nsswitchconfig
$package_name = ["ubuntu-desktop" ]
package { $package_name:
ensure => latest,
}
}
If the nsswitch class configures the file, all you need is to make sure it runs after the class that overrides it.
So in your case:
class { 'nsswitch':
passwd => ['compat'],
group => ['compat'],
hosts => ['files'],
automount => ['files'],
require => Class['desktop'],
}
should do the trick. (note the require part)

Is this the correct way to change a config file using puppet?

I have a rails app and I'd like to change the ./config/environment/production.rb file to have a different config based on what I want that server to do.
So, I'm going into the .rb file from the .pp file and changing some strings then restarting the service. This just seems really poor form to me. Is there a better way to do this? I've been asked to deliver 1 RPM and change the config via puppet, so...
class Cloud-widget($MServer, $GoogleEarthServer, $CSever) {
package { "Cloud-widget":
ensure => installed
}
service { "Cloud-widget":
ensure => running,
}
<%
file_names = ['./config/environment/production.rb']
file_names.each do |file_name|
puts text.gsub(/.*config.mserver(.*)/, "config.mserver_root = \"#{$Merver}\"")
puts text.gsub(/.*config.google_earth_url(.*)/, "config.google_earth_url( = \"#{$GoogleEarthServer}\"")
puts text.gsub(/.*config.cserver_base_url(.*)/, "config.cserver_base_url = \"#{$CServer}\"")
end
File.open(file_name, "w") {|file| file.puts output_of_gsub}
%>
service { Cloud-widget:
ensure => running,
subscribe => File["./config/environment/production.rb"],
}
}
No, that is not a good way to achieve what you need.
You could look at templates and generate the config files that way. That way, you can use variables in the config file.
If you need create conf from pattern you should use INI-file module from Puppetlabs
ini_setting { "sample setting":
path => '/tmp/foo.ini',
section => 'foo',
setting => 'foosetting',
value => 'FOO!',
ensure => present,
}
install this module from puppet:
puppet module install cprice404-inifile

Resources