config

package
v0.42.4 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package config holds the lab configuration: everything the interactive form asks for, persisted to agentlab.yaml so re-runs are reproducible.

Index

Constants

View Source
const (
	// ModelManagerBackendOllama is a host Ollama.
	ModelManagerBackendOllama = "ollama"
	// ModelManagerBackendLemonade is a host Lemonade Server
	// (lemonade-server.ai): FastFlowLM on AMD Ryzen AI NPUs, llama.cpp on
	// GPU and CPU, behind one OpenAI-compatible API plus a management API.
	ModelManagerBackendLemonade = "lemonade"
	// ModelManagerBackendLMStudio is a host LM Studio (lmstudio.ai):
	// llama.cpp on GPU and CPU, MLX on Apple silicon, behind one
	// OpenAI-compatible API plus its own /api/v1. Needs 0.4.0 or newer, and
	// it cannot delete a model — that is `lms rm` on the host.
	ModelManagerBackendLMStudio = "lmstudio"
)

The model servers the lab runs against on the host, which model-manager and agent pods reach through the kind docker network's gateway.

View Source
const (
	OllamaPort   = 11434
	LemonadePort = 13305
	LMStudioPort = 1234
)

The servers' default API ports, the ones the autodetected endpoints assume.

View Source
const (
	KubernetesClientID     = "kubernetes"
	KubernetesClientSecret = "kubernetes-lab-secret" // #nosec G101 -- static throwaway lab credential, by design
	// The ONE platform client, following the chart's global.identity
	// convention: muster and Backstage authenticate with the same Dex client,
	// so a token minted for either carries an audience the other trusts.
	AgentPlatformClientID     = "agent-platform"
	AgentPlatformClientSecret = "agent-platform-lab-secret" // #nosec G101 -- static throwaway lab credential, by design
)

Static OAuth client IDs and secrets, paired per client. The IDs also appear in the templates (Dex staticClients and each consumer's own config), which must agree with these. The lab's identity is self-contained and throwaway by design; nothing here guards anything real.

View Source
const (
	ProviderOpenAI    = "OpenAI"
	ProviderAnthropic = "Anthropic"
	ProviderGemini    = "Gemini"
	ProviderOllama    = "Ollama"
)

The provider vocabulary for extra models, spelled exactly as the kagent ModelConfig CRD's provider enum spells them.

View Source
const BrowserCallbackPort = 5555

BrowserCallbackPort is the fixed local port for the OAuth callback of `agentlab login --browser` (and its hidden `agentlab browser` alias). Fixed because it must be pre-registered in Dex's redirectURIs.

View Source
const ChartRepository = "oci://gsoci.azurecr.io/charts/giantswarm/agent-platform"

ChartRepository is where the agent-platform chart releases live.

View Source
const DefaultChartVersion = "4.7.11"

DefaultChartVersion is the agent-platform release the lab installs when agentlab.yaml pins none — the release this agentlab was verified with: the 4.x line (kagent API v2 with Agent Substrate and the platform Postgres shipped by the chart). Bump deliberately, with a lab run: the lab never floats.

View Source
const DefaultDevRegistryPort = 5001

DefaultDevRegistryPort is the host port of the lab registry when agentlab.yaml sets none: kind's documented local-registry port.

View Source
const DefaultDexPort = 32000

DefaultDexPort is the lab Dex NodePort when agentlab.yaml sets none.

View Source
const DevImageHarness = "harness"

DevImageHarness is the devImages key of the platform Harness's workload image — the Go ADK runtime every agent runs on under kagent API v2. Not a Deployment: the connectivity chart renders the image by digest into the `Harness` object, and Substrate's atelet pulls it from a registry into its own layer cache, so the lab pushes the local build to its registry (DevRegistryPort) and forwards the digest through kagent.harness.image.

View Source
const File = "agentlab.yaml"

File is the configuration file written next to the binary's working directory by `agentlab configure` and read by every other command.

View Source
const GatewayNodePort = 30443

GatewayNodePort is the fixed NodePort publishing the agentgateway edge (the chart-owned Gateway's HTTPS :443 listener) on the kind node. The data-plane Service is created by the agentgateway controller at run time — not part of the Helm release, so neither values nor a postRenderers patch can pin its NodePort. The lab renders its own selector-matched NodePort Service instead (gateway-nodeport.yaml.tmpl), pinned here so the kind port mapping has a stable node-side port. Host side: Platform.GatewayPort.

View Source
const GatewayPublicNodePort = 30444

GatewayPublicNodePort pins the NodePort of the edge Service's second port (platform.gatewayPort, rendered off 443 only) so the apiserver never picks one that collides with the other fixed NodePorts. Nothing on the host maps it.

View Source
const KagentUINodePort = 30880

KagentUINodePort is the fixed NodePort the kagent-ui Service is pinned to, so the kind port mapping (created once, at cluster creation) has a stable node-side port to publish. The kagent chart renders `ui.service.type` but no `nodePort` field, so the pin is a Kustomize patch in the kagent component's `postRenderers` (HACKS.md U9). A real Kubernetes NodePort, hence the 30000-32767 range; the host side is configurable via Platform.AgentsPort.

View Source
const MusterNodePort = 8090

MusterNodePort is the port muster's aggregator binds on the kind node (hostNetwork). It is the muster chart's default listen port, not a lab choice: in-node consumers (Backstage) always dial localhost:8090, while the host-side port mapping is configurable via Platform.MusterPort.

Variables

View Source
var DevImageComponents = []string{"muster", "backstage", "kagent", "mcp-kubernetes", "model-manager", "agent-manager", DevImageHarness}

DevImageComponents are the targets platform.devImages can swap: the agent-platform chart's component names (its `components.<name>` entries) for the Deployments the lab's dev loops build from a checkout, plus DevImageHarness for the platform Harness's runtime image.

View Source
var Groups = []string{groupPlatformAdmins, groupDevelopers, groupViewers}
View Source
var ModelManagerBackends = backendKinds()

ModelManagerBackends lists the backends the lab accepts, in the canonical order `agentlab configure` writes them — which is also the preference for the one model-manager fronts.

ModelProviderNames is ModelProviders' keys in a stable order, for the form options and error messages.

View Source
var ModelProviders = map[string]string{
	ProviderOpenAI:    "OPENAI_API_KEY",
	ProviderAnthropic: "ANTHROPIC_API_KEY",
	ProviderGemini:    "GOOGLE_API_KEY",
	ProviderOllama:    "",
}

ModelProviders maps each provider to the key name inside the Secret. The kagent controller injects that key as an env var of the same name into agent pods, and the ADK runtime looks up exactly these canonical names — so the key name is provider-derived, not configurable. Ollama is keyless (empty key = no Secret).

PinnedNodePorts are the node-side ports the lab fixes itself. They share the node's port space with DexPort, whose Service claims the host port as its NodePort, so nothing else may take one of these numbers.

Functions

func BackendPort added in v0.15.0

func BackendPort(backend string) int

BackendPort is the default API port of a backend's server, 0 for a kind the lab does not know.

func BackendServerName added in v0.15.0

func BackendServerName(backend string) string

BackendServerName is a backend's server as messages name it; an unknown kind is named by itself rather than mistaken for one of the known servers.

func SanitizeBranch added in v0.27.0

func SanitizeBranch(branch string) string

SanitizeBranch spells a git branch the way gitsemver (v2.0.1, sanitizeBranchName) embeds it in a dev version: lowercased, runs of anything but [a-z0-9] collapsed to one hyphen, hyphens trimmed off both ends — `poc/kagent-main` is `poc-kagent-main`. A purely numeric result loses its leading zeros (a semver numeric identifier forbids them); an empty result is gitsemver's "unknown". gitsemver may further shorten the name to fit its 63-character version budget (head`--`tail), which the dev-tag filter accounts for.

func ValidateAIModel

func ValidateAIModel(s string) error

ValidateAIModel constrains the DEFAULT model to Anthropic: both consumers (the kagent ModelConfig provider and Backstage's ai-chat prefix routing) are wired for Anthropic only, keyed by the one $ANTHROPIC_API_KEY secret. Other providers go through platform.extraModels instead.

func ValidateAPIKeyEnv added in v0.10.0

func ValidateAPIKeyEnv(s string) error

ValidateAPIKeyEnv accepts an env var name or empty (keyless endpoint).

func ValidateChartBranch added in v0.27.0

func ValidateChartBranch(s string) error

ValidateChartBranch accepts a branch name that leaves something to match a dev tag with; "" is the stable channel and always fine.

func ValidateChartVersion added in v0.23.0

func ValidateChartVersion(s string) error

ValidateChartVersion accepts an exact chart version only.

func ValidateClusterName

func ValidateClusterName(s string) error

ValidateClusterName is the one home of the cluster-name rule; the huh form uses it directly as an input validator.

func ValidateImageRef added in v0.23.0

func ValidateImageRef(s string) error

ValidateImageRef accepts an image reference that names its tag or digest.

func ValidateModelName added in v0.10.0

func ValidateModelName(s string) error

ValidateModelName is the one home of the extra-model-name rule; the huh form uses it directly as an input validator.

func ValidateNodePort

func ValidateNodePort(s string) error

ValidateNodePort checks the Kubernetes NodePort range; the Dex port must be a NodePort because the Service exposes it as one. String-typed (like ValidatePort) so the huh form inputs can use it directly.

func ValidatePort

func ValidatePort(s string) error

Types

type Backstage

type Backstage struct {
	Enabled bool `yaml:"enabled"`
	// Backstage binds this port on the node (hostNetwork) and kind maps the
	// same number onto the host, so the URL is identical on both sides.
	// The image is not configured here: the agent-platform chart's backstage
	// component (its version range, resolved by the chart's Flux) decides the
	// version; platform.devImages swaps in a build of your own.
	Port int `yaml:"port"`
}

type Config

type Config struct {
	// Kind cluster name; also prefixes RBAC bindings and names the muster
	// installation surfaced in Backstage.
	ClusterName string `yaml:"clusterName"`
	// Dex NodePort == host port: the issuer https://localhost:<port>/dex must
	// be the same URL from the Mac and from inside the node, so both sides
	// use one number. Must sit in the NodePort range (30000-32767).
	DexPort  int    `yaml:"dexPort"`
	DexImage string `yaml:"dexImage"`

	// The Claude model both AI consumers use: the platform agents' default
	// ModelConfig (kagent) and Backstage's ai-chat. The API key is NOT config:
	// it is read from $ANTHROPIC_API_KEY at deploy time and lands only in
	// Kubernetes Secrets, never in this file or in rendered manifests.
	AIModel string `yaml:"aiModel"`

	Users     []User    `yaml:"users"`
	Platform  Platform  `yaml:"platform"`
	Backstage Backstage `yaml:"backstage"`
}

func Default

func Default() *Config

Default returns the canonical lab setup: the agent platform enabled (it is what the lab exists to test) with the agentgateway edge and Backstage — the real platform topology — three users, and Dex on 32000.

func Load

func Load() (*Config, error)

Load reads agentlab.yaml. A missing file is reported as os.ErrNotExist so callers can decide whether to fall back to the form or to defaults.

func (*Config) AdminUser

func (c *Config) AdminUser() *User

AdminUser returns the first user in platform-admins: the identity the up verification loop and the smoke tests default to.

func (*Config) AgentgatewayBaseURL added in v0.11.0

func (c *Config) AgentgatewayBaseURL() string

AgentgatewayBaseURL is the agentgateway hostname through the edge: the path-prefixed platform APIs (the kagent controller at /kagent, model-manager at /model-manager) live here, same as the chart's Backstage app-config derives them.

func (*Config) BackstageBaseURL

func (c *Config) BackstageBaseURL() string

BackstageBaseURL is Backstage's public URL through the agentgateway edge.

func (*Config) BackstageDirectURL

func (c *Config) BackstageDirectURL() string

BackstageDirectURL bypasses the edge (hostNetwork port mapping), kept for debugging.

func (*Config) ChartMajor added in v0.39.1

func (c *Config) ChartMajor() uint64

ChartMajor is the major version of the meta chart release platform. chartVersion pins (a leading v tolerated); 0 when it is not an exact version — ValidateChartVersion rejects that before anything renders.

func (*Config) ChooseFreePorts added in v0.7.0

func (c *Config) ChooseFreePorts(ours map[int]bool, minPublishable int) []PortChange

ChooseFreePorts probes every host-side port of the configuration on 127.0.0.1 — the address all kind port mappings bind — and moves each unusable one to a nearby free port, returning what changed so the caller can tell the user. Ports in `ours` are the lab's own (published by an existing kind node of this very configuration) and never count as occupied. Ports below minPublishable are ones the container engine cannot bind at all (rootless podman and the privileged range); pass 1 where every port is available. Meant for a configuration whose cluster does not exist (yet, or any more): an existing cluster's mappings are fixed at node creation, where renumbering would only mislead — PortConflicts is the read-only check for that case.

func (*Config) ControlPlaneNode

func (c *Config) ControlPlaneNode() string

ControlPlaneNode is the docker container name kind gives the (only) node.

func (*Config) EnsureHashes

func (c *Config) EnsureHashes() (changed bool, err error)

EnsureHashes fills in User.PasswordHash wherever it is missing or no longer matches the password. The hash is cached in the config file on purpose: bcrypt salts are random, so hashing at render time would change the Dex manifest (and roll the pod) on every single run.

func (*Config) FindUser

func (c *Config) FindUser(email string) *User

func (*Config) FindUserInGroup added in v0.13.0

func (c *Config) FindUserInGroup(group string) *User

FindUserInGroup returns the first user carrying group, or nil.

func (*Config) Issuer

func (c *Config) Issuer() string

func (*Config) KagentUIBaseURL

func (c *Config) KagentUIBaseURL() string

func (*Config) LegacyChart added in v0.39.1

func (c *Config) LegacyChart() bool

LegacyChart reports whether the lab installs a released meta chart of the 3.x line: an exact platform.chartVersion below 4.0.0 on the stable channel. The 3.x line's values are a different shape (kagent 0.10 with its bundled Postgres, no Agent Substrate, no platform Postgres, a closed root schema that refuses the 4.x keys), so the lab values render in that shape for it; a dev channel (platform.chartBranch) or a chart directory (platform.chartPath) is always the current line, whatever version its Chart.yaml or resolved tag carries.

func (*Config) MCPServerName

func (c *Config) MCPServerName() string

MCPServerName is the MCPServer CR name the umbrella chart registers for its bundled mcp-kubernetes (templates/mcp-kubernetes/mcpserver.yaml): a fixed name, independent of the cluster. Muster prefixes the server's tools with it: x_mcp-kubernetes_<tool>.

func (*Config) ModelManagerBaseURL added in v0.11.0

func (c *Config) ModelManagerBaseURL() string

ModelManagerBaseURL is the model-manager API through the edge — the umbrella's components.model-manager.route (pathPrefix /model-manager, stripped before the service, so its REST API sits at <base>/api/v1). The route's JWT policy wants a Dex token on every call.

func (*Config) ModelManagerEnabled added in v0.11.0

func (c *Config) ModelManagerEnabled() bool

ModelManagerEnabled reports whether the platform installs model-manager.

func (*Config) MusterBaseURL

func (c *Config) MusterBaseURL() string

MusterBaseURL is muster's public URL: client -> agentgateway edge -> muster, the real platform topology. What Claude Code dials and what muster's OAuth server advertises.

func (*Config) MusterDirectURL

func (c *Config) MusterDirectURL() string

MusterDirectURL bypasses the edge: the hostNetwork port mapping straight to muster, kept for debugging the lab's own plumbing.

func (*Config) Normalize

func (c *Config) Normalize()

Normalize applies cross-field implications after an entry point sets the enable flags: Backstage's muster plugin is the reason to run it, so it implies the platform. Validate stays the backstop for hand-edited files.

func (*Config) ObservabilityBaseURL added in v0.6.0

func (c *Config) ObservabilityBaseURL() string

ObservabilityBaseURL is the lab Prometheus's public query API through the edge, at the /prometheus prefix Backstage's Mimir integration expects (observability-route.yaml.tmpl). Backstage itself always dials it in-cluster on 443 (the CoreDNS rewrite), so only host-side callers see GatewayPort.

func (*Config) PortConflicts added in v0.15.0

func (c *Config) PortConflicts(ours map[int]bool) []PortConflict

PortConflicts reports which host-side ports of the configuration another process holds, ignoring the lab's own (`ours`, the ports the existing kind node publishes). Nothing is changed.

func (*Config) Save

func (c *Config) Save() error

func (*Config) Validate

func (c *Config) Validate() error

type ExtraModel added in v0.10.0

type ExtraModel struct {
	// ModelConfig CR name; also names the key Secret kagent-<name>.
	Name string `yaml:"name"`
	// One of ModelProviders (a subset of the kagent CRD's enum: the providers
	// expressible with just a model + base URL).
	Provider string `yaml:"provider"`
	// The provider's model id (what the endpoint serves, e.g. `qwen3-8-27b`
	// for a local vLLM or `deepseek/deepseek-chat` on OpenRouter).
	Model string `yaml:"model"`
	// Endpoint override. Required for Ollama (the in-cluster default would be
	// useless), optional for OpenAI/Anthropic (any compatible endpoint:
	// vLLM `http://host:8000/v1`, OpenRouter `https://openrouter.ai/api/v1`),
	// not applicable to Gemini.
	BaseURL string `yaml:"baseUrl,omitempty"`
	// Host env var holding the API key at deploy time. Empty means a keyless
	// endpoint: the Secret is still created with a placeholder, because the
	// kagent ADK runtime requires the provider's env var to exist.
	APIKeyEnv string `yaml:"apiKeyEnv,omitempty"`
	// Skip TLS verification on the provider connection (ModelConfig spec.tls.
	// disableVerify) — for self-hosted endpoints with self-signed certs.
	InsecureTLS bool `yaml:"insecureTLS,omitempty"`
}

ExtraModel is one additional kagent ModelConfig. API keys are NOT config: APIKeyEnv only names the host env var read at deploy time — the value lands in the Secret kagent-<name>, never in this file or in rendered state/.

func (ExtraModel) NeedsSecret added in v0.10.0

func (m ExtraModel) NeedsSecret() bool

NeedsSecret reports whether this model's ModelConfig references a Secret.

func (ExtraModel) SecretKey added in v0.10.0

func (m ExtraModel) SecretKey() string

SecretKey is the key inside the Secret — the provider's canonical env var name. Empty for keyless providers (no Secret attached at all).

func (ExtraModel) SecretName added in v0.10.0

func (m ExtraModel) SecretName() string

SecretName is the Kubernetes Secret (in ns kagent) holding this model's key.

func (ExtraModel) Validate added in v0.10.0

func (m ExtraModel) Validate() error

Validate checks one extra model entry; string-typed like the port validators where the form shares it, entry-level here.

type ModelManager added in v0.11.0

type ModelManager struct {
	// On, `agentlab platform` enables components.model-manager in front of
	// every listed backend, its agentgateway route (JWT-validated: the portal
	// backend forwards the user's Dex token) and the muster registration.
	// `agentlab configure` turns it on whenever a host model server answers
	// (and off when none does), unless --model-manager pins it.
	Enabled bool `yaml:"enabled"`
	// The host model servers, in order; backends.go names them and owns the
	// list, so this comment cannot go stale as servers are added. ONE
	// model-manager fronts all of them at once (model-manager >= 0.17.0,
	// `model-manager.backends` in the chart values); the first entry is its
	// default backend — where a request that names none goes. `agentlab
	// configure` fills the list from what answers on this machine and can be
	// reached from pods (Ollama first); --model-manager-backends pins it.
	// kserve is no lab backend: GPU nodes and a KServe install.
	Backends []string `yaml:"backends,omitempty"`
	// Per-backend base URL as pods reach it, keyed by backend. Empty
	// autodetects http://<kind docker network gateway>:<default port> at
	// platform time (BackendPort names each server's) — the same
	// address docs/models.md documents for extraModels (`docker network inspect
	// kind`). Set one for a server elsewhere on the LAN: a backend with an
	// endpoint here is kept by `agentlab configure` whether or not a server
	// answers on this machine.
	Endpoints map[string]string `yaml:"endpoints,omitempty"`
	// The one-backend form earlier versions wrote (backend + endpoint):
	// still read, folded into backends/endpoints on load, never written.
	Backend  string `yaml:"backend,omitempty"`
	Endpoint string `yaml:"endpoint,omitempty"`
}

ModelManager configures the umbrella's model-manager component in the lab.

func (*ModelManager) ApplyDiscovered added in v0.15.0

func (m *ModelManager) ApplyDiscovered(found []string, agents bool, pinEnabled *bool, pinBackends []string)

ApplyDiscovered merges what `agentlab configure` found on this machine into the block: the backends are the servers that answer plus every backend kept by an explicit endpoint (a server elsewhere on the LAN), in canonical order; managed models go on when there is at least one and the agents runtime is on, and off otherwise. pinBackends (--model-manager-backends) replaces the list outright; pinEnabled (--model-manager) decides the flag instead of the discovery — a pinned-on block without a backend falls back to the Ollama default, so the platform preflight reports the real reachability error.

func (ModelManager) EndpointFor added in v0.15.0

func (m ModelManager) EndpointFor(backend string) string

EndpointFor is the configured endpoint override of a backend, "" to autodetect.

func (ModelManager) Primary added in v0.15.0

func (m ModelManager) Primary() string

Primary is model-manager's default backend — where a request that names none goes: the first of the list, or the historical default (an Ollama) for an enabled block that names none.

func (ModelManager) Validate added in v0.11.0

func (m ModelManager) Validate(agents bool) error

Validate checks the model-manager block; agents reports whether the kagent runtime is on (model-manager wires ModelConfigs into it).

type Platform

type Platform struct {
	Enabled bool `yaml:"enabled"`
	// The agents runtime (kagent), an optional part of the platform install.
	// On real clusters agent delivery runs through Flux/GitOps, which the lab
	// does not run, so labs that are not exercising agents can skip the
	// runtime entirely. Inert when the platform itself is disabled.
	Agents bool `yaml:"agents"`
	// A minimal observability stack: the Giant Swarm kube-prometheus-stack
	// chart (the observability bundle's own pinned constituent, with the
	// Prometheus server re-enabled — the bundle itself is MC-shaped: Alloy
	// remote-writing to Mimir, no local query endpoint) plus mcp-prometheus
	// registered in muster, so agents can answer PromQL questions
	// (x_mcp-prometheus_<tool>). On by default: asking the platform about the
	// cluster's CPU/memory is part of the demo story. Not in the umbrella's
	// BOM (yet) — the lab pins the two charts itself (observability.go).
	// Inert when the platform itself is disabled.
	Observability bool `yaml:"observability"`
	// The fake fleet (lab/fleetfixture.go): six `Auth Required` MCPServers
	// (kubernetes/capi/prometheus × two fake management clusters) that give
	// the portal's server groups, its fleet coverage and the agent Tools
	// step a federated shape to render on one cluster. Off by default: a
	// default lab lists only the MCP servers of the lab that runs it, and
	// the fixture's rows ask a person to sign in to clusters that do not
	// exist. Switching it off removes the members on the next `agentlab
	// platform`; the proofs assert the fleet shape only while it is on.
	// Inert when the platform itself is disabled.
	FakeFleet bool `yaml:"fakeFleet"`
	// Host-side port for the kagent UI (http://localhost:<port>). The kind
	// mapping onto KagentUINodePort always exists — like the other mappings,
	// it is fixed at cluster creation — so agents can be enabled later.
	AgentsPort int `yaml:"agentsPort"`
	// Host-side port for muster's DIRECT debug access (hostNetwork + kind
	// mapping, bypassing the gateway). The platform's public URLs go through
	// the agentgateway edge on GatewayPort.
	MusterPort int `yaml:"musterPort"`
	// The platform's public domain. Every public hostname derives from it
	// (muster.<domain>, backstage.<domain>, ...). The default, nip.io's
	// loopback wildcard, resolves to 127.0.0.1 from anywhere without host
	// configuration; inside pods a CoreDNS rewrite points the same names at
	// the edge Gateway Service.
	Domain string `yaml:"domain"`
	// Host-side port of the agentgateway edge (HTTPS). 443 keeps the public
	// URLs port-free; any other value suffixes every public URL with it, and
	// the lab's edge Service (gateway-nodeport.yaml.tmpl) then also serves
	// that port in-cluster, so the ported URLs resolve from pods too. Change
	// only if 443 is taken.
	GatewayPort int `yaml:"gatewayPort"`
	// TLS optionally hands the edge an externally provisioned certificate
	// pair (PEM) instead of the minted lab-CA wildcard — for users who own a
	// real domain (wildcard record -> 127.0.0.1) and run their own ACME
	// tooling. Both fields set or both empty. The Dex issuer still serves
	// the lab CA either way; see docs/tls.md.
	TLS PlatformTLS `yaml:"tls"`
	// The agent-platform chart release the lab installs
	// (oci://gsoci.azurecr.io/charts/giantswarm/agent-platform): an exact
	// version, never a range — two runs install the same thing, and the lab
	// never floats onto a release nobody tested it with. DefaultChartVersion
	// is the release this agentlab was verified against.
	ChartVersion string `yaml:"chartVersion"`
	// ChartPath installs the meta chart from a local directory instead of the
	// pinned release — an agent-platform checkout's helm/agent-platform, for
	// chart changes that have no release yet (the lab's chart loop). The
	// directory is read, never written; chartVersion is ignored while set.
	ChartPath string `yaml:"chartPath,omitempty"`
	// ChartBranch selects the DEV CHANNEL: the lab follows the newest dev
	// build of this agent-platform branch — the `X.Y.Z-dev.<branch>.<date>.
	// <time>.h<sha>` prerelease tags gitsemver publishes for every commit of
	// a branch with branch publishing on — instead of a release. `configure`,
	// `up` and `platform` resolve it against the chart registry's tags and
	// write the tag they picked into chartVersion, so `render`, the image
	// preload and a re-run install exactly what was resolved, and the boot
	// says which build it runs. Mutually exclusive with chartPath; "" is the
	// stable channel. See docs/platform.md "Dev channel".
	ChartBranch string `yaml:"chartBranch,omitempty"`
	// ChartPinned freezes chartVersion at the recorded dev build while
	// chartBranch is set: `up` and `platform` stop re-resolving, so the lab
	// keeps running the build under test until `agentlab platform --pin=false`
	// (or the key is dropped). Meaningless without chartBranch.
	ChartPinned bool `yaml:"chartPinned,omitempty"`
	// DevImages swaps a component's image for a build of your own (the lab's
	// dev-image loop): target -> image ref (`muster: muster:dev-1a2b`). Keys
	// are the DevImageComponents. For a Deployment target `agentlab platform`
	// side-loads the ref from the host docker cache, resolves the image name
	// it replaces from the component chart's render (the kagent controller is
	// `ghcr.io/giantswarm/kagent/controller` on the 4.x line and
	// `gsoci.azurecr.io/giantswarm/kagent-controller` on 3.x — a target that
	// matches nothing in the render is an error before the install, never a
	// silently dropped override) and renders it into the component's
	// HelmRelease as a kustomize image override (postRenderers) with
	// imagePullPolicy IfNotPresent. For the `harness` target it pushes the
	// build to the lab registry and forwards the digest as
	// kagent.harness.image, so the platform Harness runs it and recompiles
	// every admitted template. Either way the swap is part of the release — a
	// plain `helm upgrade` applies it, and removing the entry restores the
	// chart's image (or digest) on the next run.
	DevImages map[string]string `yaml:"devImages,omitempty"`
	// DevRegistryPort is the host port (127.0.0.1) of the lab registry that
	// serves the `harness` dev image: a `registry` container on the kind
	// docker network, created on demand by `agentlab platform` and removed by
	// `agentlab down`. Unset means DefaultDevRegistryPort.
	DevRegistryPort int `yaml:"devRegistryPort,omitempty"`
	// ValuesFiles are extra Helm values files merged over the lab's rendered
	// values before the meta chart install, in order, with `helm -f`
	// semantics (maps merge, lists replace, the later file wins): a lab that
	// points a component at another chart source
	// (components.<name>.repository / versionRange / insecure) or forwards
	// values the lab template does not know. Paths are absolute or relative
	// to the lab directory; each must exist.
	ValuesFiles []string `yaml:"valuesFiles,omitempty"`
	// Additional kagent ModelConfigs beyond the chart-rendered default
	// (aiModel): self-hosted OpenAI-compatible endpoints (vLLM, Ollama),
	// OpenRouter, Gemini, plain OpenAI. Rendered as lab-labeled ModelConfig
	// CRs by `agentlab platform`; entries removed here are pruned on the next
	// run. Inert unless agents are enabled.
	ExtraModels []ExtraModel `yaml:"extraModels,omitempty"`
	// Managed models: the chart's model-manager component in front of the
	// model servers that run on the lab host (backends.go is the list, with
	// each server's port and name) — pull, load,
	// unload and delete models from the portal (or as x_model-manager_*
	// tools through muster), each pulled model wired into kagent as a
	// keyless ModelConfig automatically. Complements extraModels, which
	// wires endpoints statically and manages nothing. Requires agents.
	// `agentlab configure` fills the backends from what answers on this
	// machine, on every run.
	ModelManager ModelManager `yaml:"modelManager"`
}

type PlatformTLS

type PlatformTLS struct {
	CertFile string `yaml:"certFile,omitempty"`
	KeyFile  string `yaml:"keyFile,omitempty"`
}

PlatformTLS is an externally provisioned certificate for the edge; see Platform.TLS.

func (PlatformTLS) Set

func (t PlatformTLS) Set() bool

Set reports whether an external edge certificate is configured.

type PortChange added in v0.7.0

type PortChange struct {
	Field    string
	What     string
	From, To int
	Why      string
	Note     string
}

PortChange records one port of the configuration that was moved off its value because this machine cannot serve the lab there. Field is the agentlab.yaml path, What names the component for the human-facing message, Why says what made the port unusable, and Note carries an extra caveat where a non-default port has consequences beyond the number itself.

func (PortChange) String added in v0.7.0

func (ch PortChange) String() string

type PortConflict added in v0.15.0

type PortConflict struct {
	Field string
	What  string
	Port  int
}

PortConflict records one port of an existing cluster's configuration that another process on this machine holds — the lab cannot renumber it (the kind mappings are fixed at node creation), so it is reported instead.

func (PortConflict) String added in v0.15.0

func (pc PortConflict) String() string

type User

type User struct {
	Email        string   `yaml:"email"`
	Username     string   `yaml:"username"`
	Name         string   `yaml:"name"`
	Password     string   `yaml:"password"`
	PasswordHash string   `yaml:"passwordHash"` // bcrypt of Password, cached so renders stay deterministic
	Groups       []string `yaml:"groups"`
}

func (User) HasGroup

func (u User) HasGroup(g string) bool

Jump to

Keyboard shortcuts

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