diff --git a/README.md b/README.md index 9acafdd57..6f692d1eb 100644 --- a/README.md +++ b/README.md @@ -1801,6 +1801,42 @@ class { '::collectd::plugin::thermal': ```puppet class { 'collectd::plugin::threshold': + hosts => [ + { + name => 'example.com', + plugins => [ + { + name => 'load', + types => [ + { + name => 'load', + data_source => 'shortterm', + warning_max => $facts.dig('processors', 'count') * 1.2, + failure_max => $facts.dig('processors', 'count') * 1.9, + }, + { + name => 'load', + data_source => 'midterm', + warning_max => $facts.dig('processors', 'count') * 1.1, + failure_max => $facts.dig('processors', 'count') * 1.7, + }, + { + name => 'load', + data_source => 'longterm', + warning_max => $facts.dig('processors', 'count'), + failure_max => $facts.dig('processors', 'count') * 1.5, + }, + ], + }, + ], + }, + ], + plugins => [ + # See plugin definition above + ], + types => [ + # See types definition above + ], } ``` diff --git a/functions/indent.pp b/functions/indent.pp new file mode 100644 index 000000000..624a79fd1 --- /dev/null +++ b/functions/indent.pp @@ -0,0 +1,4 @@ +function collectd::indent(String $arg) >> String { + $body = regsubst($arg, "\n(.)", "\n \\1", 'G') + " ${body}" +} diff --git a/manifests/plugin/threshold.pp b/manifests/plugin/threshold.pp index 1095ec90b..4bb8db780 100644 --- a/manifests/plugin/threshold.pp +++ b/manifests/plugin/threshold.pp @@ -1,13 +1,17 @@ # http://collectd.org/documentation/manpages/collectd.conf.5.shtml#plugin_threshold class collectd::plugin::threshold ( - $ensure = 'present', - $interval = undef, + Enum['present', 'absent'] $ensure = 'present', + Optional[Integer] $interval = undef, + Array[Collectd::Threshold::Type] $types = [], + Array[Collectd::Threshold::Plugin] $plugins = [], + Array[Collectd::Threshold::Host] $hosts = [], ) { include ::collectd collectd::plugin { 'threshold': ensure => $ensure, + content => epp('collectd/plugin/threshold.conf.epp'), interval => $interval, } } diff --git a/spec/classes/collectd_plugin_threshold_spec.rb b/spec/classes/collectd_plugin_threshold_spec.rb index bc65e278b..db5eb569d 100644 --- a/spec/classes/collectd_plugin_threshold_spec.rb +++ b/spec/classes/collectd_plugin_threshold_spec.rb @@ -7,6 +7,66 @@ facts end + let :custom_params do + { + 'types' => [ + { + 'name' => 'foo', + 'warning_min' => 0.00, + 'warning_max' => 1000.00, + 'failure_min' => 0.00, + 'failure_max' => 1200.00, + 'invert' => false, + 'instance' => 'bar' + } + ], + 'plugins' => [ + { + 'name' => 'interface', + 'instance' => 'eth0', + 'types' => [ + { + 'name' => 'if_octets', + 'failure_max' => 10_000_000, + 'data_source' => 'rx' + } + ] + } + ], + 'hosts' => [ + { + 'name' => 'hostname', + 'types' => [ + { + 'name' => 'cpu', + 'instance' => 'idle', + 'failure_min' => 10 + }, + { + 'name' => 'load', + 'data_source' => 'midterm', + 'failure_max' => 4, + 'hits' => 3, + 'hysteresis' => 3 + } + ], + 'plugins' => [ + { + 'name' => 'memory', + 'types' => [ + { + 'name' => 'memory', + 'instance' => 'cached', + 'warning_min' => 100_000_000 + } + ] + } + ] + } + ] + } + end + options = os_specific_options(facts) context ':ensure => present' do context ':ensure => present and default parameters' do @@ -18,6 +78,57 @@ ) end end + + context ':ensure => present and empty configurations' do + let :params do + { + 'hosts' => [ + { + 'name' => 'example.com' + } + ], + 'plugins' => [ + { + 'name' => 'interface' + } + ] + } + end + + it { is_expected.to compile } + end + + context ':ensure => present and custom parameters' do + let :params do + custom_params + end + + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{WarningMin 0\.0}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{WarningMax 1000\.0}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{FailureMin 0\.0}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{FailureMax 1200\.0}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Invert false}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Instance "bar"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Instance "eth0"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{FailureMax 10000000}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{DataSource "rx"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Instance "idle"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{FailureMin 10}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Instance "cached"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{WarningMin 100000000}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{DataSource "midterm"}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{FailureMax 4}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Hits 3}) } + it { is_expected.to contain_file('threshold.load').with(content: %r{Hysteresis 3}) } + end end end end diff --git a/templates/plugin/threshold.conf.epp b/templates/plugin/threshold.conf.epp new file mode 100644 index 000000000..d4f8cb97b --- /dev/null +++ b/templates/plugin/threshold.conf.epp @@ -0,0 +1,11 @@ + + <%- $collectd::plugin::threshold::hosts.lest || { [] }.each |$host| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/host.epp', { host => $host })) -%> + <%- } -%> + <%- $collectd::plugin::threshold::plugins.lest || { [] }.each |$plugin| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/plugin.epp', { plugin => $plugin })) -%> + <%- } -%> + <%- $collectd::plugin::threshold::types.lest || { [] }.each |$type| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/type.epp', { type => $type })) -%> + <%- } -%> + diff --git a/templates/plugin/threshold/host.epp b/templates/plugin/threshold/host.epp new file mode 100644 index 000000000..1ba4cd80b --- /dev/null +++ b/templates/plugin/threshold/host.epp @@ -0,0 +1,8 @@ +"> + <%- $host['plugins'].lest || { [] }.each |$plugin| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/plugin.epp', { plugin => $plugin })) -%> + <%- } -%> + <%- $host['types'].lest || { [] }.each |$type| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/type.epp', { type => $type })) -%> + <%- } -%> + diff --git a/templates/plugin/threshold/plugin.epp b/templates/plugin/threshold/plugin.epp new file mode 100644 index 000000000..ce5f9df9d --- /dev/null +++ b/templates/plugin/threshold/plugin.epp @@ -0,0 +1,8 @@ +"> + <%- if $plugin['instance'] != undef { -%> + Instance "<%= $plugin['instance'] %>" + <%- } -%> + <%- $plugin['types'].lest || { [] }.each |$type| { -%> +<%= collectd::indent(epp('collectd/plugin/threshold/type.epp', { type => $type })) -%> + <%- } -%> + diff --git a/templates/plugin/threshold/type.epp b/templates/plugin/threshold/type.epp new file mode 100644 index 000000000..d6b8fe220 --- /dev/null +++ b/templates/plugin/threshold/type.epp @@ -0,0 +1,41 @@ +"> + <%- if $type['instance'] != undef { -%> + Instance "<%= $type['instance'] %>" + <%- } -%> + <%- if $type['failure_max'] != undef { -%> + FailureMax <%= $type['failure_max'] %> + <%- } -%> + <%- if $type['failure_min'] != undef { -%> + FailureMin <%= $type['failure_min'] %> + <%- } -%> + <%- if $type['warning_max'] != undef { -%> + WarningMax <%= $type['warning_max'] %> + <%- } -%> + <%- if $type['warning_min'] != undef { -%> + WarningMin <%= $type['warning_min'] %> + <%- } -%> + <%- if $type['data_source'] != undef { -%> + DataSource "<%= $type['data_source'] %>" + <%- } -%> + <%- if $type['invert'] != undef { -%> + Invert <%= $type['invert'] %> + <%- } -%> + <%- if $type['persist'] != undef { -%> + Persist <%= $type['persist'] %> + <%- } -%> + <%- if $type['persist_ok'] != undef { -%> + PersistOK <%= $type['persist_ok'] %> + <%- } -%> + <%- if $type['percentage'] != undef { -%> + Percentage <%= $type['percentage'] %> + <%- } -%> + <%- if $type['hits'] != undef { -%> + Hits <%= $type['hits'] %> + <%- } -%> + <%- if $type['hysteresis'] != undef { -%> + Hysteresis <%= $type['hysteresis'] %> + <%- } -%> + <%- if $type['interesting'] != undef { -%> + Interesting <%= $type['interesting'] %> + <%- } -%> + diff --git a/types/threshold/host.pp b/types/threshold/host.pp new file mode 100644 index 000000000..2902722d8 --- /dev/null +++ b/types/threshold/host.pp @@ -0,0 +1,5 @@ +type Collectd::Threshold::Host = Struct[{ + name => String[1], + plugins => Optional[Array[Collectd::Threshold::Plugin]], + types => Optional[Array[Collectd::Threshold::Type]], +}] diff --git a/types/threshold/plugin.pp b/types/threshold/plugin.pp new file mode 100644 index 000000000..e31501f71 --- /dev/null +++ b/types/threshold/plugin.pp @@ -0,0 +1,5 @@ +type Collectd::Threshold::Plugin = Struct[{ + name => String[1], + instance => Optional[String[1]], + types => Optional[Array[Collectd::Threshold::Type]], +}] diff --git a/types/threshold/type.pp b/types/threshold/type.pp new file mode 100644 index 000000000..4cc8cc70d --- /dev/null +++ b/types/threshold/type.pp @@ -0,0 +1,16 @@ +type Collectd::Threshold::Type = Struct[{ + name => String[1], + instance => Optional[String[1]], + failure_max => Optional[Numeric], + warning_max => Optional[Numeric], + failure_min => Optional[Numeric], + warning_min => Optional[Numeric], + data_source => Optional[String[1]], + invert => Optional[Boolean], + persist => Optional[Boolean], + persist_ok => Optional[Boolean], + percentage => Optional[Boolean], + hits => Optional[Integer], + hysteresis => Optional[Integer], + interesting => Optional[Boolean], +}]