Skip to content

Set WithDeterministicExternalName on generated controllers#682

Open
polds wants to merge 1 commit into
crossplane:mainfrom
polds:set-deterministic-external-name
Open

Set WithDeterministicExternalName on generated controllers#682
polds wants to merge 1 commit into
crossplane:mainfrom
polds:set-deterministic-external-name

Conversation

@polds

@polds polds commented Jun 24, 2026

Copy link
Copy Markdown

Description of your changes

Generated controllers never pass managed.WithDeterministicExternalName, so deterministicExternalName is always false for every upjet resource. A resource with a user-supplied (deterministic) external name then cannot recover from an incomplete create: if external-create-pending ends up the newest of the three create-* annotations (for example the provider restarts mid async create), crossplane-runtime refuses to retry and the MR sticks indefinitely on:

cannot determine creation result - remove the external-create-pending annotation if it is safe to proceed

crossplane-runtime already handles this safely: with deterministicExternalName true it logs "proceeding due to deterministic external name" and continues, because re-queuing a deterministically named resource cannot leak one. This passes that flag, derived from the existing DisableNameInitializer template variable (IdentifierFromProvider sets it true, so non-deterministic; user-supplied external names leave it false, so deterministic).

Fixes #681

I have:

  • Read and followed Upjet's contribution process.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

make reviewable passes (generate is a no-op, lint and unit tests green). I also rendered the changed template fragment directly to confirm the output: DisableNameInitializer true yields managed.WithDeterministicExternalName(false), false yields (true). No committed golden/fixture controllers reference these opts, so there is nothing to regenerate.

Generated controllers never passed managed.WithDeterministicExternalName, so
deterministicExternalName was always false. Resources with a user-supplied
(deterministic) external name could not recover from an incomplete create
(external-create-pending the newest of the create-* annotations, e.g. after a
provider restart mid async create): crossplane-runtime refuses to retry and the
MR sticks on "cannot determine creation result - remove the external-create-pending
annotation if it is safe to proceed" until the annotation is removed by hand.

Derive determinism from the existing DisableNameInitializer template variable
(IdentifierFromProvider sets it true, so non-deterministic; user-supplied external
names leave it false, so deterministic) and pass it to the reconciler.

Fixes crossplane#681

Signed-off-by: Peter Olds <2372558+polds@users.noreply.github.com>
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.

Generated controllers never set WithDeterministicExternalName, blocking recovery from external-create-pending

1 participant