Skip to content

feat(api): immutability rules for DatabaseDeclaration and DbPolicy identity fields#469

Merged
kichasov merged 3 commits into
feat/operator-devfrom
feat/cr-immutability
May 22, 2026
Merged

feat(api): immutability rules for DatabaseDeclaration and DbPolicy identity fields#469
kichasov merged 3 commits into
feat/operator-devfrom
feat/cr-immutability

Conversation

@kichasov
Copy link
Copy Markdown
Collaborator

Summary

  • Add CRD-level XValidation immutability rules to:
    • DatabaseDeclaration.spec.classifier
    • DatabaseDeclaration.spec.type
    • DbPolicy.spec.microserviceName
  • Closes a consistency gap with ExternalDatabase (already locks classifier, type, dbName) and NamespaceBinding (already locks operatorNamespace). All four workload CRs now treat identity fields as frozen after create; retargeting requires delete + recreate.
  • Regenerated CRDs across config/, config-dev/, and helm-templates/.
  • Documentation updated: docs/howto/DBaaS Operator.md marks the fields as immutable with rationale, plus a one-line note in the high-level "Key design decisions" section.

Why these fields are dangerous to mutate

  • DD.classifier — switching the classifier on an existing CR re-targets the controller at a different database while status.trackingID / status.observedGeneration still reference the original one. In-flight async operation becomes irrecoverable.
  • DD.type — changing engine type mid-flight requests provisioning of a fresh database on a different adapter while the original stays registered under the same CR identity.
  • DbPolicy.microserviceName — rewriting role grants under the same K8s object destroys the audit link to who created the policy originally.

Integration test coverage

Five tests added to OperatorIT.java mirroring the existing EDB immutability suite:

Test Purpose
testDatabaseDeclarationTryToUpdateClassifier Update classifier → expect HTTP 422 + immutability message
testDatabaseDeclarationTryToUpdateType Update type → expect HTTP 422 + immutability message
testDatabaseDeclarationCanUpdateSettings Negative confirmation: spec.settings still mutable, CR converges back to Succeeded
testDbPolicyTryToUpdateMicroserviceName Update microserviceName → expect HTTP 422 + immutability message
testDbPolicyCanUpdateServices Negative confirmation: spec.services still mutable, CR converges back to Succeeded, new service visible via getAccessRoles

Test plan

  • go build ./... — Success
  • go test ./... — green across api/v1, internal/client, internal/controller, internal/ownership
  • mvn clean test-compile on dbaas-integration-tests — green
  • Manual scan of existing .edit() call sites in OperatorIT.java: none mutate the now-immutable DD/DbPolicy fields, so no existing test fails
  • CI run on this branch

kichasov added 2 commits May 21, 2026 15:04
…table

Add XValidation `self == oldSelf` to:
- DatabaseDeclaration: spec.classifier, spec.type
- DbPolicy: spec.microserviceName

Closes a consistency gap with ExternalDatabase (which already locks
classifier/type/dbName) and NamespaceBinding (which locks
operatorNamespace). All four workload CRs now treat identity as
frozen at create-time; retargeting requires delete + recreate.

Regenerated CRDs (config/, config-dev/, helm-templates/) via
`make manifests`. Updated docs/howto/DBaaS Operator.md to mark the
fields as immutable with rationale.

go build + go test green. Java IT suite scanned for `.edit()`
mutations of the now-immutable fields — none exist for DD/DbPolicy,
so existing tests remain valid.
Five integration tests in OperatorIT.java mirroring the existing
ExternalDatabase immutability suite:

- testDatabaseDeclarationTryToUpdateClassifier
- testDatabaseDeclarationTryToUpdateType
- testDatabaseDeclarationCanUpdateSettings (negative confirmation)
- testDbPolicyTryToUpdateMicroserviceName
- testDbPolicyCanUpdateServices (negative confirmation)

Each immutability test creates a CR, attempts to mutate the protected
field via .edit(), and asserts HTTP 422 + the matching XValidation
message. The two "Can*" tests confirm that mutable fields (DD.settings,
DbPolicy.services) still accept updates and the CR converges back to
Succeeded — guarding against the immutability rule accidentally
clamping more than the intended fields.

mvn clean test-compile green.
@kichasov kichasov requested a review from ArkuNC as a code owner May 21, 2026 12:14
@kichasov kichasov merged commit 8925a29 into feat/operator-dev May 22, 2026
18 of 19 checks passed
@kichasov kichasov deleted the feat/cr-immutability branch May 22, 2026 09:49
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