feat: discover contexts on login, select with ctx use#149
Open
feat: discover contexts on login, select with ctx use#149
Conversation
Collaborator
|
this looks good to me, do you want to get it out of draft so we can move it over and merge? |
459d18b to
7241d91
Compare
First slice of the multi-user / context-discovery rework, ported onto
current main. Adds the new packages and helpers; does not yet wire the
new commands into the CLI or refactor the existing auth command tree —
that lands in a follow-up so the integration with main's machine-account
and device-auth flows can be reviewed separately.
Adds:
- internal/datumconfig: v1beta1 schema with sessions and discovered
contexts, alongside the existing utilities.
- internal/discovery: API-driven org/project discovery + on-disk cache.
- internal/picker: Bubble Tea / huh-based interactive picker.
- internal/cmd/{login,logout,whoami,ctx}: top-level command packages.
- internal/authutil/login.go: PKCE login helper that produces a v1beta1
Session.
- internal/authutil/known_users.go: keyring-backed multi-user index.
- internal/miloapi/urls.go: control-plane URL helpers.
Refactors:
- internal/authutil/credentials.go: extracts shared
GetTokenSourceForUser / GetUserIDFromTokenForUser /
GetAPIHostnameForUser variants so multi-user flows can re-use the same
refresh-and-persist logic that the active-user functions use.
…strap Introduces the session layer that sits between v1beta1 config and the existing keyring-backed credential store: - GetUserKeyForCurrentSession: resolves the active session's user key, bootstrapping a Session from legacy keyring state on first run for users who logged in before the config file existed. - GetUserKey: thin wrapper that returns only the user key. - GetUserKeyForSession: looks up a session by name. Used by the kubectl exec plugin path so `auth update-kubeconfig` writes session names and `auth get-token --cluster=<name>` resolves them back. - bootstrapSessionFromKeyring handles both interactive and machine- account credentials uniformly — both already populate the fields the Session consumes.
Rewires the datumctl Kubernetes client factory to resolve identity via the active v1beta1 session instead of the old single-user keyring path: - ToRESTConfig loads the active session and context, uses session.UserKey for token sourcing and session.Endpoint.Server for the base host, and falls back to GetUserKey + stored credentials when no session exists (the bootstrap path covers pre-v1beta1 users). - resolveScope layers flags → DATUM_PROJECT / DATUM_ORGANIZATION → active context, so scripts and CI keep working without touching the config file. - URL construction moved into the miloapi package so factory, user context, and future callers share one source of truth. - user_context.go follows the same session-first pattern for code that builds a controller-runtime client outside the factory. - Adds GetAPIHostnameForUser alongside the existing per-user token helpers so multi-user flows have everything they need.
Brings the auth command tree into the v1beta1 session model: - auth list and auth switch read from the v1beta1 config, so they see every login regardless of how it was obtained (PKCE, device, or machine-account — Q1 uniform-session model). - auth get-token grows a --session flag. Without it, behaviour is unchanged (uses the active session). With it, the kubectl exec plugin can pin each kubeconfig entry to a specific datumctl session so multi-user kubectl works correctly. - auth update-kubeconfig resolves the session up front, uses its endpoint as the API hostname when available, and writes --session=<name> into the exec plugin args so the kubeconfig is tied to that specific session instead of drifting with the active one. Keeps auth login, auth logout, and auth machine-account functionality as-is on main. Deprecation of the old login/logout aliases (Q3) can land in a follow-up once the top-level login achieves feature parity (PKCE + device + machine-account).
Promotes the first-touch auth and context commands to the top level: - 'datumctl login' runs PKCE, discovers orgs/projects, and prompts for a default context in one step. - 'datumctl logout' removes credentials for one or all local users. - 'datumctl whoami' shows the active user and context. - 'datumctl ctx' lists and switches contexts. Leaves 'datumctl auth login' / 'auth logout' in place unchanged — they still carry the full feature matrix (PKCE, device flow, machine account) and should stay functional until the top-level login reaches parity. Improves the PKCE browser-open-failure message to point users at 'datumctl auth login --no-browser' when they're running in a headless environment. A dedicated '--device' flag on 'datumctl login' is future work once the device flow is lifted out of the auth login command.
- Replaces the auth-login-first flow with the new login + context discovery flow. - Adds a short 'CI and scripting' section covering the DATUM_PROJECT and DATUM_ORGANIZATION overrides. - Removes the tangent about creating an intro project with raw YAML — that belongs in the docs site, not the top-level README. - Points at the standalone datum-mcp project for MCP / AI agent integration, matching main's recent removal of the in-tree MCP.
798f400 to
149a280
Compare
The session-based rewrite of auth list and auth switch stripped the verbose help text, aliases, and examples that main's help-text overhaul (PR #132) added. Restore them with updated wording that references sessions and the new top-level commands.
073453d to
692ba86
Compare
Aligns with the rest of the CLI which uses rodaine/table via internal/output. Replaces text/tabwriter for consistent formatting.
Moves PKCE, device-code, and machine-account login logic out of cmd/auth/login.go into authutil, making it callable from the single top-level 'datumctl login' command. Deletes cmd/auth/login.go and cmd/auth/machine_account_login.go entirely — there is no longer an 'auth login' subcommand. authutil/login.go now exports: - RunInteractiveLogin: PKCE (default) or device-code (--no-browser) - BuildSession, ResolveClientID, LoginResult (unchanged) authutil/machine_account_login.go exports: - RunMachineAccountLogin: reads credentials file, mints JWT, exchanges, stores in keyring, returns LoginResult cmd/login/login.go accepts the full flag set: --hostname, --api-hostname, --client-id, --no-browser, --credentials, --debug and routes to the appropriate authutil function before running context discovery and the interactive picker.
Same consolidation as the login removal — 'datumctl logout' is the single logout command. Removes cmd/auth/logout.go and its registration.
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 changes for users
No more
--projector--organizationon every command.Before
After
New commands
datumctl logindatumctl login --no-browserdatumctl login --credentials FILEdatumctl logout [email | --all]datumctl whoamidatumctl ctxdatumctl ctx --refreshdatumctl ctx use [context]datumctl auth listdatumctl auth switch [email]Resource commands (
get,apply,create, etc.) automatically use the active context.Removed commands
datumctl auth logindatumctl login(all auth modes consolidated here)datumctl config *datumctl ctxFirst login
Run
datumctl login. A browser opens for authentication, then the CLI fetches your orgs and projects and shows a picker:If you only have one project, the picker is skipped.
Day-to-day
Switching users
Each login session remembers its last-used context, so switching users drops you right back where you left off.
CI and scripting
For non-interactive use, environment variables override the active context per-invocation:
--projectand--organizationflags still work too. For machine-to-machine auth:Existing users
datumctl auth loginhas been removed — usedatumctl logininstead. It supports all the same auth modes (PKCE,--no-browserfor device flow,--credentialsfor machine accounts).Pre-existing keyring credentials are bootstrapped into a v1beta1 session on first run, so previously authenticated users won't have to log in again. They will, however, want to run
datumctl ctx use(or rely onDATUM_PROJECT/DATUM_ORGANIZATION) to pick a context.Anyone with a kubeconfig generated by an earlier
datumctl auth update-kubeconfigwill need to re-run the command — the kubectl exec plugin args now reference session names rather than the legacy format.🤖 Generated with Claude Code