Documentation
¶
Overview ¶
Package pipeline provides the render-validate pipeline for HAProxy configuration.
Index ¶
- Variables
- func CriticalContentUnavailable(err error) bool
- func InputsMoved(err error) bool
- func RenderHeld(err error) bool
- func WaitsForCriticalContent(err error) bool
- func WithPendingContentWithheld(ctx context.Context) context.Context
- func WithRefusedOutputs(ctx context.Context, refused func(contentChecksum string) bool) context.Context
- type Pipeline
- func (p *Pipeline) Execute(ctx context.Context, provider stores.StoreProvider, ...) (*PipelineResult, error)
- func (p *Pipeline) ExecuteWithResult(ctx context.Context, provider stores.StoreProvider, ...) (*PipelineResult, *validation.ValidationResult, error)
- func (p *Pipeline) HeldRender(mode rendercontext.RenderMode) error
- type PipelineConfig
- type PipelineError
- type PipelinePhase
- type PipelineResult
- func (r *PipelineResult) MaterializeAuxiliaryFiles() (*dataplane.AuxiliaryFiles, error)
- func (r *PipelineResult) MaterializeEvents() ([]templating.RenderedEvent, error)
- func (r *PipelineResult) MaterializeRenderedResources() ([]templating.RenderedResource, error)
- func (r *PipelineResult) MaterializeStatusPatches() ([]templating.StatusPatch, error)
- type RenderedOutputValidator
Constants ¶
This section is empty.
Variables ¶
var ErrOutputRefusedByGate = errors.New("HAProxy refused this exact render before; " +
"its new HTTP content stays pending until the content or the cluster changes")
ErrOutputRefusedByGate stops an acceptance whose render HAProxy already refused.
var ErrRenderHeld = errors.New("rendering is paused until the critical http.Fetch source answers")
ErrRenderHeld marks a reconcile that did not render because it would only repeat the previous render's failure on unavailable critical content.
Functions ¶
func CriticalContentUnavailable ¶
CriticalContentUnavailable reports a failed fetch required by the rendered configuration.
func InputsMoved ¶
InputsMoved reports a render that lost the commit race to another commit.
func RenderHeld ¶
RenderHeld reports a reconcile that skipped its render; its error repeats the failure of the render that started the hold.
func WaitsForCriticalContent ¶
WaitsForCriticalContent reports a deploying render that stopped because a critical source has no accepted content yet; the acceptance attempt it requested is what lets the next render deploy.
func WithPendingContentWithheld ¶
WithPendingContentWithheld leaves new HTTP content to an independent acceptance attempt.
Types ¶
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
Pipeline composes render and validate services into a single workflow.
The pipeline: 1. Renders HAProxy configuration from stores 2. Validates the rendered configuration 3. Returns combined result
This is a pure service with no event dependencies. It can be used by: - ReconciliationCoordinator for normal reconciliation flow - ProposalValidator for validation-only requests.
func New ¶
func New(cfg *PipelineConfig) *Pipeline
New creates a new render-validate pipeline.
Panics if Renderer is nil. This is intentional: it is a required dependency, and failing at construction time is clearer than returning errors at execution time.
func (*Pipeline) Execute ¶
func (p *Pipeline) Execute(ctx context.Context, provider stores.StoreProvider, mode rendercontext.RenderMode, extraOpts ...rendercontext.Option) (*PipelineResult, error)
Execute runs the render-validate pipeline.
The render mode (production vs validation) is determined automatically: - If provider is *OverlayStoreProvider with overlays: validation mode - Otherwise: production mode
Parameters:
- ctx: Context for cancellation
- provider: StoreProvider for accessing resource stores
Returns:
- PipelineResult containing rendered config and validation status
- Error if rendering or validation fails
func (*Pipeline) ExecuteWithResult ¶
func (p *Pipeline) ExecuteWithResult(ctx context.Context, provider stores.StoreProvider, mode rendercontext.RenderMode, extraOpts ...rendercontext.Option) (*PipelineResult, *validation.ValidationResult, error)
ExecuteWithResult runs the pipeline and returns validation result even on failure. This is useful when you need details about why validation failed.
The render mode (production vs validation) is determined automatically: - If provider is *OverlayStoreProvider with overlays: validation mode - Otherwise: production mode
Parameters:
- ctx: Context for cancellation
- provider: StoreProvider for accessing resource stores
Returns:
- PipelineResult with config and timing (nil if render or authority failed)
- ValidationResult with validation details (nil if render or authority failed)
- Error if rendering fails or context authority expires; ordinary validation failures return a non-nil ValidationResult
func (*Pipeline) HeldRender ¶
func (p *Pipeline) HeldRender(mode rendercontext.RenderMode) error
HeldRender returns the error Execute would return in mode without rendering any input set, or nil when Execute would render.
type PipelineConfig ¶
type PipelineConfig struct {
// Renderer is the render service for generating configuration.
Renderer *renderer.RenderService
// Validator is the validation service for checking configuration. Nil
// makes the pipeline render-only: the reconcile instance leaves HAProxy's
// verdict to the asynchronous render gate (ADR-0022), while the proposal
// instance keeps the synchronous check admission answers with.
Validator *validation.ValidationService
// OutputValidator optionally validates rendered auxiliary formats.
OutputValidator RenderedOutputValidator
// CommitValidator gates accepting external content no previous render
// used. The reconcile pipeline has no Validator, but a render that pulls in
// new HTTP-store content is the moment that content becomes the store's
// accepted version — so it takes the full synchronous check before the
// commit, not the gate's later verdict. Renders that accept nothing new
// never reach it, which is every render in a steady state.
CommitValidator *validation.ValidationService
// Logger is the structured logger for logging.
Logger *slog.Logger
}
PipelineConfig contains configuration for creating a Pipeline.
type PipelineError ¶
type PipelineError struct {
// Phase identifies which pipeline phase failed.
Phase PipelinePhase
// ValidationPhase is set when Phase is PhaseValidation.
// It contains the specific validation sub-phase (syntax, schema, semantic).
ValidationPhase string
// Cause is the underlying error.
Cause error
}
PipelineError is a structured error that identifies which pipeline phase failed. Callers can use errors.AsType[*PipelineError] to extract phase information instead of string parsing. The Coordinator does this in handlePipelineFailure to set the reconciliation-failed event's phase field.
func (*PipelineError) Error ¶
func (e *PipelineError) Error() string
Error implements the error interface.
func (*PipelineError) Unwrap ¶
func (e *PipelineError) Unwrap() error
Unwrap returns the underlying error for errors.Is/As compatibility.
type PipelinePhase ¶
type PipelinePhase string
PipelinePhase identifies which phase of the pipeline failed.
const ( // PhaseRender indicates the render phase. PhaseRender PipelinePhase = "render" // PhaseValidation indicates the validation phase. PhaseValidation PipelinePhase = "validation" )
type PipelineResult ¶
type PipelineResult struct {
// HTTPObservations can confirm only the accepted versions read by this execution.
HTTPObservations []httpstore.ObservationToken
// CycleSnapshot binds the output and every effect from this render.
CycleSnapshot *rendercycle.Snapshot
// OutputSnapshot binds the exact config, plan, and auxiliary artifacts.
OutputSnapshot *renderoutput.Snapshot
// HAProxyConfig is the rendered HAProxy configuration.
HAProxyConfig string
// AuxiliaryFiles contains all rendered auxiliary files.
// Production results leave it nil and use AuxiliaryFileSnapshot.
AuxiliaryFiles *dataplane.AuxiliaryFiles
// AuxiliaryFileSnapshot is the authenticated immutable production representation.
AuxiliaryFileSnapshot *renderartifact.Snapshot
// Plan is the structure this render declared: its sections, backends, map
// entries and file set. Nil when the renderer produced none.
Plan *renderplan.Plan
// PlanID is the digest identifying Plan.
PlanID string
// StatusPatches is the detached compatibility representation.
// Production renders leave it nil and use StatusPatchSnapshot.
StatusPatches []templating.StatusPatch
// StatusPatchSnapshot is the authenticated immutable production representation.
StatusPatchSnapshot *templating.StatusPatchSnapshot
// Events contains Kubernetes Events templates asked to emit via recordEvent()
// (e.g. a RouteConflict Warning on an Ingress). Forwarded to the EventEmitter.
// Production renders leave it nil and use EventSnapshot.
Events []templating.RenderedEvent
// EventSnapshot is the authenticated immutable production representation.
EventSnapshot *templating.RenderedEventSnapshot
// RenderedResources contains full Kubernetes resources the templates declared
// the controller should own and reconcile (e.g. an auxiliary Service or other
// object a template emits alongside the HAProxy config).
// Production renders leave it nil and use RenderedResourceSnapshot.
RenderedResources []templating.RenderedResource
// RenderedResourceSnapshot is the authenticated immutable production representation.
RenderedResourceSnapshot *templating.RenderedResourceSnapshot
// AuxFileCount is the total number of auxiliary files.
AuxFileCount int
// ContentChecksum is the pre-computed content checksum covering config + aux files.
// Computed once in the pipeline and propagated through events to downstream consumers,
// eliminating redundant hashing across validation, publishing, and deployment.
ContentChecksum string
// RenderDurationMs is the rendering duration in milliseconds.
RenderDurationMs int64
// CacheState is "warm" when the render had a graph to build on, "cold" when it
// re-evaluated everything, and "replay" when it reused the previous output.
CacheState string
// CacheBuildMs is what the most recent completed cache build cost, 0 while none
// has completed.
CacheBuildMs int64
// ValidateDurationMs is the validation duration in milliseconds.
ValidateDurationMs int64
// TotalDurationMs is the total pipeline duration in milliseconds.
TotalDurationMs int64
// ValidationPhase indicates which validation phase completed last.
// Empty string means all phases passed.
ValidationPhase string
// ValidationWarnings contains non-fatal diagnostics produced after render.
ValidationWarnings []string
}
PipelineResult contains the output of a render-validate pipeline execution.
func (*PipelineResult) MaterializeAuxiliaryFiles ¶
func (r *PipelineResult) MaterializeAuxiliaryFiles() (*dataplane.AuxiliaryFiles, error)
MaterializeAuxiliaryFiles returns a caller-isolated compatibility view.
func (*PipelineResult) MaterializeEvents ¶
func (r *PipelineResult) MaterializeEvents() ([]templating.RenderedEvent, error)
MaterializeEvents returns a caller-isolated compatibility view.
func (*PipelineResult) MaterializeRenderedResources ¶
func (r *PipelineResult) MaterializeRenderedResources() ([]templating.RenderedResource, error)
MaterializeRenderedResources returns a caller-isolated compatibility view.
func (*PipelineResult) MaterializeStatusPatches ¶
func (r *PipelineResult) MaterializeStatusPatches() ([]templating.StatusPatch, error)
MaterializeStatusPatches returns a caller-isolated compatibility view.
type RenderedOutputValidator ¶
type RenderedOutputValidator interface {
ValidateRenderedOutput(ctx context.Context, result *PipelineResult) (warnings []string, err error)
}
RenderedOutputValidator validates the complete rendered file set.