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

webhook

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package webhook implements the mutating admission webhook that injects the berth-acquire helper into opt-in workload pods (SKA-439). It is the label/annotation opt-in surface chosen in lieu of a CRD (ADR-0002) and the producer side of the contract the berth-acquire helper consumes.

Index

Constants

View Source
const (
	LabelInject        = "berth.skaphos.io/inject"
	InjectValueAcquire = "acquire"
)

Opt-in label. Standard workload controllers copy spec.template.metadata.labels onto created Pods, so this lives on the pod template (spec.jobTemplate.spec.template.metadata for CronJobs).

View Source
const (
	AnnLeaseName           = "berth.skaphos.io/lease-name"
	AnnLeaseNamespace      = "berth.skaphos.io/lease-namespace"
	AnnMode                = "berth.skaphos.io/mode"
	AnnHolderIdentity      = "berth.skaphos.io/holder-identity"
	AnnTTLSeconds          = "berth.skaphos.io/ttl-seconds"
	AnnHeartbeatSeconds    = "berth.skaphos.io/heartbeat-interval-seconds"
	AnnReleaseOnShutdown   = "berth.skaphos.io/release-on-shutdown"
	AnnEnforce             = "berth.skaphos.io/enforce"
	AnnEnforceGraceSeconds = "berth.skaphos.io/enforce-grace-seconds"
	// AnnSignalTarget scopes enforce=signal to the workload process, matched by
	// comm or executable basename (e.g. "nginx"). Without it the sidecar signals
	// every process in the shared PID namespace except berth's own, which can
	// terminate co-located sidecars on lease loss.
	AnnSignalTarget = "berth.skaphos.io/signal-target"

	// AnnInjected is set on a Pod once it has been mutated. It is an
	// observable marker for humans and tooling — "this pod went through the
	// injector" — and nothing more.
	//
	// It MUST NOT be used to decide whether to inject. It is submitter-
	// controlled: a workload can set it on create, and treating that as proof
	// of prior injection admitted ungated pods that still carried the opt-in
	// label (#143). Which admission path a request arrived on is read from
	// the AdmissionRequest's subresource instead, which cannot be forged by
	// the object under review.
	AnnInjected = "berth.skaphos.io/injected"
)

Annotation keys (behavior & configuration). All optional except AnnLeaseName. See the design doc "Proposed Label / Annotation Contract".

View Source
const (
	VolumeName           = "berth-state"
	InitContainerName    = "berth-acquire"
	SidecarContainerName = "berth-sidecar"

	// AuthTokenVolume / AuthCABundleVolume mount the bearer token and CA
	// bundle into the injected helper containers when those sources are
	// configured (SKA-444).
	AuthTokenVolume    = "berth-auth-token"
	AuthCABundleVolume = "berth-auth-ca"
)

Names of the resources the webhook injects.

Variables

This section is empty.

Functions

func SetupWithManager

func SetupWithManager(mgr ctrl.Manager, cfg InjectorConfig) error

SetupWithManager registers the pod-injection mutating webhook with the manager's webhook server. It serves at the controller-runtime default paths for core/v1 Pods (/mutate--v1-pod and /validate--v1-pod); the webhook configurations (SKA-440) points the API server there and scopes it with object and namespace selectors.

Types

type InjectorConfig

type InjectorConfig struct {
	// HelperImage is the berth-acquire image injected as the init
	// container and (for runtime-singleton) the sidecar. Required.
	HelperImage     string
	ImagePullPolicy corev1.PullPolicy

	// API client config handed to the injected helper via env.
	APIServer          string
	APIKeyFile         string
	CABundleFile       string
	ServerName         string
	ClusterID          string
	InsecureSkipVerify bool

	// Sources that back APIKeyFile / CABundleFile inside the workload pod.
	// The webhook mounts these into the injected helper containers so those
	// file paths actually resolve (SKA-444); without them the helper would
	// reference paths that do not exist. The referenced Secret/ConfigMap must
	// exist in each opted-in workload's own namespace.
	APIKeySecretName      string
	APIKeySecretKey       string
	CABundleConfigMapName string
	CABundleKey           string

	// ControlPlaneNamespaces are never mutated (the Berth control plane
	// must not inject itself).
	ControlPlaneNamespaces []string

	// Behavior defaults applied when a pod omits the annotation.
	DefaultTTLSeconds int
	DefaultMode       acquire.Mode
	DefaultEnforce    acquire.Enforce

	// StateDir is the shared emptyDir mount path.
	StateDir string
}

InjectorConfig holds the chart/operator-level defaults the webhook applies to opted-in pods. Per-pod annotations override these where the contract allows it. Values are populated from operator flags (set by Helm in SKA-440).

func (*InjectorConfig) Validate

func (c *InjectorConfig) Validate() error

Validate checks the operator-supplied defaults so a misconfigured webhook fails fast at startup rather than admitting traffic and then rejecting every opted-in pod that relies on a default. Call it after withDefaults.

type PodInjector

type PodInjector struct {
	// contains filtered or unexported fields
}

PodInjector is the CustomDefaulter that mutates opted-in pods.

func NewPodInjector

func NewPodInjector(cfg InjectorConfig) *PodInjector

NewPodInjector returns a PodInjector with config defaults applied.

func (*PodInjector) Default

func (i *PodInjector) Default(ctx context.Context, pod *corev1.Pod) error

Default implements the typed admission.Defaulter for Pods. controller-runtime diffs the pod before and after this call and emits the JSON patch.

func (*PodInjector) ValidateCreate added in v0.4.1

func (i *PodInjector) ValidateCreate(ctx context.Context, pod *corev1.Pod) (admission.Warnings, error)

ValidateCreate checks the final Pod after all mutating webhooks have run. Another injector may append init containers after our preflight check, so runtime mode must contain only the two Berth helpers in their startup order.

func (*PodInjector) ValidateDelete added in v0.4.1

func (i *PodInjector) ValidateDelete(_ context.Context, _ *corev1.Pod) (admission.Warnings, error)

func (*PodInjector) ValidateUpdate added in v0.4.1

func (i *PodInjector) ValidateUpdate(_ context.Context, _, _ *corev1.Pod) (admission.Warnings, error)

ValidateUpdate permits updates to existing Pods. The chart registers this validator for Pod creation only; existing Pods must be drained and recreated to adopt the new injection policy. Deletion must remain possible for cleanup.

type RejectReason added in v0.4.0

type RejectReason string

RejectReason identifies why admission refused a pod. It is both the classification carried in the error and the metric label, so the synchronous explanation to the submitter and the fleet-wide count stay described in the same vocabulary.

const (
	// ReasonWritableStateMount: a workload-authored container mounts the
	// state volume writably. The state volume is reserved — a writable
	// mount lets the workload forge the health marker and replace the
	// probe's check binary, defeating at-most-once enforcement.
	ReasonWritableStateMount RejectReason = "writable_state_mount"

	// ReasonWritableStateMountEphemeral: the same, arriving through the
	// pods/ephemeralcontainers subresource rather than pod creation. Kept
	// distinct because the operator experience differs — the running pod
	// is healthy and a debug request was refused.
	ReasonWritableStateMountEphemeral RejectReason = "writable_state_mount_ephemeral"
)

Jump to

Keyboard shortcuts

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