diff --git a/REFERENCE.md b/REFERENCE.md
index 8c8de30b..001f2070 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -49,6 +49,7 @@
* [`prometheus::run_service`](#prometheus--run_service): This class is meant to be called from prometheus. It ensure the service is running
* [`prometheus::sachet`](#prometheus--sachet): This module manages prometheus sachet (https://github.com/messagebird/sachet)
* [`prometheus::server`](#prometheus--server): class to manage the actual prometheus server. This class gets called from the init.pp
+* [`prometheus::smartctl_exporter`](#prometheus--smartctl_exporter): This module manages prometheus node smartctl_exporter
* [`prometheus::snmp_exporter`](#prometheus--snmp_exporter): This module manages prometheus snmp_exporter
* [`prometheus::ssh_exporter`](#prometheus--ssh_exporter): This module manages prometheus ssh_exporter (https://github.com/treydock/ssh_exporter)
* [`prometheus::ssl_exporter`](#prometheus--ssl_exporter): This module manages prometheus ssl_exporter (https://github.com/ribbybibby/ssl_exporter)
@@ -12167,6 +12168,403 @@ Data type: `Boolean`
Default value: `$prometheus::manage_init_file`
+### `prometheus::smartctl_exporter`
+
+This module manages prometheus node smartctl_exporter
+
+#### Parameters
+
+The following parameters are available in the `prometheus::smartctl_exporter` class:
+
+* [`arch`](#-prometheus--smartctl_exporter--arch)
+* [`bin_dir`](#-prometheus--smartctl_exporter--bin_dir)
+* [`smartctl_path`](#-prometheus--smartctl_exporter--smartctl_path)
+* [`smartctl_interval`](#-prometheus--smartctl_exporter--smartctl_interval)
+* [`smartctl_rescan`](#-prometheus--smartctl_exporter--smartctl_rescan)
+* [`smartctl_device`](#-prometheus--smartctl_exporter--smartctl_device)
+* [`smartctl_device_exclude`](#-prometheus--smartctl_exporter--smartctl_device_exclude)
+* [`smartctl_device_include`](#-prometheus--smartctl_exporter--smartctl_device_include)
+* [`web_telemetry_path`](#-prometheus--smartctl_exporter--web_telemetry_path)
+* [`web_systemd_socket`](#-prometheus--smartctl_exporter--web_systemd_socket)
+* [`web_listen_address`](#-prometheus--smartctl_exporter--web_listen_address)
+* [`web_config_file`](#-prometheus--smartctl_exporter--web_config_file)
+* [`web_config_content`](#-prometheus--smartctl_exporter--web_config_content)
+* [`log_level`](#-prometheus--smartctl_exporter--log_level)
+* [`log_format`](#-prometheus--smartctl_exporter--log_format)
+* [`download_extension`](#-prometheus--smartctl_exporter--download_extension)
+* [`download_url`](#-prometheus--smartctl_exporter--download_url)
+* [`download_url_base`](#-prometheus--smartctl_exporter--download_url_base)
+* [`extra_groups`](#-prometheus--smartctl_exporter--extra_groups)
+* [`group`](#-prometheus--smartctl_exporter--group)
+* [`init_style`](#-prometheus--smartctl_exporter--init_style)
+* [`install_method`](#-prometheus--smartctl_exporter--install_method)
+* [`manage_group`](#-prometheus--smartctl_exporter--manage_group)
+* [`manage_service`](#-prometheus--smartctl_exporter--manage_service)
+* [`manage_user`](#-prometheus--smartctl_exporter--manage_user)
+* [`os`](#-prometheus--smartctl_exporter--os)
+* [`package_ensure`](#-prometheus--smartctl_exporter--package_ensure)
+* [`package_name`](#-prometheus--smartctl_exporter--package_name)
+* [`purge_config_dir`](#-prometheus--smartctl_exporter--purge_config_dir)
+* [`restart_on_change`](#-prometheus--smartctl_exporter--restart_on_change)
+* [`service_enable`](#-prometheus--smartctl_exporter--service_enable)
+* [`service_ensure`](#-prometheus--smartctl_exporter--service_ensure)
+* [`service_name`](#-prometheus--smartctl_exporter--service_name)
+* [`user`](#-prometheus--smartctl_exporter--user)
+* [`version`](#-prometheus--smartctl_exporter--version)
+* [`proxy_server`](#-prometheus--smartctl_exporter--proxy_server)
+* [`proxy_type`](#-prometheus--smartctl_exporter--proxy_type)
+* [`options`](#-prometheus--smartctl_exporter--options)
+* [`export_scrape_job`](#-prometheus--smartctl_exporter--export_scrape_job)
+* [`scrape_host`](#-prometheus--smartctl_exporter--scrape_host)
+* [`scrape_port`](#-prometheus--smartctl_exporter--scrape_port)
+* [`scrape_job_name`](#-prometheus--smartctl_exporter--scrape_job_name)
+* [`scrape_job_labels`](#-prometheus--smartctl_exporter--scrape_job_labels)
+
+##### `arch`
+
+Data type: `String[1]`
+
+Architecture (See supported archictectures at https://github.com/prometheus-community/smartctl_exporter/releases)
+
+Default value: `$prometheus::real_arch`
+
+##### `bin_dir`
+
+Data type: `Stdlib::Absolutepath`
+
+Directory where binaries are located
+
+Default value: `$prometheus::bin_dir`
+
+##### `smartctl_path`
+
+Data type: `Optional[String[1]]`
+
+Directory where smartctl binary is located, default /usr/sbin/smartctl
+
+Default value: `undef`
+
+##### `smartctl_interval`
+
+Data type: `Optional[String[1]]`
+
+The interval between smartctl polls, default 60s
+
+Default value: `undef`
+
+##### `smartctl_rescan`
+
+Data type: `Optional[String[1]]`
+
+The interval between rescanning for new/disappeared devices. If the interval is smaller than 1s no rescanning takes place.
+If any devices are configured with smartctl.device also no rescanning takes place. Default 10m
+
+Default value: `undef`
+
+##### `smartctl_device`
+
+Data type: `Array[String[1]]`
+
+The list of devices to monitor. If not supplied, the exporter will scan the host for available devices.
+
+Default value: `[]`
+
+##### `smartctl_device_exclude`
+
+Data type: `Optional[String[1]]`
+
+Regexp of devices to exclude from automatic scanning. (mutually exclusive to device-include)
+
+Default value: `undef`
+
+##### `smartctl_device_include`
+
+Data type: `Optional[String[1]]`
+
+Regexp of devices to include for automatic scanning. (mutually exclusive to device-exclude)
+
+Default value: `undef`
+
+##### `web_telemetry_path`
+
+Data type: `Optional[String[1]]`
+
+Path under which to expose metrics. Default is /metrics
+
+Default value: `undef`
+
+##### `web_systemd_socket`
+
+Data type: `Optional[String[1]]`
+
+Use systemd socket activation listeners instead of port listeners (Linux only).
+
+Default value: `undef`
+
+##### `web_listen_address`
+
+Data type: `Array[String[1]]`
+
+Addresses on which to expose metrics and web interface. Repeatable for multiple addresses. Defaults to :9633
+
+Default value: `[]`
+
+##### `web_config_file`
+
+Data type: `Stdlib::Absolutepath`
+
+[EXPERIMENTAL] Path to configuration file that can enable TLS or authentication.
+
+Default value: `'/etc/smartctl_exporter_web-config.yml'`
+
+##### `web_config_content`
+
+Data type: `Optional[Hash]`
+
+Unless empty the content of the web-config yaml which will handed over as option to the exporter
+
+Default value: `undef`
+
+##### `log_level`
+
+Data type: `Optional[Enum['debug','info','warn','error']]`
+
+Only log messages with the given severity or above. One of: [debug, info, warn, error]. Default info
+
+Default value: `undef`
+
+##### `log_format`
+
+Data type: `Optional[Enum['logfmt','json']]`
+
+Output format of log messages. One of: [logfmt, json]. Default logfmt
+
+Default value: `undef`
+
+##### `download_extension`
+
+Data type: `String`
+
+Extension for the release binary archive
+
+Default value: `'tar.gz'`
+
+##### `download_url`
+
+Data type: `Optional[Prometheus::Uri]`
+
+Complete URL corresponding to the where the release binary archive can be downloaded
+
+Default value: `undef`
+
+##### `download_url_base`
+
+Data type: `Prometheus::Uri`
+
+Base URL for the binary archive
+
+Default value: `'https://github.com/prometheus-community/smartctl_exporter/releases'`
+
+##### `extra_groups`
+
+Data type: `Array[String[1]]`
+
+Extra groups to add the binary user to
+
+Default value: `[]`
+
+##### `group`
+
+Data type: `String[1]`
+
+Group under which the binary is running. Default 'root' (or 'wheel' on Darwin), unlikely to work without root.
+
+Default value: `'root'`
+
+##### `init_style`
+
+Data type: `Prometheus::Initstyle`
+
+Service startup scripts style (e.g. rc, upstart or systemd)
+
+Default value: `$prometheus::init_style`
+
+##### `install_method`
+
+Data type: `Prometheus::Install`
+
+Installation method: url or package (only url is supported currently)
+
+Default value: `$prometheus::install_method`
+
+##### `manage_group`
+
+Data type: `Boolean`
+
+Whether to create a group for or rely on external code for that. Default false due to script needing root.
+
+Default value: `false`
+
+##### `manage_service`
+
+Data type: `Boolean`
+
+Should puppet manage the service? (default true)
+
+Default value: `true`
+
+##### `manage_user`
+
+Data type: `Boolean`
+
+Whether to create user or rely on external code for that. Default false due to script needing root.
+
+Default value: `false`
+
+##### `os`
+
+Data type: `String[1]`
+
+Operating system
+
+Default value: `downcase($facts['kernel'])`
+
+##### `package_ensure`
+
+Data type: `String[1]`
+
+If package, then use this for package ensure default 'latest'
+
+Default value: `'latest'`
+
+##### `package_name`
+
+Data type: `String[1]`
+
+The binary package name - not available yet
+
+Default value: `'smartctl_exporter'`
+
+##### `purge_config_dir`
+
+Data type: `Boolean`
+
+Purge config files no longer generated by Puppet
+
+Default value: `true`
+
+##### `restart_on_change`
+
+Data type: `Boolean`
+
+Should puppet restart the service on configuration change? (default true)
+
+Default value: `true`
+
+##### `service_enable`
+
+Data type: `Boolean`
+
+Whether to enable the service from puppet (default true)
+
+Default value: `true`
+
+##### `service_ensure`
+
+Data type: `Stdlib::Ensure::Service`
+
+State ensured for the service (default 'running')
+
+Default value: `'running'`
+
+##### `service_name`
+
+Data type: `String[1]`
+
+Name of the node exporter service (default 'smartctl_exporter')
+
+Default value: `'smartctl_exporter'`
+
+##### `user`
+
+Data type: `String[1]`
+
+User which runs the service (default 'root', unlikely to work without root)
+
+Default value: `'root'`
+
+##### `version`
+
+Data type: `String[1]`
+
+The binary release version
+
+Default value: `'0.12.0'`
+
+##### `proxy_server`
+
+Data type: `Optional[String[1]]`
+
+Optional proxy server, with port number if needed. ie: https://example.com:8080
+
+Default value: `undef`
+
+##### `proxy_type`
+
+Data type: `Optional[Enum['none', 'http', 'https', 'ftp']]`
+
+Optional proxy server type (none|http|https|ftp)
+
+Default value: `undef`
+
+##### `options`
+
+Data type: `String`
+
+
+
+Default value: `''`
+
+##### `export_scrape_job`
+
+Data type: `Boolean`
+
+
+
+Default value: `false`
+
+##### `scrape_host`
+
+Data type: `Optional[Stdlib::Host]`
+
+
+
+Default value: `undef`
+
+##### `scrape_port`
+
+Data type: `Stdlib::Port`
+
+
+
+Default value: `9633`
+
+##### `scrape_job_name`
+
+Data type: `String[1]`
+
+
+
+Default value: `'smartctl'`
+
+##### `scrape_job_labels`
+
+Data type: `Optional[Hash]`
+
+
+
+Default value: `undef`
+
### `prometheus::snmp_exporter`
This module manages prometheus snmp_exporter
diff --git a/manifests/smartctl_exporter.pp b/manifests/smartctl_exporter.pp
new file mode 100644
index 00000000..b2ffbc81
--- /dev/null
+++ b/manifests/smartctl_exporter.pp
@@ -0,0 +1,251 @@
+# @summary This module manages prometheus node smartctl_exporter
+# @param arch
+# Architecture (See supported archictectures at https://github.com/prometheus-community/smartctl_exporter/releases)
+# @param bin_dir
+# Directory where binaries are located
+# @param smartctl_path
+# Directory where smartctl binary is located, default /usr/sbin/smartctl
+# @param smartctl_interval
+# The interval between smartctl polls, default 60s
+# @param smartctl_rescan
+# The interval between rescanning for new/disappeared devices. If the interval is smaller than 1s no rescanning takes place.
+# If any devices are configured with smartctl.device also no rescanning takes place. Default 10m
+# @param smartctl_device
+# The list of devices to monitor. If not supplied, the exporter will scan the host for available devices.
+# @param smartctl_device_exclude
+# Regexp of devices to exclude from automatic scanning. (mutually exclusive to device-include)
+# @param smartctl_device_include
+# Regexp of devices to include for automatic scanning. (mutually exclusive to device-exclude)
+# @param web_telemetry_path
+# Path under which to expose metrics. Default is /metrics
+# @param web_systemd_socket
+# Use systemd socket activation listeners instead of port listeners (Linux only).
+# @param web_listen_address
+# Addresses on which to expose metrics and web interface. Repeatable for multiple addresses. Defaults to :9633
+# @param web_config_file
+# [EXPERIMENTAL] Path to configuration file that can enable TLS or authentication.
+# @param web_config_content
+# Unless empty the content of the web-config yaml which will handed over as option to the exporter
+# @param log_level
+# Only log messages with the given severity or above. One of: [debug, info, warn, error]. Default info
+# @param log_format
+# Output format of log messages. One of: [logfmt, json]. Default logfmt
+# @param download_extension
+# Extension for the release binary archive
+# @param download_url
+# Complete URL corresponding to the where the release binary archive can be downloaded
+# @param download_url_base
+# Base URL for the binary archive
+# @param extra_groups
+# Extra groups to add the binary user to
+# @param group
+# Group under which the binary is running. Default 'root' (or 'wheel' on Darwin), unlikely to work without root.
+# @param init_style
+# Service startup scripts style (e.g. rc, upstart or systemd)
+# @param install_method
+# Installation method: url or package (only url is supported currently)
+# @param manage_group
+# Whether to create a group for or rely on external code for that. Default false due to script needing root.
+# @param manage_service
+# Should puppet manage the service? (default true)
+# @param manage_user
+# Whether to create user or rely on external code for that. Default false due to script needing root.
+# @param os
+# Operating system
+# @param package_ensure
+# If package, then use this for package ensure default 'latest'
+# @param package_name
+# The binary package name - not available yet
+# @param purge_config_dir
+# Purge config files no longer generated by Puppet
+# @param restart_on_change
+# Should puppet restart the service on configuration change? (default true)
+# @param service_enable
+# Whether to enable the service from puppet (default true)
+# @param service_ensure
+# State ensured for the service (default 'running')
+# @param service_name
+# Name of the node exporter service (default 'smartctl_exporter')
+# @param user
+# User which runs the service (default 'root', unlikely to work without root)
+# @param version
+# The binary release version
+# @param proxy_server
+# Optional proxy server, with port number if needed. ie: https://example.com:8080
+# @param proxy_type
+# Optional proxy server type (none|http|https|ftp)
+class prometheus::smartctl_exporter (
+ String $download_extension = 'tar.gz',
+ Prometheus::Uri $download_url_base = 'https://github.com/prometheus-community/smartctl_exporter/releases',
+ Array[String[1]] $extra_groups = [],
+ String[1] $group = 'root',
+ String[1] $package_ensure = 'latest',
+ String[1] $package_name = 'smartctl_exporter',
+ String[1] $user = 'root',
+ String[1] $version = '0.12.0',
+ Optional[String[1]] $smartctl_path = undef,
+ Optional[String[1]] $smartctl_interval = undef,
+ Optional[String[1]] $smartctl_rescan = undef,
+ Array[String[1]] $smartctl_device = [],
+ Optional[String[1]] $smartctl_device_exclude = undef,
+ Optional[String[1]] $smartctl_device_include = undef,
+ Optional[String[1]] $web_telemetry_path = undef,
+ Optional[String[1]] $web_systemd_socket = undef,
+ Array[String[1]] $web_listen_address = [],
+ Optional[Enum['debug','info','warn','error']] $log_level = undef,
+ Optional[Enum['logfmt','json']] $log_format = undef,
+ Boolean $purge_config_dir = true,
+ Boolean $restart_on_change = true,
+ Boolean $service_enable = true,
+ Stdlib::Ensure::Service $service_ensure = 'running',
+ String[1] $service_name = 'smartctl_exporter',
+ Prometheus::Initstyle $init_style = $prometheus::init_style,
+ Prometheus::Install $install_method = $prometheus::install_method,
+ Boolean $manage_group = false,
+ Boolean $manage_service = true,
+ Boolean $manage_user = false,
+ String[1] $os = downcase($facts['kernel']),
+ String $options = '', # lint:ignore:params_empty_string_assignment
+ Optional[Prometheus::Uri] $download_url = undef,
+ String[1] $arch = $prometheus::real_arch,
+ Stdlib::Absolutepath $bin_dir = $prometheus::bin_dir,
+ Boolean $export_scrape_job = false,
+ Optional[Stdlib::Host] $scrape_host = undef,
+ Stdlib::Port $scrape_port = 9633,
+ String[1] $scrape_job_name = 'smartctl',
+ Optional[Hash] $scrape_job_labels = undef,
+ Stdlib::Absolutepath $web_config_file = '/etc/smartctl_exporter_web-config.yml',
+ Optional[Hash] $web_config_content = undef,
+ Optional[String[1]] $proxy_server = undef,
+ Optional[Enum['none', 'http', 'https', 'ftp']] $proxy_type = undef,
+) inherits prometheus {
+ $release = "v${version}"
+
+ $real_download_url = pick($download_url, "${download_url_base}/download/${release}/${package_name}-${version}.${os}-${arch}.${download_extension}") # lint:ignore:140chars
+
+ $notify_service = $restart_on_change ? {
+ true => Service[$service_name],
+ default => undef,
+ }
+
+ $_web_config_ensure = $web_config_content.empty ? {
+ true => absent,
+ default => file,
+ }
+
+ file { $web_config_file:
+ ensure => $_web_config_ensure,
+ owner => $user,
+ group => $group,
+ mode => '0640',
+ content => $web_config_content.stdlib::to_yaml,
+ notify => $notify_service,
+ }
+
+ $_web_config = if $web_config_content.empty {
+ ''
+ } else {
+ "--web.config.file=${$web_config_file}"
+ }
+
+ $_cmd_smartctl_device = $smartctl_device.map |$device| {
+ "--smartctl.device=${device}"
+ }
+
+ $_cmd_web_listen_address = $web_listen_address.map |$address| {
+ "--web.listen-address=${address}"
+ }
+
+ $_smartctl_path = $smartctl_path ? {
+ undef => '',
+ default => "--smartctl.path=${smartctl_path}"
+ }
+
+ $_smartctl_interval = $smartctl_interval ? {
+ undef => '',
+ default => "--smartctl.interval=${smartctl_interval}"
+ }
+
+ $_smartctl_rescan = $smartctl_rescan ? {
+ undef => '',
+ default => "--smartctl.rescan=${smartctl_rescan}"
+ }
+
+ $_smartctl_device_exclude = $smartctl_device_exclude ? {
+ undef => '',
+ default => "--smartctl.device-exclude=${smartctl_device_exclude}"
+ }
+
+ $_smartctl_device_include = $smartctl_device_include ? {
+ undef => '',
+ default => "--smartctl.device-include=${smartctl_device_include}"
+ }
+
+ $_web_telemetry_path = $web_telemetry_path ? {
+ undef => '',
+ default => "--web.telemetry-path=${web_telemetry_path}"
+ }
+
+ $_web_systemd_socket = $web_systemd_socket ? {
+ undef => '',
+ default => '--web.systemd-socket'
+ }
+
+ $_log_level = $log_level ? {
+ undef => '',
+ default => "--log.level=${log_level}"
+ }
+
+ $_log_format = $log_format ? {
+ undef => '',
+ default => "--log.format=${log_format}"
+ }
+
+ $_options = [
+ $options,
+ $_web_config,
+ $_cmd_smartctl_device,
+ $_cmd_web_listen_address,
+ $_smartctl_path,
+ $_smartctl_interval,
+ $_smartctl_rescan,
+ $_smartctl_device_exclude,
+ $_smartctl_device_include,
+ $_web_telemetry_path,
+ $_web_systemd_socket,
+ $_log_level,
+ $_log_format,
+ ].filter |$x| { !$x.empty }.join(' ')
+
+ prometheus::daemon { $service_name:
+ install_method => $install_method,
+ version => $version,
+ download_extension => $download_extension,
+ env_vars => {},
+ os => $os,
+ arch => $arch,
+ bin_dir => $bin_dir,
+ notify_service => $notify_service,
+ package_name => $package_name,
+ package_ensure => $package_ensure,
+ manage_user => $manage_user,
+ user => $user,
+ extra_groups => $extra_groups,
+ real_download_url => $real_download_url,
+ group => $group,
+ manage_group => $manage_group,
+ purge => $purge_config_dir,
+ options => $_options,
+ init_style => $init_style,
+ service_ensure => $service_ensure,
+ service_enable => $service_enable,
+ manage_service => $manage_service,
+ export_scrape_job => $export_scrape_job,
+ scrape_host => $scrape_host,
+ scrape_port => $scrape_port,
+ scrape_job_name => $scrape_job_name,
+ scrape_job_labels => $scrape_job_labels,
+ proxy_server => $proxy_server,
+ proxy_type => $proxy_type,
+ }
+}
diff --git a/spec/classes/smartctl_exporter_spec.rb b/spec/classes/smartctl_exporter_spec.rb
new file mode 100644
index 00000000..6a9dfd40
--- /dev/null
+++ b/spec/classes/smartctl_exporter_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'prometheus::smartctl_exporter' do
+ on_supported_os.each do |os, facts|
+ context "on #{os}" do
+ let(:facts) do
+ facts.merge(os_specific_facts(facts))
+ end
+
+ context 'with version specified' do
+ let(:params) do
+ {
+ version: '0.12.0',
+ arch: 'amd64',
+ os: 'linux',
+ bin_dir: '/usr/local/bin',
+ install_method: 'url',
+ }
+ end
+
+ describe 'with all defaults' do
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_file('/usr/local/bin/smartctl_exporter').with('target' => '/opt/smartctl_exporter-0.12.0.linux-amd64/smartctl_exporter') }
+ it { is_expected.to contain_prometheus__daemon('smartctl_exporter') }
+ it { is_expected.to contain_service('smartctl_exporter') }
+ end
+
+ context 'with tls set in web-config.yml' do
+ let(:params) do
+ super().merge(
+ web_config_content: {
+ tls_server_config: {
+ cert_file: '/etc/smartctl_exporter/foo.cert',
+ key_file: '/etc/smartctl_exporter/foo.key'
+ }
+ }
+ )
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_file('/etc/smartctl_exporter_web-config.yml').with(ensure: 'file') }
+ it { is_expected.to contain_prometheus__daemon('smartctl_exporter').with(options: '--web.config.file=/etc/smartctl_exporter_web-config.yml') }
+ end
+ end
+ end
+ end
+end