Documentation
¶
Overview ¶
Package localconfig models Burrow's client-side selector state: the human-edited ~/.burrow/config file that names environment handles and records which one a command targets (ADR-0036). A handle maps a user-chosen name to {context, control-plane namespace, app namespace}; the current selection is either a pinned handle or, by default, whatever kube context kubectl points at ("follow"). This is selector state like the kubeconfig, never agent configuration, so it lives client-side: both `burrow` (the operator CLI) and `burrow-agent` (the agent control channel) consume this package, hence it is a shared top-level package rather than living under cmd/burrow.
It also holds the TARGET the CLI points at (ADR-0078): the managed product, or a Kubernetes cluster the person holds a kubeconfig context for. A target is the layer above an environment handle — it says which control plane, where the handle says which environment inside it — and, for a cluster, it records the context NAME only and never a copy of the credential.
This package is foundation only (ADR-0036 slice 1): the config model plus the resolution that decides the active target. Command wiring (`burrow env`, install, `burrow-agent`) lands in later slices.
Index ¶
- Constants
- func Exists() (bool, error)
- func Path() (string, error)
- type Config
- func (c *Config) ActiveTarget() (Target, bool, error)
- func (c *Config) Add(env Environment) error
- func (c *Config) Lookup(name string) (Environment, bool)
- func (c *Config) LookupByContext(context string) (Environment, bool)
- func (c *Config) LookupTarget(name string) (Target, bool)
- func (c *Config) Remove(name string) error
- func (c *Config) Rename(oldName, newName string) error
- func (c *Config) Save() error
- func (c *Config) SetAgentCredential(name, kubeconfig, context string) bool
- func (c *Config) SetTarget(t Target) error
- func (c *Config) SwitchTarget(name string) error
- func (c *Config) TargetNames() string
- type Environment
- type Mode
- type Resolved
- type Target
- type TargetKind
Constants ¶
const ( // APIVersion is the schema version stamped into the config header so the format can be // migrated safely across Burrow versions (ADR-0036). APIVersion = "burrow.dev/v1" // Kind identifies the document, mirroring the Kubernetes-style header on ~/.kube/config. Kind = "Config" // DefaultControlPlaneNamespace is where burrowd runs unless a handle says otherwise. The // dimension is carried from day one so a future multi-burrowd-per-cluster setup is a // non-default value, not a breaking change (ADR-0036). DefaultControlPlaneNamespace = "burrow" )
const CloudEndpoint = "burrow-cloud.dev"
CloudEndpoint is the managed product's host, and the name its target carries.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Current string `yaml:"current,omitempty"`
Environments []Environment `yaml:"environments,omitempty"`
Targets []Target `yaml:"targets,omitempty"`
CurrentTarget string `yaml:"currentTarget,omitempty"`
}
Config is the on-disk selector state. APIVersion/Kind form the migratable header; Current names the pinned handle, or is empty to follow the current kube context (the default); Environments is the set of named handles.
Targets/CurrentTarget are the ADR-0078 layer above the handles: WHERE the control plane is (the managed product, or a cluster you hold a kubeconfig context for), chosen with `burrow auth login`. They are additive — with no target recorded the CLI resolves exactly as it did before, following the kubeconfig — and they never hold a credential (see target.go).
func Load ¶
Load reads and parses the config from Path. A missing file is not an error: it returns a zero/empty Config (first run). Use Exists to detect the first-run case. An empty file is tolerated as first-run; a present apiVersion/kind is validated so future migrations are safe.
func (*Config) ActiveTarget ¶
ActiveTarget returns the target commands act against, and whether one is selected at all. No target selected is the pre-ADR-0078 world and is not an error: the CLI then behaves exactly as it did, following the kubeconfig. A CurrentTarget naming an unregistered target is an error, and is caught on load by validateTargets.
func (*Config) Add ¶
func (c *Config) Add(env Environment) error
Add registers a new handle. The name must be non-empty and not already in use.
func (*Config) Lookup ¶
func (c *Config) Lookup(name string) (Environment, bool)
Lookup returns the handle with the given name, and whether it was found.
func (*Config) LookupByContext ¶ added in v0.8.0
func (c *Config) LookupByContext(context string) (Environment, bool)
LookupByContext returns the handle registered for a kube context name, and whether one matched. It backs follow-mode resolution, where the current context is matched to a handle, and `burrow-agent`'s per-context resolution of the scoped agent kubeconfig (ADR-0038).
func (*Config) LookupTarget ¶
LookupTarget returns the target with the given name, and whether it was found.
func (*Config) Remove ¶
Remove deletes the named handle. Removing the pinned handle reverts the selection to follow mode. It errors if the name is not registered.
func (*Config) Rename ¶
Rename changes a handle's name, carrying the pin if the renamed handle was pinned. The new name must be non-empty and unused; the old name must be registered.
func (*Config) Save ¶
Save writes the config to Path, creating ~/.burrow (0700) as needed and writing the file 0600. The apiVersion/kind header is always stamped.
func (*Config) SetAgentCredential ¶ added in v0.8.0
SetAgentCredential records the scoped agent kubeconfig path and its context on the named handle, backing the ADR-0038 phase 3 backfill (`upgrade` and a re-run `install` join provisioning the scoped credential onto a handle registered before it existed). It reports whether a handle by that name was found; the caller Saves.
func (*Config) SetTarget ¶
SetTarget records a target and makes it active, replacing any existing entry with the same name (re-authenticating against a target you already have is an ordinary thing to do). The caller Saves.
func (*Config) SwitchTarget ¶
SwitchTarget makes an already-recorded target active without re-authenticating (ADR-0078 §4). It errors, naming what is registered, when the name is not one of them. The caller Saves.
func (*Config) TargetNames ¶
TargetNames returns the registered target names, sorted, joined for an error or a hint. It reads "none" when there are no targets, so a message never trails off into an empty list.
type Environment ¶
type Environment struct {
Name string `yaml:"name"`
Context string `yaml:"context"`
ControlPlaneNamespace string `yaml:"controlPlaneNamespace,omitempty"`
AppNamespace string `yaml:"appNamespace,omitempty"`
Env string `yaml:"env,omitempty"`
// AgentKubeconfig is the path to the self-contained, burrowd-only kubeconfig `burrow install`
// mints for the scoped agent credential (ADR-0038), written under ~/.burrow/ (never
// ~/.kube/config). AgentContext names the single context inside it. Both are empty for handles
// created before the scoped credential existed or joined out of band; consumers fall back to
// the ambient kubeconfig then. The operate path (`burrow-agent` and the CLI) reads them to reach
// burrowd with the scoped credential; `install` (fresh mint or join), `env list --discover`, and `upgrade`
// write them.
AgentKubeconfig string `yaml:"agentKubeconfig,omitempty"`
AgentContext string `yaml:"agentContext,omitempty"`
}
Environment is a user-named handle resolving to a kube context and the namespaces the environment lives in (ADR-0036). ControlPlaneNamespace defaults to DefaultControlPlaneNamespace when empty; AppNamespace empty means callers fall back to the burrowd default app namespace.
Env is the burrowd-registered environment NAME a command sends with each operation, which burrowd maps to the operation's namespace and per-environment guardrails. Empty means the cluster's default app namespace and the global guardrails (the cluster-per-environment case, where the whole cluster is the environment); a namespace-per-environment handle carries the same name it was registered with via `burrow env add`. It is deliberately distinct from AppNamespace, which is for display only: burrowd resolves a registered NAME, not a raw namespace.
type Mode ¶
type Mode string
Mode is how the active target was selected: pinned to a named handle, or following the current kube context.
const ( // ModePinned means a handle was pinned with `burrow env use`. ModePinned Mode = "pinned" // ModeFollowing means the target tracks the current kube context (the default). ModeFollowing Mode = "following" // ModeTargeted means an ADR-0078 target chosen with `burrow auth login` decided the cluster, // and no pinned handle inside that cluster narrowed it further. ModeTargeted Mode = "targeted" )
type Resolved ¶
type Resolved struct {
Name string
Context string
Namespace string
ControlPlaneNamespace string
Env string
Mode Mode
Target string
AgentKubeconfig string
AgentContext string
}
Resolved is the concrete target a command will act against, derived from the config and the kubeconfig. Namespace is the app namespace (for display); empty means the caller falls back to the burrowd default app namespace. Env is the burrowd-registered environment NAME to send with the operation (empty means the cluster's default namespace and global guardrails); it is what burrowd resolves, not a raw namespace. In follow mode Name (and Env) are empty when the current context matches no registered handle (an "unregistered" current context). AgentKubeconfig/AgentContext carry the resolved handle's scoped, burrowd-only credential (ADR-0038) so the operate path can default to it; both are empty when the handle records none. Target names the ADR-0078 target that decided the cluster, and is empty when no target is selected (the pre-ADR-0078 behaviour, and still the default).
func Resolve ¶
Resolve decides which environment a command targets (ADR-0036, ADR-0078).
When an ADR-0078 target is selected it decides the CLUSTER first, since that is what the target says: a Kubernetes target resolves to its kubeconfig context, and a pinned handle applies only when it is a handle inside that same cluster (a pin for a different cluster is not a narrowing of this one). A Burrow Cloud target has no kubeconfig to resolve and is reported as such.
With no target selected the behaviour is exactly as before. When a handle is pinned (cfg.Current set), it resolves to that handle, erroring clearly if the pinned name is not registered. Otherwise it follows the kubeconfig's current context: the target is that context, its namespace (so kubens moves Burrow too; empty when the context sets none, leaving the burrowd default to apply), and the default control-plane namespace. If the current context matches a registered handle by context name, that handle's Name and Env (the burrowd env name to send) are surfaced; otherwise both are empty.
type Target ¶
type Target struct {
Name string `yaml:"name"`
Kind TargetKind `yaml:"kind"`
Context string `yaml:"context,omitempty"` // Kubernetes only: the kubeconfig context name
Endpoint string `yaml:"endpoint,omitempty"` // Burrow Cloud only: the host signed in to
}
Target is a control plane the CLI can point at, recorded in ~/.burrow/config.
A Kubernetes target stores the kubeconfig context NAME and NEVER a copy of the credential (ADR-0078 §1). The kubeconfig stays the single source of truth, so rotating it, re-issuing a certificate, or having a cloud provider's CLI manage it all keep working with nothing here going stale. A copied credential is a credential nobody remembers to rotate.
A Burrow Cloud target likewise stores no token: only the endpoint it signs in to. Where the token lives is cloud ADR-0028's decision, not this file's.
func KubernetesTarget ¶
KubernetesTarget builds a target for a kubeconfig context, named after the context so a person selects a cluster by a name they already recognise.
type TargetKind ¶
type TargetKind string
TargetKind distinguishes the two kinds of target (ADR-0078 §1).
const ( // TargetKindCloud is the managed product. The credential is a token obtained by signing in, and // it is never written here (cloud ADR-0028 owns it). TargetKindCloud TargetKind = "burrow-cloud" // TargetKindKubernetes is a cluster with Burrow installed in it. The credential is the // kubeconfig the person already has, used exactly as ADR-0014 already uses it. TargetKindKubernetes TargetKind = "kubernetes" )
A target is where the control plane is (ADR-0078 §1). There are two kinds and deliberately not three: the managed product, or a Kubernetes cluster the person holds a kubeconfig context for. A managed control plane operated on somebody else's cluster is a shape the roadmap keeps open and is not modelled here, because inventing a kind for it now would be inventing the product it is a target for.