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
- func SetupWithManager(mgr ctrl.Manager, cfg InjectorConfig) error
- type InjectorConfig
- type PodInjector
- func (i *PodInjector) Default(ctx context.Context, pod *corev1.Pod) error
- func (i *PodInjector) ValidateCreate(ctx context.Context, pod *corev1.Pod) (admission.Warnings, error)
- func (i *PodInjector) ValidateDelete(_ context.Context, _ *corev1.Pod) (admission.Warnings, error)
- func (i *PodInjector) ValidateUpdate(_ context.Context, _, _ *corev1.Pod) (admission.Warnings, error)
- type RejectReason
Constants ¶
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).
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".
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 ¶
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 (*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" )