Description
In the Helm chart v0.25.6, setting configs.watch.namespaces in user-provided values.yaml has no effect on the rendered ConfigMap. The config.yaml data inside ConfigMap clickhouse-operator-files always contains watch.namespaces: [], regardless of what is passed via values.
This means the operator only watches its own namespace and never discovers CHI resources in other namespaces — a common deployment pattern (e.g., operator in clickhouse-operator, CHI in clickhouse).
Root Cause
The values.yaml has two separate paths that both define watch.namespaces:
-
configs.watch.namespaces (line ~153 in values.yaml) — appears to be intended as the user-facing config knob, but is never used by any template.
-
configs.files.config.yaml.watch.namespaces (line ~261 in values.yaml) — this is the actual YAML blob embedded as a multi-level dict inside configs.files, and it is hardcoded to []. The ConfigMap template (ConfigMap-etc-clickhouse-operator-files.yaml) renders configs.files directly via:
data: {{ include "altinity-clickhouse-operator.configmap-data" (list . .Values.configs.files) | nindent 2 }}
Since the template reads from configs.files (which contains the full config.yaml structure with watch.namespaces: [] hardcoded), the top-level configs.watch.namespaces value is completely ignored.
Steps to Reproduce
# 1. Add the Altinity Helm repo
helm repo add altinity https://helm.altinity.com
helm repo update
# 2. Create a values file that sets watch.namespaces
cat > /tmp/test-values.yaml << 'YAML'
configs:
watch:
namespaces:
- clickhouse
- my-other-namespace
YAML
# 3. Render the template
helm template test-operator altinity/altinity-clickhouse-operator \
--version 0.25.6 \
-n clickhouse-operator \
-f /tmp/test-values.yaml \
--show-only templates/generated/ConfigMap-etc-clickhouse-operator-files.yaml \
2>&1 | grep -A2 'watch'
Expected output
watch:
namespaces:
- clickhouse
- my-other-namespace
Actual output
The user-provided configs.watch.namespaces is silently ignored.
Workaround
To actually set watch namespaces, users must override the deeply nested configs.files path instead:
# This works (but is not discoverable):
configs:
files:
config.yaml:
watch:
namespaces:
- clickhouse
However, overriding configs.files.config.yaml replaces the entire config.yaml blob due to Helm's deep merge behavior on maps, which means users must copy the full default config.yaml content and modify only the watch section — error-prone and not maintainable across upgrades.
An alternative workaround is to patch the ConfigMap after helm install and restart the operator pod:
# Patch ConfigMap and restart
kubectl get configmap clickhouse-operator-files -n clickhouse-operator -o json | \
python3 -c "
import json, sys, yaml
cm = json.load(sys.stdin)
config = yaml.safe_load(cm['data']['config.yaml'])
config['watch']['namespaces'] = ['clickhouse']
cm['data']['config.yaml'] = yaml.dump(config, default_flow_style=False)
json.dump(cm, sys.stdout)
" | kubectl apply -f -
kubectl delete pod -n clickhouse-operator -l app.kubernetes.io/name=altinity-clickhouse-operator
Suggested Fix
The ConfigMap template (or the configmap-data helper) should merge configs.watch.namespaces into the config.yaml content before rendering, or the values.yaml should be restructured so that the user-facing configs.watch.namespaces actually controls the value inside configs.files.config.yaml.watch.namespaces.
Environment
- Chart:
altinity/altinity-clickhouse-operator v0.25.6
- Helm: v3.x / v4.x
- Kubernetes: EKS 1.29–1.33
Description
In the Helm chart v0.25.6, setting
configs.watch.namespacesin user-providedvalues.yamlhas no effect on the rendered ConfigMap. Theconfig.yamldata inside ConfigMapclickhouse-operator-filesalways containswatch.namespaces: [], regardless of what is passed via values.This means the operator only watches its own namespace and never discovers CHI resources in other namespaces — a common deployment pattern (e.g., operator in
clickhouse-operator, CHI inclickhouse).Root Cause
The
values.yamlhas two separate paths that both definewatch.namespaces:configs.watch.namespaces(line ~153 in values.yaml) — appears to be intended as the user-facing config knob, but is never used by any template.configs.files.config.yaml.watch.namespaces(line ~261 in values.yaml) — this is the actual YAML blob embedded as a multi-level dict insideconfigs.files, and it is hardcoded to[]. The ConfigMap template (ConfigMap-etc-clickhouse-operator-files.yaml) rendersconfigs.filesdirectly via:Since the template reads from
configs.files(which contains the fullconfig.yamlstructure withwatch.namespaces: []hardcoded), the top-levelconfigs.watch.namespacesvalue is completely ignored.Steps to Reproduce
Expected output
Actual output
The user-provided
configs.watch.namespacesis silently ignored.Workaround
To actually set watch namespaces, users must override the deeply nested
configs.filespath instead:However, overriding
configs.files.config.yamlreplaces the entireconfig.yamlblob due to Helm's deep merge behavior on maps, which means users must copy the full defaultconfig.yamlcontent and modify only the watch section — error-prone and not maintainable across upgrades.An alternative workaround is to patch the ConfigMap after
helm installand restart the operator pod:Suggested Fix
The ConfigMap template (or the
configmap-datahelper) should mergeconfigs.watch.namespacesinto theconfig.yamlcontent before rendering, or thevalues.yamlshould be restructured so that the user-facingconfigs.watch.namespacesactually controls the value insideconfigs.files.config.yaml.watch.namespaces.Environment
altinity/altinity-clickhouse-operatorv0.25.6