renderer

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: 23 Imported by: 0

README

pkg/controller/renderer

Pure render service that turns the controller's templates + Kubernetes state into a complete HAProxy configuration plus auxiliary files. Wraps pkg/templating.Engine with the controller-side concerns (path resolution, template context building, status-patch collection).

Overview

RenderService (service.go) is the synchronous, library-style API. The render-validate pipeline (pkg/controller/pipeline.Pipeline) calls service.Render(ctx, storeProvider) directly, with no event hop. The leader-only Coordinator drives the pipeline; it then publishes TemplateRenderedEvent itself.

The renderer is a library, not an event-driven component. See docs/adr/0001-renderer-is-synchronous-not-event-adapter.md for the rationale.

Quick Start (RenderService)

import "gitlab.com/haproxy-haptic/haptic/pkg/controller/renderer"

svc := renderer.NewRenderService(&renderer.RenderServiceConfig{
    Engine:             templateEngine,        // pre-compiled *templating.Engine
    Config:             cfg,                   // built from the HAProxyTemplateConfig CRD
    Logger:             logger,
    Capabilities:       capabilities,          // from local HAProxy probe
    HAProxyPodStore:    haproxyPodStore,       // optional; needed for {{ controller.haproxy_pods }}
    HTTPStoreComponent: httpStoreComponent,    // optional; needed for {{ http.Fetch(...) }}
    CurrentConfigStore: currentConfigStore,    // optional; needed for slot-aware server assignment
})

result, err := svc.Render(ctx, storeProvider) // *RenderResult, error

RenderResult carries everything downstream consumers need:

  • HAProxyConfig string — the rendered config
  • AuxiliaryFiles *dataplane.AuxiliaryFiles — maps + general files + SSL certificates + crt-list files
  • StatusPatches []templating.StatusPatch — status mutations templates registered during the render
  • DurationMs int64 — wall time
  • AuxFileCount int — convenience aggregate

Path resolution uses relative paths derived from cfg.Dataplane.{MapsDir,SSLCertsDir,GeneralStorageDir}. The rendered config relies on HAProxy's default-path origin <baseDir> directive, so the same render output works in:

  • Local validation, where the validation service swaps baseDir for a temp directory.
  • Production deployment, where baseDir is wherever the Dataplane API actually writes auxiliary files.

Template Context

The rendering context is assembled by service.go's own buildRenderingContext method (not via rendercontext.NewBuilder; see pkg/controller/rendercontext README for the full key list). The resources map exposes one *rendercontext.StoreWrapper per spec.watchedResources entry; templates iterate them with .List() / .Fetch(keys...) / .GetSingle(keys...).

StoreWrapper lazy-caches .List() per render — every resource is unwrapped from *unstructured.Unstructured to a plain map on the first call and reused for the rest of the reconciliation. .Get / .GetSingle unwrap on demand for the matched subset only.

See Also

License

Apache-2.0 — see root LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

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

	// StatusPatches contains status patches registered by templates during rendering.
	// Each patch targets a Kubernetes resource and contains outcome-keyed variants.
	StatusPatches []templating.StatusPatch

	// 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). The applier compares
	// each against the last-applied checksum and skips unchanged entries to avoid
	// hammering the API server.
	RenderedResources []templating.RenderedResource

	// 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 path.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

	// TypedResourceTypes carries the generated Go types produced
	// by pkg/controller/typebootstrap at iteration start. The
	// renderer emits one *[]*<generated-struct> top-level context
	// entry per type at render time, matching the typed-global
	// declarations the engine constructor received.
	//
	// Optional. nil or empty means typed-resource access isn't
	// available and templates fall back to the untyped
	// resources["<name>"] path.
	TypedResourceTypes map[string]reflect.Type
}

RenderServiceConfig contains configuration for creating a RenderService.

Jump to

Keyboard shortcuts

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