Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
914d0e4
feat(rustdesk): add support for HAProxy domain expose and documentation
VILJkid Aug 26, 2026
bd88a08
fix: set haproxy 3.2.0 default and remove domains dependency from rus…
VILJkid Sep 7, 2026
c405754
fix: set default values for manual_config and configure haproxy params
VILJkid Sep 7, 2026
28af996
fix: allow apt to be safely referenced without duplicate declaration …
VILJkid Sep 7, 2026
73414cb
fix: wrap apt class to prevent duplicate declaration error
VILJkid Sep 7, 2026
4c66263
fix: remove apt class declaration to fix eit_repos and eit_haproxy or…
VILJkid Sep 7, 2026
061b1ac
fix: move haproxy default values to role heira file and call profile …
VILJkid Sep 8, 2026
23e8dcf
fix: define role haproxy default confuigure value in role rustfs values
VILJkid Sep 8, 2026
d0e27cf
fix: remove expose param for rustdesk since it's expected to setup it…
VILJkid Sep 8, 2026
28c3dae
fix: pin haproxy version to 3.2 as default while adding support for o…
VILJkid Sep 11, 2026
d2cabfc
fix: ensure prometheus scrape jobs are filtered and collected based o…
VILJkid Sep 11, 2026
768a6c3
chore: update rustfs container image version to 1.0.0-rc.5
VILJkid Sep 11, 2026
6d85275
fix: update haproxy dump certs script to reduce noise
VILJkid Sep 13, 2026
676cc33
fix: update haproxy dump certs script to analyze unused domain expiry…
VILJkid Sep 13, 2026
ea6e4b5
fix: ensure haproxy 3.x correctly maps to the latest version
VILJkid Sep 14, 2026
809c814
fix: install latest haproxy for both manual and basic config approaches
VILJkid Sep 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
File <| tag == 'prometheus::scrape_job' |> {
noop => $noop_value,
}
Prometheus::Scrape_job <<| job_name == 'probe_blackbox_domains' and tag == $customer_id |>> {
Prometheus::Scrape_job <<| job_name == 'probe_blackbox_domains' and tag == $trusted['certname'] |>> {
notify => Class['prometheus::service_reload'],
}
}
Expand Down
15 changes: 8 additions & 7 deletions modules/enableit/common/manifests/software/rustdesk.pp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@
#
# @groups server server_enable, server_version, server_extra_dependencies.
#
# @groups networking, domains.
class common::software::rustdesk (
Boolean $manage = false,
Boolean $manage = false,

Boolean $client_enable = false,
Array[String] $client_extra_dependencies = [],
Eit_types::Version $client_version = '1.4.3',
Boolean $client_enable = false,
Array[String] $client_extra_dependencies = [],
Eit_types::Version $client_version = '1.4.3',

Boolean $server_enable = false,
Array[String] $server_extra_dependencies = [],
Eit_types::Version $server_version = '1.7.1',
Boolean $server_enable = false,
Array[String] $server_extra_dependencies = [],
Eit_types::Version $server_version = '1.7.1',
) {
if $manage {
include profile::software::rustdesk
Expand Down
40 changes: 34 additions & 6 deletions modules/enableit/eit_haproxy/files/haproxy-dump-certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ RETRY_DELAY=10
# Restored argument parsing
usage() {
cat <<EOF
Usage: $(basename "$0") [-s SOCKET]
Usage: $(basename "$0") [-s SOCKET] [-d]
-s SOCKET HAProxy stats socket (default: ${SOCKET})
-d Enable debug/verbose logging
EOF
}

while getopts ":s:h" opt; do
DEBUG=false

while getopts ":s:hd" opt; do
case "$opt" in
s) SOCKET="$OPTARG" ;;
d) DEBUG=true ;;
h) usage; exit 0 ;;
*) usage >&2; exit 2 ;;
esac
Expand All @@ -37,7 +41,9 @@ hap() { socat - "UNIX-CONNECT:${SOCKET}"; }

dump_one() {
local path="$1"
echo "Attempting dump for: ${path}" >&2
if [ "${DEBUG:-false}" = true ]; then
echo "Attempting dump for: ${path}" >&2
fi
local dir tmp
dir=$(dirname "$path")
tmp=$(mktemp "${dir}/.$(basename "$path").XXXXXX")
Expand Down Expand Up @@ -71,12 +77,20 @@ dump_one() {
return 0
fi

local cn
cn=$(openssl x509 -in "$tmp" -noout -subject 2>/dev/null | sed -n 's/.*CN[[:space:]]*=[[:space:]]*\([^,/[:space:]]*\).*/\1/p')
if [ -n "$cn" ]; then
echo "$cn" >> /tmp/active_cert_domains.txt
fi

# Optimization: Content verification with fast sha256sum
if [ -f "$path" ]; then
if cmp -s \
<(sha256sum "$tmp" | cut -d ' ' -f1) \
<(sha256sum "$path" | cut -d ' ' -f1); then
echo "Already up-to-date: ${path}" >&2
if [ "${DEBUG:-false}" = true ]; then
echo "Already up-to-date: ${path}" >&2
fi
return 0
fi
fi
Expand All @@ -97,10 +111,24 @@ else
done < /tmp/cert_list.txt

echo "----------------------------------------------------------------------------------"
echo "Analyzing for unused certificates..."
echo "Analyzing for unused certificates which can be removed..."
comm -23 \
<(ls /etc/haproxy/certs/*.pem 2>/dev/null | sort) \
<(sort /tmp/cert_list.txt) | while read -r unused_cert; do
echo "The following certificate is no longer being used and can be removed: $unused_cert"
echo "$unused_cert"
done

echo "----------------------------------------------------------------------------------"
echo "Analyzing for unused domain expiry threshold .prom files which can be removed..."
if [ -f /tmp/active_cert_domains.txt ]; then
sort -u /tmp/active_cert_domains.txt -o /tmp/active_cert_domains.txt
for prom_file in /var/lib/node_exporter/textfile_collector/threshold_monitor_domains_expiry_*.prom; do
[ -e "$prom_file" ] || continue
prom_domain=$(basename "$prom_file" | sed 's/^threshold_monitor_domains_expiry_//;s/\.prom$//')
if ! grep -q "^${prom_domain}$" /tmp/active_cert_domains.txt; then
echo "$prom_file"
fi
done
rm -f /tmp/active_cert_domains.txt
fi
fi
6 changes: 3 additions & 3 deletions modules/enableit/eit_haproxy/manifests/basic_config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#
# @param encryption_ciphers The encryption ciphers to use. Defaults to 'Modern'.
#
# @param version The version of haproxy. Defaults to 'latest'.
# @param version The version of haproxy. Defaults to '3.2.0'.
#
# @param native_acme Internal switch for native ACME mode.
#
Expand All @@ -43,12 +43,12 @@
Boolean $https = true,
Boolean $http = false,
Boolean $use_hsts = true,
Boolean $use_lets_encrypt = true,
Boolean $use_lets_encrypt = false,
Enum['http','tcp'] $mode = 'http',
Array[Stdlib::IP::Address,1] $listen_on = ['0.0.0.0'],
Enum['Modern','Intermediate'] $encryption_ciphers = 'Modern',
Eit_types::Version $version = 'latest',
Boolean $native_acme = false,
Boolean $native_acme = true,
Eit_types::Email $acme_contact = $eit_haproxy::acme_contact,
String $acme_ca = 'https://acme-v02.api.letsencrypt.org/directory',
) {
Expand Down
39 changes: 24 additions & 15 deletions modules/enableit/eit_haproxy/manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
#
# @param use_hsts Boolean to enable or disable HSTS. Defaults to true.
#
# @param use_lets_encrypt Boolean to enable or disable Let's Encrypt. Defaults to true.
# @param use_lets_encrypt Boolean to enable or disable Let's Encrypt / certbot legacy mode. Defaults to false (native ACME used for HAProxy 3.2+).
#
# @param mode The mode of haproxy. Defaults to 'http'.
#
# @param listen_on The IP addresses for haproxy to listen on. Defaults to ['0.0.0.0'].
#
# @param encryption_ciphers The encryption ciphers to use. Defaults to 'Modern'.
#
# @param version The version of haproxy. Defaults to 'latest'.
# @param version The version or LTS stream of haproxy (e.g. '3.2', '3.4'). Defaults to '3.2'. Even-minor LTS streams (3.2, 3.4, etc.) are supported for HAProxy 3.x.
#
# @param acme_contact The contact email for Let's Encrypt ACME. Defaults to 'ops@enableit.dk'.
#
Expand Down Expand Up @@ -77,11 +77,11 @@
Boolean $https = true,
Boolean $http = false,
Boolean $use_hsts = true,
Boolean $use_lets_encrypt = true,
Boolean $use_lets_encrypt = false,
Enum['http','tcp'] $mode = 'http',
Array[Stdlib::IP::Address,1] $listen_on = ['0.0.0.0'],
Enum['Modern','Intermediate'] $encryption_ciphers = 'Modern',
Eit_types::Version $version = 'latest',
Eit_types::Version $version = '3.2',
Eit_types::Email $acme_contact = 'ops@enableit.dk',
Enum['production','staging'] $ca_type = 'production',
Eit_types::Service_Ensure $service_ensure = true,
Expand All @@ -102,7 +102,23 @@
if $configure == 'auto' {
$_is_ubuntu = $facts['os']['name'] == 'Ubuntu'

$_wants_haproxy3 = String($version) =~ /^\d+(\.\d+)*$/ and versioncmp(String($version), '3.0.0') >= 0
if String($version) =~ /^(\d+)\.(\d+)(?:\.(\d+))?$/ {
$major = Integer($1)
$minor = Integer($2)

if $major >= 3 {
if $minor % 2 != 0 {
fail("HAProxy version ${version} is invalid. Only even minor versions (LTS releases like 3.2, 3.4, etc.) are supported for HAProxy 3.x.")
}
$_wants_haproxy3 = true
$haproxy_lts_version = "${major}.${minor}"
} else {
$_wants_haproxy3 = false
}
} else {
$_wants_haproxy3 = versioncmp(String($version), '3.2.0') >= 0
$haproxy_lts_version = '3.2'
}

if $_wants_haproxy3 and !$_is_ubuntu {
fail("HAProxy 3.x is only supported on Ubuntu, not ${facts['os']['name']}")
Expand All @@ -122,18 +138,16 @@
if $_wants_haproxy3 {
if $_is_ubuntu {
# Ubuntu 24.04 ships HAProxy 2.8 — need vbernat's PPA for 3.x.
# See: https://launchpad.net/~vbernat/+archive/ubuntu/haproxy-3.2 (adjusting the suffix for newer LTS like haproxy-3.4).
# Newer Ubuntu LTS (26.04+) ships HAProxy 3.x in stock repos,
# so the PPA is unnecessary there.
if $facts['os']['release']['major'] =~ /^24/ {
contain apt

$haproxy_lts_version = '3.2'
apt::ppa { "ppa:vbernat/haproxy-${haproxy_lts_version}": }

Class['apt'] -> Apt::Ppa["ppa:vbernat/haproxy-${haproxy_lts_version}"] -> Class['eit_haproxy::basic_config']
}
} else {
warning('HAProxy 3.x auto-native ACME path is only supported on Ubuntu')
warning("HAProxy ${haproxy_lts_version} auto-native ACME path is only supported on Ubuntu")
}
}

Expand All @@ -143,14 +157,9 @@
}
}

$_version = $_wants_haproxy3 ? {
true => 'latest',
default => $version
}

class { 'eit_haproxy::basic_config':
domains => $domains,
version => $_version,
version => 'latest',
native_acme => $_use_native_acme,
ddos_protection => $ddos_protection,
https => $https,
Expand Down
7 changes: 6 additions & 1 deletion modules/enableit/eit_haproxy/manifests/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
String $package_name,
Eit_types::Version $ensure = 'present',
) {
$_package_ensure = $eit_haproxy::version =~ /^\d+\.\d+$/ ? {
true => 'present',
default => $eit_haproxy::version,
}

package { $package_name:
ensure => $eit_haproxy::version,
ensure => $_package_ensure,
notify => Service[$eit_haproxy::service_name],
}

Expand Down
2 changes: 1 addition & 1 deletion modules/enableit/eit_types/types/version.pp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Version
# NOTE: Regex may not work for all types of versioning numbers current
type Eit_types::Version = Variant[Pattern[/^(\d+\.)?(\d+\.)?(\d+)$/],Eit_types::Package_version]
type Eit_types::Version = Variant[Pattern[/^(\d+)\.(\d+)(?:\.(\d+))?$/],Eit_types::Package_version]
2 changes: 1 addition & 1 deletion modules/enableit/profile/manifests/storage/rustfs.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
String[1] $secret_key = $role::storage::rustfs::secret_key,
Boolean $enable = $role::storage::rustfs::enable,
Stdlib::Unixpath $data_dir = $role::storage::rustfs::data_dir,
String[1] $version = '1.0.0-rc.3',
String[1] $version = '1.0.0-rc.5',
Hash $env_vars = {},
) {
# 1. Manage RustFS
Expand Down
28 changes: 14 additions & 14 deletions modules/enableit/profile/manifests/web/haproxy.pp
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@
# @groups mode http
#
class profile::web::haproxy (
Enum['auto', 'manual'] $configure,
Optional[String] $manual_config,
Eit_haproxy::Domains $domains = {},
Eit_haproxy::Listen $listens = {},
Boolean $ddos_protection = false,
Boolean $https = true,
Boolean $http = false,
Boolean $use_hsts = true,
Boolean $use_lets_encrypt = true,
Eit_types::Version $version = 'latest',
Eit_types::Email $acme_contact = 'ops@enableit.dk',
Enum['Modern','Intermediate'] $encryption_ciphers = 'Modern',
Enum['auto', 'manual'] $configure = $role::web::haproxy::configure,
Optional[String] $manual_config = $role::web::haproxy::manual_config,
Eit_haproxy::Domains $domains = $role::web::haproxy::domains,
Eit_haproxy::Listen $listens = $role::web::haproxy::listens,
Boolean $ddos_protection = $role::web::haproxy::ddos_protection,
Boolean $https = $role::web::haproxy::https,
Boolean $http = $role::web::haproxy::http,
Boolean $use_hsts = $role::web::haproxy::use_hsts,
Boolean $use_lets_encrypt = $role::web::haproxy::use_lets_encrypt,
Eit_types::Version $version = $role::web::haproxy::version,
Eit_types::Email $acme_contact = $role::web::haproxy::acme_contact,
Enum['Modern','Intermediate'] $encryption_ciphers = $role::web::haproxy::encryption_ciphers,
Hash[Eit_types::IP,Variant[
Array[Stdlib::Port],
Stdlib::Port
]] $firewall = {},
Boolean $log_compressed = true,
]] $firewall = $role::web::haproxy::firewall,
Boolean $log_compressed = $role::web::haproxy::log_compressed,
) inherits profile {
# Monitoring
$facts.dig('haproxy_version').then |$_haproxy_version| {
Expand Down
2 changes: 2 additions & 0 deletions modules/enableit/role/data/role/role::storage::rustfs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
role::web::haproxy::configure: "auto"
15 changes: 15 additions & 0 deletions modules/enableit/role/data/role/role::web::haproxy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
role::web::haproxy::configure: "auto"
role::web::haproxy::manual_config:
role::web::haproxy::domains: {}
role::web::haproxy::listens: {}
role::web::haproxy::ddos_protection: false
role::web::haproxy::https: true
role::web::haproxy::http: false
role::web::haproxy::use_hsts: true
role::web::haproxy::use_lets_encrypt: false
role::web::haproxy::version: "3.2"
role::web::haproxy::acme_contact: "ops@enableit.dk"
role::web::haproxy::encryption_ciphers: "Modern"
role::web::haproxy::firewall: {}
role::web::haproxy::log_compressed: true
10 changes: 1 addition & 9 deletions modules/enableit/role/manifests/storage/rustfs.pp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# @param secret_key The S3 secret access key.
# @param enable Whether to enable and manage the rustfs component.
# @param expose Whether to expose the service via HAProxy.
# @param domains HAProxy domain configuration.
#
# @example Usage
# include role::storage::rustfs
Expand All @@ -16,17 +15,10 @@
Stdlib::Unixpath $data_dir,
Boolean $enable = true,
Boolean $expose = false,
Eit_haproxy::Domains $domains = {},
) inherits role::storage {
contain role::virtualization::docker
contain profile::storage::rustfs
if $expose {
confine($expose, $domains.empty, 'Exposing rustfs via HAProxy requires domains to be provided')

class { 'role::web::haproxy':
domains => $domains,
version => '3.2.0',
encryption_ciphers => 'Intermediate',
}
include role::web::haproxy
}
}
Loading