Repository navigation
feat(cli): .policies holds what each cluster's Kyverno policies need, and deploy applies it - #578
Conversation
…sses PR #540 merged into feat/kyverno-check after #539 had been squashed onto main, so it never reached main. This is that change on today's main. kates kyverno check --chart <name> (repeatable) and --stack check the charts kates deploy installs: strimzi-operator, monitoring, kafka-cluster, connect-cluster, mirror-maker2 and kates. --stack takes the ones deploy's --with-* flags select, each in the namespace deploy's --*-ns flags resolve (-n puts every chart in one), after the helm dependency command deploy runs on it. -f and --set apply to every chart, or to one as <chart>=... --write-values <dir> writes <chart>-kyverno.yaml for each chart with a failed rule: a missing pod label set to the value --label gives, under every value that labels the chart's pods (the keys label_args in scripts/check-chart-policies.sh uses, held equal by a test), and every other rule as a commented kyvernoPolicy.exceptions entry, or a note where the chart has none. Values already in the file are kept. inNamespace now edits YAML nodes: kube-prometheus-stack renders a label twice when commonLabels and a component's podLabels both set it, which helm and kyverno accept and a map decode refused. #541's exception scope carries over to every chart: the admission controller's exception namespace is read once, exceptions Kyverno would ignore are dropped, the render's own PolicyException counts only where Kyverno accepts exceptions, and each chart's report has exceptionNote. -o json is now a list, one report per chart, each naming its chart.
… and deploy applies it .policies is a git-ignored YAML file with one environment per kube context: namespaceLabels, podLabels, values per chart, and the rules the last check left unresolved. Kates writes it 0600 and warns when git tracks it. kates deploy reads the environment of the context it deploys to. namespaceLabels label its namespaces, after .labels and before KATES_NAMESPACE_LABELS and --namespace-label. podLabels go under every value that labels each chart's pods (chartPodLabelKeys, held equal to label_args in scripts/check-chart-policies.sh for every chart deploy installs). values go to each chart in a file passed after deploy's own. Unresolved rules are a warning. --policies-file names another file. kates kyverno check applies the current context's environment to each render the way deploy does, and checks each namespace as the Namespace deploy would create, with its labels. --write-policies writes that environment: a rule that failed on a missing label sets every label its policy's pattern requires there (Kyverno reports only the first), from --label, else the one exact value the pattern names. A label with no known value, a value a policy refuses, and every other failed rule go under unresolved with the fix the check suggests. Other environments and values already set are kept. .labels is still read as namespace labels, with a hint that .policies holds them now.
…lues file The notes kyverno check writes into <chart>-kyverno.yaml quote the cluster's policy messages. Only \n was folded, so a \r, NEL, LS or PS in a message ended the comment and the rest parsed as values. Every whitespace run now folds to a space, after invalid UTF-8 is replaced.
…nto feat/labels-pod-section
There was a problem hiding this comment.
Graphify reviewed this change.
Code graph out of date: Health delta baseline: last indexed commit 0a08117, 7 commit(s) behind this PR's base. Impact and hotspot numbers below may be wrong.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Not checked: tests were not run; no formal proof of the changed code.
Graphify review — findings
Adds a per-kube-context .policies file that feeds namespace labels and per-chart Helm values into kates deploy. It is re-read once the target context is pinned, and each chart's values are appended after deploy's own -f files so they take precedence. In namespaceUserLabels, its namespaceLabels are merged after .labels but before KATES_NAMESPACE_LABELS and --namespace-label, and a hint tells users .labels is superseded. Also adds a Kyverno check that resolves the chart stack against those policies, with the CLI reference and deployment docs updated to match.
Worth a look
- .policies namespaceLabels bypass label validation and the reserved-domain check —
cli/cmd/deploy_labels.go:76· Escalate · medium- NOT verified (no proof, no reproducing execution) — needs human review
- Kafka stack chart uses chart-root-relative values path with chart prefix —
cli/cmd/kyverno_check.go:62· Escalate · medium- NOT verified (no proof, no reproducing execution) — needs human review
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 976 functions depend on the 603 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
runDeploy()— 20 callers, 30 callees - worse:
namespaceUserLabels()— 11 callers, 6 callees - new:
writeKyvernoValues()— 4 callers, 6 callees - new:
recoverStuckReleases()— 6 callers, 4 callees - worse:
runComponents()— 7 callers, 3 callees - new:
recoverStuckRelease()— 1 callers, 8 callees - new:
checkKyvernoChart()— 1 callers, 7 callees - new:
runDeployAndReport()— 1 callers, 6 callees - …and 1 more — each is listed as a finding
Verification — 976 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 0a08117, 7 commit(s) behind this PR's base.
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 862 function(s) in the blast radius were not formally verified this run
Docs that may be stale (advisory)
docs/book/05-test-types.md§ How a ROUND_TRIP Run Works (lines 249-276): references changed symbolsnotedocs/book/06-chaos-theory.md§ Leader Election (lines 180-204): references changed symbolsaccepts,notedocs/book/11-api-reference.md§ Workflow 3: Export Results in Different Formats (lines 1600-1643): references changed symbolsacceptsdocs/book/21-kafka-connect.md§ How EOS Works (lines 663-685): references changed symbolsnotedocs/book/STYLE.md§ Callouts (lines 74-92): references changed symbolsnotedocs/book/appendix-compliance-language.md§ Waivers (lines 307-327): references changed symbolsnotedocs/book/appendix-compliance-language.md§ The Report (lines 328-365): references changed symbolsnotedocs/book/compliance.md§ When the Cluster Falls Short (lines 479-516): references changed symbolsnoteplans/book-professional-edition.md§ 04-performance-theory.md (lines 176-225): references changed symbolsnoteplans/book-professional-edition.md§ 22-mirror-maker2-migration.md (lines 960-996): references changed symbolsnote
…and 2 more.
· 4 grounded finding(s) anchored inline below; 5 more finding(s) on lines outside this diff (see the check run).
…to Check the Labels lands The first namespaceUserLabels call in runDeploy only validates, so its results go unassigned (ineffassign). The Check the Labels heading gets the explicit id its GitHub slug has, so Quarto renders the id the new .policies section links to.
…into named helpers namespaceUserLabels reads .labels and .policies through addLabelsFileLabels and addPoliciesNamespaceLabels. checkKyvernoChart runs kyverno through runKyvernoApply, renderKyvernoChartCheck prints exceptions through renderKyvernoExceptions, and writeKyvernoValues reads its file through readValuesFile. setPodLabels is the one walk that puts pod labels under a chart's label values, shared by writeKyvernoValues and .policies' chartValues, which each had their own copy.
… the checkout alone Review fixes: - --stack and --chart also cover cdc-postgresql, apicurio-registry, kafka-ui and kates-chaos, selected by deploy's --with-kafka-connect, --with-schema-registry, --with-kafka-ui and --with-chaos. - The check takes deploy's --topology, --db-ns, --chaos-ns and --ui-ns, so a stack's namespaces are deploy's under either topology. - A chart's helm dependency command runs only when helm dependency list finds a dependency missing: it rewrites Chart.lock and charts/ and needs the network. - --label is held to the label syntax, and needs --write-values. - Cluster-scoped policies and every namespace's exceptions are listed once a run, not once per namespace; a refused -A is asked once. - The default chart is chosen by name, not by its place in the list. - Kyverno with exceptions on but no --exceptionNamespace accepts none (Kyverno 1.17's NewExceptionSelector); the note now says so. - The book's Check the Labels heading gets its explicit id.
…nto feat/labels-pod-section # Conflicts: # cli/cmd/kyverno_check.go # docs/book/10-cli-reference.md
# Conflicts: # cli/cmd/kyverno_check.go # cli/cmd/kyverno_check_test.go # docs/book/10-cli-reference.md
Merge #577 first. This branch carries #577's two commits; after #577 squash-merges, I'll merge main in.
Why
kates deploygave namespaces their labels from.labels, but had no way to label pods or pass the chart values a cluster's Kyverno policies need. On a cluster with an Enforce "pods needteam" policy, the namespaces were created and thenhelm upgrade --installwas refused at admission. #577'skyverno checkcould find the gap but deploy couldn't act on it.What
.policies, git-ignored (.gitignore), written mode 0600, with a warning if git tracks it. It has one environment per kube context:kates deployreads the environment of the context it deploys to:namespaceLabelssit between.labelsandKATES_NAMESPACE_LABELSin precedence.podLabelsgo under every value that labels each chart's pods.chartPodLabelKeyscovers every chart deploy installs; a test holds it equal tolabel_argsinscripts/check-chart-policies.sh, which proves in CI that those values reach every pod.values.<chart>goes in a file passed after deploy's own values files, so deploy's--setvalues still win.unresolvedentries are a warning.--policies-filenames another file.kates kyverno check--write-policiesfills the environment. Kyverno reports only the first missing label of a rule, so the check reads the failing rule's pattern for every label it requires. A label's value comes from--label, else the one exact value the pattern names.?*,a | b, a refused value, and every non-label rule go underunresolvedwith the suggested fix..labelsis still read as namespace labels, with a one-line hint that.policiesholds them now.--labels-fileis unchanged.Not covered
kates auto,kates kyverno applyand the admin-less gate's scratch installs don't applypodLabels/valuesyet. They do get.policies' namespace labels, through the shared label reader.Tests
cli:go test ./...,go vet,golangci-lint --new-from-rev=origin/main(0 issues),govulncheck(none). New tests:withFindingsscripts/check-cli-style.sh,check-cli-compat.sh,check-book-style.sh,gen-book-index.py --check,gen-version-matrix.sh --checkkyvpol, deleted after) with Kyverno 1.17.2 and two Enforce ClusterPolicies: Namespace needscost-center: cc-42andowner: ?*; Pod needsteam: ?*andtier: data.kyverno check --chart kates -n kates --label team=payments --write-policies: exit 1. It wrotecost-center: cc-42,team: paymentsandtier: data, and listedowneras unresolved. Another environment in the file was kept, and the file ended up 0600.owner: exit 0, "Every rule passes (6 passed)".katesnamespace was refused and the labelled one created. The kates chart with onlytierset was denied 5 times on a server dry-run, and with both labels it applied with no errors../mvnw test(no backend change; feat(cli): kyverno check covers the stack and writes the values it misses #577's run on the same backend tree was 1,790 green), a fullkates deployon the scratch cluster, and the book render.