diff --git a/data/common.yaml b/data/common.yaml new file mode 100644 index 0000000..e623008 --- /dev/null +++ b/data/common.yaml @@ -0,0 +1,25 @@ +--- +# Controlling puppet +munin::master::collect_nodes: "enabled" +munin::master::node_definitions: {} + +# For munin configuration +munin::master::host_name: "%{trusted.certname}" +munin::master::graph_strategy: "cgi" +munin::master::html_strategy: "cgi" +munin::master::extra_config: [] +munin::master::tls: "disabled" +munin::master::tls_certificate: "%{lookup(munin::master::config_root)}/cert.pem" +munin::master::tls_private_key: "%{lookup(munin::master::config_root)}/key.pem" +munin::master::tls_verify_certificate: "yes" + +munin::master::dbdir: :undef +munin::master::rundir: :undef +munin::master::htmldir: :undef +munin::master::logdir: :undef + +# OS support +munin::master::config_root: "/etc/munin" + +munin::master::file_group: "root" +munin::master::package_name: "munin" diff --git a/data/osfamily/ArchLinux.yaml b/data/osfamily/ArchLinux.yaml new file mode 100644 index 0000000..a304355 --- /dev/null +++ b/data/osfamily/ArchLinux.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: "/etc/munin" +munin::master::file_group: "root" +munin::master::package_name: "munin" diff --git a/data/osfamily/Debian.yaml b/data/osfamily/Debian.yaml new file mode 100644 index 0000000..a304355 --- /dev/null +++ b/data/osfamily/Debian.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: "/etc/munin" +munin::master::file_group: "root" +munin::master::package_name: "munin" diff --git a/data/osfamily/DragonFly.yaml b/data/osfamily/DragonFly.yaml new file mode 100644 index 0000000..2bbf593 --- /dev/null +++ b/data/osfamily/DragonFly.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: '/usr/local/etc/munin' +munin::master::file_group: 'wheel' +munin::master::package_name: 'munin-master' diff --git a/data/osfamily/FreeBSD.yaml b/data/osfamily/FreeBSD.yaml new file mode 100644 index 0000000..2bbf593 --- /dev/null +++ b/data/osfamily/FreeBSD.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: '/usr/local/etc/munin' +munin::master::file_group: 'wheel' +munin::master::package_name: 'munin-master' diff --git a/data/osfamily/RedHat.yaml b/data/osfamily/RedHat.yaml new file mode 100644 index 0000000..a0cdc4a --- /dev/null +++ b/data/osfamily/RedHat.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: '/etc/munin' +munin::master::file_group: 'root' +munin::master::package_name: 'munin' diff --git a/data/osfamily/Solaris.yaml b/data/osfamily/Solaris.yaml new file mode 100644 index 0000000..8fa4846 --- /dev/null +++ b/data/osfamily/Solaris.yaml @@ -0,0 +1,4 @@ +--- +munin::master::config_root: '/opt/local/etc/munin' +munin::master::file_group: 'root' +munin::master::package_name: 'munin' diff --git a/hiera.yaml b/hiera.yaml new file mode 100644 index 0000000..a918995 --- /dev/null +++ b/hiera.yaml @@ -0,0 +1,12 @@ +--- +version: 5 +defaults: + datadir: data + data_hash: yaml_data + +hierarchy: + - name: "OS Family" + path: "osfamily/%{facts.os.family}.yaml" + + - name: "Common data" + path: "common.yaml" diff --git a/manifests/master.pp b/manifests/master.pp index 620565f..9915ad5 100644 --- a/manifests/master.pp +++ b/manifests/master.pp @@ -1,168 +1,133 @@ # @summary configure a munin master # # @see http://guide.munin-monitoring.org/en/latest/ # # @example Basic usage # include munin::master # # @example With TLS # class { 'munin::master': # tls => 'enabled', # tls_certificate => '/path/to/tls/certificate', # tls_private_key => '/path/to/tls/key', # } # # The munin master will install munin, and collect all exported munin # node definitions as files into /etc/munin/munin-conf.d/. # # Parameters: # # @param node_definitions [Hash] A hash of node definitions used by # create_resources to make static node definitions. # # @param host_name [String] A host name for this munin master, matched # with munin::node::mastername for collecting nodes. Defaults to # $::fqdn # # @param graph_strategy [Enum['cgi','cron']] '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) # # @param html_strategy [Enum['cgi','cron']] '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) # # @param config_root [String] the root directory of the munin master # configuration. Default: /etc/munin on most platforms. # # @param file_group [String] The group name for configuration file # permissions. # # @param collect_nodes [Enum['enabled','disabled', # 'mine','unclaimed']] '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. # # @param dbdir [String] Path to the munin dbdir, where munin stores # everything. # # @param htmldir [String] Path to where munin will generate HTML # documents and graphs, used if graph_strategy is cron. # # @param rundir [String] Path to directory munin uses for pid and lock # files. # # @param logdir [String] Path to directory munin uses for log files. # # @param package_name [String] The package name used for installing # the munin master. # # @param tls [Enum['enabled','disabled']] 'enabled' or 'disabled' # (default). Controls the use of TLS globally for master to node # communications. # # @param tls_certificate [String] Path to a file containing a TLS # certificate. No default. Required if tls is enabled. # # @param tls_private_key [String] Path to a file containing a TLS # key. No default. Required if tls is enabled. # # @param tls_verify_certificate [Enum['yes','no']] 'yes' (default) or # 'no'. # # @param extra_config [Array] Extra lines of config to put in # munin.conf. class munin::master ( - $node_definitions = $munin::params::master::node_definitions, - $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, - $file_group = $munin::params::master::file_group, - $package_name = $munin::params::master::package_name, - $extra_config = $munin::params::master::extra_config, - ) inherits munin::params::master { + Hash $node_definitions, + Enum['cgi', 'cron'] $graph_strategy, + Enum['cgi', 'cron'] $html_strategy, + Stdlib::Absolutepath $config_root, + Enum['enabled', 'disabled', 'mine', 'unclaimed'] $collect_nodes, + Optional[Stdlib::Absolutepath] $dbdir, + Optional[Stdlib::Absolutepath] $htmldir, + Optional[Stdlib::Absolutepath] $logdir, + Optional[Stdlib::Absolutepath] $rundir, + Enum['enabled', 'disabled'] $tls, + Stdlib::Absolutepath $tls_certificate, + Stdlib::Absolutepath $tls_private_key, + Enum['yes','no'] $tls_verify_certificate, + Stdlib::Host $host_name, + String $file_group, + Variant[String,Array[String]] $package_name, + Array[String] $extra_config, +) { - 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_string($file_group) - - validate_string($package_name) - - validate_array($extra_config) - - # The munin package and configuration package { $package_name: - ensure => latest, + ensure => installed, } File { owner => 'root', group => $file_group, mode => '0644', require => Package[$package_name], } 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 != 'disabled' { + if $settings::storeconfigs == 'true' { 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 index 149be33..349eb7b 100644 --- a/manifests/master/collect.pp +++ b/manifests/master/collect.pp @@ -1,35 +1,35 @@ # @summary Helper class to collect the exported munin nodes. # # This is separated into its own class to avoid warnings about missing # storeconfigs. # # @api private # # @param collect_nodes[Enum['enabled','mine', 'unclaimed','disabled']] # -# @param host_name [String] Host named used for selecting exported +# @param host_name [Stdlib::Host] Host named used for selecting exported # resources to collect. class munin::master::collect ( - $collect_nodes, - $host_name, + Enum['enabled', 'disabled', 'mine', 'unclaimed'] $collect_nodes, + Stdlib::Host $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/master/node_definition.pp b/manifests/master/node_definition.pp index 2a3cee1..4075ebf 100644 --- a/manifests/master/node_definition.pp +++ b/manifests/master/node_definition.pp @@ -1,40 +1,34 @@ # @summary Configure information about a munin node on the munin # master # # The title of the defined resource should be a munin FQN, # ('hostname', 'group;hostname', 'group;subgroup;hostname'). If a # group is not set, munin will by default use the domain of the node # as a group. # # @param address [String] The address of the munin node. A hostname, # an IP address, or a ssh:// uri for munin-async node. # # @param mastername [String] The name of the munin master server which # will collect the node definition. # # @param config [Array[String]] An array of configuration lines to be # added to the node definition. # define munin::master::node_definition ( - $address, - $mastername='', - $config=[], + String $address, + Optional[String] $mastername='', + Array[String] $config=[], ) { - include ::munin::params::master - - $config_root = $munin::params::master::config_root - - validate_string($address) - validate_array($config) - validate_string($config_root) + $config_root = lookup('munin::master::config_root', Stdlib::Absolutepath) $filename=sprintf('%s/munin-conf.d/node.%s.conf', $config_root, regsubst($name, '[^[:alnum:]\.]', '_', 'IG')) file { $filename: content => template('munin/master/node.definition.conf.erb'), } } diff --git a/manifests/params/master.pp b/manifests/params/master.pp deleted file mode 100644 index 747f55b..0000000 --- a/manifests/params/master.pp +++ /dev/null @@ -1,43 +0,0 @@ -# Parameters for the munin::master class. Add support for new OS -# families here. -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 { - 'Archlinux', - 'Debian', - 'RedHat': { - $config_root = '/etc/munin' - $file_group = 'root' - $package_name = 'munin' - } - 'Solaris': { - $config_root = '/opt/local/etc/munin' - $file_group = 'root' - $package_name = 'munin' - } - 'DragonFly', 'FreeBSD': { - $config_root = '/usr/local/etc/munin' - $file_group = 'wheel' - $package_name = 'munin-master' - } - default: { - fail($message) - } - } -} diff --git a/spec/classes/munin_master_spec.rb b/spec/classes/munin_master_spec.rb index df595a7..4eb59c6 100644 --- a/spec/classes/munin_master_spec.rb +++ b/spec/classes/munin_master_spec.rb @@ -1,192 +1,155 @@ require 'spec_helper' t_conf_dir = {} t_conf_dir.default = '/etc/munin' t_conf_dir['Solaris'] = '/opt/local/etc/munin' t_conf_dir['FreeBSD'] = '/usr/local/etc/munin' t_package = {} t_package.default = 'munin' t_package['FreeBSD'] = 'munin-master' describe 'munin::master' do on_supported_os.each do |os, facts| # Avoid testing on distributions similar to RedHat and Debian next if os =~ %r{^(ubuntu|centos|scientific|oraclelinux)-} context "on #{os}" do let(:facts) do facts end conf_dir = t_conf_dir[facts[:osfamily]] package = t_package[facts[:osfamily]] it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package(package) } context 'with default params' do it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{graph_strategy\s+cgi}) .with_content(%r{html_strategy\s+cgi}) end it do is_expected.to contain_file("#{conf_dir}/munin-conf.d") .with_ensure('directory') end end context 'with html_strategy => cron' do let(:params) { { html_strategy: 'cron' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{html_strategy\s+cron}) end end context 'with graph_strategy => cron' do let(:params) { { graph_strategy: 'cron' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{graph_strategy\s+cron}) end end context 'with dbdir => /var/lib/munin' do let(:params) { { dbdir: '/var/lib/munin' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{dbdir\s+/var/lib/munin}) end end context 'with htmldir => /var/www/munin' do let(:params) { { htmldir: '/var/www/munin' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{htmldir\s+/var/www/munin}) end end context 'with logdir => /var/log/munin' do let(:params) { { dbdir: '/var/log/munin' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{dbdir\s+/var/log/munin}) end end context 'with rundir => /var/run/munin' do let(:params) { { dbdir: '/var/run/munin' } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{dbdir\s+/var/run/munin}) end end context 'with tls => enabled' do let(:params) do { tls: 'enabled', tls_certificate: '/path/to/certificate.pem', tls_private_key: '/path/to/key.pem', tls_verify_certificate: 'yes', } end it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{tls = enabled}) .with_content(%r{tls_certificate = /path/to/certificate\.pem}) .with_content(%r{tls_private_key = /path/to/key\.pem}) .with_content(%r{tls_verify_certificate = yes}) end end context 'with node_definitions' do let(:params) do { node_definitions: { 'node-a' => { 'address' => 'munin://node-a.example.com', }, 'node-b' => { 'address' => 'munin://node-b.example.com', }, }, } end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_munin__master__node_definition('node-a') } it { is_expected.to contain_munin__master__node_definition('node-b') } end context 'with extra_config' do token = '1b7febce-bb2d-4c18-b889-84c73538a900' let(:params) do { extra_config: [token] } end it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file("#{conf_dir}/munin.conf") .with_content(%r{#{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 { is_expected.to raise_error(Puppet::Error, %r{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 =~ %r{invalid} - it { is_expected.to raise_error(Puppet::Error, %r{valid domain name}) } - else - it { is_expected.to compile.with_all_deps } - end - end - end - - ['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 { is_expected.to raise_error(Puppet::Error, %r{validate_re}) } - else - it { is_expected.to compile.with_all_deps } - end - end - end end end end