Skip to content

Mark slice reference fields nullable to survive reference-resolution clearing - #2

Draft
Breee with Copilot wants to merge 2 commits into
mainfrom
copilot/425-work-on-provider-keycloak
Draft

Mark slice reference fields nullable to survive reference-resolution clearing#2
Breee with Copilot wants to merge 2 commits into
mainfrom
copilot/425-work-on-provider-keycloak

Conversation

Copilot AI commented Jun 25, 2026

Copy link
Copy Markdown

Resources with a multi-reference selector (e.g. compositeRolesSelector) fail reconciliation once the selector stops matching anything, after having matched previously:

Role.role.keycloak.crossplane.io "role4" is invalid:
spec.forProvider.compositeRolesRefs: Invalid value: "null":
  spec.forProvider.compositeRolesRefs in body must be of type array: "null"

Root cause

crossplane-runtime's APISimpleReferenceResolver persists resolved references with a JSON merge patch (prepareJSONMergejsonpatch.CreateMergePatch). When resolution clears a slice field, omitempty drops it from the resolved object, so the merge patch encodes the removal as an explicit null. The generated CRD types these as non-nullable arrays, so the apply is rejected. Dropping omitempty sidesteps the null but produces empty arrays that drive a reconcile loop, so it isn't viable.

Changes

  • kubebuilder markers: add a Nullable *bool option that emits the +nullable marker (wired through setFrom/String). Note this is the field-only +nullable marker that controller-gen actually recognizes — +kubebuilder:validation:Nullable is not registered by controller-tools and would be ignored.
  • Reference fields (reference.go): generated slice …Refs fields now carry the nullable marker; single-valued …Selector fields are left unchanged.
  • Value fields (field.go): a slice-typed field that has a reference (e.g. compositeRoles) is marked nullable in both forProvider and initProvider.

Regenerated CRDs then accept the null the merge patch produces:

compositeRoles:
  type: array
  nullable: true
  items:
    type: string
compositeRolesRefs:
  type: array
  nullable: true
  items: { ... }

Notes

  • Behavior is scoped to slice reference fields; scalar references and selectors are unaffected.
  • Providers need to regenerate (make generate against this branch) to pick up the nullable schema.

@Breee

Breee commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Copilot AI commented Jun 25, 2026

Copy link
Copy Markdown
Author

@copilot crossplane-contrib/provider-keycloak#586 (comment)

Fixed in 1f0bc5f. The marker is now emitted as +nullable (the field-only marker controller-tools actually registers) instead of +kubebuilder:validation:Nullable, so controller-gen produces nullable: true in the CRDs. Tests updated accordingly.

Copilot AI requested a review from Breee June 25, 2026 12:10
Copilot finished work on behalf of Breee June 25, 2026 12:10
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.

2 participants