Repository navigation
fix(chart): render namespace scoping and netobs keys into the Edge config - #18
Conversation
helm-unittest covers ConfigMap shape and render failures. tests/render/run.sh renders each case under tests/render/cases, checks config.json with jq, and with EDGE_SRC set also loads it with the Edge's own config loader (built via go build -overlay, so the Edge checkout is never written to). tests/ and ci/ are excluded from the packaged chart. Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
The template dropped config.kube.namespaceFilter, so namespace scoping set in values never reached the Edge. Write it whenever the map is non-empty. Before: cases ns-filter-allow/deny/none FAIL: .kube.namespaceFilter missing Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Mirror the Edge's validation (config.go:708-725) so a bad filter fails at helm install time instead of crashlooping the pod. Before: cases ns-filter-fail-* FAIL: render succeeded, expected failure Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Written whenever set, including "0s"; an explicit null counts as unset (Helm keeps the nil for keys not in the chart defaults, so it is checked). Before: cases ttl-1h, ttl-zero FAIL: .netobs.edgeExistenceTtl missing Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Written when set, including [] (which replaces the Edge default list); an explicit null counts as unset. Before: cases exclude-ns, exclude-ns-empty FAIL: .netobs.excludeNamespaces missing Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
services.address alone failed helm template (nil pointer on the missing
tls/compression/handshake maps) and the old fallbacks (empty durations,
unset maxConns) would have been rejected by the Edge anyway. Scalars are
now emitted only when set; services-full guards the previously supported
full config.
Before: case services-address-only FAIL: render failed: nil pointer evaluating interface {}.enabled
Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
The objects were rebuilt with ""/false/-1 fallbacks for every field, so a
partial config overrode Edge defaults with invalid zero values. Now only the
keys the user set are written, and an object is omitted when none are set
(never null); the Edge merges the partial object into its defaults.
Before: cases services-tls-enabled, services-handshake-timeout,
services-empty-objects FAIL: .services.tls == {"enabled":true} was false (all fields filled)
Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Covers compression.enabled=false, compression.level=0, workers=0 and empty
cipherSuites. No template change: the pickSet-based rendering from the
previous commit already handles them.
Against the pre-fix template: compression.enabled=false rendered
{enabled:false,type:"",level:-1}; level: 0 was rewritten to -1 by
`default -1`; falsy-scalars compression rendered null.
Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
…es defaults Add commented config.kube.namespaceFilter, netobs.edgeExistenceTtl and netobs.excludeNamespaces examples (noting that excludeNamespaces replaces the Edge default). Correct the config.services comments to the Edge v3.6.0 defaults. The values-examples render case uncomments the examples and checks they render and pass the Edge's config loader. Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Installs the chart on a throwaway kind cluster and checks the rendered ConfigMap, that the Edge accepts it and rolls out, that its startup log shows the namespace filter, that an upgrade to deny changes checksum/config and rolls the pod, and that an invalid filter fails at render. Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
Values given as strings (--set-string, quoted YAML) rendered as JSON strings and crashed the Edge's decoder, e.g. workers "8". Each key is now coerced per type (int64, bool, string, list) with a clear failure for values that cannot be, and objects are built without the float64 fromJson round-trip. An empty services.address is treated as unset (Edge default :6000) as before, and non-map tls/compression/handshake fail with a clear message. Before: services-quoted-scalars FAIL (workers rendered "8"), services-empty-address FAIL (address "" written, disabling DNSTap), services-fail-tls-not-map / -tls-false FAIL (raw Go template error) Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
The namespaceFilter guard accepted names the Edge rejects (uppercase, underscores, non-strings, empty, over 63 chars), which crashlooped the pod. Each entry is now checked as a DNS-1123 label. Wrong-typed namespaceFilter, excludeNamespaces and edgeExistenceTtl fail with a clear message instead of a Go template error or a bad config, and null mode/namespaces count as unset. Expect-fail patterns and unittest patterns now match their own guard's wording so a test cannot pass on the wrong guard. run.sh normalises a relative EDGE_SRC. Before: ns-filter-fail-uppercase/-nonstring/-empty-entry/-too-long FAIL (render succeeded), ns-filter-null-fields FAIL (nulls rendered), exclude-ns-fail-string and ttl-fail-number FAIL (render succeeded) Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
This fixes code introduced by PR #13, not by this change. helm upgrade --reuse-values from 0.5.2 reuses 0.5.2's values, which have no config.configMapCapture or config.envCapture maps, so the template hit a nil pointer. Default-values output is byte-identical to before. run.sh gains a replace-values marker: the case values.yaml replaces the chart defaults, which is what --reuse-values does. Before: case reuse-values-0.5.2 FAIL: nil pointer evaluating .Values.config.configMapCapture.clearText Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
After helm upgrade, pick the pod by its checksum/config annotation instead of reading logs from every pod of the release, so a leftover old pod cannot satisfy the deny assertion. Select the deployment by chart name too, and list yq in the dependencies. Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
|
@claude-fleet review |
|
Review task queued. Task: 86b67d97-f0fe-4ec5-845e-e2992f5f9698 |
There was a problem hiding this comment.
Workspace restored; git status shows only the pre-existing untracked node_modules.
Request changes — one narrow should_fix gap, the rest nits. The core of this PR is solid: the three unrendered keys now render, the validation is well-targeted, and the test suite genuinely covers it.
Findings:
- should_fix, templates/configmap.yaml:102 —
netobs.excludeNamespacesentries are not type-checked, so non-string entries reach the pod - nit, templates/configmap.yaml:93 —
edgeExistenceTtlis checked as a string but not as a parseable duration - nit, templates/configmap.yaml:33 — a
namespaceFiltermap with only unrecognized keys silently renders no filter - nit, tests/render/run.sh:61 — stderr is folded into the YAML the harness parses, so any benign helm warning fails every case
- nit, templates/configmap.yaml:69 — "byte-identical to #13's" in the description is not accurate
Verified:
kube.namespaceFilter,netobs.edgeExistenceTtlandnetobs.excludeNamespacesare written only when set, andnullcounts as unset — templates/configmap.yaml:27-54, 92-103; confirmed by thedefaults,ns-filter-null-fields,ttl-nullandexclude-ns-nullcases- Falsy values survive:
workers: 0,cipherSuites: [],excludeNamespaces: [],edgeExistenceTtl: 0s,requireClientCert: false— templates/_helpers.tpl:146 keeps a key onhasKeyand onlykindIs "invalid"drops it --set-stringcoercion works:workers: "8"renders8,enabled: "true"renderstrue— templates/_helpers.tpl:152-159, caseservices-quoted-scalarsservices.addressalone no longer panics. Reverting templates/configmap.yaml:69 to #13's block reproduces the reported error verbatim:nil pointer evaluating interface {}.enabledat configmap.yaml:77tls/compression/handshakerender as partial objects and empty ones are dropped — templates/_helpers.tpl:186-192, casesservices-empty-objects,services-tls-enabled--reuse-valuesfrom 0.5.2 works, and not only for the ConfigMap:helm templateof the whole chart against the 0.5.2 values file renders clean, soconfigMapCapture/envCaptureat templates/configmap.yaml:105,116 are the only two sites that needed guarding. I greppedtemplates/for other uses of the new #13 keys and found none- The rendered default config is semantically identical to #13's (
jq -Sdiff empty) — see the nit below for the byte-level caveat config.servicesis the only consumer of those values; nothing else intemplates/readsservices.addressor the filter
Checks run:
tests/render/run.sh→41 passed, 0 failed(helm v3.18.4)helm lint .→ 0 failed;helm unittest .(plugin v1.2.1) → 4 of 4 pass- Revert check, namespace filter: deleted templates/configmap.yaml:27-54, ran
run.sh ns-filter→ 14 of 15 fail (all 10expect-failcases render successfully;ns-filter-allow/deny/none/duplicatesfail theirexpect.jq). Restored. - Revert check, netobs: deleted templates/configmap.yaml:92-103, ran
run.sh ttlandrun.sh exclude-ns→ 6 of 8 fail. Restored. - Revert check, services: replaced templates/configmap.yaml:69 with #13's inline block, ran
run.sh services→ 12 of 15 fail, including the nil-pointer crash. Restored;git statusclean.
Smaller things:
.github/workflows/ci.yaml:4triggers only onpull_request. Pushes straight tomain(and the release path) run nothing.tests/render/run.sh:45doescp -R "$chart_root"for thereplace-valuescase, which copies.gitand anynode_modulesinto the temp chart.git archiveor--excludewould be cheaper.templates/configmap.yaml:108,119:$cmc.captureCap | default 4096means an explicitcaptureCap: 0silently becomes 4096. Inherited from #13 and the semantics are unchanged here, but the line is in this diff and the rest of the PR is careful about exactly this.tests/e2e/kind.shreadsimage.repository/image.tagfromvalues.yaml(lines 23-25), so it tracks the Chart.yaml pin automatically. Nice.
Not checked: the kind e2e run (no docker/kind in this environment), the EDGE_SRC loader path and tests/render/edgecheck/main.go (no Edge checkout reachable), and therefore the claim that the render-time checks mirror Edge v3.6.0's own validation — in particular whether the Edge accepts {"mode":"none"}, an empty mode, or duplicate namespaces, all of which this chart now renders.
Not checked:
- tests/e2e/kind.sh was not executed: no docker or kind in this environment. Reviewed by reading only.
- tests/render/edgecheck/main.go and the EDGE_SRC code path: no Edge checkout reachable, so
go build -overlayandconfig.LoadConfigFromReaderwere not exercised. - The claim that the render-time namespace-filter checks mirror Edge v3.6.0's own validation. In particular, whether the Edge accepts
{"mode":"none"}, an emptymodestring, or duplicate namespace entries, all of which the chart now renders (tests/render/cases/ns-filter-none, ns-filter-duplicates). - The documented Edge defaults added to values.yaml (maxConns 100, writeTimeout 10s, compression gzip, handshake 10s) were not verified against the Edge source.
Task 86b67d97-f0fe-4ec5-845e-e2992f5f9698 on rp2, model claude-opus-5, effort medium.
| {{- if not (kindIs "slice" .Values.config.netobs.excludeNamespaces) }} | ||
| {{- fail "config.netobs.excludeNamespaces must be a list" }} | ||
| {{- end }}, | ||
| "excludeNamespaces": {{ .Values.config.netobs.excludeNamespaces | toJson }} |
There was a problem hiding this comment.
should_fix: netobs.excludeNamespaces is checked for being a list but its entries are never type-checked, so non-string entries are passed straight through toJson into config.json. This is the one input in the PR that can still reach the pod malformed, which is the failure mode the rest of the change exists to prevent. The sibling key kube.namespaceFilter.namespaces goes through nofire-edge.typedPick's strlist, which rejects a non-string entry at render (templates/_helpers.tpl:164-166) and has a dedicated case (tests/render/cases/ns-filter-fail-nonstring).
Failure: config.netobs.excludeNamespaces: [1, 2] renders "excludeNamespaces":[1,2]; the Edge decodes that field into a []string and fails at startup, crashlooping the pod.
Evidence: I ran helm template t . -f /tmp/v1.yaml -s templates/configmap.yaml | yq -r '.data["config.json"]' | jq -c '.netobs.excludeNamespaces' with those values and got [1,2]. The only guard is the kindIs "slice" check at templates/configmap.yaml:99.
Fix: route it through the existing helper, e.g. {{- $ne := dict }}{{- $_ := include "nofire-edge.typedPick" (dict "src" .Values.config.netobs "path" "config.netobs" "out" $ne "spec" (dict "excludeNamespaces" "strlist")) }}. Validating entries as DNS-1123 labels too, as the filter does at line 46, would make the two lists consistent.
There was a problem hiding this comment.
Fixed in f0ea3d1. Every entry is now type-checked and the render fails on a non-string: excludeNamespaces: [1,2] gives config.netobs.excludeNamespaces entry 1 must be a string. I confirmed the Edge v3.6.0 loader rejects [1,2] (cannot unmarshal number … of type string).
I deliberately did not add the DNS-1123 check. The Edge loader accepts ["Prod_1"] here (unlike namespaceFilter.namespaces), and an unmatched name just excludes nothing. So the chart stays aligned with what the Edge accepts. The exclude-ns-uppercase case records that decision. Tests: unittest plus exclude-ns-fail-number, exclude-ns-fail-string, exclude-ns-uppercase, exclude-ns-empty, exclude-ns-null.
| "source": {{ .Values.config.netobs.source | default "" | quote }}, | ||
| "prometheusTimeout": {{ .Values.config.netobs.prometheusTimeout | default "10s" | quote }} | ||
| {{- if and (hasKey .Values.config.netobs "edgeExistenceTtl") (not (kindIs "invalid" .Values.config.netobs.edgeExistenceTtl)) }} | ||
| {{- if not (kindIs "string" .Values.config.netobs.edgeExistenceTtl) }} |
There was a problem hiding this comment.
nit: edgeExistenceTtl is validated as a string but not as a Go duration, so a typo renders successfully and only fails inside the Edge. Narrow, and it fails closed (the pod does not start with a wrong TTL), but the PR validates namespace names at render for exactly this reason.
Failure: config.netobs.edgeExistenceTtl: "not-a-duration" renders "edgeExistenceTtl":"not-a-duration" and the Edge's time.ParseDuration rejects it at startup.
Evidence: ran helm template with that value and jq -c '.netobs.edgeExistenceTtl' printed "not-a-duration". templates/configmap.yaml:93 only checks kindIs "string".
Fix: add regexMatch "^-?([0-9]+(\\.[0-9]+)?(ns|us|ms|s|m|h))+$" alongside the kind check.
There was a problem hiding this comment.
Fixed in 206d63b. edgeExistenceTtl must now match Go duration syntax. not-a-duration gives … is not a valid duration; use Go syntax such as 2h, 90m or 1h30m, and so does a bare 30 with no unit. The leading -, fractions, compound values, µs/us and "0" are still accepted, since time.ParseDuration accepts them. Every ttl-ok-* case also passes the Edge v3.6.0 loader.
| {{- end }} | ||
| {{- $nf := dict }} | ||
| {{- $_ := include "nofire-edge.typedPick" (dict "src" $nfRaw "path" "config.kube.namespaceFilter" "out" $nf "spec" (dict "mode" "string" "namespaces" "strlist")) }} | ||
| {{- if $nf }} |
There was a problem hiding this comment.
nit: {{- if $nf }} skips both the validation and the render when typedPick produced an empty dict, which happens when the user's namespaceFilter map contains only keys the spec does not know. The result is a silently ignored namespace filter: the same class of bug this PR fixes.
Failure: config.kube.namespaceFilter: {node: allow} (a plausible typo for mode) renders with no namespaceFilter key at all and no warning; the Edge graphs the whole cluster. A typo in only one of the two keys, such as {modes: allow, namespaces: [x]}, does fail, so the behaviour is inconsistent.
Evidence: ran helm template with namespaceFilter: {node: allow}; jq '.kube | has("namespaceFilter")' returned false.
Fix: when the source map is non-empty but $nf is empty, fail with the unrecognized key names.
There was a problem hiding this comment.
Fixed in 446f0cb. Any key other than mode/namespaces now fails the render: {node: allow} gives config.kube.namespaceFilter has unknown key "node"; supported keys are mode and namespaces. This applies with or without a valid mode alongside (cases ns-filter-fail-unknown-key, ns-filter-fail-unknown-key-valid-mode, plus a unittest).
| continue | ||
| fi | ||
|
|
||
| if ! out="$(helm template t "$chart" ${vals[@]+"${vals[@]}"} -s templates/configmap.yaml 2>&1)"; then |
There was a problem hiding this comment.
nit: The success path captures stderr into $out (2>&1) and then feeds $out to yq as YAML at line 66. Any non-fatal warning helm writes to stderr corrupts the document and every case fails with a message that points nowhere near the cause.
Failure: with a symlink anywhere under the chart root, helm prints walk.go:75: found symbolic link in path: ... to stderr; the suite then aborts on the first case with Error: bad file '-': yaml: mapping values are not allowed in this context and reports nothing else. I hit this on the first run of the suite in this workspace.
Evidence: helm template t . -f tests/render/cases/defaults/values.yaml -s templates/configmap.yaml 2>&1 1>/dev/null prints the warning, confirming it is on stderr. After removing the symlink the suite reports 41 passed, 0 failed.
Fix: capture stderr separately on the success path (2>"$tmp/stderr") and only merge it in the expect-fail branch at line 51, which does need it.
There was a problem hiding this comment.
Fixed in f4ca8f6. On the success path, stderr now goes to its own file and is printed only when a case fails; the expect-fail branch still matches against it. The new tests/render/harness_test.sh reproduces your symlink scenario in a temp copy of the chart and asserts the suite still passes. It runs in CI. The same commit replaces the cp -R for replace-values with a chart-only copy that skips .git, node_modules and tests.
| } | ||
| {{- end }} | ||
| }, | ||
| "services": {{ include "nofire-edge.servicesJson" . }}, |
There was a problem hiding this comment.
nit: The description says the generated config.json is "byte-identical to #13's" with default values and with examples/production-values.yaml. It is semantically identical, not byte-identical: the services object is now emitted by toJson on one line.
Failure: none at runtime, but checksum/config in the Deployment is a hash of the ConfigMap text, so anyone already on a 0.6.0 pre-release gets a pod roll on upgrade even with unchanged values. Worth stating accurately in the body since the PR's upgrade notes are otherwise thorough.
Evidence: diff of the two renders shows "services": {\n "workers": 4\n }, becoming "services": {"workers":4}, for both value sets; diff <(jq -S . base.json) <(jq -S . head.json) is empty.
There was a problem hiding this comment.
Agreed, that was inaccurate. I updated the description: it is semantically identical (jq -S diff empty), not byte-identical. The services line is now compact JSON, so checksum/config changes and pods roll once on upgrade, even with unchanged values.
excludeNamespaces [1, 2] rendered and the Edge then failed to unmarshal a number into a string. Entries are now type-checked (strings only). Names are deliberately not validated further: the Edge accepts e.g. "Prod_1" here, which exclude-ns-uppercase documents. Before: case exclude-ns-fail-number FAIL (render succeeded, expected failure); unittest 'fails on a non-string excludeNamespaces entry' failed Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
"not-a-duration" rendered and the Edge rejected it at startup. The value is now matched against Go duration syntax (sign, fractions, compound 1h30m, ns/us/µs/ms/s/m/h, and plain "0") and fails the render otherwise. The ttl-ok-* cases pass the Edge loader, including "-1h" which it accepts. Before: ttl-fail-invalid and ttl-fail-missing-unit FAIL (render succeeded); two unittest cases failed Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
namespaceFilter {node: allow} (a typo for mode) rendered nothing and silently
left every namespace in scope. Any key other than mode and namespaces now
fails the render and names the key.
Before: cases ns-filter-fail-unknown-key and -valid-mode FAIL (render
succeeded); unittest 'fails on an unknown namespaceFilter key' failed
Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
run.sh merged stderr into the manifest it parsed, so a helm warning on a successful render (e.g. a symlink in the chart) broke yq. stdout and stderr are now captured separately; stderr is matched only for expect-fail cases and printed on failure. replace-values cases copy only chart files (no .git, node_modules or tests). harness_test.sh covers this with a symlink in a temp copy of the chart and runs in CI, which now also triggers on push to main. Before: harness_test.sh FAIL: yq 'bad file -: mapping values are not allowed' (helm's 'found symbolic link in path' warning parsed as YAML) Signed-off-by: stheppi <stefan.bocutiu@gmail.com>
|
All five inline findings are addressed in f0ea3d1..f4ca8f6 Smaller points from the review body
Your "Not checked" list, now checked
Current numbers: |
5eb7078
into
feat/endpoints-access-and-configmap-capture
Summary
Chart 0.5.2 (and #13 as it stands) never writes
config.kube.namespaceFilter,config.netobs.excludeNamespacesorconfig.netobs.edgeExistenceTtlinto the Edge'sconfig.json. Setting them through Helm does nothing, and nothing reports it. Settingconfig.services.addresson its own also breakshelm templatewith a nil pointer.This PR makes the ConfigMap template write those keys whenever they're set, and makes every
services.*sub-key optional. It targets #13 so the fix ships in 0.6.0 rather than as a separate 0.5.3.kube.namespaceFilterwhen it's set. Invalid filters failhelm install/upgradewith a clear message instead of crashlooping the pod. That covers an unknown mode, a mode and namespace list that don't agree, names that aren't DNS-1123 labels, and wrong types. The checks mirror the Edge v3.6.0 validation.edgeExistenceTtlandexcludeNamespacesare written when set and left out when unset, so the Edge defaults apply. Explicitfalse,0and[]are kept.nullcounts as unset.services: each key is written only when you set it, and coerced to the type the Edge expects, so--set-string workers=8gives a number.tls,compressionandhandshakerender as partial objects, which the Edge merges into its defaults.--reuse-valuesfrom 0.5.2: upgrading this way crashed on a nil pointer in feat(chart): enable Edge v3.6.0 features and pin to v3.6.0 (chart 0.6.0) #13'sconfigMapCapture/envCaptureblocks, because 0.5.2's values have no such maps. A separate commit makes those blocks nil-safe.values.yamldocuments the new keys and the real Edge defaults forservices.Testing
Each fix was written test-first; the failing output from before each change is in the commit bodies.
helm lint .: passeshelm unittest .: 10 of 10 pass (tests/configmap_test.yaml)tests/render/run.sh: 53 of 53 cases pass. Each case renders the chart with its own values and checks the exactconfig.jsonwithjq, or checks that rendering fails with the right message.EDGE_SRC=<edge checkout at v3.6.0> tests/render/run.shalso feeds every rendered config to the Edge's ownconfig.LoadConfigFromReader.tests/e2e/kind.shpasses end to end on a local kind cluster:allowfilter and checks the installed ConfigMap and the Edge's startup loghelm upgradetodenyand checks thatchecksum/configchanges and the new pod logsdenyexamples/production-values.yaml, the generatedconfig.jsonis semantically identical to feat(chart): enable Edge v3.6.0 features and pin to v3.6.0 (chart 0.6.0) #13's (jq -Sdiff empty). It is not byte-identical:servicesis now written as one line of compact JSON, so thechecksum/confighash changes and pods roll once on upgrade, even with unchanged values.tests/render/harness_test.shchecks that helm's stderr warnings (e.g. a symlink in the chart) don't leak into the parsed output. It also runs in CI..github/workflows/ci.yamlruns lint, helm-unittest, the render cases and the harness test on every PR and on pushes tomain. The Edge loader check and kind stay local-only.Local kind evidence
These runs were on a local kind cluster against commit
530084b(re-run onf4ca8f6after the review fixes: all checks pass):nofireai/edge:v3.6.0(sha256:4b577d0e…62bd32f).ci/kind-values.yaml(namespaceFilter: allow [default],excludeNamespaces: [x],edgeExistenceTtl: 1h, publishing off).7e8108e.1. Behaviour: what each Edge actually graphs
The cluster ran a
webDeployment indefaultand another inpayments. After a 45s initial sync, I port-forwarded to each Edge and counted the resources per namespace in its liveGET /graph:/graph(resources)/graph/statsdefault14,kube-system24,local-path-storage6,payments5,base9,kube-public2,kube-node-lease1default14With #13's chart the filter never reaches the Edge, so it graphs the whole cluster. With this PR it graphs only
default.2. The installed ConfigMap (
kubectl get cm … -o jsonpath='{.data.config\.json}')Before (#13):
namespaceFilter=false excludeNamespaces=false edgeExistenceTtl=falsehelm template --set config.services.address=:6000→nil pointer evaluating interface {}.enabledAfter (this PR)
3. The Edge accepted it
The pod
e2e-nofire-edge-7f7b7dcf89-9tg2jreached1/1 Runningwith 0 restarts. The Edge's own startup log shows the filter it loaded, along with the Edge defaults it filled in forservices:4.
helm upgraderolls the pod with the new confighelm upgrade --set config.kube.namespaceFilter.mode=deny:5. Invalid values fail at install, not in the pod
Neither release was created (
helm list -Ashows onlybaseande2e).6. Scripted e2e
tests/e2e/kind.shasserts sections 2 to 5 automatically and passed on530084b:The
/graphcomparison in section 1 was a one-off script run, not part ofkind.sh.Notes
Merge this into #13 before #13 lands.
release.ymlpublishes whenChart.yamlchanges onmain, and #13 already sets0.6.0. If #13 merges first, 0.6.0 ships without this fix and it needs a 0.6.1.Behaviour changes for existing users
services.addressalso wrote compression as disabled with an empty type, an empty handshake content type, and empty TLS paths. Now the Edge defaults apply: compression on with gzip, a 10s handshake,maxConns100.address:services.address: ""is treated as unset, so the Edge listens on its default:6000.excludeNamespacesreplaces the list: setting it replaces the Edge default[kube-system, monitoring]instead of adding to it. Namespaces from adenyfilter are still added by the Edge.Out of scope
services.nameLabels,versionLabels,serviceNameEnvVarsorenableOTEL, and this PR leaves them out too.manifests.yaml(the static manifest at the repo root) is unchanged.Follow-ups after 0.6.0 releases
EDGE_CHART_VERSIONto 0.6.0.0.5.2" notes (NOFireAI/docs#43).I implemented this with Claude Code: Sonnet wrote the changes test-first, and Opus reviewed the plan and the final diff adversarially. I re-ran every test locally before opening this PR.
Fixes #17
Refs: #13, NOFireAI/docs#42, NOFireAI/docs#43, NOFireAI/dashboard#915