diff --git a/manifests/discovery/configure_targets.pp b/manifests/discovery/configure_targets.pp new file mode 100644 index 000000000..e72fe1466 --- /dev/null +++ b/manifests/discovery/configure_targets.pp @@ -0,0 +1,43 @@ +# Copyright (c) 2024 The Regents of the University of Michigan. +# All Rights Reserved. Licensed according to the terms of the Revised +# BSD License. See LICENSE.txt for details. + +define nebula::discovery::configure_targets ( + Integer $port, +) { + case $facts["mlibrary_ip_addresses"] { + Hash[String, Array[String]]: { + $all_public_addresses = $facts["mlibrary_ip_addresses"]["public"] + $all_private_addresses = $facts["mlibrary_ip_addresses"]["private"] + } + + default: { + $all_public_addresses = [$::ipaddress] + $all_private_addresses = [] + } + } + + Concat_fragment <<| tag == $title |>> + + $all_public_addresses.each |$address| { + @@firewall { "${title} ${::hostname} ${address}": + tag => "${title}_public", + dport => $port, + source => $address, + proto => "tcp", + state => "new", + action => "accept", + } + } + + $all_private_addresses.each |$address| { + @@firewall { "${title} ${::hostname} ${address}": + tag => "${title}_private", + dport => $port, + source => $address, + proto => "tcp", + state => "new", + action => "accept", + } + } +} diff --git a/manifests/discovery/listen_on_port.pp b/manifests/discovery/listen_on_port.pp new file mode 100644 index 000000000..6f312edee --- /dev/null +++ b/manifests/discovery/listen_on_port.pp @@ -0,0 +1,49 @@ +# Copyright (c) 2024 The Regents of the University of Michigan. +# All Rights Reserved. Licensed according to the terms of the Revised +# BSD License. See LICENSE.txt for details. + +define nebula::discovery::listen_on_port ( + String $concat_target, + String $concat_content, + Optional[String] $concat_order = undef, + Boolean $require_public_ip = false, +) { + case $facts["mlibrary_ip_addresses"] { + Hash[String, Array[String]]: { + $all_public_addresses = $facts["mlibrary_ip_addresses"]["public"] + $all_private_addresses = $facts["mlibrary_ip_addresses"]["private"] + } + + default: { + $all_public_addresses = [$::ipaddress] + $all_private_addresses = [] + } + } + + if $require_public_ip or $all_private_addresses == [] { + if $all_public_addresses == [] { + fail("At least one IP address is required") + } else { + $the_main_ip_address = $all_public_addresses[0] + Firewall <<| tag == "${title}_public" |>> + } + } else { + $the_main_ip_address = $all_private_addresses[0] + Firewall <<| tag == "${title}_private" |>> + } + + if $concat_order == undef { + @@concat_fragment { "${title} ${::hostname}": + tag => $title, + target => $concat_target, + content => regsubst($concat_content, "\\\$IP_ADDRESS", $the_main_ip_address, "G"), + } + } else { + @@concat_fragment { "${title} ${::hostname}": + tag => $title, + target => $concat_target, + order => $concat_order, + content => regsubst($concat_content, "\\\$IP_ADDRESS", $the_main_ip_address, "G"), + } + } +} diff --git a/manifests/profile/prometheus.pp b/manifests/profile/prometheus.pp index 5269496af..ee027b19d 100644 --- a/manifests/profile/prometheus.pp +++ b/manifests/profile/prometheus.pp @@ -102,7 +102,9 @@ content => "scrape_configs:\n" } - Concat_fragment <<| tag == "${::datacenter}_prometheus_ipmi_exporter" |>> + nebula::discovery::configure_targets { "prometheus_ipmi_${::datacenter}": + port => 9290, + } file { '/etc/prometheus': ensure => 'directory', @@ -201,11 +203,6 @@ tag => "${::datacenter}_prometheus_public_node_exporter", dport => 9100, ; - - "010 prometheus public ipmi exporter ${::hostname} ${address}": - tag => "${::datacenter}_prometheus_public_ipmi_exporter", - dport => 9290, - ; } } @@ -222,11 +219,6 @@ tag => "${::datacenter}_prometheus_private_node_exporter", dport => 9100, ; - - "010 prometheus private ipmi exporter ${::hostname} ${address}": - tag => "${::datacenter}_prometheus_private_ipmi_exporter", - dport => 9290, - ; } } diff --git a/manifests/profile/prometheus/exporter/ipmi.pp b/manifests/profile/prometheus/exporter/ipmi.pp index bee37d888..f74ac4e0f 100644 --- a/manifests/profile/prometheus/exporter/ipmi.pp +++ b/manifests/profile/prometheus/exporter/ipmi.pp @@ -20,30 +20,10 @@ content => template("nebula/profile/prometheus/exporter/ipmi/config.yaml.erb") } - # This looks awfully similar to, but not the same as, the code in - # node.pp. Once mysql and haproxy exporters support public/private - # ip addresses, I expect a shape will emerge. Some differences are - # that, for ipmi exporters, I'm not supporting datacenters that lack - # a dedicated prometheus server, plus I don't have to care about the - # pushgateway script. I just need to open a port and export config. - $all_public_addresses = $facts["mlibrary_ip_addresses"]["public"] - $all_private_addresses = $facts["mlibrary_ip_addresses"]["private"] - - if $all_public_addresses == [] and $all_private_addresses == [] { - fail("Host cannot be scraped without a public or private IP address") - } elsif $all_private_addresses != [] { - $ipaddress = $all_private_addresses[0] - Firewall <<| tag == "${::datacenter}_prometheus_private_ipmi_exporter" |>> - } else { - $ipaddress = $all_public_addresses[0] - Firewall <<| tag == "${::datacenter}_prometheus_public_ipmi_exporter" |>> - } - - @@concat_fragment { "prometheus ipmi scrape config ${::hostname}": - tag => "${::datacenter}_prometheus_ipmi_exporter", - target => "/etc/prometheus/ipmi.yml", - order => "02", - content => template("nebula/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb") + nebula::discovery::listen_on_port { "prometheus_ipmi_${::datacenter}": + concat_target => "/etc/prometheus/ipmi.yml", + concat_order => "02", + concat_content => template("nebula/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb") } } } diff --git a/spec/defines/discovery/configure_targets_spec.rb b/spec/defines/discovery/configure_targets_spec.rb new file mode 100644 index 000000000..a0fc7772f --- /dev/null +++ b/spec/defines/discovery/configure_targets_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Copyright (c) 2024 The Regents of the University of Michigan. +# All Rights Reserved. Licensed according to the terms of the Revised +# BSD License. See LICENSE.txt for details. +require 'spec_helper' + +describe 'nebula::discovery::configure_targets' do + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + context "with title set to example_client" do + let(:title) { "example_client" } + let(:params) { { port: 12345 } } + + it { is_expected.to compile } + end + end + end +end diff --git a/spec/defines/discovery/listen_on_port_spec.rb b/spec/defines/discovery/listen_on_port_spec.rb new file mode 100644 index 000000000..870fafe94 --- /dev/null +++ b/spec/defines/discovery/listen_on_port_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# Copyright (c) 2024 The Regents of the University of Michigan. +# All Rights Reserved. Licensed according to the terms of the Revised +# BSD License. See LICENSE.txt for details. +require 'spec_helper' + +describe 'nebula::discovery::listen_on_port' do + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + context "with title set to example_service" do + let(:title) { "example_service" } + let(:params) do + { + concat_target: "/path/to/config_file", + concat_content: <<~FILE + [main] + ip_address = $IP_ADDRESS + FILE + } + end + + it { is_expected.to compile } + + it do + expect(exported_resources).to contain_concat_fragment("#{title} #{facts[:hostname]}") + .with_content(/#{facts[:ipaddress]}/) + end + end + end + end +end diff --git a/templates/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb b/templates/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb index c5d5af3e0..39163c2d4 100644 --- a/templates/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb +++ b/templates/profile/prometheus/exporter/ipmi/scrape_config.yaml.erb @@ -24,4 +24,4 @@ source_labels: ["__param_target"] - action: "replace" target_label: "__address__" - replacement: "<%= @ipaddress %>:9290" + replacement: "$IP_ADDRESS:9290"