meshconfig

package
v0.0.0-...-01ed9ff Latest Latest
Warning

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

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

Documentation

Overview

Package meshconfig hosts the MeshConfig CRD machinery that runs in the aether-controller: a validating admission webhook (protovalidate) and a reconciler that projects the singleton MeshConfig custom resource into the ConfigMap the agent consumes. It works against the typed MeshConfig object (api/aether/config/v1), not unstructured. See docs/proposals/015_mesh-config.md.

Index

Constants

View Source
const (
	// DefaultCABundleCallTimeout bounds the read and the write of ONE webhook
	// configuration. Both are single-object calls an apiserver answers in
	// milliseconds, so a call that is still out after this long is failing, and
	// is reported and retried as a failure (issue #1431).
	DefaultCABundleCallTimeout = 15 * time.Second
	// DefaultCABundleRetryMin and DefaultCABundleRetryMax bound the backoff
	// between retries while a webhook configuration cannot be injected. The
	// ceiling is also how long the injector takes, at worst, to notice that a
	// missing permission has been granted.
	DefaultCABundleRetryMin = time.Second
	DefaultCABundleRetryMax = time.Minute

	// CABundleInjectionFailuresMetric counts failed injection attempts, one per
	// webhook configuration and attempt, by `kind` (validating, mutating) and
	// `reason` (trust_bundle, get, update). Expected to stay 0.
	CABundleInjectionFailuresMetric = "aether.controller.webhook.cabundle_injection_failures"
)
View Source
const (
	// SingletonName is the only MeshConfig name the controller acts on; the CRD
	// is a cluster-scoped singleton.
	SingletonName = "default"

	// ConfigMapKey is the key under which the projected config is written.
	ConfigMapKey = "mesh-config.yaml"

	// DefaultMeshConfigMapName is the ConfigMap the reconciler projects into and
	// that the agent mounts.
	DefaultMeshConfigMapName = "aether-mesh-config"
)

Variables

This section is empty.

Functions

func RenderConfigMapData

func RenderConfigMapData(spec *configv1.MeshConfigSpec) (map[string]string, error)

RenderConfigMapData serializes a MeshConfig spec to the YAML document the agent loads, returning the ConfigMap `data` map. A nil spec renders an empty document (the agent then inherits everything from the aether config).

func Validate

func Validate(spec *configv1.MeshConfigSpec) error

Validate runs protovalidate on a MeshConfig spec. A nil spec (the proxy inherits everything from the aether config) is valid.

Types

type CABundleInjector

type CABundleInjector struct {
	// Reader reads the webhook configurations. It MUST be uncached (the
	// manager's GetAPIReader): see the type comment. Two single-object reads per
	// pass cost nothing next to a cluster-wide informer on both resources, and
	// need only the `get` permission.
	Reader client.Reader
	// Writer updates them.
	Writer client.Writer
	// Source is this workload's SVID source. It is the narrow SVIDSource interface
	// rather than a *spire.Source because the controller's source may still be
	// waiting for its first SVID when this runnable starts (issue #740): the
	// initial injection is then deferred (INFO, not ERROR) and performed on the
	// Updated() wake that WaitingSource fires when the SVID lands.
	Source            spire.SVIDSource
	WebhookConfigName string
	// MutatingWebhookConfigName is the pod-mutating MutatingWebhookConfiguration
	// to keep in sync too; empty skips it.
	MutatingWebhookConfigName string
	Log                       *slog.Logger

	// CallTimeout, RetryMin and RetryMax override the Default* constants above;
	// zero keeps the default.
	CallTimeout time.Duration
	RetryMin    time.Duration
	RetryMax    time.Duration
	// contains filtered or unexported fields
}

CABundleInjector keeps the webhooks' caBundle in sync with the SPIRE trust bundle. The webhooks are served with a SPIRE X.509 SVID, so the kube-apiserver must trust the SPIRE CA — this runnable writes the current bundle into the ValidatingWebhookConfiguration (and the MutatingWebhookConfiguration, when one is named) on startup and on every SVID rotation. It runs on the leader only (a cluster-wide single writer).

Two properties are load-bearing (issue #1431):

  • It cannot hang. Every read goes to the apiserver through Reader, never through the manager's informer cache, and each configuration's read and write share one bounded context. A cached read waits, with no deadline of its own, for an informer that may never sync — a missing list permission is enough — and the loop that should have reported the failure never came back.
  • The configurations are independent. Each is read, written, reported and retried on its own, so one that keeps failing never stops the other from following a trust-bundle rotation.

func NewCABundleInjector

func NewCABundleInjector(m ClientSource, source spire.SVIDSource, webhookConfigName, mutatingWebhookConfigName string, log *slog.Logger) *CABundleInjector

NewCABundleInjector builds the injector from a manager's clients: reads go through the manager's API reader, writes through its client.

func (*CABundleInjector) NeedLeaderElection

func (i *CABundleInjector) NeedLeaderElection() bool

NeedLeaderElection keeps caBundle writes to a single replica.

func (*CABundleInjector) Start

func (i *CABundleInjector) Start(ctx context.Context) error

Start injects the bundle once, then re-injects whenever the SPIRE source reports a rotation, until the context is cancelled. A pass in which a configuration failed is repeated with exponential backoff, so a failure never has to wait for the next rotation to be retried.

It never fails startup: failurePolicy=Ignore means an un-injected webhook fails open, and the retry keeps trying.

type ClientSource

type ClientSource interface {
	// GetClient is the manager's client: reads come from the informer cache.
	GetClient() client.Client
	// GetAPIReader reads from the apiserver directly.
	GetAPIReader() client.Reader
}

ClientSource is the part of a controller-runtime manager the injector takes its clients from. The manager satisfies it.

type Reconciler

type Reconciler struct {
	client.Client
	ConfigMapName     string
	FallbackNamespace string
	Log               *slog.Logger
}

Reconciler projects each namespace's MeshConfig CR into a ConfigMap in that SAME namespace (co-located), which the agent/edge in that namespace mount. MeshConfig is namespaced: a namespace's `default` CR overrides the FallbackNamespace (aether-system) MeshConfig field-by-field, so a namespace inherits the mesh-wide config unless it sets its own. It re-validates with protovalidate before writing, so an invalid CR that slipped past the (best-effort) webhook never overwrites the last-good ConfigMap — the failure surfaces on the CR's status instead.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error)

Reconcile validates a namespace's effective MeshConfig and upserts the co-located ConfigMap. A validation failure is recorded on the CR status and does not return an error (retrying wouldn't help an invalid spec).

func (*Reconciler) SetupWithManager

func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager registers the reconciler. A change to a namespace's MeshConfig re-projects that namespace (For); a change to the FallbackNamespace MeshConfig re-projects every inheriting namespace (the fan-out map func).

type Validator

type Validator struct {
	Log *slog.Logger
}

Validator is an admission webhook that rejects MeshConfig resources whose spec fails protovalidate — the same check the agent's file loader and the reconciler run, so a CR can never describe a config the binaries would refuse to load. It is served by the controller's shared /validate dispatcher (see controller/internal/webhook), keyed by the MeshConfig Kind.

func (*Validator) Handle

Handle validates the incoming MeshConfig's spec.

Jump to

Keyboard shortcuts

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