diff --git a/manifests/master.pp b/manifests/master.pp index 6c14981..287677a 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -1,117 +1,147 @@ # munin::master - Define a munin master # # The munin master will install munin, and collect all exported munin # node definitions as files into /etc/munin/munin-conf.d/. # # Parameters: # # - node_definitions: A hash of node definitions used by # create_resources to make static node definitions. # +# - host_name: A host name for this munin master, matched with +# munin::node::mastername for collecting nodes. Defaults to $::fqdn +# # - graph_strategy: 'cgi' (default) or 'cron' # Controls if munin-graph graphs all services ('cron') or if graphing is done # by munin-cgi-graph (which must configured seperatly) # # - html_strategy: 'cgi' (default) or 'cron' # Controls if munin-html will recreate all html pages every run interval # ('cron') or if html pages are generated by munin-cgi-graph (which must # configured seperatly) # # - config_root: the root directory of the munin master configuration. # Default: /etc/munin on most platforms. # -# - collect_nodes: 'enabled' or 'disabled' default 'enabled'. -# Makes puppetmaster collect exported node_definitions. +# - collect_nodes: 'enabled' (default), 'disabled', 'mine' or +# 'unclaimed'. 'enabled' makes the munin master collect all exported +# node_definitions. 'disabled' disables it. 'mine' makes the munin +# master collect nodes matching $munin::master::host_name, while +# 'unclaimed' makes the munin master collect nodes not tagged with a +# host name. # # - dbdir: Path to the munin dbdir, where munin stores everything # # - htmldir: Path to where munin will generate HTML documents and # graphs, used if graph_strategy is cron. # # - rundir: Path to directory munin uses for pid and lock files. # # - tls: 'enabled' or 'disabled' (default). Controls the use of TLS # globally for master to node communications. # # - tls_certificate: Path to a file containing a TLS certificate. No # default. Required if tls is enabled. # # - tls_private_key: Path to a file containing a TLS key. No default. # Required if tls is enabled. # # - tls_verify_certificate: 'yes' (default) or 'no'. # # - extra_config: Extra lines of config to put in munin.conf. class munin::master ( $node_definitions = $munin::params::master::node_defintions, $graph_strategy = $munin::params::master::graph_strategy, $html_strategy = $munin::params::master::html_strategy, $config_root = $munin::params::master::config_root, $collect_nodes = $munin::params::master::collect_nodes, $dbdir = $munin::params::master::dbdir, $htmldir = $munin::params::master::htmldir, $logdir = $munin::params::master::logdir, $rundir = $munin::params::master::rundir, $tls = $munin::params::master::tls, $tls_certificate = $munin::params::master::tls_certificate, $tls_private_key = $munin::params::master::tls_private_key, $tls_verify_certificate = $munin::params::master::tls_verify_certificate, + $host_name = $munin::params::master::host_name, $extra_config = $munin::params::master::extra_config, ) inherits munin::params::master { if $node_definitions { validate_hash($node_definitions) } if $graph_strategy { validate_re($graph_strategy, [ '^cgi$', '^cron$' ]) } if $html_strategy { validate_re($html_strategy, [ '^cgi$', '^cron$' ]) } - validate_re($collect_nodes, [ '^enabled$', '^disabled$' ]) + validate_re($collect_nodes, [ '^enabled$', '^disabled$', '^mine$', + '^unclaimed$' ]) validate_absolute_path($config_root) validate_re($tls, [ '^enabled$', '^disabled$' ]) if $tls == 'enabled' { validate_re($tls_verify_certificate, [ '^yes$', '^no$' ]) validate_absolute_path($tls_private_key) validate_absolute_path($tls_certificate) } + if $host_name { + validate_string($host_name) + if ! is_domain_name($host_name) { + fail('host_name should be a valid domain name') + } + } + validate_array($extra_config) # The munin package and configuration package { 'munin': ensure => latest, } File { owner => 'root', group => 'root', mode => '0644', require => Package['munin'], } file { "${config_root}/munin.conf": content => template('munin/munin.conf.erb'), } file { "${config_root}/munin-conf.d": ensure => directory, recurse => true, purge => true, force => true, } - if $collect_nodes == 'enabled' { - # Collect all exported node definitions - Munin::Master::Node_definition <<| mastername == $::fqdn or mastername == '' |>> + case $collect_nodes { + 'enabled': { + Munin::Master::Node_definition <<| |>> + } + 'mine': { + # Collect nodes explicitly tagged with this master + Munin::Master::Node_definition <<| tag == "munin::master::${host_name}" |>> + } + 'unclaimed': { + # Collect all exported node definitions, except the ones tagged + # for a specific master + Munin::Master::Node_definition <<| tag == 'munin::master::' |>> + } + 'disabled', + default: { + # do nothing + } } # Create static node definitions if $node_definitions { create_resources(munin::master::node_definition, $node_definitions, {}) } } diff --git a/manifests/node.pp b/manifests/node.pp index 48d815b..85eaadf 100644 --- a/manifests/node.pp +++ b/manifests/node.pp @@ -1,126 +1,127 @@ # munin::node - Configure a munin node, and export configuration a # munin master can collect. # # Parameters: # # allow: List of IPv4 and IPv6 addresses and networks to allow to connect. # # config_root: Root directory for munin configuration. # # nodeconfig: List of lines to append to the munin node configuration. # # host_name: The host name munin node identifies as. Defaults to # the $::fqdn fact. # # log_dir: The log directory for the munin node process. Defaults # change according to osfamily, see munin::params::node for details. # # masterconfig: List of configuration lines to append to the munin # master node definitinon # # mastername: The name of the munin master server which will collect # the node definition. # # mastergroup: The group used on the master to construct a FQN for # this node. Defaults to "", which in turn makes munin master use the # domain. Note: changing this for a node also means you need to move # rrd files on the master, or graph history will be lost. # # plugins: A hash used by create_resources to create munin::plugin # instances. # # address: The address used in the munin master node definition. # # package_name: The name of the munin node package to install. # # service_name: The name of the munin node service. # # service_ensure: Defaults to "". If set to "running" or "stopped", it # is used as parameter "ensure" for the munin node service. # # export_node: "enabled" or "disabled". Defaults to "enabled". # Causes the node config to be exported to puppetmaster. # # file_group: The UNIX group name owning the configuration files, # log files, etc. class munin::node ( $address = $munin::params::node::address, $allow = $munin::params::node::allow, $config_root = $munin::params::node::config_root, $host_name = $munin::params::node::host_name, $log_dir = $munin::params::node::log_dir, $masterconfig = $munin::params::node::masterconfig, $mastergroup = $munin::params::node::mastergroup, $mastername = $munin::params::node::mastername, $nodeconfig = $munin::params::node::nodeconfig, $package_name = $munin::params::node::package_name, $plugins = $munin::params::node::plugins, $service_ensure = $munin::params::node::service_ensure, $service_name = $munin::params::node::service_name, $export_node = $munin::params::node::export_node, $file_group = $munin::params::node::file_group, ) inherits munin::params::node { validate_array($allow) validate_array($nodeconfig) validate_array($masterconfig) validate_string($mastergroup) validate_string($mastername) validate_hash($plugins) validate_string($address) validate_absolute_path($config_root) validate_string($package_name) validate_string($service_name) validate_re($service_ensure, '^(|running|stopped)$') validate_re($export_node, '^(enabled|disabled)$') validate_absolute_path($log_dir) validate_string($file_group) if $mastergroup { $fqn = "${mastergroup};${host_name}" } else { $fqn = $host_name } # Defaults File { ensure => present, owner => 'root', group => $file_group, mode => '0444', } package { $package_name: ensure => installed, } service { $service_name: ensure => $service_ensure ? { '' => undef, default => $service_ensure, }, enable => true, require => Package[$package_name], } file { "${config_root}/munin-node.conf": content => template('munin/munin-node.conf.erb'), require => Package[$package_name], notify => Service[$service_name], } # Export a node definition to be collected by the munin master if $export_node == 'enabled' { @@munin::master::node_definition{ $fqn: address => $address, mastername => $mastername, config => $masterconfig, + tag => [ "munin::master::${mastername}" ] } } # Generate plugin resources from hiera or class parameter. create_resources(munin::plugin, $plugins, {}) } diff --git a/manifests/params/master.pp b/manifests/params/master.pp index 862e224..30b4c9e 100644 --- a/manifests/params/master.pp +++ b/manifests/params/master.pp @@ -1,30 +1,31 @@ class munin::params::master { $message = "Unsupported osfamily ${::osfamily}" $graph_strategy = 'cgi' $html_strategy = 'cgi' $node_definitions = '' $collect_nodes = 'enabled' $dbdir = undef $htmldir = undef $logdir = undef $rundir = undef $tls = 'disabled' $tls_certificate = undef $tls_private_key = undef $tls_verify_certificate = 'yes' $extra_config = [] + $host_name = $::fqdn case $::osfamily { 'Debian', 'RedHat': { $config_root = '/etc/munin' } 'Solaris': { $config_root = '/opt/local/etc/munin' } default: { fail($message) } } } diff --git a/spec/classes/munin_master_spec.rb b/spec/classes/munin_master_spec.rb index b477416..81e1aae 100644 --- a/spec/classes/munin_master_spec.rb +++ b/spec/classes/munin_master_spec.rb @@ -1,133 +1,165 @@ require 'spec_helper' describe 'munin::master' do [ :CentOS, :Debian, :RedHat, :Ubuntu ].each do |sc| context "Check for supported operatingsystem #{sc}" do include_context sc it { should compile } it { should contain_class('munin::master') } it { should contain_package('munin') should contain_file('/etc/munin/munin.conf') should contain_file('/etc/munin/munin-conf.d') .with_ensure('directory') } end end [ :SmartOS ].each do |sc| context "Check for supported operatingsystem #{sc}" do include_context sc it { should compile } it { should contain_class('munin::master') } it { should contain_package('munin') should contain_file('/opt/local/etc/munin/munin.conf') should contain_file('/opt/local/etc/munin/munin-conf.d') .with_ensure('directory') } end end context 'with default params' do it { should contain_file('/etc/munin/munin.conf') .with_content(/graph_strategy\s+cgi/) .with_content(/html_strategy\s+cgi/) } end context 'with html_strategy => cron' do let (:params) { { :html_strategy => 'cron' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/html_strategy\s+cron/) } end context 'with graph_strategy => cron' do let (:params) { { :graph_strategy => 'cron' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/graph_strategy\s+cron/) } end context 'with dbdir => /var/lib/munin' do let (:params) { { :dbdir => '/var/lib/munin' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/dbdir\s+\/var\/lib\/munin/) } end context 'with htmldir => /var/www/munin' do let (:params) { { :htmldir => '/var/www/munin' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/htmldir\s+\/var\/www\/munin/) } end context 'with logdir => /var/log/munin' do let (:params) { { :dbdir => '/var/log/munin' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/dbdir\s+\/var\/log\/munin/) } end context 'with rudir => /var/run/munin' do let (:params) { { :dbdir => '/var/run/munin' } } it { should contain_file('/etc/munin/munin.conf') .with_content(/dbdir\s+\/var\/run\/munin/) } end context 'with tls => enabled' do let(:params) { { :tls => 'enabled', :tls_certificate => '/path/to/certificate.pem', :tls_private_key => '/path/to/key.pem', :tls_verify_certificate => 'yes', } } it { should compile } it { should contain_file('/etc/munin/munin.conf') .with_content(/tls = enabled/) .with_content(/tls_certificate = \/path\/to\/certificate\.pem/) .with_content(/tls_private_key = \/path\/to\/key\.pem/) .with_content(/tls_verify_certificate = yes/) } end context 'with extra_config' do token = '1b7febce-bb2d-4c18-b889-84c73538a900' let(:params) do { :extra_config => [ token ] } end it { should compile } it do should contain_file('/etc/munin/munin.conf') .with_content(/#{token}/) end end context 'with extra_config set to a string' do token = '1b7febce-bb2d-4c18-b889-84c73538a900' let(:params) do { :extra_config => token } end it do expect { should compile } .to raise_error(Puppet::Error, /is not an Array/) end end + ['test.example.com', 'invalid/hostname.example.com'].each do |param| + context "with host_name => #{param}" do + let(:params) do + { :host_name => param } + end + if param =~ /invalid/ + it do + expect { should compile } + .to raise_error(Puppet::Error, /valid domain name/) + end + else + it { should compile } + end + end + end + + %w( enabled disabled mine unclaimed invalid ).each do |param| + context "with collect_nodes => #{param}" do + let(:params) do + { :collect_nodes => param } + end + if param == 'invalid' + it do + expect { should compile } + .to raise_error(Puppet::Error, /validate_re/) + end + else + it { should compile } + end + end + end + end