validator

package
v0.1.0-alpha.9 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

README

pkg/controller/validator

Configuration validation components using scatter-gather pattern.

Overview

Validates controller configuration using multiple independent validators coordinated via scatter-gather EventBus pattern.

Validators

  • BasicValidator: Structural validation
  • TemplateValidator: Template syntax
  • JSONPathValidator: JSONPath expressions

Quick Start

// Start all validators
basicValidator := validator.NewBasicValidator(bus, logger)
templateValidator := validator.NewTemplateValidator(bus, logger, engine)
jsonpathValidator := validator.NewJSONPathValidator(bus, logger)

go basicValidator.Start(ctx)
go templateValidator.Start(ctx)
go jsonpathValidator.Start(ctx)

Events

Subscribes To
  • ConfigValidationRequest: Scatter-gather validation request
Publishes
  • ConfigValidationResponse: Individual validator response
  • ConfigValidatedEvent: All validators passed (from coordinator)
  • ConfigInvalidEvent: Any validator failed (from coordinator)

License

See main repository for license information.

Documentation

Overview

Package validator implements validation components for HAProxy configuration.

The HAProxyValidatorComponent validates rendered HAProxy configurations using a two-phase approach: syntax validation (client-native parser) and semantic validation (haproxy binary with -c flag).

Index

Constants

View Source
const (
	// HAProxyValidatorComponentName is the unique identifier for this component.
	HAProxyValidatorComponentName = "haproxy-validator"

	// HAProxyValidatorEventBufferSize is the size of the event subscription buffer.
	// Size 50: Medium-volume component (validation events during reconciliation).
	HAProxyValidatorEventBufferSize = 50
)
View Source
const (
	// ValidatorNameBasic is the name for the basic structure validator.
	ValidatorNameBasic = "basic"

	// ValidatorNameTemplate is the name for the template syntax validator.
	ValidatorNameTemplate = "template"

	// ValidatorNameJSONPath is the name for the JSONPath expression validator.
	ValidatorNameJSONPath = "jsonpath"
)

Validator names used in the scatter-gather validation pattern.

These constants ensure consistency between: - Validator responder names (in ConfigValidationResponse) - Expected responders list (in ConfigChangeHandler)

Using constants prevents typos and silent failures where the scatter-gather pattern would timeout waiting for a validator that uses a different name.

View Source
const (
	// EventBufferSize is the size of the event subscription buffer.
	// Size 10: Low-volume component (~1 validation request per reconciliation).
	EventBufferSize = 10
)

Variables

This section is empty.

Functions

func AllValidatorNames

func AllValidatorNames() []string

AllValidatorNames returns a slice of all validator names. Use this when registering validators in the ConfigChangeHandler.

Types

type BaseValidator

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

BaseValidator provides common event loop infrastructure for all validators.

It handles:

  • Event subscription and routing
  • Panic recovery
  • Graceful shutdown
  • Stop idempotency

Validators embed this struct and provide a ValidationHandler implementation for their specific validation logic.

func NewBaseValidator

func NewBaseValidator(
	eventBus *busevents.EventBus,
	logger *slog.Logger,
	name string,
	description string,
	handler ValidationHandler,
) *BaseValidator

NewBaseValidator creates a new base validator with the given configuration.

Parameters:

  • eventBus: The EventBus to subscribe to and publish on
  • logger: Structured logger for diagnostics
  • name: Validator name (for error messages and responses)
  • description: Human-readable component description (for logging)
  • handler: ValidationHandler implementation for validator-specific logic

Returns:

  • *BaseValidator ready to start

func (*BaseValidator) Start

func (v *BaseValidator) Start(ctx context.Context) error

Start begins processing validation requests from the EventBus.

This method blocks until Stop() is called or the context is canceled. The component is already subscribed to the EventBus (subscription happens in constructor). Returns nil on graceful shutdown.

The event loop:

  1. Filters for ConfigValidationRequest events
  2. Wraps handling in panic recovery
  3. Delegates to the ValidationHandler

Example:

go validator.Start(ctx)

func (*BaseValidator) Stop

func (v *BaseValidator) Stop()

Stop gracefully stops the validator. Safe to call multiple times.

type BasicValidator

type BasicValidator struct {
	*BaseValidator
	// contains filtered or unexported fields
}

BasicValidator validates basic structural configuration requirements.

This component subscribes to ConfigValidationRequest events and validates basic structural requirements such as: - Required fields are present - Field types and values are correct - Port numbers are in valid ranges - Non-empty slices where required

This validator uses the existing config.ValidateStructure() function and does NOT validate template syntax or JSONPath expressions (handled by specialized validators).

This component is part of the scatter-gather validation pattern and publishes ConfigValidationResponse events with validation results.

func NewBasicValidator

func NewBasicValidator(eventBus *busevents.EventBus, logger *slog.Logger) *BasicValidator

NewBasicValidator creates a new basic validator component.

Parameters:

  • eventBus: The EventBus to subscribe to and publish on
  • logger: Structured logger for diagnostics

Returns:

  • *BasicValidator ready to start

func (*BasicValidator) HandleRequest

func (v *BasicValidator) HandleRequest(req *events.ConfigValidationRequest)

HandleRequest processes a ConfigValidationRequest by validating basic structure. This implements the ValidationHandler interface.

type HAProxyValidatorComponent

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

HAProxyValidatorComponent validates rendered HAProxy configurations.

It subscribes to TemplateRenderedEvent and BecameLeaderEvent, validates the configuration using dataplane.ValidateConfiguration(), and publishes validation result events for the next phase (deployment).

Validation is performed in two phases:

  1. Syntax validation using client-native parser
  2. Semantic validation using haproxy binary (-c flag)

The component caches the last validation result to support: - State replay during leadership transitions (when new leader-only components start subscribing). - Skipping re-validation of identical failed configs (reduces log spam).

func NewHAProxyValidator

func NewHAProxyValidator(
	eventBus *busevents.EventBus,
	logger *slog.Logger,
) *HAProxyValidatorComponent

NewHAProxyValidator creates a new HAProxy validator component.

The validator extracts validation paths from TemplateRenderedEvent, which are created per-render by the Renderer component for isolated validation.

Parameters:

  • eventBus: The EventBus for subscribing to events and publishing results
  • logger: Structured logger for component logging

Returns:

  • A new HAProxyValidatorComponent instance ready to be started

func (*HAProxyValidatorComponent) Name

Name returns the unique identifier for this component. Implements the lifecycle.Component interface.

func (*HAProxyValidatorComponent) Start

Start begins the validator's event loop.

This method blocks until the context is cancelled or an error occurs. The component is already subscribed to the EventBus (subscription happens in NewHAProxyValidator()), so this method only processes events:

  • TemplateRenderedEvent: Starts HAProxy configuration validation
  • BecameLeaderEvent: Replays last validation state for new leader-only components

The component runs until the context is cancelled, at which point it performs cleanup and returns.

Parameters:

  • ctx: Context for cancellation and lifecycle management

Returns:

  • nil when context is cancelled (graceful shutdown)
  • Error only in exceptional circumstances

type JSONPathValidator

type JSONPathValidator struct {
	*BaseValidator
	// contains filtered or unexported fields
}

JSONPathValidator validates JSONPath expressions in configuration.

This component subscribes to ConfigValidationRequest events and validates all JSONPath expressions in the configuration using the k8s indexer package.

Validated fields: - WatchedResourcesIgnoreFields (all expressions) - WatchedResources[*].IndexBy (all expressions)

This component is part of the scatter-gather validation pattern and publishes ConfigValidationResponse events with validation results.

func NewJSONPathValidator

func NewJSONPathValidator(eventBus *busevents.EventBus, logger *slog.Logger) *JSONPathValidator

NewJSONPathValidator creates a new JSONPath validator component.

Parameters:

  • eventBus: The EventBus to subscribe to and publish on
  • logger: Structured logger for diagnostics

Returns:

  • *JSONPathValidator ready to start

func (*JSONPathValidator) HandleRequest

func (v *JSONPathValidator) HandleRequest(req *events.ConfigValidationRequest)

HandleRequest processes a ConfigValidationRequest by validating all JSONPath expressions. This implements the ValidationHandler interface.

type TemplateValidator

type TemplateValidator struct {
	*BaseValidator
	// contains filtered or unexported fields
}

TemplateValidator validates template syntax in configuration.

This component subscribes to ConfigValidationRequest events and validates all templates together as a complete set. It uses helpers.ExtractTemplatesFromConfig to ensure validation matches production behavior exactly (DRY principle).

Templates are validated together, not in isolation, so snippets that reference each other via render, import, or inherit_context work correctly.

This component is part of the scatter-gather validation pattern and publishes ConfigValidationResponse events with validation results.

func NewTemplateValidator

func NewTemplateValidator(eventBus *busevents.EventBus, logger *slog.Logger) *TemplateValidator

NewTemplateValidator creates a new template validator component.

Parameters:

  • eventBus: The EventBus to subscribe to and publish on
  • logger: Structured logger for diagnostics

Returns:

  • *TemplateValidator ready to start

func (*TemplateValidator) HandleRequest

func (v *TemplateValidator) HandleRequest(req *events.ConfigValidationRequest)

HandleRequest processes a ConfigValidationRequest by validating all templates. This implements the ValidationHandler interface.

Templates are validated together as a complete set, matching production behavior. This ensures snippets that reference each other via render/import work correctly.

type ValidationHandler

type ValidationHandler interface {
	// HandleRequest processes a ConfigValidationRequest and publishes a response.
	// The implementation should validate the config and publish a ConfigValidationResponse
	// event to the bus.
	HandleRequest(req *events.ConfigValidationRequest)
}

ValidationHandler defines the interface for validator-specific validation logic.

Each validator (basic, template, jsonpath) implements this interface to provide their specific validation logic while reusing the common event loop infrastructure.

Jump to

Keyboard shortcuts

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