From 9c4915a0b036f37706807bf4689612c6815a7db0 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Thu, 21 Mar 2024 09:47:16 -0400 Subject: [PATCH 1/4] Adds smartctl exporter --- manifests/smartctl_exporter.pp | 251 +++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 manifests/smartctl_exporter.pp 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, + } +} From fecb267df56fc4027616464da0513de8f27df3f1 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Thu, 21 Mar 2024 10:01:47 -0400 Subject: [PATCH 2/4] Adds test --- spec/classes/smartctl_exporter_spec.rb | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 spec/classes/smartctl_exporter_spec.rb diff --git a/spec/classes/smartctl_exporter_spec.rb b/spec/classes/smartctl_exporter_spec.rb new file mode 100644 index 00000000..2d22bc24 --- /dev/null +++ b/spec/classes/smartctl_exporter_spec.rb @@ -0,0 +1,51 @@ +# 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_user('root') } + it { is_expected.to contain_group('root') } + 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 From 3703488f094e73a9d5adcdede610eeb8558f598c Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Sun, 19 May 2024 07:39:05 -0600 Subject: [PATCH 3/4] Update REFERENCE.md --- REFERENCE.md | 398 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) 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 From 8034ed81fdc41d57b3d6740667371b9bd62f671c Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Sun, 19 May 2024 11:25:06 -0600 Subject: [PATCH 4/4] Remove user/group requirements since they're present on every system anyhow --- spec/classes/smartctl_exporter_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/classes/smartctl_exporter_spec.rb b/spec/classes/smartctl_exporter_spec.rb index 2d22bc24..6a9dfd40 100644 --- a/spec/classes/smartctl_exporter_spec.rb +++ b/spec/classes/smartctl_exporter_spec.rb @@ -24,8 +24,6 @@ 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_user('root') } - it { is_expected.to contain_group('root') } it { is_expected.to contain_service('smartctl_exporter') } end