diff --git a/README.md b/README.md index 82b9d53..5c369c5 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,22 @@ pointing to the load balancer instance's CNS records. See the [2]: https://github.com/TritonDataCenter/triton-dehydrated?tab=readme-ov-file#how-to-use-inside-a-user-container-on-triton +## Metrics polling + +If the `cloud.tritoncompute:metrics_acl` metadata key is not empty then the +metrics endpoint will be enabled on port `8405`. The ACL must be an IP prefix +(e.g., `198.51.100.0/24`). Multiple comma or space separated prefixes can be +included. + +If the `cloud.tritoncompute:certificate_name` key is supplied then the metrics +endpoint will be served via HTTPS. If the key is not supplied then the metrics +encpoint will be served via HTTP. + +**Note:** The load balancer will respond to *all hosts*. on port `8405`. Hosts +outside of the configured ACL will receive a `403` response. If you want the +load balancer to not respond at all then you must also configure Cloud Firewall +for the instance. + ## Development Typically development is done by: diff --git a/haproxy.cfg/000-global.cfg b/haproxy.cfg/000-global.cfg index 39af3d0..a6a198c 100644 --- a/haproxy.cfg/000-global.cfg +++ b/haproxy.cfg/000-global.cfg @@ -13,6 +13,7 @@ # # global + default-path config master-worker mworker-max-reloads 10 log 127.0.0.1 len 4096 local0 diff --git a/reconfigure b/reconfigure index 5dc7e15..539d6d3 100755 --- a/reconfigure +++ b/reconfigure @@ -18,7 +18,17 @@ fi TOP=$(cd "$(dirname "$0")"; pwd) # SMF doesn't give us a sane path. -PATH=/$TOP/build/node/bin:/usr/local/sbin:/usr/local/bin:/opt/local/sbin:/opt/local/bin:/usr/sbin:/usr/bin:/sbin +PATH=/$TOP/build/node/bin:/usr/local/sbin:/usr/local/bin:/opt/local/sbin:/opt/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +stat_f="-c %s" + +# For testing +if [[ "$OSTYPE" != "solaris2.11" ]]; then + shopt -s expand_aliases + # shellcheck disable=SC2139 + alias mdata-get="${TOP}/tools/mock-mdata-get" + stat_f="-f %z" +fi skel_config_dir="${TOP}/haproxy.cfg" real_config_dir=/opt/local/etc/haproxy.cfg @@ -29,7 +39,7 @@ candidate_domains=$(mktemp /tmp/domains.txt.XXXXXX) config_is_different=true -function ensure_haproxy { +function do_ensure_haproxy { haproxy_state=$(svcs -Ho state haproxy) case "$haproxy_state" in disabled) @@ -49,7 +59,29 @@ function ensure_haproxy { esac } -function configure_haproxy { +function do_configure_acl { + acl_file="${candidate_config_dir}/210-metrics_acl.txt" + # shellcheck disable=SC2020 + mdata-get cloud.tritoncompute:metrics_acl | tr ' ,' '\n\n' > "$acl_file" + if [[ -f /opt/triton/ssl/default/fullchain.pem ]]; then + bind_tls="ssl crt /opt/triton/ssl/default/fullchain.pem" + fi + fsize=$(stat "$stat_f" "$acl_file") + if (( fsize > 0 )); then +cat << EOF > "${candidate_config_dir}/200-metrics.cfg" +frontend __cloud_tritoncompute__metrics + bind *:8405 $bind_tls + mode http + http-request deny if !{ src -f 210-metrics_acl.txt } + http-request use-service prometheus-exporter if { path /metrics } + no log +EOF + else + rm -f "${acl_file:?}" + fi +} + +function do_configure_haproxy { rsync -a "${skel_config_dir}/" "${candidate_config_dir}/" { printf '# #\n' @@ -58,6 +90,7 @@ function configure_haproxy { } > "${candidate_config_dir}/100-services.cfg" "${TOP}/parser.js" > "${candidate_config_dir}/100-services.cfg" + do_configure_acl if diff -qr "${real_config_dir}" "${candidate_config_dir}"; then config_is_different=false @@ -73,7 +106,7 @@ function configure_haproxy { rm -rf "${candidate_config_dir:?}" } -function configure_tls { +function do_configure_tls { cert_subject=$(mdata-get cloud.tritoncompute:certificate_name || true) ( if [[ -n "$cert_subject" ]]; then @@ -86,7 +119,7 @@ function configure_tls { ./dehydrated -c >> /var/log/triton-dehydrated.log 2>&1 else echo 'No certificate name present. Generating self-signed.' - generate_self_signed_certificate + do_generate_self_signed_certificate fi if [[ -f $candidate_domains ]]; then rm -f "$candidate_domains" @@ -94,7 +127,7 @@ function configure_tls { ) } -function generate_self_signed_certificate { +function do_generate_self_signed_certificate { if [[ -f ${self_signed_cert_dir}/privkey.pem && \ -f ${self_signed_cert_dir}/cert.pem ]]; then echo "TLS Certificate Exists" @@ -111,6 +144,6 @@ function generate_self_signed_certificate { fi } -configure_haproxy -configure_tls -ensure_haproxy +do_configure_tls +do_configure_haproxy +do_ensure_haproxy diff --git a/tools/mock-mdata-get b/tools/mock-mdata-get index 4b554d8..6b19b0c 100755 --- a/tools/mock-mdata-get +++ b/tools/mock-mdata-get @@ -25,6 +25,8 @@ case $1 in echo 'Foo.exAmpLe.Com' ;; cloud.tritoncompute:max_rs) echo '64' ;; + cloud.tritoncompute:metrics_acl) + echo '192.168.1.1/24 192.168.2.0/24,192.168.3.3' ;; *) exit 1 ;;