localconfig

package
v0.14.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

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

View Source
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"
)
View Source
const CloudEndpoint = "burrow-cloud.dev"

CloudEndpoint is the managed product's host, and the name its target carries.

Variables

This section is empty.

Functions

func Exists

func Exists() (bool, error)

Exists reports whether the config file is present, for first-run detection.

func Path

func Path() (string, error)

Path resolves the config location: $BURROW_CONFIG when set, otherwise ~/.burrow/config (mirroring how the kubeconfig resolves $KUBECONFIG else ~/.kube/config).

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

func Load() (*Config, error)

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

func (c *Config) ActiveTarget() (Target, bool, error)

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

func (c *Config) LookupTarget(name string) (Target, bool)

LookupTarget returns the target with the given name, and whether it was found.

func (*Config) Remove

func (c *Config) Remove(name string) error

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

func (c *Config) Rename(oldName, newName string) error

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

func (c *Config) Save() error

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

func (c *Config) SetAgentCredential(name, kubeconfig, context string) bool

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

func (c *Config) SetTarget(t Target) error

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

func (c *Config) SwitchTarget(name string) error

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

func (c *Config) TargetNames() string

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

func Resolve(cfg *Config, kubeconfigPath string) (Resolved, error)

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.

func (Resolved) Render

func (r Resolved) Render() string

Render formats a resolved target for display on a command, so the target is never ambiguous (ADR-0036, ADR-0078). Examples:

nonprod (context "do-nyc1-nonprod", namespace "team-x")
following kubectl: do-nyc1-dev (unregistered)
target "do-nyc1" (no environment registered)

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 CloudTarget

func CloudTarget() Target

CloudTarget builds the target for the managed product.

func KubernetesTarget

func KubernetesTarget(context string) Target

KubernetesTarget builds a target for a kubeconfig context, named after the context so a person selects a cluster by a name they already recognise.

func (Target) Describe

func (t Target) Describe() string

Describe renders what a target IS, for `burrow auth status` and for any message that has to name one.

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.

Jump to

Keyboard shortcuts

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