Files
mgmt/modules/prometheus/main.mcl
2025-03-11 04:18:02 -04:00

252 lines
5.8 KiB
Plaintext

import "deploy"
import "fmt"
import "golang"
import "golang/strings" as golang_strings
import "golang/strconv" as golang_strconv
import "local"
import "os"
import "strings"
class server() {
pkg "golang-github-prometheus" { # fedora
state => "installed",
Before => File["/etc/prometheus/"],
Before => Svc["prometheus"],
}
file "/etc/prometheus/" {
state => $const.res.file.state.exists,
recurse => true,
purge => true,
owner => "prometheus",
group => "root",
mode => "u=rwx,g=rx,o=", # dir
}
file "${vardir}prometheus.yml.header" {
state => $const.res.file.state.exists,
content => golang.template(deploy.readfile("/files/prometheus.yml.tmpl")),
owner => "root",
group => "root",
mode => "u=rw,go=",
}
file "/etc/prometheus/prometheus.yml" {
state => $const.res.file.state.exists,
fragments => [
"${vardir}prometheus.yml.header", # also pull this one file
"${vardir}jobs.d/", # pull from this dir
],
owner => "prometheus",
group => "root",
mode => "u=rw,g=r,o=",
Notify => Svc["prometheus"],
}
svc "prometheus" {
state => "running",
startup => "enabled",
}
# permissions are important for this dir, make sure they're correct
file "/var/lib/prometheus/" {
state => $const.res.file.state.exists,
owner => "prometheus",
group => "root",
mode => "u=rwx,g=rx,o=", # dir
}
$vardir = local.vardir("prometheus/")
# Add the default exporter.
include job("node", struct{
#host => "localhost",
#port => 9100,
})
}
class server:job_base() {
file "${vardir}jobs.d/" {
state => $const.res.file.state.exists,
recurse => true,
purge => true,
owner => "root",
group => "root",
mode => "u=rwx,go=", # dir
}
}
class server:job($name, $st) {
# XXX: document why this is named job_base instead of base:job_base or
# change the compiler to use the second version?
include job_base
$host = $st->host || "localhost"
$port = $st->port || 9100
$comment = $st->comment || ""
$tmpl = struct{
name => "${name}",
host => "${host}",
port => fmt.printf("%d", $port),
comment => "${comment}",
}
file "${vardir}jobs.d/${name}.job" {
state => $const.res.file.state.exists,
content => golang.template(deploy.readfile("/files/prometheus.yml.frag.tmpl"), $tmpl),
owner => "root",
group => "root",
mode => "u=rw,go=",
}
}
class exporter() {
if os.is_family_redhat() { # we only use fedora atm
pkg "node-exporter" { # fedora
state => "installed",
#Before => File["/etc/default/prometheus-node-exporter"],
Before => Svc["prometheus-node-exporter"],
}
}
if os.is_family_debian() {
pkg "prometheus-node-exporter" { # debian
state => "installed",
#Before => File["/etc/default/prometheus-node-exporter"],
Before => Svc["prometheus-node-exporter"],
}
}
# TODO: manage /etc/default/prometheus-node-exporter
svc "prometheus-node-exporter" {
state => "running",
startup => "enabled",
}
}
class postgresql_base() {
#if os.is_family_redhat() {
# pkg [
# "", # XXX: No obvious Fedora package available
# ] {
# state => "installed",
# }
#}
if os.is_family_debian() {
pkg [
"prometheus-postgres-exporter",
] {
state => "installed",
Before => Svc["prometheus-postgres-exporter"],
}
}
# systemd service template file to allow for multiple of these
file "/etc/systemd/system/prometheus-postgres-exporter@.service" {
state => $const.res.file.state.exists,
content => deploy.readfile("/files/prometheus-postgres-exporter.service"),
owner => "root",
group => "root",
mode => "u=rw,go=r",
# Depend => Pkg["prometheus-postgres-exporter"],
# Before => Svc["prometheus-postgres-exporter"],
}
}
# We call this postgresql instead of postgres.
# XXX: you may not wish to have spaces in your passwords
class postgresql($config) {
include postgresql_base
$host = $config->host || "127.0.0.1"
$port = $config->port || 5432
$user = $config->user || "prometheus"
$pass = $config->pass || ""
$dbname = $config->dbname || ""
$sslmode = $config->sslmode || false
$listen_port = $config->listen_port || 9187
panic($port <= 0)
$h = if $host == "" {
""
} else {
"host=${host}"
}
$o = fmt.printf("port=%d", $port)
$u = if $user == "" {
""
} else {
"user=${user}"
}
$p = if $pass == "" {
""
} else {
"password=${pass}"
}
$d = if $dbname == "" {
""
} else {
"dbname=${dbname}"
}
$m = if $sslmode {
""
} else {
"sslmode=disable"
}
$l = [$h, $o, $u, $p, $d, $m,] # filter out empties first (IT'S REQUIRED)
$dsn = strings.join_nonempty($l, " ") # trailing spaces break this exporter
$str_port = golang_strconv.itoa($port)
$str_listen_port = golang_strconv.itoa($listen_port)
$args = "--web.listen-address=:${str_listen_port}"
$tmpl = struct{
# DATA_SOURCE_NAME='postgresql://login:password@hostname:port/' # untested?
# DATA_SOURCE_NAME='user=prometheus host=/run/postgresql dbname=postgres' # untested?
# DATA_SOURCE_NAME='host=127.0.0.1 port=5432 user=prometheus password=hunter2 dbname=postgres sslmode=disable' # works
port => $port,
dsn => $dsn,
args => $args,
}
file "/etc/default/prometheus-postgres-exporter-${str_port}" {
state => $const.res.file.state.exists,
content => golang.template(deploy.readfile("/files/prometheus-postgres-exporter.default.tmpl"), $tmpl),
owner => "prometheus",
group => "root",
mode => "ug=rw,o=",
Depend => Pkg["prometheus-postgres-exporter"],
Before => Svc["prometheus-postgres-exporter@${str_port}"],
}
svc "prometheus-postgres-exporter@${str_port}" {
state => "running",
startup => "enabled",
}
$vardir = local.vardir("prometheus/")
# there can only be one on each listen port!
# if more than one of these is set on the same machine we'd error
file "${vardir}postgresql-${str_listen_port}" {
state => $const.res.file.state.exists,
content => "${str_port}",
owner => "root",
group => "root",
mode => "u=rw,go=",
}
}