dryrunvalidator

package
v0.2.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

README

pkg/controller/dryrunvalidator

Webhook-side validator: implements the DryRunValidator interface that pkg/controller/webhook calls into when an admission request arrives.

Overview

The validating admission webhook needs a synchronous answer to "would this proposed change render and validate cleanly?" — not via events, just a direct function call returning allowed bool, reason string. This component bridges that synchronous call into the controller's render-validate pipeline by:

  1. Receiving the proposed object from the webhook adapter (ValidateDirect).
  2. Building a *stores.StoreOverlay per admission verb (NewStoreOverlayForCreate / …Update / …Delete) and wrapping it in a map[string]*stores.StoreOverlay keyed by the resource type.
  3. Delegating render+validate to pkg/controller/proposalvalidator.Component's ValidateSync(ctx, overlays), which merges the overlay on top of the live stores for the duration of the call.
  4. Optionally dispatching the rendered file set to any configured pluggable validators (e.g. the SPOA hub in --validate-socket mode).
  5. Returning a flat allow/deny + simplified reason string (plus soft warnings) for the webhook response.

The component does not subscribe to any events. It does not run the chart's embedded validationTests — those are chart-author scenarios with their own fixtures, run in CI via haptic-controller validate / make test-templates, not per admission request.

Quick Start

import (
    "gitlab.com/haproxy-haptic/haptic/pkg/controller/dryrunvalidator"
)

component := dryrunvalidator.New(&dryrunvalidator.ComponentConfig{
    ProposalValidator:  proposalValidator,  // sync-mode *proposalvalidator.Component
    RESTMapper:         restMapper,
    Logger:             logger,
    PluggableValidator: pluggableValidator, // optional; nil disables sidecar dispatch
})

// pkg/controller/webhook hands this component as DryRunValidator and
// calls ValidateDirect synchronously per admission request. There is
// no Start() — the validator is a library, not a lifecycle component.

Webhook Wiring

// In iteration.go (sketch)
webhookComp := webhook.New(logger, &webhook.Config{
    // ... TLS material from the cert Secret loaded at controller startup,
    //     rules from ExtractWebhookRules ...
    DryRunValidator: dryRunComp, // <- this package's *Component
}, restMapper, metricsRecorder)

The webhook adapter then registers a webhook.ValidationFunc per GVK that pulls (namespace, name, operation) from the AdmissionRequest and calls dryRunComp.ValidateDirect(ctx, gvk, namespace, name, object, operation).

Failure Modes

  • (false, reason, nil) — proposed change failed render or validation; the webhook denies and the API server forwards reason to the user.
  • (true, "", nil) — proposed change is admissible with no warnings.
  • (true, "", warnings) — proposed change is admissible; warnings are soft diagnostics from pluggable validators, surfaced via AdmissionResponse.Warnings.
  • ValidateDirect returns (allowed bool, reason string, warnings []string). Internal errors (e.g. a render panic) are logged and surface as a deny with a descriptive reason — the webhook never returns HTTP 500 from this path. Configure failurePolicy: Fail in the ValidatingWebhookConfiguration if you want the API server to reject on transport failures (TLS handshake, dial errors); deny-with-reason is for application-level rejections.

See Also

  • pkg/controller/webhook — HTTPS adapter that calls ValidateDirect
  • pkg/controller/proposalvalidator — render-validate pipeline driven in sync mode
  • pkg/storesNewStoreOverlayForCreate / NewStoreOverlayForUpdate / NewStoreOverlayForDelete are what createOverlay actually calls per admission verb
  • pkg/controller/dryrunvalidator/CLAUDE.md — design notes (overlay-store pattern, why direct calls are acceptable here)

License

Apache-2.0 — see root LICENSE.

Documentation

Overview

Package dryrunvalidator implements the DryRunValidator that performs dry-run reconciliation for webhook validation.

The validator is called synchronously by pkg/controller/webhook via ValidateDirect. It creates an overlay store simulating the admission request's hypothetical state and delegates to ProposalValidator.ValidateSync for rendering and validation.

Index

Constants

View Source
const ComponentName = "dryrun-validator"

ComponentName identifies this validator in log records.

Variables

This section is empty.

Functions

This section is empty.

Types

type Component

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

Component implements the dry-run validator.

It creates store overlays from admission requests and delegates validation to ProposalValidator. After a successful dry-run, it dispatches the rendered file set to any configured pluggable validators (e.g. the SPOA hub running in --validate-socket mode); their errors deny admission with line/col-precise diagnostics, their warnings flow up to the webhook handler unchanged.

func New

func New(cfg *ComponentConfig) *Component

New creates a new DryRunValidator component.

func (*Component) ValidateDirect

func (c *Component) ValidateDirect(ctx context.Context, gvk, namespace, name string, object any, operation string) (allowed bool, reason string, warnings []string)

ValidateDirect performs synchronous dry-run validation.

Parameters:

  • ctx: Context for cancellation and timeout
  • gvk: GroupVersionKind string (e.g., "networking.k8s.io/v1.Ingress")
  • namespace: Resource namespace
  • name: Resource name
  • object: The Kubernetes resource object
  • operation: Admission operation (CREATE, UPDATE, DELETE)

Returns:

  • allowed: Whether the resource passed validation
  • reason: Denial reason if not allowed, empty otherwise
  • warnings: Soft warnings from pluggable validators, surfaced via AdmissionResponse.Warnings on both allow and deny paths

type ComponentConfig

type ComponentConfig struct {
	// ProposalValidator is the component that performs render-validate pipeline.
	ProposalValidator *proposalvalidator.Component

	// RESTMapper resolves an admission request's GVK to the watched
	// resource's plural (the overlay store key) using the cluster's
	// discovery data. This keeps the validator resource-agnostic: any
	// watched CRD — including one with an irregular or custom plural —
	// resolves correctly, with no hardcoded pluralization table (RULE #1).
	RESTMapper meta.RESTMapper

	// Logger is the structured logger.
	Logger *slog.Logger

	// PluggableValidator is the optional pluggable-validator manager that
	// dispatches the rendered file set to external validator sidecars
	// (e.g. the SPOA hub running in --validate-socket mode). Nil disables
	// the dispatch entirely. When non-nil but Configured() returns false
	// (no validators in the CRD), the manager's ValidateAll is a no-op,
	// so callers don't need to pre-check before wiring this in.
	PluggableValidator *pluggablevalidator.Manager
}

ComponentConfig contains configuration for creating a DryRunValidator.

Jump to

Keyboard shortcuts

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