Skip to content

Record installation defaults in the status instead of the spec - #5203

Open
caseydavenport wants to merge 6 commits into
tigera:masterfrom
caseydavenport:casey-installation-defaults
Open

Record installation defaults in the status instead of the spec#5203
caseydavenport wants to merge 6 commits into
tigera:masterfrom
caseydavenport:casey-installation-defaults

Conversation

@caseydavenport

@caseydavenport caseydavenport commented Aug 17, 2026

Copy link
Copy Markdown
Member

Description

The operator writes its computed defaults back into the Installation spec, which makes the operator the field manager for anything it defaulted. Helm and Argo then conflict on those fields, and a server-side apply from the chart gets rejected. See #5102.

This changes the defaulting to leave the spec alone:

  • computed defaults are recorded on the status instead of the spec, as a sparse object holding only the fields the user left unset
  • defaulting seeds from the recorded values first, so a default that changes between operator versions doesn't change an existing cluster
  • a field drops out of the recorded set as soon as the user sets it, and the effective config is still published in the status as before
  • every other controller reads that effective config and waits until the core controller has published it, so there is one place that merges the spec, the defaults and the overlay
  • the write that persists finalizers and migrated Calico config stays, so an upgrade from a manifest install is unaffected

Also fixes a bug this uncovered: an empty ipPools list marshalled the same as an unset one, so asking for no IP pools got the default pool instead. The documented behavior now holds.

Existing clusters where the operator already owns spec fields need one helm upgrade --force-conflicts to hand ownership back to the chart.

Constants that could be plain CRD schema defaults are left alone here - that's a follow-up.

Fixes server-side apply conflicts on Installation fields between the operator and the tool that manages the resource, such as Helm or Argo CD. The operator records the values it defaults in the Installation status rather than writing them into the spec.
Fixes an issue where an empty list of IP pools in the Installation was treated as unset, causing a default IP pool to be created.

Defaulting seeds from the recorded values, so a user-set field takes over
and drops out of the recorded set.
Downstream controllers read the computed spec and wait until the core controller publishes it.
@marvin-tigera marvin-tigera added this to the v1.45.0 milestone Aug 17, 2026
The pool list merges whole, so a declared pool that omits the name dropped the
recorded default for it. Per-pool fields now come from the recorded default with
the same CIDR, and the IP pool controller diffs its defaults against the raw spec.
@caseydavenport
caseydavenport marked this pull request as ready for review August 18, 2026 12:34
@caseydavenport
caseydavenport requested review from a team and marvin-tigera as code owners August 18, 2026 12:34
Comment thread pkg/controller/installation/core_controller.go
Comment thread pkg/controller/installation/core_controller.go Outdated
Comment thread pkg/controller/ippool/pool_controller.go Outdated
Comment thread pkg/controller/ippool/pool_controller.go Outdated
Comment thread pkg/controller/ippool/pool_controller.go Outdated
Comment thread pkg/controller/utils/utils.go Outdated
Comment thread pkg/controller/utils/utils.go Outdated
Comment thread test/gatewayapi_test.go Outdated
Each controller declares the spec paths it defaults, and downstream controllers read the computed spec published on the status.
Keeps the object we write back exactly as the user declared it, so the
patch and the status writes don't need to restore the spec afterwards.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants