feat(serviceactivation): shared, status-keyed service-enablement SDK#242
Draft
scotwells wants to merge 4 commits into
Draft
feat(serviceactivation): shared, status-keyed service-enablement SDK#242scotwells wants to merge 4 commits into
scotwells wants to merge 4 commits into
Conversation
Turn a project's ServiceEntitlement into an honest CLI experience with a service-agnostic package that plugins and datumctl core can adopt instead of forking the flow. It provides a pure classifier for the eight activation states (not requested, processing, pending approval, active, denied, revoked, unavailable, catalog unavailable), an interactive/non-interactive preflight gate, explicit request/renew/wait primitives, a shared status renderer, and a documented exit-code contract (10-13 for not-enabled / denied-or-revoked / pending / unavailable). Consumers configure it per service (object name, canonical name, display noun, and their own access verb) and inject a client and IO streams, so every consumer gets consistent wording and exit codes. Adds the go.miloapis.com/service-catalog dependency; the dependency-free plugin package is left untouched.
…ed clientset Swap the SDK's EntitlementClient implementation from a hand-built controller-runtime client to the generated services clientset (go.miloapis.com/service-catalog/pkg/generated). The public surface is unchanged — same EntitlementClient interface, Gate, Requester, and typed errors — so consumers are unaffected. The flow tests now run against the generated fake clientset, exercising the real adapter path. controller-runtime is no longer imported by this package; it remains a direct datumctl dependency only because core (internal/discovery, internal/client) still uses it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this enables
Datum services are enabled per project through a
ServiceEntitlement, and for a gated service (like compute) that request awaits a human approval on the provider side. Every CLI plugin that gates on enablement has had to hand-roll the same flow — and has gotten it wrong the same way: request access, wait a fixed 15 seconds, then printError:and "try again in a moment" no matter what actually happened, pointing atdatumctl services …commands that don't exist.This PR adds a shared, service-agnostic
serviceactivationpackage so plugins stop forking that flow and instead get one honest experience. It re-keys everything off the entitlement's own status, so the CLI tells the truth in every state.Before (what a user sees today, verbatim):
After (compute, the first consumer):
The request no longer reads as an error, pending approval is a legible waiting state, and every printed command exists. Scripts get deterministic, documented exit codes instead of a blanket exit 1.
What's in the package
serviceactivationis configured per service (object name, canonical name, display noun, and the plugin's own access verb) and takes an injected client plus IO streams:entitledAt;ServiceNotPublishedmaps to unavailable; transient relay reasons never drive control flow.--waitthat states up front that approval is a manual provider step with no time bound.The dependency-free
pluginpackage is deliberately left untouched; this package is its sibling and takes thego.miloapis.com/service-catalogdependency on its own.Follow-ups (not in this PR)
internaltoday — theReadycondition type and reason constants, and a canonicalstatus.serviceNamefor lookup. The SDK carries local copies with a one-line seam to switch over once those are promoted toapi/v1alpha1.datumctl servicescommand group on these same internals, and ipam adopting the shared exit codes) are separate proposals.Design/rationale: the compute repo RFC
docs/compute/development/rfcs/cli-service-activation.md.Related
The compute plugin PR datum-cloud/compute#113 is the first consumer and depends on this PR. It currently pins this branch by pseudo-version for CI; it must be re-pinned to a tagged/merged datumctl version before merge.
Update — backed by the generated service-catalog clientset
The SDK's
EntitlementClientis now implemented over the generated typed clientset from milo-os/service-catalog#50 (go.miloapis.com/service-catalog/pkg/generated) instead of a hand-built controller-runtime client. The public surface is unchanged (sameEntitlementClientinterface,Gate,Requester, typed errors), and the flow tests run against the generated fake clientset, exercising the real adapter path.go.miloapis.com/service-catalogis pinned by pseudo-version to that PR's branch commit; it must be re-pinned to a tagged/merged service-catalog release before this merges.internal/discovery,internal/client) still uses it — so nothing was dropped from the module.Dependency chain: datum-cloud/compute#113 → this PR → milo-os/service-catalog#50 (merge in reverse order).