Skip to content

feat(groups,projects): accept the full path as external-name - #411

Open
ahauserv wants to merge 3 commits into
crossplane-contrib:masterfrom
ahauserv:feat/path-external-name
Open

ahauserv wants to merge 3 commits into
crossplane-contrib:masterfrom
ahauserv:feat/path-external-name

Conversation

@ahauserv

@ahauserv ahauserv commented Sep 18, 2026

Copy link
Copy Markdown

Description of your changes

I want to declare observe-only Group and Project resources for cases where only the full path is known, not the numeric ID.
This implements the approach @markussiebert outlined in #318.

  • A numeric crossplane.io/external-name is still the ID.
  • A non-numeric one is used as the full path for the lookup. The returned ID is written back into the annotation and reported as late-initialized, so the resource tracks the immutable ID from then on.

On the open question in #318: the first reconcile always persists the ID, because the finalizer is added after Observe with a full object update. LateInitialize is only needed to persist a later change of the annotation to a path. Without it the path is resolved on every reconcile, which still works.

Fixes #318

I have:

  • Read and followed Crossplane's contribution process.
  • Run make reviewable test to ensure this PR is ready for review.

How has this code been tested

  • Unit tests for both controllers cover the path case, plus a table test for the helper.
  • Ran the branch with make run against GitLab 19.3.2-ee using a scratch group and project:
    • path lookups for namespaced and cluster-scoped Group and for Project, with [Observe, LateInitialize] and [Observe]
    • a non-existent path: Synced=False, nothing created
    • a group rename after pinning: resources stayed Ready and Synced
    • deleting the observe-only resources: GitLab objects untouched

Observe rejected any external-name that was not a numeric ID, so an
observe-only Group could not be declared when only the path was known.
GitLab's GET /groups/:id accepts the URL-encoded full path as well, and
the client already takes either form.

Pass the external-name through unchanged and, when it is not numeric,
replace it with the returned ID and report the resource as
late-initialized. The path is mutable through renames and transfers, so
it only bootstraps the lookup; the immutable ID is tracked afterwards.
The pin persists when the management policy includes LateInitialize.

Refs crossplane-contrib#318

Signed-off-by: ahauser <andreas.hauser@vector.com>
Apply the same lookup as for groups: a non-numeric external-name is sent
to GET /projects/:id as the full path, replaced by the returned ID and
reported as late-initialized so the immutable ID is tracked afterwards.

Refs crossplane-contrib#318

Signed-off-by: ahauser <andreas.hauser@vector.com>
Observe-only Group and Project examples show the path form together with
the LateInitialize policy that persists the resolved ID.

Fixes crossplane-contrib#318

Signed-off-by: ahauser <andreas.hauser@vector.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.

Support GitLab group resource with full path

1 participant