klist

package
v0.27.0 Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package klist reads and merges cluster registry YAML files from a local klist clone. The layout is:

clusters/<customerid>/_customer.yaml   (optional, shared OIDC issuers)
clusters/<customerid>/<clustername>.yaml (required, per-cluster config)

A cluster lists every OIDC issuer its kube-apiserver trusts. Customer-level issuers from _customer.yaml are prepended to each cluster's own issuer list; the cluster file wins on every other (scalar) field.

Index

Constants

View Source
const (
	// GlobalConfigFile is the optional top-level YAML in the klist clone
	// that declares deployment-wide defaults (NetBird server, peer
	// naming convention).
	GlobalConfigFile = "global.yaml"

	// DefaultClusterPeerPrefix is what AccessibleClusters expects in
	// front of a peer FQDN to recognise it as a cluster.
	DefaultClusterPeerPrefix = "k8s-"
	// DefaultClusterPeerSuffix is the FQDN suffix matching the example
	// in docs/netbird-vpn-architecture.md. Real deployments usually
	// override this in global.yaml (Obmondo's, for instance, ends in
	// `.netbird.selfhosted`).
	DefaultClusterPeerSuffix = ".netbird"
)

Variables

View Source
var ErrClusterNotFound = errors.New("cluster file not found in klist registry")

ErrClusterNotFound is the sentinel returned (wrapped) by Load when the requested clusterName.yaml does not exist in the registry. Use errors.Is to detect it — callers then have the option to surface a "did you mean …" list of available clusters.

Functions

This section is empty.

Types

type ClusterConfig

type ClusterConfig struct {
	Name          string       `yaml:"name"`
	Server        string       `yaml:"server"`
	CABundle      string       `yaml:"caBundle"`
	OIDC          []OIDCIssuer `yaml:"oidc"`
	AllowedGroups []string     `yaml:"allowedGroups"`
}

ClusterConfig holds the merged per-cluster configuration. After merging, OIDC holds every issuer the cluster trusts (customer-level issuers first, then the cluster's own); Validate enforces the required fields.

func Load

func Load(registryPath, clusterName, customerID string) (*ClusterConfig, error)

Load reads the optional _customer.yaml and the required <clustername>.yaml from registryPath/clusters/<customerid>/, then returns a merged ClusterConfig: customer-level OIDC issuers are prepended to the cluster's own, and the cluster file wins on every scalar field.

Each issuer's GroupsClaim defaults to "groups" and UsernameClaim to "email" when omitted.

func (*ClusterConfig) Validate

func (c *ClusterConfig) Validate() error

Validate returns an error listing every required field that is empty or invalid after merging. The message names each problem so the user knows exactly what to fix. It enforces the top-level fields, that at least one OIDC issuer is present, that each issuer carries an issuerUrl and clientId, and — when the cluster lists more than one issuer — that every issuer has a unique name (the picker needs a stable label to select on).

type ClusterRef

type ClusterRef struct {
	Customer    string
	ClusterName string
	YAMLPath    string
}

ClusterRef points at one entry in the klist registry: the directory (customer) it belongs to, the cluster's name (file basename without the .yaml extension), and the path to the YAML on disk.

func ListClusters

func ListClusters(registryPath string) ([]ClusterRef, error)

ListClusters walks registryPath/clusters and returns every per-cluster YAML it finds, sorted (customer, cluster) for stable output. Files starting with "_" (e.g. "_customer.yaml") are skipped — they're per-customer defaults, not clusters.

type CustomerDefaults

type CustomerDefaults struct {
	Customer    string       `yaml:"customer"`
	DisplayName string       `yaml:"displayName"`
	OIDC        []OIDCIssuer `yaml:"oidc"`
}

CustomerDefaults holds optional per-customer defaults from _customer.yaml. Its OIDC issuers (if any) are shared across all of the customer's clusters and are prepended to each cluster's own issuer list during merge.

type GlobalConfig

type GlobalConfig struct {
	NetBird NetBirdSettings `yaml:"netbird"`
	// ContextPrefix is prepended to every cluster/context/user name
	// kubeaid-cli writes into the user's kubeconfig. Empty by default
	// (no prefix). Useful in merge mode so kubeaid-managed entries are
	// distinguishable from entries added by other tools — for example,
	// setting "kubeaid-" gives contexts like "kubeaid-staging.acme".
	ContextPrefix string `yaml:"contextPrefix,omitempty"`
}

GlobalConfig is the parsed shape of klist/global.yaml.

func LoadGlobal

func LoadGlobal(registryPath string) (*GlobalConfig, error)

LoadGlobal reads registryPath/global.yaml (optional). If the file is missing, returns a GlobalConfig with everything unset — call Prefix() and Suffix() on the embedded NetBirdSettings to get values that fall back to baked-in defaults.

type NetBirdSettings

type NetBirdSettings struct {
	// ManagementURL is the expected `management.url` reported by the
	// local netbird daemon. Used for sanity-checking; mismatch is a
	// warning, not a failure.
	ManagementURL string `yaml:"managementUrl"`
	// ClusterPeerPrefix and ClusterPeerSuffix bracket the cluster name
	// in the NetBird peer FQDN, e.g. prefix "k8s-" + cluster name
	// "staging" + suffix ".netbird.selfhosted". Use the Prefix() and
	// Suffix() accessors instead of dereferencing — they apply
	// baked-in defaults when the field is nil.
	ClusterPeerPrefix *string `yaml:"clusterPeerPrefix,omitempty"`
	ClusterPeerSuffix *string `yaml:"clusterPeerSuffix,omitempty"`
}

NetBirdSettings declares the NetBird deployment that hosts a cluster's kube-api endpoint. Per-customer files may override individual fields; missing fields fall back to the global file or to baked-in defaults.

ClusterPeerPrefix and ClusterPeerSuffix are *string so we can tell "field omitted" (use default) apart from "field explicitly empty" (use empty). A plain string can't carry that distinction — the zero value is indistinguishable from `field: ""`.

func (*NetBirdSettings) Prefix

func (n *NetBirdSettings) Prefix() string

Prefix returns the configured ClusterPeerPrefix, or the baked-in default when the field was omitted from YAML. Explicit empty string in YAML is preserved as "".

func (*NetBirdSettings) Suffix

func (n *NetBirdSettings) Suffix() string

Suffix is the same as Prefix, for ClusterPeerSuffix.

type OIDCIssuer added in v0.27.0

type OIDCIssuer struct {
	// Name labels the issuer in the interactive picker and selects it via
	// `login --issuer <name>`. Required and unique when a cluster lists more
	// than one issuer; optional for a single-issuer cluster.
	Name string `yaml:"name"`
	// IssuerURL is the Keycloak realm URL kube-apiserver validates JWTs against.
	IssuerURL string `yaml:"issuerUrl"`
	// ClientID is the OIDC client whose tokens kube-apiserver accepts (the
	// token's `aud`). Per-issuer — the customer and Obmondo entries differ.
	ClientID string `yaml:"clientId"`
	// GroupsClaim is the JWT claim kube-apiserver reads for RBAC groups.
	// Defaults to "groups" when omitted.
	GroupsClaim string `yaml:"groupsClaim"`
	// UsernameClaim is the JWT claim kube-apiserver maps to the user identity.
	// Defaults to "email" when omitted.
	UsernameClaim string `yaml:"usernameClaim"`
}

OIDCIssuer is one OpenID Connect issuer a cluster's kube-apiserver trusts. A cluster lists every issuer a user may authenticate through; `login` prompts the user to choose when there is more than one (typically the customer's own Keycloak and Obmondo's central SRE Keycloak).

Jump to

Keyboard shortcuts

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