Skip to content

fix(chaos): a fault that names no targetNamespace is in the Kafka cluster's namespace, wherever it is - #442

Merged
bmscomp merged 2 commits into
mainfrom
fix/faultspec-namespace-follows-kafka
Oct 21, 2026
Merged

bmscomp merged 2 commits into
mainfrom
fix/faultspec-namespace-follows-kafka

Conversation

@bmscomp

@bmscomp bmscomp commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Merge #441 first. Rebased onto #441, which is rebased onto main after #438, #440 and #439. Until #441 lands, the diff here includes its commit.

Problem

FaultSpec.Builder defaulted targetNamespace to the literal "kafka" (chaos/FaultSpec.java:83). The safety guard lets a step target only kates.chaos.kafka.namespace and the Kates API's own namespace (DisruptionSafetyGuard.java:140-149).

So with Kafka anywhere but kafka, every fault that names no namespace was aimed at kafka, and the guard refused it. That covers ad-hoc plans, the playbooks, the templates and the resilience scenarios. #441 makes the chart set kates.chaos.kafka.namespace from where Kafka runs, which made this the next thing to break.

Fix

  • Backend. The builder's default reads kates.chaos.kafka.namespace through ConfigProvider (default kafka). A spec that names a namespace keeps it.
  • Why the builder reads config itself. Specs are built by Jackson from REST bodies and stored plans, by the playbook and template catalogs, and by the resilience scenarios. None of those can inject config into the builder, and a missed path would then get a null namespace, which fabric8 may resolve to the client's own namespace. The read happens when a Builder is constructed. All of those paths do that per request, at runtime.
  • MCP preview_disruption, which assumed the literal:
    • A step that leaves targetNamespace out is in the namespace the dry run reads, so it no longer draws dry-run-other-namespace.
    • outsideAgentLimits compares a step's namespace with the Kafka namespace the topology names (kafka when unknown), not with kafka. A playbook comes back as the backend built it, so with Kafka in kafka-prod its steps name kafka-prod. Compared with kafka, every playbook step would have counted as beyond the agent limits.
    • The caveat says kates.chaos.kafka.namespace. Its two FaultSpec.java refs are re-pointed and anchored, and two plain comment refs are re-pointed.
  • Book. Chapter 07, Targeting Pods, says the same.

Tests

  • FaultSpecTest.absentNamespaceIsTheConfiguredKafkaNamespace registers a config with namespace streaming for a fresh context class loader. It checks the builder, JSON without the field, and an explicit namespace. It fails on the old default (expected: <streaming> but was: <kafka>).
  • TestMCPPreviewAgentLimitsKafkaNamespace uses a topology in kafka-prod. A playbook step in kafka-prod is within limits; one in kafka is not. It fails on the old comparison.
  • TestMCPPreviewOtherNamespace now expects no caveat for a step without a namespace when the dry run names kafka-prod.

Local checks

  • In kates/:
    • ./mvnw test -Dquarkus.grpc.codegen.skip=true -Dquarkus.http.test-port=0 passes on the rebased tip: 1,496 tests in 141 classes, 0 failures, 1 skipped.
    • spotless:check (JDK 25) passes.
    • ITs and the Docker and native builds run in CI only.
  • In cli/: go vet ./..., go test ./... (including TestMCPCaveatRefAnchors), golangci-lint run --new-from-rev=origin/main (0 issues), govulncheck (none), check-cli-style.sh, check-cli-compat.sh.
  • Book: check-book-style.sh, check-book-contrast.py, gen-version-matrix.sh --check, gen-chart-table.sh --check. The change is one sentence, so the book was not rendered.

Upgrading

A disruption schedule stores its plan as the backend parsed it (DisruptionScheduleResource.java:110,146). A schedule created before this change keeps "targetNamespace":"kafka" in the plan it stored. Recreate it to pick up another Kafka namespace.

Not in this PR

  • The consumer-isolation playbook names targetNamespace: kates, the Kates API's namespace on a default install. With Kates elsewhere, kates-platform included, the guard refuses that step.

… Kafka namespace and cluster name

The backend reads the Kafka cluster it acts on from kates.chaos.kafka.namespace
and .cluster (chaos guard, orchestrator, orphan recovery, lease, Prometheus
capture) and kates.topology.kafka-namespace and -cluster (topology, cluster
alerts, conformity, CDC's fallback). Nothing set them, so they stayed at
kafka/krafter. With `kates deploy --kafka-ns X` or `--kafka-name Y`, or
kates-platform in any namespace but kafka, chaos refused every plan with "No
broker pods found", topology came back empty and every conformity check
returned 409.

- kates 0.12.1: the configmap sets KATES_CHAOS_KAFKA_NAMESPACE and
  KATES_TOPOLOGY_KAFKA_NAMESPACE from networkPolicy.kafka.namespace, through
  tpl, with the policy on or off. It sets KATES_CHAOS_KAFKA_CLUSTER and
  KATES_TOPOLOGY_KAFKA_CLUSTER from a new kafka.clusterName (default krafter).
  The defaults are the backend's own, so a default render sets the same values
  as before. An extraEnv entry still wins over the configmap. The
  rbac.scope=namespace block that set KATES_TOPOLOGY_KAFKA_NAMESPACE (#439)
  goes: it rendered the same value, and would now be a duplicate key.
- kates deploy sets kafka.clusterName from --kafka-name. It already set
  networkPolicy.kafka.namespace from the Kafka namespace.
- kates-platform 0.8.2: the kates floor moves to 0.12.1, and the umbrella sets
  kates.kafka.clusterName (krafter) next to the bootstrap address, which names
  the same cluster. CI's kates-platform render check now also asserts both
  namespace variables.
- MCP caveats dry-run-other-namespace and topology-unread-looks-empty say which
  chart values set these settings, with anchored refs to the configmap. Four
  refs into charts/kates are re-pointed past the added lines.
…ster's namespace, wherever it is

FaultSpec.Builder defaulted targetNamespace to the literal "kafka". With
kates.chaos.kafka.namespace set elsewhere, which charts/kates 0.11.8 does from
networkPolicy.kafka.namespace, every step, playbook, template and resilience
scenario that left the namespace out was aimed at kafka. The safety guard then
refused it: kafka was neither the Kafka cluster's namespace nor the Kates
API's own.

The builder's default now reads kates.chaos.kafka.namespace (default kafka).
JSON and plain callers both build specs through the builder, outside CDI, so
the builder reads it from config itself. A spec that names a namespace keeps
it. FaultSpecTest registers a config with namespace streaming and checks the
builder, JSON without the field, and an explicit namespace.

MCP preview_disruption, which assumed the literal:
- A step that leaves targetNamespace out is in the namespace the dry run
  reads, so it never draws the dry-run-other-namespace caveat.
- A playbook step's namespace is within the agent limits when it is the
  Kafka namespace the topology names, not only when it is kafka. A playbook
  comes back as the backend built it, so with Kafka in kafka-prod its steps
  name kafka-prod.
- The caveat text says kates.chaos.kafka.namespace. Its FaultSpec refs are
  re-pointed and anchored.

Book chapter 07 says the same.
@bmscomp
bmscomp force-pushed the fix/faultspec-namespace-follows-kafka branch from 1321659 to 4df5ad9 Compare October 21, 2026 16:06
@bmscomp
bmscomp merged commit f1605f4 into main Oct 21, 2026
63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant