contexts

package
v0.11.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package contexts is the kubectl-style context store for the Entire CLIs.

One on-disk file at $ENTIRE_CONFIG_DIR/contexts.json (default ~/.config/entire/contexts.json) holds:

  • a list of named contexts, each pairing a core URL, principal handle, and OS-keychain slot where the access + refresh tokens live;
  • current_context, the active login: the preferred identity for cluster operations and the default for direct CLI commands not tied to a cluster.

File invariants: 0600, atomic temp+rename, exclusive flock under load. Both CLIs share the same file so a login from either is visible to the other.

Index

Constants

View Source
const EnvContextVar = "ENTIRE_CONTEXT"

EnvContextVar selects the acting login context for one process — the environment counterpart to `--context`.

Both exist because they reach different entry points. The flag is parsed by the `entire` CLI, which exports it under this name so the git and `git-remote-entire` processes it spawns act as the same login; a git operation the user runs directly (`git push`) parses no `entire` flag, so `ENTIRE_CONTEXT=staging git push` is how that one is scoped. The env var also survives into hooks and subprocesses, which is what makes a whole shell session scopable without mutating shared state.

Variables

This section is empty.

Functions

func FilePath

func FilePath(configDir string) (string, error)

FilePath returns $configDir/contexts.json after ensuring the directory exists and is private to its owner — 0700, or stricter if the user already made it so; see userdirs.EnsurePrivateDir.

The path is for messages and for the flock, which takes one. Reads and writes go through configRoot.

func Modify

func Modify(configDir string, fn func(*File) (changed bool, err error)) error

Modify atomically applies fn to contexts.json under a single exclusive flock — load, mutate, write all happen with the lock held. Use this for any read-modify-write sequence; calling Load and Save separately releases the lock between them and races concurrent writers (e.g. a parallel login recording a context).

fn returns (changed, err). When changed is false the file isn't rewritten — useful for idempotent operations that often have nothing to do. When err is non-nil the change is discarded.

func Requested added in v0.11.0

func Requested() bool

Requested reports whether this invocation named an identity explicitly, via `--context` or $ENTIRE_CONTEXT, without resolving it.

It exists for callers that must behave differently when the user already knows which login is acting — the acting-login notice, which would otherwise echo back the name just typed. Resolving through Active would answer the same question but costs a contexts.json read, and the notice runs on paths that have one in flight already.

func Save

func Save(configDir string, f *File) error

Save writes f to contexts.json atomically (temp+rename) under an exclusive flock.

func SetFlagOverride added in v0.10.1

func SetFlagOverride(name string)

SetFlagOverride records the `--context` value for this process. Call it once, during flag handling, before anything resolves a token. An empty or whitespace-only name clears the override rather than selecting a nameless context.

func SetFlagOverrideForTest added in v0.10.1

func SetFlagOverrideForTest(t interface {
	Helper()
	Cleanup(restore func())
}, name string,
)

SetFlagOverrideForTest sets the override for one test and restores the previous value when it ends.

Tests using it MUST NOT call t.Parallel(): the override is process-wide, so a parallel test would resolve against another test's selection. That is also why this restores the prior value rather than clearing — nesting stays honest.

Types

type Context

type Context struct {
	// Name is the user-facing identifier: the issuer host, qualified
	// with the handle when another identity already holds that host.
	Name string `json:"name"`
	// CoreURL is the JWT issuer URL — what STS exchanges hit. Set from
	// the access token's signed iss claim, not the typed login URL.
	CoreURL string `json:"core_url"`
	// Handle is the principal handle returned from /api/auth/token.
	Handle string `json:"handle"`
	// KeychainService is the OS-keyring slot where the access token is
	// filed; the refresh token lives at KeychainService+":refresh".
	KeychainService string `json:"keychain_service"`
	// JurisdictionAudiences lists the audiences this context has a jurisdiction
	// (data-plane) access token filed for, trailing-slash-trimmed; each lives at
	// tokenstore.JurisdictionService(audience), also keyed by Handle.
	JurisdictionAudiences []string `json:"jurisdiction_audiences,omitempty"`
}

Context is a single kubectl-style entry: which core to talk to, as whom, and where the credentials are stored.

type File

type File struct {
	// CurrentContext is the active login; preferred identity for cluster
	// operations (used when its CoreURL is eligible for the target cluster)
	// and the default for direct CLI commands. Empty until the first login.
	CurrentContext string `json:"current_context,omitempty"`
	// Contexts is the list of stored credentials. Order is preserved on
	// disk so list output stays stable across saves.
	Contexts []*Context `json:"contexts,omitempty"`
}

File is the on-disk shape of contexts.json.

func Load

func Load(configDir string) (*File, error)

Load reads contexts.json under configDir, returning an empty *File when the file doesn't exist yet (a fresh user). Holds an exclusive flock for the duration of the read.

func (*File) Active added in v0.10.1

func (f *File) Active() (Selection, error)

Active resolves which stored login this process should act as: an explicit `--context`, else $ENTIRE_CONTEXT, else the stored current_context.

An explicit request naming no stored context is an error, never a silent fallback to current_context. Acting as an identity other than the one asked for is precisely the failure the explicit selection exists to prevent, and it would be invisible — the command would succeed as the wrong account.

A missing current_context is NOT an error: that is just "logged out", and the caller renders its own hint. So a nil Context with a nil error means no identity is available, and callers must handle it.

func (*File) ContextsForIssuer

func (f *File) ContextsForIssuer(issuer string) []*Context

ContextsForIssuer returns every context whose CoreURL matches issuer after trimming. Used by CLI flows that prompt the operator when multiple sessions are stored against the same core (logout, entiredb's admin/repo prompts). Order matches the on-disk order so prompt numbering is stable across saves.

func (*File) Delete

func (f *File) Delete(name string)

Delete drops the context with the given name. If it was the current context, current_context is cleared — never reassigned to another context, so deleting your active login never silently switches you to a different identity.

func (*File) Find

func (f *File) Find(name string) *Context

Find returns the context with the given name, or nil.

func (*File) Names added in v0.10.1

func (f *File) Names() []string

Names returns the stored context names in on-disk order, for listing in messages. On-disk order is stable across saves, so the output is too.

func (*File) Upsert

func (f *File) Upsert(c *Context)

Upsert replaces the context with matching Name, or appends. Sets the current context when there isn't one already (first login).

type Selection added in v0.10.1

type Selection struct {
	// Context is the login to act as, or nil when there is none (logged out, or
	// current_context unset/dangling). Never nil when Source is non-empty: an
	// unmatched explicit request is an error instead.
	Context *Context
	// Source names the mechanism that chose it: "--context", "$ENTIRE_CONTEXT",
	// or "" for the stored current_context.
	Source string
}

Selection is a resolved acting identity plus where the choice came from.

Source is what lets callers name the right remedy, which differs by origin: a wrong `--context` is fixed by correcting the argument, a wrong current_context by `entire auth switch`. Telling someone to run `auth switch` when they passed an explicit flag sends them to change the wrong thing.

func (Selection) Explicit added in v0.10.1

func (s Selection) Explicit() bool

Explicit reports whether the identity was requested for this invocation rather than inherited from current_context.

type UnknownContextError added in v0.10.1

type UnknownContextError struct {
	Name      string
	Source    string
	Available []string
}

UnknownContextError reports an explicit context selection that names no stored login. It carries the available names so the caller can print them without re-reading the store, and is a distinct type so callers can tell "you asked for something that doesn't exist" from "this login isn't trusted here" — different mistakes with different fixes.

func (*UnknownContextError) Error added in v0.10.1

func (e *UnknownContextError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL