Documentation
¶
Overview ¶
Package renderer implements the Renderer component that renders HAProxy configuration and auxiliary files from templates.
The Renderer is a Stage 5 component that subscribes to reconciliation trigger events, builds rendering context from resource stores, and publishes rendered output events for the next phase (validation/deployment).
Index ¶
Constants ¶
const (
// ComponentName is the unique identifier for this component.
ComponentName = "renderer"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Component ¶
type Component struct {
// contains filtered or unexported fields
}
Component implements the renderer component.
It subscribes to ReconciliationTriggeredEvent, renders all templates using the template engine and resource stores, and publishes the results via TemplateRenderedEvent or TemplateRenderFailedEvent.
The component renders configurations twice per reconciliation: 1. Production version with absolute paths for HAProxy pods (/etc/haproxy/*) 2. Validation version with temp directory paths for controller validation
This is a leader-only component that starts when leadership is acquired. The Reconciler triggers a fresh reconciliation on BecameLeaderEvent to provide current state.
CRT-list Fallback: The component determines CRT-list storage capability from the local HAProxy version (passed at construction time). When CRT-list storage is not supported (HAProxy < 3.2), CRT-list file paths are resolved to the general files directory instead of the SSL directory, ensuring the generated configuration matches where files are actually stored.
func New ¶
func New( eventBus *busevents.EventBus, cfg *config.Config, storeMap map[string]stores.Store, haproxyPodStore stores.Store, currentConfigStore *currentconfigstore.Store, capabilities dataplane.Capabilities, logger *slog.Logger, ) (*Component, error)
New creates a new Renderer component.
The component pre-compiles all templates during initialization for optimal runtime performance.
Parameters:
- eventBus: The EventBus for subscribing to events and publishing results
- config: Controller configuration containing templates
- stores: Map of resource type names to their stores (e.g., "ingresses" -> Store)
- haproxyPodStore: Store containing HAProxy controller pods for pod-maxconn calculations
- currentConfigStore: Store containing the current deployed HAProxy config (for slot preservation)
- capabilities: HAProxy capabilities determined from local version
- logger: Structured logger for component logging
Returns:
- A new Component instance ready to be started
- Error if template compilation fails
func (*Component) HealthCheck ¶
HealthCheck implements the lifecycle.HealthChecker interface. Returns an error if the component appears to be stalled (processing for > timeout). Returns nil when idle (not processing) - idle is always healthy for event-driven components.
func (*Component) Name ¶
Name returns the unique identifier for this component. Implements the lifecycle.Component interface.
func (*Component) SetHTTPStoreComponent ¶
SetHTTPStoreComponent sets the HTTP store component for dynamic HTTP resource fetching. This must be called before Start() to enable http.Fetch() in templates.
func (*Component) Start ¶
Start begins the renderer's event loop.
This method blocks until the context is cancelled or an error occurs. As a leader-only component, it subscribes to events when started (after leadership is acquired).
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
func (*Component) SubscriptionReady ¶
func (c *Component) SubscriptionReady() <-chan struct{}
SubscriptionReady returns a channel that is closed when the component has completed its event subscription. This implements lifecycle.SubscriptionReadySignaler.
For leader-only components like the Renderer, subscription happens in Start() rather than in the constructor. This method allows the lifecycle registry to wait for subscription before signaling that the component is ready.
type RenderResult ¶
type RenderResult struct {
// HAProxyConfig is the rendered HAProxy configuration.
HAProxyConfig string
// AuxiliaryFiles contains all rendered auxiliary files (maps, certs, general).
AuxiliaryFiles *dataplane.AuxiliaryFiles
// DurationMs is the total render duration in milliseconds.
DurationMs int64
// AuxFileCount is the total number of auxiliary files.
AuxFileCount int
}
RenderResult contains the output of a render operation.
type RenderService ¶
type RenderService struct {
// contains filtered or unexported fields
}
RenderService is a pure service that transforms stores into HAProxy configuration.
This service uses absolute paths from the config's Dataplane settings to ensure rendered configs reference files at the correct locations where DataPlane API stores auxiliary files.
Resources in stores are already converted (floats to ints) at storage time, so the service simply passes through store data without additional processing.
func NewRenderService ¶
func NewRenderService(cfg *RenderServiceConfig) *RenderService
NewRenderService creates a new RenderService.
The service uses relative paths derived from the config's Dataplane settings. The directory names are extracted using filepath.Base() to get just the final directory component (e.g., /etc/haproxy/maps → maps).
These relative paths are resolved by HAProxy using the `default-path origin <baseDir>` directive in the global section, which makes HAProxy resolve paths from the specified base directory regardless of where the config file is located. This works for:
- Local validation: ValidationService replaces baseDir with temp directory
- DataPlane API deployment: baseDir points to where files are stored (e.g., /etc/haproxy)
func (*RenderService) ClearVMPool ¶
func (s *RenderService) ClearVMPool()
ClearVMPool releases pooled template engine VMs. Call after rendering completes to reduce memory from parallel rendering spikes.
func (*RenderService) Render ¶
func (s *RenderService) Render(ctx context.Context, provider stores.StoreProvider) (*RenderResult, error)
Render transforms the stores into HAProxy configuration.
The render mode (production vs validation) is determined automatically:
- If provider is *OverlayStoreProvider with HTTP overlay: validation mode
- Otherwise: production mode
Parameters:
- ctx: Context for cancellation
- provider: StoreProvider for accessing resource stores
Returns:
- RenderResult containing the rendered configuration and auxiliary files
- Error if rendering fails
type RenderServiceConfig ¶
type RenderServiceConfig struct {
// Engine is the template engine to use for rendering.
Engine templating.Engine
// Config is the controller configuration.
Config *config.Config
// Logger is the structured logger for logging.
Logger *slog.Logger
// Capabilities defines HAProxy version capabilities.
Capabilities dataplane.Capabilities
// HAProxyPodStore is the store containing HAProxy pods (optional).
HAProxyPodStore stores.Store
// HTTPStoreComponent is the HTTP store for dynamic content (optional).
HTTPStoreComponent *httpstore.Component
// CurrentConfigStore is the store for current deployed config (optional).
CurrentConfigStore *currentconfigstore.Store
}
RenderServiceConfig contains configuration for creating a RenderService.