Help us shape the future of Go! Take the 2026 Go Developer Survey

addons

package
v1.37.1-stratum.0 Latest Latest
Warning

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

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

Documentation

Overview

Package addons carries the cluster add-on manifests (CoreDNS, local-path storage, Cilium CNI) embedded in the stratum binary, and renders each one for the cluster it is about to be installed into — substituting the mirrored image registry, the pinned versions, and the per-cluster apiserver endpoint.

Rendering is all this package does. The controller writes the rendered bundles into /var/lib/stratum/manifests (internal/cluster.writeBundles) and the operator's deployer server-side-applies and prunes them, so there is one apply path rather than two.

Index

Constants

View Source
const (
	DNSAddressSentinel     = "__STRATUM_DNS_IP__"
	ClusterDomainSentinel  = "__STRATUM_CLUSTER_DOMAIN__"
	EnableIPv6Sentinel     = "__STRATUM_ENABLE_IPV6__"
	StorageDefaultSentinel = "__STRATUM_STORAGE_DEFAULT__"
)

The four per-cluster inputs the staged bundles carry as named sentinels instead of the staging node's local values. The staging path leaves them unfilled, so every control plane stages the same bytes; the deployer fills each at apply time from the cluster-inputs record the staging writes beside the prune inventory (operator.manifestSentinels is the consuming table). They resolve to what their name says:

  • DNSAddressSentinel: the kube-dns Service's clusterIP, the tenth address of the cluster's service CIDR (netcfg.DNSIPFor).
  • ClusterDomainSentinel: the cluster domain the Corefile serves.
  • EnableIPv6Sentinel: Cilium's dual-stack toggle, true or false.
  • StorageDefaultSentinel: whether local-path claims the default StorageClass, true when spec.storage.default is local-path.
View Source
const (
	StorageLocalPath = "local-path"
	StorageNone      = "none"
)

Storage backends selectable in the cluster config (spec.storage.default). Only local-path and none are selectable here.

View Source
const (
	DashboardStack         = "dashboard"
	DashboardNamespace     = "stratum-dashboard"
	DashboardName          = "stratum-dashboard"
	DashboardTLSSecret     = "stratum-dashboard-tls"
	DashboardSessionSecret = "stratum-dashboard-session"
	DashboardCASecret      = "stratum-dashboard-ca"
	DashboardHostsKey      = "stratum.ciq.com/serving-hosts"
	DefaultDashboardPort   = 30443
)

The in-cluster dashboard's fixed names, shared with the operator that keeps its Secrets.

Variables

View Source
var (
	CorednsVersion   = "unknown"
	LocalPathVersion = "unknown"

	// ImageRegistry is the namespace every bundled manifest pulls from. A
	// running cluster reaches no upstream registry: the images are mirrored
	// here by digest (tools/mirror-images.sh) and carried in the airgap payload
	// under these exact names, so the manifest and the payload agree by
	// construction. Unstamped builds get a name that resolves nowhere, on
	// purpose — same reason as CorednsVersion.
	ImageRegistry = "unknown"
)

Stamped from build/versions.mk at link time (see the repo Makefile) so the deployed images always match the pin manifest and the airgap payload.

View Source
var DashImage = "unknown"

DashImage is the dashboard image the payload carries, stamped at link time.

View Source
var DashboardTokenSecrets = map[string]string{
	"stratum-dashboard-admin-token":  "stratum-dashboard-admin",
	"stratum-dashboard-viewer-token": "stratum-dashboard-viewer",
}

DashboardTokenSecrets maps each sign-in token Secret the stack carries to its ServiceAccount.

Functions

func FillAPIServer

func FillAPIServer(m []byte, a APIServer) []byte

FillAPIServer resolves the apiserver sentinels. The URL list is space separated, which is the form Cilium's chart renders for k8s.apiServerURLs in both places it appears.

func NeedsAPIServer

func NeedsAPIServer(m []byte) bool

NeedsAPIServer reports whether a manifest still carries an apiserver sentinel that FillAPIServer must resolve before it is applied.

func RenderCilium

func RenderCilium(dualStack bool, s CiliumSettings) []byte

RenderCilium substitutes the per-node-independent values into the embedded manifest: the registry, the operator replica count, and the cluster's spec.network.cilium settings. The apiserver sentinels are left for FillAPIServer, because the right values depend on the cluster, not on the node rendering the file — and so is the dual-stack toggle: what enable-ipv6 should say is the cluster's, not the staging node's, so the staging path calls RenderCiliumStaged, which leaves it as EnableIPv6Sentinel for the deployer to fill at apply time. The dualStack argument only decides what a direct RenderCilium caller's bytes say.

func RenderCiliumStaged

func RenderCiliumStaged(s CiliumSettings) []byte

RenderCiliumStaged renders the Cilium bundle the staging path stages: RenderCilium's render with the dual-stack toggle left as the EnableIPv6Sentinel instead of the staging node's own DualStack answer. Every control plane therefore stages the same bytes, and the deployer fills the toggle at apply time from the cluster-inputs record, the way it fills the apiserver sentinels from cluster state.

func RenderCoreDNS

func RenderCoreDNS() []byte

RenderCoreDNS renders the CoreDNS stack the staging path stages: the registry, the pinned busybox helper image and the CoreDNS version resolve here, while the two per-cluster inputs stay as the DNSAddressSentinel (the kube-dns Service's clusterIP) and the ClusterDomainSentinel (the Corefile's zone) — the deployer fills both at apply time from the cluster-inputs record, so every control plane stages the same bytes whatever its own service CIDR and domain are. Both inputs live in cluster state, so the render takes no dnsIP or domain argument: an argument that the bytes never read states an intent the manifest does not carry.

func RenderDashboard

func RenderDashboard(s DashboardSettings) []byte

RenderDashboard renders the dashboard stack. A zero NodePort gives a ClusterIP Service.

func RenderHelmCRDs

func RenderHelmCRDs() []byte

func RenderJoinFencePolicy

func RenderJoinFencePolicy() []byte

RenderJoinFencePolicy is the join fence admission policy and its binding.

func RenderLocalPath

func RenderLocalPath() []byte

RenderLocalPath renders the local-path stack the staging path stages: the registry, the pinned busybox helper image and the provisioner's version resolve here, while whether the StorageClass claims the cluster default stays as the StorageDefaultSentinel — the cluster's storage decision, which the deployer fills at apply time from the cluster-inputs record.

func RenderNodeMarkPolicy

func RenderNodeMarkPolicy() []byte

RenderNodeMarkPolicy is the node-mark admission policy stack.

Types

type APIServer

type APIServer struct {
	// Host is KUBERNETES_SERVICE_HOST in every Cilium pod.
	Host string
	// URLs is k8s-api-server-urls: every control plane, which the agents rotate
	// through until they reach the kubernetes Service. Empty means Host alone.
	URLs []string
}

APIServer is how Cilium reaches the apiserver before Kubernetes networking exists: kube-proxy-free agents cannot use the in-cluster Service until they are themselves up.

func APIServerFor

func APIServerFor(vip, selfIP string, controlPlaneIPs []string) APIServer

APIServerFor derives the Cilium apiserver settings from facts every control plane sees identically, so the manifest is the same whichever of them the operator leader runs on. A render that bakes in the rendering node's own IP would differ per control plane: a leader change re-points every agent at the new leader and rolls the DaemonSet during the failover it was reacting to, and an agent pinned to one control plane loses the API whenever that one does.

  • With a VIP: the VIP alone. kube-vip already moves it.
  • Without one: every control plane's address, sorted, and the first of them as Host. Losing a node does not remove its Node object, so failover changes neither value; a join or a removal does, and rolls the agents once, as a planned change.

selfIP is the fallback while no Node carries the control-plane label yet (the first apply on a fresh cluster). An empty result means there is nothing to render with, and the caller must not apply.

type CiliumSettings

type CiliumSettings struct {
	MTU                   int      `json:"mtu,omitempty"`
	Devices               []string `json:"devices,omitempty"`
	BGPControlPlane       bool     `json:"bgpControlPlane,omitempty"`
	NativeRouting         bool     `json:"nativeRouting,omitempty"`
	IPv4NativeRoutingCIDR string   `json:"ipv4NativeRoutingCIDR,omitempty"`
	IPv6NativeRoutingCIDR string   `json:"ipv6NativeRoutingCIDR,omitempty"`
	AutoDirectNodeRoutes  bool     `json:"autoDirectNodeRoutes,omitempty"`
}

CiliumSettings are the cluster's Cilium options from spec.network.cilium. The zero value is the shipped configuration: VXLAN tunnel, auto-detected devices, Cilium's own MTU, no BGP control plane.

func DecodeCiliumSettings

func DecodeCiliumSettings(b []byte) (CiliumSettings, error)

DecodeCiliumSettings reads an Encode. Empty input is the shipped configuration, which is what a cluster that predates the settings runs.

func (CiliumSettings) Encode

func (s CiliumSettings) Encode() []byte

Encode is s in the one form two control planes compare: they agree on the cluster's Cilium configuration exactly when their encodings are equal.

func (CiliumSettings) IsDefault

func (s CiliumSettings) IsDefault() bool

IsDefault reports whether s is the shipped configuration.

type DashboardSettings

type DashboardSettings struct {
	NodePort      int
	PublicURL     string
	TLSSecretName string
	NodeShell     bool
	TokenSecrets  bool
}

DashboardSettings is spec.dashboard as the render takes it.

Jump to

Keyboard shortcuts

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