diff --git a/README.md b/README.md index d21fc828c..89939d8c6 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ documentation for each plugin for configurable attributes. * `memcached`(see [collectd::plugin::memcached](#class-collectdpluginmemcached) below ) * `memory`(see [collectd::plugin::memory](#class-collectdpluginmemory) below ) +* `modbus` (see [collectd::plugin::modbus](#class-collectdpluginmodbus) below) * `mongodb`(see [collectd::plugin::mongodb](#class-collectdpluginmongodb) below ) * `mysql` (see [collectd::plugin::mysql](#class-collectdpluginmysql) below) * `netlink` (see [collectd::plugin::netlink](#class-collectdpluginnetlink) below) @@ -1073,6 +1074,35 @@ class { 'collectd::plugin::memory': } ``` +#### Class: `collectd::plugin::modbus` + +```puppet +class {'collectd::plugin::modbus': + ensure => 'present', + data => { + current_phase_a => { + 'type' => 'gauge', + 'instance' => 'current phase A', + 'register_base' => 1234, + 'register_type' => 'Float', + } + }, + hosts => { + meter123 => { + 'address' => '127.0.0.1', + 'port' => '502', + 'interval' => 10, + 'slaves' => { + 255 => { + 'instance' => 'power meter 255', + 'collect' => ['current_phase_a'], + } + }, + } + }, +} +``` + #### Class: `collectd::plugin::mysql` ```puppet diff --git a/manifests/plugin/modbus.pp b/manifests/plugin/modbus.pp new file mode 100644 index 000000000..41e32f009 --- /dev/null +++ b/manifests/plugin/modbus.pp @@ -0,0 +1,72 @@ +# @summary Creates configuration for a collectd modbus plugin +# +# More information on the modbus plugin configuration options: +# https://collectd.org/wiki/index.php/Plugin:Modbus +# +# @example +# +# class {'collectd::plugin::modbus': +# ensure => 'present', +# data => { +# current_phase_a => { +# 'type' => 'gauge', +# 'instance' => 'current phase A', +# 'register_base' => 1234, +# 'register_type' => 'Float', +# } +# }, +# hosts => { +# meter123 => { +# 'address' => '127.0.0.1', +# 'port' => '502', +# 'interval' => 10, +# 'slaves' => { +# 255 => { +# 'instance' => 'power meter 255', +# 'collect' => ['current_phase_a'], +# } +# }, +# } +# }, +# } +# +# @param ensure +# Ensures modbus module +# @param manage_package +# If enabled, install required packages +# @param data +# Defines data set configuration +# @param hosts +# Defines hosts configuration + +class collectd::plugin::modbus ( + Enum['present', 'absent'] $ensure = 'present', + Optional[Boolean] $manage_package = undef, + Hash[String[1], Collectd::Modbus::Data] $data = {}, + Hash[String[1], Collectd::Modbus::Host] $hosts = {}, +) { + include collectd + + $_manage_package = pick($manage_package, $collectd::manage_package) + + if $facts['os']['family'] == 'RedHat' { + if $_manage_package { + package { 'collectd-modbus': + ensure => $ensure, + } + } + } + + if $facts['os']['family'] == 'Debian' { + if $_manage_package { + package { 'libmodbus5': + ensure => $ensure, + } + } + } + + collectd::plugin { 'modbus': + ensure => $ensure, + content => template('collectd/plugin/modbus.conf.erb'), + } +} diff --git a/spec/classes/collectd_plugin_modbus_spec.rb b/spec/classes/collectd_plugin_modbus_spec.rb new file mode 100644 index 000000000..c8f2d655a --- /dev/null +++ b/spec/classes/collectd_plugin_modbus_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe 'collectd::plugin::modbus', type: :class do + on_supported_os(baseline_os_hash).each do |os, facts| + context "on #{os} " do + let :facts do + facts + end + let :pre_condition do + 'include collectd' + end + + options = os_specific_options(facts) + + context ':ensure => present and dataset for Current Phase A' do + let :params do + { + data: { + 'current_phase_a' => { + 'type' => 'gauge', + 'instance' => 'Current Phase A', + 'register_base' => 1234, + 'register_type' => 'Float', + } + }, + hosts: { + 'power123' => { + 'address' => '127.0.0.1', + 'port' => '502', + 'interval' => 10, + 'slaves' => { + 255 => { + 'instance' => 'power meter 255', + 'collect' => ['current_phase_a'], + } + } + } + } + } + end + + it "Will create #{options[:plugin_conf_dir]}/10-modbus.conf" do + is_expected.to contain_file('modbus.load').with( + ensure: 'present', + path: "#{options[:plugin_conf_dir]}/10-modbus.conf", + content: %r{Data "current_phase_a".+Instance "Current Phase A".+Host "power123".+Slave 255}m + ) + end + end + + context ':ensure => absent' do + let :params do + { + ensure: 'absent', + data: { + 'current_phase_a' => { + 'type' => 'gauge', + 'instance' => 'Current Phase A', + 'register_base' => 1234, + 'register_type' => 'Float', + } + }, + hosts: { + 'power123' => { + 'address' => '127.0.0.1', + 'port' => '502', + 'interval' => 10, + 'slaves' => { + 255 => { + 'instance' => 'power meter 255', + 'collect' => ['current_phase_a'], + } + } + } + } + } + end + + it "Will not create #{options[:plugin_conf_dir]}/10-modbus.conf" do + is_expected.to contain_file('modbus.load').with( + ensure: 'absent', + path: "#{options[:plugin_conf_dir]}/10-modbus.conf" + ) + end + end + end + end +end diff --git a/templates/plugin/modbus.conf.erb b/templates/plugin/modbus.conf.erb new file mode 100644 index 000000000..fe82c1dc8 --- /dev/null +++ b/templates/plugin/modbus.conf.erb @@ -0,0 +1,42 @@ +<% if @data or @hosts -%> + +<% @data.sort_by {|k,v| k}.each do |key,val| -%> + "> + Type "<%= val['type'] %>" +<% if val['instance'] -%> + Instance "<%= val['instance'] %>" +<% end -%> +<% if val['register_base'] -%> + RegisterBase <%= val['register_base'] %> +<% end -%> +<% if val['register_type'] -%> + RegisterType <%= val['register_type'] %> +<% end -%> + +<% end -%> + +<% @hosts.sort_by {|k,v| k}.each do |key,val| -%> + "> + Address "<%= val['address'] %>" +<% if val['port'] -%> + Port <%= val['port'] %> +<% end -%> +<% if val['interval'] -%> + Interval <%= val['interval'] %> +<% end -%> +<% if val['slaves'] -%> +<% Array(val['slaves']).sort_by {|k,v| k}.each do |slave_key,slave_val| -%> + > +<% if slave_val['instance'] -%> + Instance "<%= slave_val['instance'] %>" +<% end -%> +<% Array(slave_val['collect']).sort_by {|x| x}.each do |data_name| -%> + Collect "<%= data_name %>" +<% end -%> + +<% end -%> +<% end -%> + +<% end -%> + +<% end -%> diff --git a/types/modbus/data.pp b/types/modbus/data.pp new file mode 100644 index 000000000..97245affc --- /dev/null +++ b/types/modbus/data.pp @@ -0,0 +1,2 @@ +# +type Collectd::Modbus::Data = Struct[{Optional['instance'] => String, NotUndef['type'] => String[1], NotUndef['register_base'] => Numeric, NotUndef['register_type'] => String[1]}] diff --git a/types/modbus/host.pp b/types/modbus/host.pp new file mode 100644 index 000000000..95122d438 --- /dev/null +++ b/types/modbus/host.pp @@ -0,0 +1,2 @@ +# +type Collectd::Modbus::Host = Struct[{NotUndef['address'] => String[1], NotUndef['port'] => String[1], NotUndef['slaves'] => Hash[Integer, Collectd::Modbus::Slave], Optional['interval'] => Integer[0]}] diff --git a/types/modbus/slave.pp b/types/modbus/slave.pp new file mode 100644 index 000000000..844750cef --- /dev/null +++ b/types/modbus/slave.pp @@ -0,0 +1,2 @@ +# +type Collectd::Modbus::Slave = Struct[{NotUndef['instance'] => String[1], NotUndef['collect'] => Variant[String[1], Array[String[1], 1]]}]