diff --git a/README.md b/README.md
index 1f987247f..e264b24fb 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ documentation for each plugin for configurable attributes.
* `nginx` (see [collectd::plugin::nginx](#class-collectdpluginnginx) below)
* `ntpd` (see [collectd::plugin::ntpd](#class-collectdpluginntpd) below)
* `openvpn` (see [collectd::plugin::openvpn](#class-collectdpluginopenvpn) below)
+* `perl` (see [collectd::plugin::perl](#class-collectdpluginperl) below)
* `ping` (see [collectd::plugin::ping](#class-collectdpluginping) below)
* `postgresql` (see [collectd::plugin::postgresql](#class-collectdpluginpostgresql) below)
* `processes` (see [collectd::plugin:processes](#class-collectdpluginprocesses) below)
@@ -383,6 +384,74 @@ class { 'collectd::plugin::openvpn':
}
```
+####Class: `collectd::plugin::perl`
+
+This class has no parameters and will load the actual perl plugin.
+It will be automatically included if any `perl::plugin` is defined.
+
+#####Example:
+```puppet
+include collectd::plugin::perl
+```
+
+####Define: `collectd::plugin::perl::plugin`
+
+This define will load a new perl plugin.
+
+#####Parameters:
+
+* `module` (String): name of perl module to load (mandatory)
+* `enable_debugger` (False or String): whether to load the perl debugger. See *collectd-perl* manpage for more details.
+* `include_dir` (String or Array): directories to add to *@INC*
+* `provider` (`"package"`,`"cpan"`,`"file"` or `false`): method to get the plugin code
+* `source` (String): this parameter is consumed by the provider to infer the source of the plugin code
+* `destination (String or false): path to plugin code if `provider` is `file`. Ignored otherwise.
+* `order` (String containing numbers): order in which the plugin should be loaded. Defaults to `"00"`
+* `config` (Hash): plugin configuration in form of a hash. This will be converted to a suitable structure understood by *liboconfig* which is the *collectd* configuration parser. Defaults to `{}`
+
+#####Examples:
+
+######Using a preinstalled plugin:
+```puppet
+collectd::plugin::perl::plugin { 'foo':
+ module => 'Collectd::Plugins::Foo',
+ enable_debugger => "",
+ include_dir => '/usr/lib/collectd/perl5/lib',
+}
+```
+
+######Using a plugin from a file from *source*:
+```puppet
+collectd::plugin::perl::plugin { 'baz':
+ module => 'Collectd::Plugins::Baz',
+ provider => 'file',
+ source => 'puppet:///modules/myorg/baz_collectd.pm',
+ destination => '/path/to/my/perl5/modules'
+}
+```
+
+######Using a plugin from cpan (requires the [puppet cpan module](https://forge.puppetlabs.com/meltwater/cpan)):
+```puppet
+collectd::plugin::perl::plugin {
+ 'openafs_vos':
+ module => 'Collectd::Plugins::OpenAFS::VOS',
+ provider => 'cpan',
+ source => 'Collectd::Plugins::OpenAFS',
+ config => {'VosBin' => '/usr/afsws/etc/vos'},
+}
+```
+
+######Using a plugin from package source:
+```puppet
+collectd::plugin::perl::plugin {
+ 'bar':
+ module => 'Collectd::Plugins::Bar',
+ provider => 'package',
+ source => 'perl-Collectd-Plugins-Bar',
+ config => {'foo' => 'bar'},
+}
+```
+
####Class: `collectd::plugin::ping`
```puppet
diff --git a/files/tests/Foo.pm b/files/tests/Foo.pm
new file mode 100644
index 000000000..e69de29bb
diff --git a/manifests/plugin/perl.pp b/manifests/plugin/perl.pp
new file mode 100644
index 000000000..e093e05e9
--- /dev/null
+++ b/manifests/plugin/perl.pp
@@ -0,0 +1,21 @@
+# See http://collectd.org/documentation/manpages/collectd-perl.5.shtml
+class collectd::plugin::perl ()
+{
+ include collectd::params
+ $conf_dir = $collectd::params::plugin_conf_dir
+ $filename = "${conf_dir}/perl.conf"
+ file { $filename:
+ mode => '0644',
+ owner => $collectd::params::root_user,
+ group => $collectd::params::root_group,
+ notify => Service['collectd'],
+ content => template('collectd/plugin/perl.conf.erb'),
+ }
+ file { "${conf_dir}/perl":
+ ensure => directory,
+ mode => '0755',
+ owner => $collectd::params::root_user,
+ group => $collectd::params::root_group,
+ }
+}
+
diff --git a/manifests/plugin/perl/plugin.pp b/manifests/plugin/perl/plugin.pp
new file mode 100644
index 000000000..5ab1e26bf
--- /dev/null
+++ b/manifests/plugin/perl/plugin.pp
@@ -0,0 +1,77 @@
+#
+define collectd::plugin::perl::plugin (
+ $module,
+ $enable_debugger = false,
+ $include_dir = false,
+ $provider = false,
+ $source = false,
+ $destination = false,
+ $order = '01',
+ $config = {},
+) {
+ include collectd::params
+ if ! defined(Class['Collectd::Plugin::Perl']) {
+ include collectd::plugin::perl
+ }
+
+ validate_hash($config)
+ validate_re($order, '\d+')
+ if $enable_debugger {
+ validate_string($enable_debugger)
+ }
+ if $include_dir {
+ if is_string($include_dir) {
+ $include_dirs = [ $include_dir ]
+ } elsif is_array($include_dir) {
+ $include_dirs = $include_dir
+ } else {
+ fail("include_dir must be either array or string: ${include_dir}")
+ }
+ } else {
+ $include_dirs = []
+ }
+
+ $conf_dir = $collectd::params::plugin_conf_dir
+ $base_filename = $collectd::plugin::perl::filename
+ $filename = "${conf_dir}/perl/plugin-${order}_${name}.conf"
+
+ file { $filename:
+ owner => $collectd::params::root_user,
+ group => $collectd::params::root_group,
+ mode => '0644',
+ content => template('collectd/plugin/perl/plugin.erb'),
+ }
+
+ case $provider {
+ 'package': {
+ validate_string($source)
+ package { $source:
+ require => File[$base_filename],
+ }
+ }
+ 'cpan': {
+ validate_string($source)
+ include cpan
+ cpan { $source:
+ require => File[$base_filename],
+ }
+ }
+ 'file': {
+ validate_string($source)
+ validate_string($destination)
+ file { "collectd_plugin_perl_${name}.pm":
+ path => "${destination}/${module}.pm",
+ mode => '0644',
+ source => $source,
+ require => File[$base_filename],
+ }
+ }
+ false: {
+ # this will fail if perl collectd plugin module is not installed
+ exec { "perl -M${module} -e 1": path => $::path }
+ }
+ default: {
+ fail("Unsupported provider: ${provider}. Use 'package', 'cpan', 'file' or false.")
+ }
+ }
+}
diff --git a/templates/plugin/perl.conf.erb b/templates/plugin/perl.conf.erb
new file mode 100644
index 000000000..0f27ee7f5
--- /dev/null
+++ b/templates/plugin/perl.conf.erb
@@ -0,0 +1,7 @@
+#
+
+ Globals true
+
+
+Include "<%= @conf_dir %>/perl/*.conf"
+
diff --git a/templates/plugin/perl/plugin.erb b/templates/plugin/perl/plugin.erb
new file mode 100644
index 000000000..a0a4e0a68
--- /dev/null
+++ b/templates/plugin/perl/plugin.erb
@@ -0,0 +1,48 @@
+
+<% if @enable_debugger -%>
+ EnableDebugger "<% @enable_debugger %>"
+<% end -%>
+<% if @include_dir -%>
+<% @include_dirs.each do |dir| -%>
+ IncludeDir "<%= dir %>"
+<% end -%>
+<% end -%>
+ LoadPlugin "<%= @module %>"
+<% if ! @config.empty? -%>
+ ">
+<% @config.each do |key,value| -%>
+<% if value.is_a?(Array) -%>
+<% value.each do |v| -%>
+ <%= key %> "<%= v %>"
+<% end -%>
+<% elsif value.is_a?(Hash) -%>
+ <<%=key%>>
+<% value.each do |k,v| -%>
+<% if v.is_a?(String) -%>
+ <%=k%> "<%=v%>"
+<% elsif v.is_a?(Array) -%>
+<% v.each do |l| -%>
+ <%= k %> "<%= l %>"
+<% end -%>
+<% elsif v.is_a?(Hash) -%>
+ <<%=k%>>
+<% v.each do |i,j| -%>
+<% if j.is_a?(Array) -%>
+<% j.each do |k| -%>
+ <%=i%> "<%=k%>"
+<% end -%>
+<% else -%>
+ <%=i%> "<%=j%>"
+<% end -%>
+<% end -%>
+ <%=k%>>
+<% end -%>
+<% end -%>
+ <%=key%>>
+<% else -%>
+ <%= key -%> "<%= value -%>"
+<% end -%>
+<% end -%>
+
+<% end -%>
+
diff --git a/tests/plugins/perl.pp b/tests/plugins/perl.pp
new file mode 100644
index 000000000..d14a7aed9
--- /dev/null
+++ b/tests/plugins/perl.pp
@@ -0,0 +1,52 @@
+class { collectd:
+ purge_config => true,
+ purge => true,
+ recurse => true,
+}
+
+include collectd::plugin::perl
+
+collectd::plugin::perl::plugin { 'foo':
+ include_dir => '/tmp',
+ module => 'Collectd::Plugins::Foo',
+ provider => 'file',
+ source => 'puppet:///modules/collectd/tests/Foo.pm',
+ destination => '/tmp',
+ order => 99,
+ config => {
+ 'foo' => 'bar',
+ 'key' => [ 'val1', 'val2' ],
+ }
+}
+
+collectd::plugin::perl::plugin { 'bar':
+ module => 'B',
+ enable_debugger => "DProf",
+ include_dir => ['/tmp', '/tmp/lib' ]
+}
+
+#collectd::plugin::perl {
+# 'openafs_vos':
+# module => 'Collectd::Plugins::OpenAFS::VOS',
+# provider => 'cpan',
+# source => 'Collectd::Plugins::OpenAFS',
+# config => {'VosBin' => '/usr/afsws/etc/vos'},
+#}
+
+collectd::plugin::perl::plugin {
+ 'baar':
+ module => 'Collectd::Plugins::Bar',
+ provider => 'package',
+ source => 'perl-Collectd-Plugins-Bar',
+ config => {
+ 'foo' => 'bar',
+ 'more' => {
+ 'complex' => 'structure',
+ 'no' => [ "a", "b" ],
+ 'yes' => {
+ 'last' => 'level',
+ 'and' => [ "array" , "thing" ]
+ },
+ },
+ },
+}