diff --git a/.travis.yml b/.travis.yml index bb8adfd..e5cff13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,17 @@ --- +sudo: false language: ruby +cache: bundler bundler_args: --without development -before_install: rm Gemfile.lock || true rvm: - 1.9.3 - - 2.0.0 - - 2.1.4 + - 2.1.6 + - 2.2.2 env: - - PUPPET_VERSION="~> 3.3.0" - - PUPPET_VERSION="~> 3.7.0" - - PUPPET_VERSION="~> 3.7.0" FUTURE_PARSER="yes" + - PUPPET_VERSION="~> 3.0" + - PUPPET_VERSION="~> 4.0" matrix: exclude: - - rvm: 2.1.4 - env: PUPPET_VERSION="~> 3.3.0" - - rvm: 2.1.4 - env: PUPPET_VERSION="~> 3.3.0" + - rvm: 2.2.2 + env: PUPPET_VERSION="~> 3.0" script: bundle exec rake spec diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a7e933..4945acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,128 +1,160 @@ # Changelog +## 0.0.9 - 2015-07-29 + +* Bugfix: The mastergroup, if used in the node's FQN (Fully Qualified + Name), should no longer be empty on Puppet 4.0. + ([#27](https://github.com/ssm/ssm-munin/pull/27)) + +* Bugfix: Using munin::master and munin::node with export and collect + disabled should no longer trigger warnings about missing + storeconfigs. ([#30](https://github.com/ssm/ssm-munin/issues/30), + [#33](https://github.com/ssm/ssm-munin/pull/33)) + +### munin::master + +* Add FreeBSD support. + +### munin::node + +* New feature: Log to syslog with the "log\_destination" and + "syslog\_facility" parameters. + ([#23](https://github.com/ssm/ssm-munin/issues/23), + [#24](https://github.com/ssm/ssm-munin/pull/24), + [#25](https://github.com/ssm/ssm-munin/pull/25)) + +* New feature: Set the plugin runtime timeout with the "timeout" + parameter. ([#29](https://github.com/ssm/ssm-munin/issues/29), + [#32](https://github.com/ssm/ssm-munin/pull/32)) + +* New feature: Purge unmanaged plugins and plugin configuration with + the "purge_configs" parameter. + ([#28](https://github.com/ssm/ssm-munin/issues/28), + [#31](https://github.com/ssm/ssm-munin/pull/31)) + ## 0.0.8 - 2015-02-06 Support the future parser. Contributors to this release: Rike-Benjamin Schuppner, Stig Sandbeck Mathisen ## 0.0.7 - 2014-12-05 This release adds support for DragonFly BSD, FreeBSD, OpenBSD. Other changes listed below, per component. Contributors to this release: Alex Hornung, Chris Roddy, Frank Groeneveld, Fredrik Thulin, Julien Pivotto, Martin Jackson, Sebastian Wiesinger, Stig Sandbeck Mathisen ### munin::node * Add "host_name" parameter to override the host name of the munin node. * Add "file_group" parameter, used for configuration and log files. * Add "log_dir" parameter. * Improved handling of "allow" ACL parameter. ### munin::master * Improved collection logic. Set "collect_nodes" to "mine" to collect nodes which are targeted for this master, or "unclaimed" to pick up nodes not aimed a specific master. * Add global tls_* parameters for connecting to nodes. * Add "dbdir", "htmldir", "rundir" parameters. * Add "extra_config" parameter, which takes an array of extra configuration lines for munin.conf. ### munin::plugin * Support absolute paths as target for a plugin. ## 0.0.6 - 2014-12-05 * Retracted, had a breaking bug on older (3.4.x) puppet versions. ## 0.0.5 - 2014-03-19 * Support multiple masters with different nodes (Thanks: Cristian Gae) * Support older (1.4.6) munin versions (Thanks: Sergio Oliveira) * Update for compatibility with puppet 3.4 (Thanks: Harald Skoglund) * Easier configuration with more parameters. All parameters have trivial validation. ### munin::master - new parameter "config_root". Defaults should match supported operating systems. ### munin::plugin - new parameter "config_root". Defaults should match supported operating systems. ### munin::node - new parameter "address". Default is $::fqdn. This will be used as the "address" when registering with the munin master. - new parameter "config_root". Defaults should match supported operating systems. - new parameter "package_name". Default should match supported operating systems. - new parameter "service_name". Default should match supported operating systems. - new parameter "service_ensure". Default is "". Possible values: "", "running" or "stopped". ### munin::params - new class ## 0.0.4 - 2013-08-13 Bugfix for the munin::plugin define. - Bugfix: Ensure that we can run tests on ruby 1.8. - Bugfix: No longer requires the class `Munin::Plugins`, which does not exist in this module. ([#3](https://github.com/ssm/ssm-munin/issues/3)) - The `ensure` attribute no longer defaults to "link". If not set, a potentially existing plugin with the same name is not touched. - Plugin and configuration directories are now configurable. - Improved rspec tests, which now actually match the documentation. ## 0.0.2 - 2013-06-31 A few pull requests - Bugfix: Install munin package before creating munin-conf.d directory ([#1](https://github.com/ssm/ssm-munin/pull/1)) - Make graph strategy configurable ([#2](https://github.com/ssm/ssm-munin/pull/2)) - Improve documentation ## 0.0.1 - 2013-06-02 Initial release diff --git a/Gemfile b/Gemfile index 3e72d45..8baf230 100644 --- a/Gemfile +++ b/Gemfile @@ -1,17 +1,16 @@ source 'https://rubygems.org' group :test do gem 'rake' - gem 'puppet', ENV['PUPPET_VERSION'] || '~> 3.7.0' - gem 'rspec-puppet', :git => 'https://github.com/rodjek/rspec-puppet.git', :ref => 'v2.0.0' - gem 'puppetlabs_spec_helper' + gem 'puppet', ENV['PUPPET_VERSION'] || '~> 4.0' + gem 'rspec-puppet' + gem 'rspec-puppet-facts', :require => false + gem 'puppetlabs_spec_helper', '~> 0.10.2' + gem 'metadata-json-lint' end group :development do gem 'travis' - gem 'travis-lint' gem 'vagrant-wrapper' - gem 'puppet-blacksmith' gem 'guard-rake' - gem 'metadata-json-lint' end diff --git a/Guardfile b/Guardfile index 2cd45cb..f84d6e4 100644 --- a/Guardfile +++ b/Guardfile @@ -1,11 +1,13 @@ notification :off +directories %w(manifests templates spec/classes spec/defines) + guard 'rake', :task => 'test' do - watch('Rakefile') watch(%r{^manifests\/(.+)\.pp$}) watch(%r{^templates\/(.+)\.erb$}) + watch(%r{^spec/.*_spec.rb}) end guard 'rake', :task => 'metadata' do watch('metadata.json') end diff --git a/README.md b/README.md index 9fb0265..9779528 100644 --- a/README.md +++ b/README.md @@ -1,212 +1,224 @@ -# Puppet munin module [![Build Status](https://travis-ci.org/ssm/ssm-munin.png?branch=master)](https://travis-ci.org/ssm/ssm-munin) +# Puppet munin module + +[![Puppet Forge](http://img.shields.io/puppetforge/v/ssm/munin.svg)](https://forge.puppetlabs.com/ssm/munin) +[![Build Status](https://travis-ci.org/ssm/ssm-munin.png?branch=master)](https://travis-ci.org/ssm/ssm-munin) + +# Table of contents + +1. [Overview](#overview) +2. [Munin Master](#munin-master) +3. [Munin Node](#munin-node) +4. [Munin Plugins](#munin-plugins) + +# Overview Control munin master, munin node, and munin plugins. Munin nodes are automatically configured on the master. (Requires puppetdb) # Munin master Typical usage: include munin::master Installs a munin master, and automatically collects configuration from all munin nodes configured with munin::node. # Munin node definition munin::master::node_definition { 'fqn': address => $address, config => ['additional', 'configuration' 'lines'], } The resource title is used as the munin FQN, or "fully qualified name". This defines the node name and group. It is common to use the host's fully qualified domain name, where the domain name will be implicitly used as the node group. The address is the host name, ip address, or alternate transport used to contact the node. To add more configuration, specify it as an array for the "config" attribute. For more information about configuring a munin node definition, see http://munin.readthedocs.org/en/latest/reference/munin.conf.html#node-definitions If you have multiple munin master servers in your infrastructure and want to assign different nodes to different masters, you can specify the master's fully qualified domain name on the node's definition: munin::master::node_definition { 'fqn': address => $address, mastername => 'munin.example.com', } ## Static node definitions The munin master class will collect all "munin::master::node_definition" exported by "munin::node". For extra nodes, you can define them in hiera, and munin::master will create them. Example: munin::master::node_definition { 'foo.example.com': address => '192.0.2.1' } munin::master::node_definition { 'bar.example.com': address => '192.0.2.1', config => [ 'load.graph_future 30', 'load.load.trend yes', 'load.load.predict 86400,12' ], } ### node definitions as class parameter If you define your nodes as a data structure in a puppet manifest, or from the puppet External Node Classifier, you can use a class parameter: $nodes = { ... } class { 'puppet::master': node_definitions => $nodes, } ### node definitions with hiera A JSON definition. { "munin::master::node_definitions" : { "foo.example.com" : { "address" : "192.0.2.1" }, "bar.example.com" : { "address" : "192.0.2.2", "config" : [ "load.graph_future 30", "load.load.trend yes", "load.load.predict 86400,12" ] } } } A YAML definition --- munin::master::node_definitions: foo.example.com: address: 192.0.2.1 bar.example.com: address: 192.0.2.2 config: - load.graph_future 30 - load.load.trend yes - load.load.predict 86400,12 # Munin node Typical usage: class { 'munin::node': allow => [ '192.0.2.0/24', '2001:db8::/64' ] } or in hiera: --- munin::node::allow: - 192.0.2.0/24 - 2001:db8::/64 Installs munin-node, and exports a munin::master::node_definition which munin::master will collect, and allows munin masters on specified networks to connect. The munin::node class does take more parameters, see the 'manifests/node.pp' file for complete documentation. # Munin plugins The defined type munin::plugin is used to control the munin plugins used on a munin node. Typical usage: munin::plugin { 'cpu': ensure => link, } ## Examples ### Activate a plugin Here, we activate an already installed plugin. The use of "ensure => link" creates an implicit "target => /usr/share/munin/plugins/$title". The "target" parameter can be set to an absolute path (starting with a "/"), or a relative path (anything else). If relative, $munin::params::node::plugin_share_dir is prepended to the path. munin::plugin { 'apt': ensure => link; 'something': ensure => link, target => '/usr/local/share/munin/plugins/something'; 'ip_eth0': ensure => link, target => 'ip_'; # becomes $munin::params::node::plugin_share_dir/ip_ } ### Install and activate a plugin The use of "ensure => present" creates a file in /etc/munin/plugins munin::plugin { 'somedaemon': ensure => present, source => 'puppet:///modules/munin/plugins/somedaemon', } ### Activate wildcard plugin A pair of plugins we provide, with a _name symlink (This is also known as "wildcard" plugins) munin::plugin { 'foo_bar': ensure => present, target => 'foo_', source => 'puppet:///modules/munin/plugins/foo_'; 'foo_baz': ensure => present, target => 'foo_', source => 'puppet:///modules/munin/plugins/foo_'; } ### Plugin with configuration This creates an additional "/etc/munin/plugin-conf.d/${title}.conf" munin::plugin { 'bletch': ensure => link, config => 'env.database flumpelump'; 'thud': ensure => present, source => 'puppet:///modules/munin/plugins/thud', config => ['env.database zotto', 'user root']; } ### A plugin configuration file This only adds a plugin configuration file. munin::plugin { 'slapd': config => ['env.rootdn cn=admin,dc=example,dc=org'], config_label => 'slapd_*', } diff --git a/manifests/master.pp b/manifests/master.pp index 32b760f..e1aeeca 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -1,147 +1,135 @@ # 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' (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$', '^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, } - 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 + if $collect_nodes != 'disabled' { + class { 'munin::master::collect': + collect_nodes => $collect_nodes, + host_name => $host_name, } } # Create static node definitions if $node_definitions { create_resources(munin::master::node_definition, $node_definitions, {}) } } diff --git a/manifests/master/collect.pp b/manifests/master/collect.pp new file mode 100644 index 0000000..875f07d --- /dev/null +++ b/manifests/master/collect.pp @@ -0,0 +1,30 @@ +# Class to collect the exported munin nodes. +# +# This is separated into its own class to avoid warnings about missing +# storeconfigs. +# + +class munin::master::collect ( + $collect_nodes, + $host_name, +) +{ + 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 + } + } +} diff --git a/manifests/node.pp b/manifests/node.pp index 85eaadf..ca4d423 100644 --- a/manifests/node.pp +++ b/manifests/node.pp @@ -1,127 +1,183 @@ # 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. # +# log_file: Appended to "log_dir". Defaults to "munin-node.log". +# +# log_destination: "file" or "syslog". Defaults to "file". If log_destination +# is "syslog", the "log_file" and "log_dir" parameters are ignored, and the +# "syslog_*" parameters are used if set. +# +# purge_configs: Removes all other munin plugins and munin plugin +# configuration files. Boolean, defaults to false. +# +# syslog_facility: Defaults to undef, which makes munin-node use the +# perl Net::Server module default of "daemon". Possible values are any +# syslog facility by number, or lowercase name. +# # 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. +# +# timeout: Used to set the global plugin runtime timeout for this +# node. Integer. Defaults to undef, which lets munin-node use its +# default of 10 seconds. 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, + $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, + $log_file = $munin::params::node::log_file, + $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, + $purge_configs = $munin::params::node::purge_configs, + $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, + $log_destination = $munin::params::node::log_destination, + $syslog_facility = $munin::params::node::syslog_facility, + $timeout = $munin::params::node::timeout, ) inherits munin::params::node { validate_array($allow) validate_array($nodeconfig) validate_array($masterconfig) - validate_string($mastergroup) - validate_string($mastername) + if $mastergroup { validate_string($mastergroup) } + if $mastername { 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)$') + if $service_ensure { validate_re($service_ensure, '^(running|stopped)$') } validate_re($export_node, '^(enabled|disabled)$') validate_absolute_path($log_dir) + validate_re($log_destination, '^(?:file|syslog)$') + validate_string($log_file) validate_string($file_group) + validate_bool($purge_configs) + if $timeout { validate_integer($timeout) } + + case $log_destination { + 'file': { + $_log_file = "${log_dir}/${log_file}" + validate_absolute_path($_log_file) + } + 'syslog': { + $_log_file = 'Sys::Syslog' + if $syslog_facility { + validate_string($syslog_facility) + validate_re($syslog_facility, + '^(?:\d+|(?:kern|user|mail|daemon|auth|syslog|lpr|news|uucp|authpriv|ftp|cron|local[0-7]))$') + } + } + default: { + fail('log_destination is not set') + } + } if $mastergroup { $fqn = "${mastergroup};${host_name}" } else { $fqn = $host_name } + if $service_ensure { $_service_ensure = $service_ensure } + else { $_service_ensure = undef } + # 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, - }, + ensure => $_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 + # Export a node definition to be collected by the munin master. + # (Separated into its own class to prevent warnings about "missing + # storeconfigs", even if $export_node is not enabled) if $export_node == 'enabled' { - @@munin::master::node_definition{ $fqn: - address => $address, - mastername => $mastername, - config => $masterconfig, - tag => [ "munin::master::${mastername}" ] + class { 'munin::node::export': + address => $address, + fqn => $fqn, + mastername => $mastername, + masterconfig => $masterconfig, } } # Generate plugin resources from hiera or class parameter. create_resources(munin::plugin, $plugins, {}) + # Purge unmanaged plugins and plugin configuration files. + if $purge_configs { + file { ["${config_root}/plugins", "${config_root}/plugin-conf.d" ]: + ensure => directory, + recurse => true, + purge => true, + notify => Service[$service_name], + } + } + } diff --git a/manifests/node/export.pp b/manifests/node/export.pp new file mode 100644 index 0000000..49130fa --- /dev/null +++ b/manifests/node/export.pp @@ -0,0 +1,19 @@ +# Class to export the munin node. +# +# This is separated into its own class to avoid warnings about missing +# storeconfigs. +# +class munin::node::export ( + $address, + $fqn, + $masterconfig, + $mastername, +) +{ + @@munin::master::node_definition{ $fqn: + address => $address, + mastername => $mastername, + config => $masterconfig, + tag => [ "munin::master::${mastername}" ], + } +} diff --git a/manifests/params/master.pp b/manifests/params/master.pp index 30b4c9e..b745b6a 100644 --- a/manifests/params/master.pp +++ b/manifests/params/master.pp @@ -1,31 +1,34 @@ 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' } + 'FreeBSD': { + $config_root = '/usr/local/etc/munin' + } default: { fail($message) } } } diff --git a/manifests/params/node.pp b/manifests/params/node.pp index 587733a..f2ae4ca 100644 --- a/manifests/params/node.pp +++ b/manifests/params/node.pp @@ -1,70 +1,75 @@ class munin::params::node { $message = "Unsupported osfamily: ${::osfamily}" $address = $::fqdn $host_name = $::fqdn $allow = [] $masterconfig = [] - $mastergroup = '' - $mastername = '' + $mastergroup = undef + $mastername = undef $nodeconfig = [] $plugins = {} - $service_ensure = '' + $service_ensure = undef $export_node = 'enabled' + $log_file = 'munin-node.log' + $log_destination = 'file' + $syslog_facility = undef + $purge_configs = false + $timeout = undef case $::osfamily { 'RedHat': { $config_root = '/etc/munin' $log_dir = '/var/log/munin-node' $service_name = 'munin-node' $package_name = 'munin-node' $plugin_share_dir = '/usr/share/munin/plugins' $file_group = 'root' } 'Debian': { $config_root = '/etc/munin' $log_dir = '/var/log/munin' $service_name = 'munin-node' $package_name = 'munin-node' $plugin_share_dir = '/usr/share/munin/plugins' $file_group = 'root' } 'Solaris': { case $::operatingsystem { 'SmartOS': { $config_root = '/opt/local/etc/munin' $log_dir = '/var/opt/log/munin' $service_name = 'smf:/munin-node' $package_name = 'munin-node' $plugin_share_dir = '/opt/local/share/munin/plugins' $file_group = 'root' } default: { fail("Unsupported operatingsystem ${::operatingsystem} for osfamily ${::osfamily}") } } } 'FreeBSD', 'DragonFly': { $config_root = '/usr/local/etc/munin' $log_dir = '/var/log/munin' $service_name = 'munin-node' $package_name = 'munin-node' $plugin_share_dir = '/usr/local/share/munin/plugins' $file_group = 'wheel' } 'OpenBSD': { $config_root = '/etc/munin' $log_dir = '/var/log/munin' $service_name = 'munin_node' $package_name = 'munin-node' $plugin_share_dir = '/usr/local/libexec/munin/plugins' $file_group = 'wheel' } default: { fail($message) } } } diff --git a/manifests/plugin.pp b/manifests/plugin.pp index da75473..9d8a90b 100644 --- a/manifests/plugin.pp +++ b/manifests/plugin.pp @@ -1,87 +1,92 @@ # munin::plugin # # Parameters: # -# - ensure: link, present, absent +# - ensure: "link", "present", "absent" or "". Default is "". The +# ensure parameter is mandatory for installing a plugin. # - source: when ensure => present, source file -# - target: when ensure => link, link target +# - target: when ensure => link, link target. If target is an +# absolute path (starts with "/") it is used directly. If target is +# a relative path, $munin::node::plugin_share_dir is prepended. # - config: array of lines for munin plugin config # - config_label: label for munin plugin config define munin::plugin ( - $ensure=undef, + $ensure='', $source=undef, - $target=undef, + $target='', $config=undef, $config_label=undef, ) { include munin::node $plugin_share_dir=$munin::node::plugin_share_dir validate_absolute_path($plugin_share_dir) File { require => Package[$munin::node::package_name], notify => Service[$munin::node::service_name], } + validate_re($ensure, '^(|link|present|absent)$') case $ensure { - present: { + 'present': { $handle_plugin = true - $plugin_ensure = present + $plugin_ensure = 'present' } - absent: { + 'absent': { $handle_plugin = true - $plugin_ensure = absent + $plugin_ensure = 'absent' } - link: { + 'link': { $handle_plugin = true - $plugin_ensure = link + $plugin_ensure = 'link' case $target { '': { $plugin_target = "${munin::node::plugin_share_dir}/${title}" } /^\//: { $plugin_target = $target } default: { $plugin_target = "${munin::node::plugin_share_dir}/${target}" } } + validate_absolute_path($plugin_target) } default: { $handle_plugin = false } } if $config { $config_ensure = $ensure ? { absent => absent, default => present, } } else { $config_ensure = absent } if $handle_plugin { # Install the plugin file {"${munin::node::config_root}/plugins/${name}": - ensure => $plugin_ensure, - source => $source, - target => $plugin_target, - mode => '0755', + ensure => $plugin_ensure, + source => $source, + target => $plugin_target, + mode => '0755', } } # Config file{ "${munin::node::config_root}/plugin-conf.d/${name}.conf": ensure => $config_ensure, content => template('munin/plugin_conf.erb'), } } diff --git a/metadata.json b/metadata.json index a1cffca..cb71aca 100644 --- a/metadata.json +++ b/metadata.json @@ -1,61 +1,62 @@ { "name": "ssm/munin", - "version": "0.0.8", + "version": "0.0.9", "author": "ssm", "license": "Apache-2.0", "summary": "Configure munin master, node and plugins", "source": "https://github.com/ssm/ssm-munin", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 2.3.0" } ], "project_page": "https://github.com/ssm/ssm-munin", "issues_url": "https://github.com/ssm/ssm-munin/issues", "operatingsystem_support": [ { "operatingsystem": "CentOS", - "operatingsystemrelease": [ "5.0", "6.0", "7.0" ] + "operatingsystemrelease": [ "5", "6", "7" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "6", "7", "8" ] }, { "operatingsystem": "OracleLinux", - "operatingsystemrelease": [ "5.0", "6.0", "7.0" ] + "operatingsystemrelease": [ "5", "6", "7" ] }, { "operatingsystem": "RedHat", - "operatingsystemrelease": [ "5.0", "6.0", "7.0" ] + "operatingsystemrelease": [ "5", "6", "7" ] }, { "operatingsystem": "Scientific", - "operatingsystemrelease": [ "5.0", "6.0", "7.0" ] + "operatingsystemrelease": [ "5", "6", "7" ] }, { "operatingsystem": "SmartOS" }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "10.04", "12.04", "14.04" ] }, { - "operatingsystem": "FreeBSD" + "operatingsystem": "FreeBSD", + "operatingsystemrelease": [ "9", "10" ] }, { "operatingsystem": "DragonFly" }, { "operatingsystem": "OpenBSD" } ], "tags": [ "munin", "monitoring", "graphing", "performance", "trending" ] } diff --git a/spec/classes/munin_master_spec.rb b/spec/classes/munin_master_spec.rb index f8728e5..a56cb64 100644 --- a/spec/classes/munin_master_spec.rb +++ b/spec/classes/munin_master_spec.rb @@ -1,155 +1,167 @@ require 'spec_helper' +_conf_dir = {} +_conf_dir.default = '/etc/munin' +_conf_dir['Solaris'] = '/opt/local/etc/munin' +_conf_dir['FreeBSD'] = '/usr/local/etc/munin' + 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 + on_supported_os.each do |os, facts| - [ :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 + # Avoid testing on distributions similar to RedHat and Debian + next if /^(ubuntu|centos|scientific|oraclelinux)-/.match(os) - 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 + # No need to test all os versions as long as os version is not + # used in the params class + next if /^(debian-[67]|redhat-[56]|freebsd-9)-/.match(os) - 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 "on #{os}" do + let(:facts) do + facts + 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 + conf_dir = _conf_dir[facts[:osfamily]] - 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 + it { should compile.with_all_deps } - 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 + it { should contain_package('munin') } - 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 default params' do + it do + should contain_file("#{conf_dir}/munin.conf") + .with_content(/graph_strategy\s+cgi/) + .with_content(/html_strategy\s+cgi/) + 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 + it do + should contain_file("#{conf_dir}/munin-conf.d") + .with_ensure('directory') + end + 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 html_strategy => cron' do + let (:params) { { :html_strategy => 'cron' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/html_strategy\s+cron/) + } + 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 graph_strategy => cron' do + let (:params) { { :graph_strategy => 'cron' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/graph_strategy\s+cron/) + } + end - context 'with extra_config set to a string' do - token = '1b7febce-bb2d-4c18-b889-84c73538a900' - let(:params) do - { :extra_config => token } - end - it { should raise_error(Puppet::Error, /is not an Array/) } - end + context 'with dbdir => /var/lib/munin' do + let (:params) { { :dbdir => '/var/lib/munin' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/dbdir\s+\/var\/lib\/munin/) + } + end - ['test.example.com', 'invalid/hostname.example.com'].each do |param| - context "with host_name => #{param}" do - let(:params) do - { :host_name => param } + context 'with htmldir => /var/www/munin' do + let (:params) { { :htmldir => '/var/www/munin' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/htmldir\s+\/var\/www\/munin/) + } end - if param =~ /invalid/ - it { should raise_error(Puppet::Error, /valid domain name/) } - else - it { should compile } + + context 'with logdir => /var/log/munin' do + let (:params) { { :dbdir => '/var/log/munin' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/dbdir\s+\/var\/log\/munin/) + } end - end - end - %w( enabled disabled mine unclaimed invalid ).each do |param| - context "with collect_nodes => #{param}" do - let(:params) do - { :collect_nodes => param } + context 'with rundir => /var/run/munin' do + let (:params) { { :dbdir => '/var/run/munin' } } + it { should compile.with_all_deps } + it { + should contain_file("#{conf_dir}/munin.conf") + .with_content(/dbdir\s+\/var\/run\/munin/) + } end - if param == 'invalid' - it { should raise_error(Puppet::Error, /validate_re/) } - else - it { should compile } + + 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.with_all_deps } + it { + should contain_file("#{conf_dir}/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.with_all_deps } + it do + should contain_file("#{conf_dir}/munin.conf") + .with_content(/#{token}/) + end 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 { should raise_error(Puppet::Error, /is not an Array/) } + 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 { should raise_error(Puppet::Error, /valid domain name/) } + else + it { should compile.with_all_deps } + 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 { should raise_error(Puppet::Error, /validate_re/) } + else + it { should compile.with_all_deps } + end + end + end + + end # on os end end diff --git a/spec/classes/munin_node_spec.rb b/spec/classes/munin_node_spec.rb index 9e8d0db..2fbac6f 100644 --- a/spec/classes/munin_node_spec.rb +++ b/spec/classes/munin_node_spec.rb @@ -1,79 +1,195 @@ require 'spec_helper' +_conf_dir = {} +_conf_dir.default = '/etc/munin' +_conf_dir['DragonFly'] = '/usr/local/etc/munin' +_conf_dir['FreeBSD'] = '/usr/local/etc/munin' +_conf_dir['Solaris'] = '/opt/local/etc/munin' + describe 'munin::node' 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::node') } - it { - should contain_package('munin-node') - should contain_service('munin-node') - should contain_file('/etc/munin/munin-node.conf') - } - end - end + on_supported_os.each do |os, facts| + + # Avoid testing on distributions similar to RedHat and Debian + next if /^(ubuntu|centos|scientific|oraclelinux)-/.match(os) + + # No need to test all os versions as long as os version is not + # used in the params class + next if /^(debian-[67]|redhat-[56]|freebsd-9)-/.match(os) + + context "on #{os}" do + let(:facts) do + facts + end + + it { should compile.with_all_deps } + + it { should contain_package('munin-node') } + + munin_confdir = _conf_dir[facts[:osfamily]] + + munin_node_conf = "#{munin_confdir}/munin-node.conf" + munin_plugin_dir = "#{munin_confdir}/plugins" + munin_plugin_conf_dir = "#{munin_confdir}/plugin-conf.d" + + case facts[:osfamily] + when 'Solaris' + munin_node_service = 'smf:/munin-node' + else + munin_node_service = 'munin-node' + end + + case facts[:osfamily] + when 'Solaris' + log_dir = '/var/opt/log/munin' + when 'RedHat' + log_dir = '/var/log/munin-node' + else + log_dir = '/var/log/munin' + end + + it { should contain_service(munin_node_service) } + it { should contain_file(munin_node_conf) } + + context 'with no parameters' do + it { should compile.with_all_deps } + it do + should contain_service(munin_node_service) + .without_ensure() + end + it do + should contain_file(munin_node_conf) + .with_content(/host_name\s+foo.example.com/) + .with_content(/log_file\s+#{log_dir}\/munin-node.log/) + end + end + + context 'with parameter allow' do + let(:params) do + { allow: ['2001:db8:1::', + '2001:db8:2::/64', + '192.0.2.129', + '192.0.2.0/25', + '192\.0\.2'] + } + end + it { should compile.with_all_deps } + it do + should contain_file(munin_node_conf) + .with_content(/^cidr_allow 192.0.2.0\/25$/) + .with_content(/^cidr_allow 2001:db8:2::\/64$/) + .with_content(/^allow \^192\\.0\\.2\\.129\$$/) + .with_content(/^allow 192\\.0\\.2$/) + .with_content(/^allow \^2001:db8:1::\$$/) + end + end + + context 'with parameter host_name' do + let(:params) do + { host_name: 'something.example.com' } + end + it { should compile.with_all_deps } + it do + should contain_file(munin_node_conf) + .with_content(/host_name\s+something.example.com/) + end + end + + context 'with parameter service_ensure' do + let(:params) do + { service_ensure: 'running' } + end + it { should compile.with_all_deps } + it do + should contain_service('munin-node') + .with_ensure('running') + end + end + + context 'logging to syslog' do + context 'defaults' do + let(:params) do + { log_destination: 'syslog' } + end + it{ should compile.with_all_deps } + it do + should contain_file(munin_node_conf) + .with_content(/log_file\s+Sys::Syslog/) + end + end + + context 'with syslog options' do + let(:params) do + { log_destination: 'syslog', + syslog_facility: 'local1', + } + end + it{ should compile.with_all_deps } + it do + should contain_file(munin_node_conf) + .with_content(/log_file\s+Sys::Syslog/) + .with_content(/syslog_facility\s+local1/) + end + end + + context 'with syslog_facility set to wrong value ' do + let(:params) do + { log_destination: 'syslog', + syslog_facility: 'wrong', + } + end + it { expect { should compile.with_all_deps }.to raise_error(/validate_re/) } + end + end + + context 'purge_configs' do + context 'set' do + let(:params) { { purge_configs: true } } + it { should compile.with_all_deps } + it do should contain_file(munin_plugin_dir) + .with_ensure('directory') + .with_recurse(true) + .with_purge(true) + end + it do should contain_file(munin_plugin_conf_dir) + .with_ensure('directory') + .with_recurse(true) + .with_purge(true) + end + end + context 'unset' do + it { should compile.with_all_deps } + it { should_not contain_file(munin_plugin_dir) } + it { should_not contain_file(munin_plugin_conf_dir) } + end + end + + context 'timeout' do + context 'set' do + let(:params) { { timeout: 123 } } + it { should compile.with_all_deps } + it do should contain_file(munin_node_conf) + .with_content(/^timeout 123/) + end + end + context 'unset' do + it { should compile.with_all_deps } + it do should contain_file(munin_node_conf) + .without_content(/^timeout/) + end + end + end - [ :SmartOS ].each do |sc| - context "Check for supported operatingsystem #{sc}" do - include_context sc - it { should compile } - it { should contain_class('munin::node') } - it { - should contain_package('munin-node') - should contain_service('smf:/munin-node') - should contain_file('/opt/local/etc/munin/munin-node.conf') - } end end context 'unsupported' do include_context :unsupported it { expect { should contain_class('munin::node') }.to raise_error(Puppet::Error, /Unsupported osfamily/) } end - context 'acl with ipv4 and ipv6 addresses' do - include_context :Debian - let(:params) do - { allow: ['2001:db8:1::', - '2001:db8:2::/64', - '192.0.2.129', - '192.0.2.0/25', - '192\.0\.2'] - } - end - it do - should contain_file('/etc/munin/munin-node.conf') - .with_content(/^cidr_allow 192.0.2.0\/25$/) - .with_content(/^cidr_allow 2001:db8:2::\/64$/) - .with_content(/^allow \^192\\.0\\.2\\.129\$$/) - .with_content(/^allow 192\\.0\\.2$/) - .with_content(/^allow \^2001:db8:1::\$$/) - end - end - - context 'with host_name unset' do - include_context :Debian - it do - should contain_file('/etc/munin/munin-node.conf') - .with_content(/host_name\s+testnode.example.com/) - end - end - - context 'with host_name set' do - include_context :Debian - let(:params) do - { host_name: 'something.example.com' } - end - it do - should contain_file('/etc/munin/munin-node.conf') - .with_content(/host_name\s+something.example.com/) - end - end - end diff --git a/spec/defines/munin_plugin_spec.rb b/spec/defines/munin_plugin_spec.rb index 9d9cd6a..dbf36da 100644 --- a/spec/defines/munin_plugin_spec.rb +++ b/spec/defines/munin_plugin_spec.rb @@ -1,108 +1,143 @@ require 'spec_helper' -describe 'munin::plugin', :type => 'define' do - - let(:title) { 'testplugin' } - - context 'with no parameters' do - include_context :Debian - it { - expect { - should contain_file('/etc/munin/plugins/testplugin') - }.to raise_error("expected that the catalogue would contain File[/etc/munin/plugins/testplugin]") +_conf_dir = {} +_conf_dir.default = '/etc/munin' +_conf_dir['Solaris'] = '/opt/local/etc/munin' +_conf_dir['FreeBSD'] = '/usr/local/etc/munin' - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf').with_ensure('absent') - } - end - - context 'with ensure=link parameter' do - include_context :Debian - let(:params) { { :ensure => 'link' } } - it { - should contain_file('/etc/munin/plugins/testplugin').with_ensure('link').with_target('/usr/share/munin/plugins/testplugin') - - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf').with_ensure('absent') - } - end +_share_dir = {} +_share_dir.default = '/usr/share/munin' +_share_dir['Solaris'] = '/opt/local/share/munin' +_share_dir['FreeBSD'] = '/usr/local/share/munin' - context 'with ensure=link and target parameters' do - include_context :Debian - let (:title) { 'test_foo' } - let (:params) { - { :ensure => 'link', - :target => 'test_' } - } - - it { - should contain_file('/etc/munin/plugins/test_foo').with_ensure('link').with_target('/usr/share/munin/plugins/test_') - - should contain_file('/etc/munin/plugin-conf.d/test_foo.conf').with_ensure('absent') - } - end - - context 'with ensure=present and source parameters' do - include_context :SmartOS - let(:params) { - { :ensure => 'present', - :source => 'puppet:///modules/munin/plugins/testplugin' } - } - - it { - - expect { - should contain_file('/opt/local/etc/munin/plugins/testplugin').with_ensure('present').with_source('puppet:///modules/munin/plugins/testplugin') - } - should contain_file('/opt/local/etc/munin/plugin-conf.d/testplugin.conf').with_ensure('absent') - } - end - - context 'with ensure=present, source and config parameters' do - include_context :Debian - let(:params) { - { :ensure => 'present', - :source => 'puppet:///modules/munin/plugins/testplugin', - :config => [ 'something wonderful' ], - } - } - - it { - should contain_file('/etc/munin/plugins/testplugin').with_ensure('present').with_source('puppet:///modules/munin/plugins/testplugin') - - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf').with_ensure('present').with_content(/something wonderful/) - } - end - - context 'only configuration' do - include_context :Debian - let (:params) { - { :config => ['env.rootdn cn=admin,dc=example,dc=org'], - :config_label => 'slapd_*', - } - } - - it { - - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf').with_ensure('present').with_content(/env.rootdn/) - - expect { - should contain_file('/etc/munin/plugins/testplugin') - }.to raise_error("expected that the catalogue would contain File[/etc/munin/plugins/testplugin]") - - } - end +describe 'munin::plugin', :type => 'define' do - context 'with absolute target' do - include_context :Debian + let(:title) { 'testplugin' } - let(:params) do - { ensure: 'link', - target: '/full/path/to/testplugin' } - end + on_supported_os.each do |os, facts| + + # Avoid testing on distributions similar to RedHat and Debian + next if /^(ubuntu|centos|scientific|oraclelinux)-/.match(os) + + # No need to test all os versions as long as os version is not + # used in the params class + next if /^(debian-[67]|redhat-[56]|freebsd-9)-/.match(os) + + context "on #{os}" do + let(:facts) do + facts + end + + conf_dir = _conf_dir[facts[:osfamily]] + plugin_share_dir = "#{_share_dir[facts[:osfamily]]}/plugins" + + context 'with no parameters' do + it do + expect { should contain_file("#{conf_dir}/plugins/testplugin") } + .to raise_error("expected that the catalogue would contain File[#{conf_dir}/plugins/testplugin]") + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_ensure('absent') + end + end + + context 'with ensure=link parameter' do + let(:params) { { :ensure => 'link' } } + it do + should contain_file("#{conf_dir}/plugins/testplugin") + .with_ensure('link') + .with_target("#{plugin_share_dir}/testplugin") + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_ensure('absent') + end + end + + context 'with ensure=link and target parameters' do + let (:title) { 'test_foo' } + let (:params) do + { :ensure => 'link', + :target => 'test_' } + end + it do + should contain_file("#{conf_dir}/plugins/test_foo") + .with_ensure('link') + .with_target("#{plugin_share_dir}/test_") + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/test_foo.conf") + .with_ensure('absent') + end + end + + context 'with ensure=present and source parameters' do + let(:params) do + { :ensure => 'present', + :source => 'puppet:///modules/munin/plugins/testplugin' } + end + it do + should contain_file("#{conf_dir}/plugins/testplugin") + .with_ensure('present') + .with_source('puppet:///modules/munin/plugins/testplugin') + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_ensure('absent') + end + end + + context 'with ensure=present, source and config parameters' do + let(:params) do + { :ensure => 'present', + :source => 'puppet:///modules/munin/plugins/testplugin', + :config => [ 'something wonderful' ], + } + end + it do + should contain_file("#{conf_dir}/plugins/testplugin") + .with_ensure('present') + .with_source('puppet:///modules/munin/plugins/testplugin') + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_ensure('present') + .with_content(/something wonderful/) + end + end + + context 'only configuration' do + let (:params) do + { :config => ['env.rootdn cn=admin,dc=example,dc=org'], + :config_label => 'slapd_*', + } + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_ensure('present') + .with_content(/env.rootdn/) + + end + it do + expect { should contain_file("#{conf_dir}/plugins/testplugin") } + .to raise_error("expected that the catalogue would contain File[#{conf_dir}/plugins/testplugin]") + end + end + + context 'with absolute target' do + let(:params) do + { ensure: 'link', + target: '/full/path/to/testplugin' } + end + it do + should contain_file("#{conf_dir}/plugins/testplugin") + .with_ensure('link') + .with_target('/full/path/to/testplugin') + end + end - it do - should contain_file('/etc/munin/plugins/testplugin') - .with_ensure('link') - .with_target('/full/path/to/testplugin') end end + end diff --git a/spec/defines/regression_13_munin_plugin_config_name_spec.rb b/spec/defines/regression_13_munin_plugin_config_name_spec.rb index f9a01b8..862327c 100644 --- a/spec/defines/regression_13_munin_plugin_config_name_spec.rb +++ b/spec/defines/regression_13_munin_plugin_config_name_spec.rb @@ -1,30 +1,52 @@ require 'spec_helper' -describe 'munin::plugin' do +_conf_dir = {} +_conf_dir.default = '/etc/munin' +_conf_dir['Solaris'] = '/opt/local/etc/munin' +_conf_dir['FreeBSD'] = '/usr/local/etc/munin' - include_context :Debian +describe 'munin::plugin' do let(:title) { 'testplugin' } - context 'with config_label unset, label should be set to title' do - let(:params) do - { config: ['env.foo bar'] } - end + on_supported_os.each do |os, facts| - it do - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf') - .with_content(/^\[testplugin\]$/) - end - end + # Avoid testing on distributions similar to RedHat and Debian + next if /^(ubuntu|centos|scientific|oraclelinux)-/.match(os) + + # No need to test all os versions as long as os version is not + # used in the params class + next if /^(debian-[67]|redhat-[56]|freebsd-9)-/.match(os) + + context "on #{os}" do + let(:facts) do + facts + end + + conf_dir = _conf_dir[facts[:osfamily]] + + context 'with config_label unset, label should be set to title' do + let(:params) do + { config: ['env.foo bar'] } + end + + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_content(/^\[testplugin\]$/) + end + end + + context 'with config_label set, label should be set to config_label' do + let(:params) do + { config: ['env.foo bar'], + config_label: 'foo_' } + end + it do + should contain_file("#{conf_dir}/plugin-conf.d/testplugin.conf") + .with_content(/^\[foo_\]$/) + end + end - context 'with config_label set, label should be set to config_label' do - let(:params) do - { config: ['env.foo bar'], - config_label: 'foo_' } - end - it do - should contain_file('/etc/munin/plugin-conf.d/testplugin.conf') - .with_content(/^\[foo_\]$/) - end + end # on os end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c0b921b..bc2982e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,34 +1,11 @@ require 'puppetlabs_spec_helper/module_spec_helper' +require 'rspec-puppet-facts' +include RspecPuppetFacts RSpec.configure do |c| - c.default_facts = { - :operatingsystem => 'Debian', - :osfamily => 'Debian', - :fqdn => 'testnode.example.com', - } + c.fail_fast = true end - shared_context :unsupported do - let(:facts) { { :osfamily => 'Unsupported', } } -end - -shared_context :Debian do -end - -shared_context :Ubuntu do - let(:facts) { { :operatingsystem => 'Ubuntu', } } -end - -shared_context :CentOS do - let(:facts) { { :operatingsystem => 'CentOS', :osfamily => 'RedHat', } } -end - -shared_context :RedHat do - let(:facts) { { :osfamily => 'RedHat', } } + let(:facts) { { osfamily: 'Unsupported' } } end - -shared_context :SmartOS do - let(:facts) { { :operatingsystem => 'SmartOS', :osfamily => 'Solaris', } } -end - diff --git a/templates/master/node.definition.conf.erb b/templates/master/node.definition.conf.erb index 80ad992..99bd0cf 100644 --- a/templates/master/node.definition.conf.erb +++ b/templates/master/node.definition.conf.erb @@ -1,9 +1,9 @@ -# Munin master configuration fragment for <%= title %> +# Munin master configuration fragment for <%= @title %> # # This file is handled by puppet, all modifications will be lost [<%= @title %>] address <%= @address %> <% Array(@config).each do |line| -%> <%= line %> <% end -%> diff --git a/templates/munin-node.conf.erb b/templates/munin-node.conf.erb index 187acd8..3e076b4 100644 --- a/templates/munin-node.conf.erb +++ b/templates/munin-node.conf.erb @@ -1,61 +1,69 @@ # /etc/munin/munin-node.conf - config-file for munin-node # # This file is handled by puppet, any local changes will be lost # <% require 'ipaddr' addresses = [] unrecognized = [] Array(@allow).flatten.each do |line| begin a = IPAddr.new(line) if a.ipv4? or a.ipv6? addresses << line end rescue ArgumentError, IPAddr::InvalidAddressError # Treat invalid addresses as "allow" arguments, as they can be # regular expressions. unrecognized << line end end -%> host_name <%= @host_name %> log_level 4 -log_file <%= @log_dir %>/munin-node.log +log_file <%= @_log_file %> +<% if @log_destination == 'syslog' -%> +<% if @syslog_facility -%> +syslog_facility <%= @syslog_facility %> +<% end -%> +<% end -%> port 4949 pid_file /var/run/munin/munin-node.pid background 1 setsid 1 # Which port to bind to; user root group <%= @file_group %> # Regexps for files to ignore ignore_file ~$ ignore_file \.bak$ ignore_file %$ ignore_file \.dpkg-(tmp|new|old|dist)$ ignore_file \.rpm(save|new)$ ignore_file \.puppet-bak$ # Hosts to allow <% addresses.each do |line| -%> <% if line.match(/\//) -%> cidr_allow <%= line %> <% else -%> allow ^<%= Regexp.quote(line) %>$ <% end -%> <% end -%> <% unrecognized.each do |line| -%> allow <%= line %> <% end -%> +<% if @timeout -%> +timeout <%= @timeout %> +<% end -%> <% Array(@nodeconfig).each do |line| -%> <%= line %> <% end -%>