Skip to content

Commit e032f1a

Browse files
fix(observability): reject prometheusScrape with no monitors
prometheusScrape.enabled=true with both serviceMonitor.enabled and podMonitor.enabled false is contradictory: otelCIScrapeEnabled stayed true, so an idle Target Allocator rendered and CRDs bundled while nothing was discovered. Add validatePrometheusScrape, invoked from the always-rendered custom-resource template, to fail loudly with guidance (enable a monitor or set prometheusScrape.enabled=false). Add a matrix expect_fail assertion.
1 parent 6d95450 commit e032f1a

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

charts/amazon-cloudwatch-observability/templates/_helpers.tpl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,20 @@ otelContainerInsights.serviceMonitor.enabled / .podMonitor.enabled if set
254254
{{- if $v -}}true{{- end -}}
255255
{{- end -}}
256256

257+
{{/*
258+
Reject a contradictory scraping config. prometheusScrape.enabled=true with BOTH
259+
ServiceMonitor and PodMonitor discovery disabled would render an idle Target Allocator
260+
(and bundle CRDs) that discovers nothing. Fail loudly rather than ship a no-op path.
261+
Invoked from an always-rendered template so it runs regardless of which agents render.
262+
*/}}
263+
{{- define "cloudwatch-agent.validatePrometheusScrape" -}}
264+
{{- if and .Values.otelContainerInsights.enabled (dig "prometheusScrape" "enabled" true .Values.otelContainerInsights) -}}
265+
{{- if and (ne (include "cloudwatch-agent.serviceMonitorEnabled" .) "true") (ne (include "cloudwatch-agent.podMonitorEnabled" .) "true") -}}
266+
{{- fail "otelContainerInsights.prometheusScrape.enabled=true requires at least one of prometheusScrape.serviceMonitor.enabled or prometheusScrape.podMonitor.enabled to be true; enable one, or set prometheusScrape.enabled=false" -}}
267+
{{- end -}}
268+
{{- end -}}
269+
{{- end -}}
270+
257271
{{/*
258272
Helper function to modify cloudwatch-agent config
259273
*/}}

charts/amazon-cloudwatch-observability/templates/linux/cloudwatch-agent-custom-resource.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{{- if .Values.agent.enabled }}
2+
{{- include "cloudwatch-agent.validatePrometheusScrape" . -}}
23
{{- if and (.Values.agent.autoGenerateCert.enabled) (not .Values.agent.certManager.enabled) -}}
34
{{- $altNames := list ( printf "%s-service" (include "dcgm-exporter.name" .) ) ( printf "%s-service" (include "neuron-monitor.name" .) ) ( printf "%s-service.%s.svc" (include "dcgm-exporter.name" .) .Release.Namespace ) ( printf "%s-service.%s.svc" (include "neuron-monitor.name" .) .Release.Namespace ) ( printf "%s-service" (include "node-exporter.name" .) ) ( printf "%s-service.%s.svc" (include "node-exporter.name" .) .Release.Namespace ) ( include "kube-state-metrics.name" . ) ( printf "%s.%s.svc" (include "kube-state-metrics.name" .) .Release.Namespace ) -}}
45
{{- range $i, $customAgent := .Values.agents }}

charts/amazon-cloudwatch-observability/tests/prometheus_crds_matrix.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ expect_count() {
5353
fi
5454
}
5555

56+
# expect_fail <desc> <pattern> <render-args...> -- expects helm to error with output matching <pattern>
57+
expect_fail() {
58+
local desc="$1" pattern="$2"; shift 2
59+
local out
60+
if out="$(render "$@")"; then
61+
printf "${R}FAIL${N} %s (expected helm error, render succeeded) [%s]\n" "$desc" "$*"
62+
fail_count=$((fail_count+1)); return
63+
fi
64+
if printf '%s\n' "$out" | grep -qE "$pattern"; then
65+
printf "${G}PASS${N} %s (rejected as expected)\n" "$desc"
66+
pass_count=$((pass_count+1))
67+
else
68+
printf "${R}FAIL${N} %s (errored but message missing /%s/) [%s]\n" "$desc" "$pattern" "$*"
69+
fail_count=$((fail_count+1))
70+
fi
71+
}
72+
5673
printf "${Y}== CRD bundling gating ==${N}\n"
5774
# auto (default): bundle only when otelContainerInsights.enabled (and prometheusScrape enabled).
5875
expect_count "auto + otelCI on => ServiceMonitor CRD bundled" "$SM_CRD" 1 --set otelContainerInsights.enabled=true
@@ -87,6 +104,14 @@ expect_count "TA absent when scrape off" 'targetAllocator:' 0 --set
87104
expect_count "SM disabled => serviceMonitorSelector rendered" 'serviceMonitorSelector' 1 --set otelContainerInsights.enabled=true --set otelContainerInsights.prometheusScrape.serviceMonitor.enabled=false
88105
expect_count "SM disabled => podMonitorSelector absent" 'podMonitorSelector' 0 --set otelContainerInsights.enabled=true --set otelContainerInsights.prometheusScrape.serviceMonitor.enabled=false
89106

107+
printf "\n${Y}== both monitors disabled => rejected ==${N}\n"
108+
# prometheusScrape.enabled=true with both monitor types off is contradictory (idle TA,
109+
# bundled CRDs, nothing discovered) and must fail rather than render a no-op path.
110+
expect_fail "scrape on + both monitors off => render fails" 'requires at least one of' \
111+
--set otelContainerInsights.enabled=true \
112+
--set otelContainerInsights.prometheusScrape.serviceMonitor.enabled=false \
113+
--set otelContainerInsights.prometheusScrape.podMonitor.enabled=false
114+
90115
printf "\n${Y}== per-node allocation strategy default ==${N}\n"
91116
expect_count "otelCI on => TA allocationStrategy per-node" 'allocationStrategy: "per-node"' 1 --set otelContainerInsights.enabled=true
92117
expect_count "override => TA allocationStrategy consistent-hashing" 'allocationStrategy: "consistent-hashing"' 1 --set otelContainerInsights.enabled=true --set otelContainerInsights.prometheusScrape.allocationStrategy=consistent-hashing

0 commit comments

Comments
 (0)