v1alpha1

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package v1alpha1 contains API Schema definitions for the haproxytemplate v1alpha1 API group.

Overview

This package defines the HAProxyTemplateConfig custom resource, which provides configuration for the HAProxy Template Ingress Controller as a Kubernetes-native CRD.

Key Features

  • Type-safe configuration with OpenAPI validation
  • Embedded validation tests for templates
  • Support for admission webhook validation
  • Credential reference management via Secrets

API Group

Group: haproxy-haptic.org Version: v1alpha1

Resources

HAProxyTemplateConfig: Controller configuration with embedded validation tests

Examples

See docs/site/docs/development/crd-validation-design.md for comprehensive examples and usage patterns.

+k8s:deepcopy-gen=package +groupName=haproxy-haptic.org groupGoName is required, not cosmetic: client-gen derives Go identifiers from the group name, and "haproxy-haptic" yields FakeHaproxy-hapticV1alpha1, which does not compile. +groupGoName=HaproxyTemplateIC

Index

Constants

View Source
const (
	// GroupName is the group name for this API.
	GroupName = "haproxy-haptic.org"

	// Version is the version for this API.
	Version = "v1alpha1"
)
View Source
const (
	ConditionTypeValidated = "Validated"

	ReasonValidationSucceeded     = "ValidationSucceeded"
	ReasonConfigInvalid           = "ConfigInvalid"
	ReasonValidationInconclusive  = "ValidationInconclusive"
	ReasonHAProxyValidationFailed = "HAProxyValidationFailed"
	ReasonLoadGateFailed          = "LoadGateFailed"
)

ConditionTypeValidated reports whether the controller accepted the observed generation; the reasons below are the ones it writes with it.

Variables

View Source
var (
	// SchemeGroupVersion is the group version used to register these objects.
	SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)

Functions

func Resource

func Resource(resource string) schema.GroupResource

Resource takes an unqualified resource and returns a Group qualified GroupResource.

Types

type AuxiliaryFileReferences

type AuxiliaryFileReferences struct {
	// SetID identifies the auxiliary publication committed with these references.
	// +optional
	SetID string `json:"setID,omitempty"`

	// MapFiles lists the HAProxyMapFile resources associated with this config.
	// +optional
	MapFiles []ResourceReference `json:"mapFiles,omitempty"`

	// SSLCertificates lists the Secret resources containing SSL certificates.
	// +optional
	SSLCertificates []ResourceReference `json:"sslCertificates,omitempty"`

	// SSLCaFiles lists the Secret resources containing SSL CA files.
	// +optional
	SSLCaFiles []ResourceReference `json:"sslCaFiles,omitempty"`

	// GeneralFiles lists the HAProxyGeneralFile resources associated with this config.
	// +optional
	GeneralFiles []ResourceReference `json:"generalFiles,omitempty"`

	// CRTListFiles lists the HAProxyCRTListFile resources associated with this config.
	// +optional
	CRTListFiles []ResourceReference `json:"crtListFiles,omitempty"`
}

AuxiliaryFileReferences references the associated maps, certificates, CA files, general files, and crt-lists.

func (*AuxiliaryFileReferences) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuxiliaryFileReferences.

func (*AuxiliaryFileReferences) DeepCopyInto

func (in *AuxiliaryFileReferences) DeepCopyInto(out *AuxiliaryFileReferences)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ConfigPublishingConfig

type ConfigPublishingConfig struct {
	// CompressionThreshold is the payload size in bytes above which configs are compressed.
	// It includes the encoded recovery plan when one is present.
	//
	// Compression uses zstd+base64 encoding.
	//
	// Default: 1048576 (1 MiB)
	// A value of 0 is treated as unset and the default applies.
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:default=1048576
	// +optional
	CompressionThreshold int64 `json:"compressionThreshold,omitempty"`
}

ConfigPublishingConfig configures how rendered configs are stored in CRDs.

func (*ConfigPublishingConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigPublishingConfig.

func (*ConfigPublishingConfig) DeepCopyInto

func (in *ConfigPublishingConfig) DeepCopyInto(out *ConfigPublishingConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ControllerConfig

type ControllerConfig struct {
	// LeaderElection configures leader election for high availability.
	// +optional
	LeaderElection LeaderElectionConfig `json:"leaderElection,omitempty"`

	// ConfigPublishing configures how rendered configs are stored in CRDs.
	// +optional
	ConfigPublishing ConfigPublishingConfig `json:"configPublishing,omitempty"`

	// RenderGateInterval is the shortest start-to-start spacing of the render
	// gate's `haproxy -c` runs.
	//
	// The gate validates each render off the reconcile wall clock, on its own
	// semaphore slot. This caps its duty cycle so a render storm cannot keep a
	// core busy back-to-back and slow the admission webhook.
	// Format: Go duration string (e.g., "1s", "500ms")
	// Default: 1s
	// +optional
	RenderGateInterval string `json:"renderGateInterval,omitempty"`
}

ControllerConfig contains controller-level configuration.

func (*ControllerConfig) DeepCopy

func (in *ControllerConfig) DeepCopy() *ControllerConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerConfig.

func (*ControllerConfig) DeepCopyInto

func (in *ControllerConfig) DeepCopyInto(out *ControllerConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type DataplaneConfig

type DataplaneConfig struct {
	// Port is the agent's apply/state API port on each HAProxy pod.
	//
	// Default: 5555
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=65535
	// +optional
	Port int `json:"port,omitempty"`

	// MinDeploymentInterval is the shortest interval between two HAProxy
	// reloads of one pod. The chart passes it to the HAPTIC agent as
	// --reload-interval-min: a reload inside the window is scheduled, never
	// dropped, and the controller holds further renders until it fires. Runtime
	// applies are never paced by it. At most 60s.
	//
	// Format: Go duration string (e.g., "5s", "500ms")
	// Default: 5s
	// +optional
	MinDeploymentInterval string `json:"minDeploymentInterval,omitempty"`

	// DriftPreventionInterval triggers periodic deployments to prevent configuration drift.
	//
	// A deployment is automatically triggered if no deployment has occurred within this interval.
	// This detects and corrects a pod whose file tree drifted from the render.
	// Format: Go duration string (e.g., "60s", "5m")
	// Default: 60s
	// +optional
	DriftPreventionInterval string `json:"driftPreventionInterval,omitempty"`

	// MapsDir is the directory for HAProxy map files.
	//
	// Used for both validation and deployment.
	// Default: /etc/haproxy/maps
	// +optional
	MapsDir string `json:"mapsDir,omitempty"`

	// SSLCertsDir is the directory for SSL certificates.
	//
	// Used for both validation and deployment.
	// Default: /etc/haproxy/certs (the Helm chart sets /etc/haproxy/ssl)
	// +optional
	SSLCertsDir string `json:"sslCertsDir,omitempty"`

	// GeneralStorageDir is the directory for general files (error pages, etc.).
	//
	// Used for both validation and deployment.
	// Default: /etc/haproxy/general
	// +optional
	GeneralStorageDir string `json:"generalStorageDir,omitempty"`

	// ConfigFile is the path to the main HAProxy configuration file.
	//
	// Used for validation.
	// Default: /etc/haproxy/haproxy.cfg
	// +optional
	ConfigFile string `json:"configFile,omitempty"`

	// DeploymentTimeout is the maximum time to wait for a deployment to complete.
	// If exceeded, the scheduler assumes the deployment was lost and retries.
	// This is a safety net for race conditions during leadership transitions.
	// Format: Go duration string (e.g., "30s", "1m")
	// Default: 30s
	// +optional
	DeploymentTimeout string `json:"deploymentTimeout,omitempty"`

	// ConfigPublishInterval throttles how often the rendered HAProxy config is
	// republished as the HAProxyCfg observability CRD. The CRD itself is not on
	// the deployment hot path, but during endpoint churn rewriting the (~500 KB)
	// CRD on every reconciliation creates significant etcd write pressure;
	// throttling republishes reduces that write load while leaving the
	// event-driven push to HAProxy pods untouched.
	//
	// Format: Go duration string (e.g., "10s", "1m").
	// Default: 10s
	// +optional
	ConfigPublishInterval string `json:"configPublishInterval,omitempty"`

	// ReloadVerificationTimeout is how long the HAPTIC agent waits for the
	// HAProxy master to report a reload as finished before it fails the apply
	// and restores the last known good file set. The chart passes it to the
	// agent as --reload-timeout; at most 60s.
	//
	// Format: Go duration string (e.g., "10s", "30s").
	// Default: 60s (the agent's ceiling)
	// +optional
	ReloadVerificationTimeout string `json:"reloadVerificationTimeout,omitempty"`

	// SyncTimeout is the overall timeout for a single Dataplane sync to one
	// HAProxy endpoint. The sync covers parse + diff + raw config push +
	// optional reload-verification. If exceeded, the sync is cancelled and the
	// scheduler retries on the next reconciliation.
	//
	// Format: Go duration string (e.g., "2m", "30s").
	// Default: 2m
	// +optional
	SyncTimeout string `json:"syncTimeout,omitempty"`
}

DataplaneConfig configures how the controller reaches the HAProxy pods and where their files live. The block keeps its name across the agent cutover.

func (*DataplaneConfig) DeepCopy

func (in *DataplaneConfig) DeepCopy() *DataplaneConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataplaneConfig.

func (*DataplaneConfig) DeepCopyInto

func (in *DataplaneConfig) DeepCopyInto(out *DataplaneConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GeneralFile

type GeneralFile struct {
	// Template is the template for generating the file content.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// PostProcessing defines optional post-processors to apply after rendering.
	//
	// Post-processors run in the order specified and can transform the rendered output.
	// +optional
	PostProcessing []PostProcessorConfig `json:"postProcessing,omitempty"`

	// ReloadOnPush controls whether a content change to this file reloads HAProxy.
	//
	// Keep it true for anything HAProxy itself reads — error pages, ca-files,
	// host-match lists — since only a reload makes the new content take effect.
	// Set it to false for a file a sidecar owns and watches on its own (the
	// spoa-hub TOML, the Vector config): HAProxy never opens those, so the
	// reload buys nothing and only costs a worker respawn.
	//
	// This governs writes. Removing a file reloads only when the rendered
	// configuration (or a crt-list) still names it, which no sidecar-owned file
	// ever does.
	// +optional
	// +kubebuilder:default=true
	ReloadOnPush *bool `json:"reloadOnPush,omitempty"`
}

GeneralFile defines a general file generated from a template.

The filename is derived from the map key in the configuration. The full path is constructed using the pathResolver.GetPath() method in templates:

Example: pathResolver.GetPath("503.http", "file") returns /etc/haproxy/general/503.http

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (GeneralFile)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function - files section)

func (*GeneralFile) DeepCopy

func (in *GeneralFile) DeepCopy() *GeneralFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneralFile.

func (*GeneralFile) DeepCopyInto

func (in *GeneralFile) DeepCopyInto(out *GeneralFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyCRTListFile

type HAProxyCRTListFile struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyCRTListFileSpec   `json:"spec,omitempty"`
	Status HAProxyCRTListFileStatus `json:"status,omitempty"`
}

HAProxyCRTListFile contains a rendered HAProxy crt-list file.

CRT-list files contain SSL certificate references with per-certificate options and SNI filters. This is a read-only resource automatically created and updated by the controller. Each HAProxyCRTListFile is owned by a HAProxyCfg resource.

func (*HAProxyCRTListFile) DeepCopy

func (in *HAProxyCRTListFile) DeepCopy() *HAProxyCRTListFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCRTListFile.

func (*HAProxyCRTListFile) DeepCopyInto

func (in *HAProxyCRTListFile) DeepCopyInto(out *HAProxyCRTListFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyCRTListFile) DeepCopyObject

func (in *HAProxyCRTListFile) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyCRTListFileList

type HAProxyCRTListFileList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyCRTListFile `json:"items"`
}

HAProxyCRTListFileList contains a list of HAProxyCRTListFile.

func (*HAProxyCRTListFileList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCRTListFileList.

func (*HAProxyCRTListFileList) DeepCopyInto

func (in *HAProxyCRTListFileList) DeepCopyInto(out *HAProxyCRTListFileList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyCRTListFileList) DeepCopyObject

func (in *HAProxyCRTListFileList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyCRTListFileSpec

type HAProxyCRTListFileSpec struct {
	// ListName is the logical name of the crt-list file.
	//
	// Example: "frontend-certs" or "backend-client-certs"
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	ListName string `json:"listName"`

	// Path is the file system path where this crt-list file is stored.
	//
	// Example: /etc/haproxy/crt-lists/frontend.crtlist
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Entries is the crt-list file content.
	//
	// Each line contains a certificate path with optional SSL options and SNI filters.
	// Format: <cert-path> [ssl-options] [sni-filter]
	// Example:
	//   /etc/haproxy/ssl/example.com.pem [ocsp-update on] example.com
	//   /etc/haproxy/ssl/wildcard.pem *.example.org
	// +optional
	// +kubebuilder:validation:MinLength=1
	Entries string `json:"entries,omitempty"`

	// Empty explicitly represents a zero-byte file without omitting its content declaration.
	// +optional
	Empty bool `json:"empty,omitempty"`

	// Checksum is the SHA-256 hash of the crt-list entries.
	//
	// Used to detect changes and verify consistency across pods.
	// Format: sha256:<hex-digest>
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Checksum string `json:"checksum"`

	// Compressed indicates the entries are zstd+base64 encoded.
	//
	// When true, consumers must decompress before use.
	// +optional
	Compressed bool `json:"compressed,omitempty"`
}

HAProxyCRTListFileSpec contains the crt-list file content. +kubebuilder:validation:XValidation:rule="has(self.entries) != (has(self.empty) && self.empty)",message="set nonempty entries or empty: true" +kubebuilder:validation:XValidation:rule="!has(self.empty) || !self.empty || ((!has(self.compressed) || !self.compressed) && self.checksum == 'sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')",message="empty files must be uncompressed and use the checksum of zero bytes"

func (*HAProxyCRTListFileSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCRTListFileSpec.

func (*HAProxyCRTListFileSpec) DeepCopyInto

func (in *HAProxyCRTListFileSpec) DeepCopyInto(out *HAProxyCRTListFileSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyCRTListFileStatus

type HAProxyCRTListFileStatus struct {
	// DeployedToPods tracks which HAProxy pods currently have this crt-list file.
	//
	// Pods are automatically added when the crt-list file is applied and removed when
	// the pod terminates.
	// +optional
	// +listType=map
	// +listMapKey=podName
	DeployedToPods []PodDeploymentStatus `json:"deployedToPods,omitempty"`

	// ObservedGeneration reflects the generation of the spec that was most recently processed.
	//
	// This is used to track whether status is up-to-date with latest spec changes.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions represent the latest available observations of the resource's state.
	//
	// Standard conditions include:
	// - "Synced": CRT-list file has been successfully applied to all target pods
	// - "Ready": Resource is ready for use
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

HAProxyCRTListFileStatus tracks deployment state to HAProxy pods.

func (*HAProxyCRTListFileStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCRTListFileStatus.

func (*HAProxyCRTListFileStatus) DeepCopyInto

func (in *HAProxyCRTListFileStatus) DeepCopyInto(out *HAProxyCRTListFileStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyCfg

type HAProxyCfg struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyCfgSpec   `json:"spec,omitempty"`
	Status HAProxyCfgStatus `json:"status,omitempty"`
}

HAProxyCfg contains the rendered HAProxy configuration for a specific HAProxyTemplateConfig.

This is a read-only resource automatically created and updated by the controller to expose the actual runtime configuration applied to HAProxy pods.

func (*HAProxyCfg) DeepCopy

func (in *HAProxyCfg) DeepCopy() *HAProxyCfg

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCfg.

func (*HAProxyCfg) DeepCopyInto

func (in *HAProxyCfg) DeepCopyInto(out *HAProxyCfg)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyCfg) DeepCopyObject

func (in *HAProxyCfg) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyCfgList

type HAProxyCfgList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyCfg `json:"items"`
}

HAProxyCfgList contains a list of HAProxyCfg.

func (*HAProxyCfgList) DeepCopy

func (in *HAProxyCfgList) DeepCopy() *HAProxyCfgList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCfgList.

func (*HAProxyCfgList) DeepCopyInto

func (in *HAProxyCfgList) DeepCopyInto(out *HAProxyCfgList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyCfgList) DeepCopyObject

func (in *HAProxyCfgList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyCfgSpec

type HAProxyCfgSpec struct {
	// Path is the file system path where this configuration is stored.
	//
	// Default: /etc/haproxy/haproxy.cfg
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Content is the rendered HAProxy configuration file content.
	//
	// This is the actual haproxy.cfg content that was validated and deployed
	// to HAProxy pods.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Content string `json:"content"`

	// Checksum is the SHA-256 hash of the original (uncompressed) configuration content.
	//
	// Used to detect configuration changes and verify consistency across pods.
	// Format: sha256:<hex-digest>
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Checksum string `json:"checksum"`

	// Compressed indicates the content is zstd+base64 encoded.
	//
	// When true, consumers must decompress before use.
	// +optional
	Compressed bool `json:"compressed,omitempty"`

	// RetainedPlan contains zstd+base64 encoded deployment declarations for a retained snapshot.
	// +optional
	RetainedPlan string `json:"retainedPlan,omitempty"`
}

HAProxyCfgSpec contains the rendered configuration content.

func (*HAProxyCfgSpec) DeepCopy

func (in *HAProxyCfgSpec) DeepCopy() *HAProxyCfgSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCfgSpec.

func (*HAProxyCfgSpec) DeepCopyInto

func (in *HAProxyCfgSpec) DeepCopyInto(out *HAProxyCfgSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyCfgStatus

type HAProxyCfgStatus struct {
	// RetainedConfigs references complete, acknowledged snapshots, newest first.
	// +optional
	RetainedConfigs []RetainedConfigReference `json:"retainedConfigs,omitempty"`

	// DeployedToPods tracks which HAProxy pods currently have this configuration.
	//
	// Pods are automatically added when configuration is applied and removed when
	// the pod terminates.
	//
	// The list is keyed by podName so each pod's status update can land via
	// Server-Side Apply with its own field manager — concurrent updates from
	// different pods merge naturally instead of last-write-wins on the
	// full-object UpdateStatus path that preceded this CRD shape.
	// +optional
	// +listType=map
	// +listMapKey=podName
	DeployedToPods []PodDeploymentStatus `json:"deployedToPods,omitempty"`

	// AuxiliaryFiles references the associated map files and certificates.
	// +optional
	AuxiliaryFiles *AuxiliaryFileReferences `json:"auxiliaryFiles,omitempty"`

	// ValidationError contains the error message if this configuration failed validation.
	//
	// Only populated for HAProxyCfg resources published with the -invalid suffix.
	// When present, this configuration was not deployed to HAProxy instances.
	// +optional
	ValidationError string `json:"validationError,omitempty"`

	// ObservedGeneration reflects the generation of the spec that was most recently processed.
	//
	// This is used to track whether status is up-to-date with latest spec changes.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions represent the latest available observations of the resource's state.
	//
	// Standard conditions include:
	// - "Synced": Configuration has been successfully applied to all target pods
	// - "Ready": Resource is ready for use
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

HAProxyCfgStatus tracks deployment state and auxiliary files.

func (*HAProxyCfgStatus) DeepCopy

func (in *HAProxyCfgStatus) DeepCopy() *HAProxyCfgStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyCfgStatus.

func (*HAProxyCfgStatus) DeepCopyInto

func (in *HAProxyCfgStatus) DeepCopyInto(out *HAProxyCfgStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyConfig

type HAProxyConfig struct {
	// Template is the template for generating haproxy.cfg.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// PostProcessing defines optional post-processors to apply after rendering.
	//
	// Post-processors run in the order specified and can transform the rendered output.
	// Common use case: Normalize indentation with regex_replace.
	// +optional
	PostProcessing []PostProcessorConfig `json:"postProcessing,omitempty"`
}

HAProxyConfig defines the main HAProxy configuration.

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (HAProxyConfig)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function - haproxyConfig section)

func (*HAProxyConfig) DeepCopy

func (in *HAProxyConfig) DeepCopy() *HAProxyConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyConfig.

func (*HAProxyConfig) DeepCopyInto

func (in *HAProxyConfig) DeepCopyInto(out *HAProxyConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyGeneralFile

type HAProxyGeneralFile struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyGeneralFileSpec   `json:"spec,omitempty"`
	Status HAProxyGeneralFileStatus `json:"status,omitempty"`
}

HAProxyGeneralFile contains a rendered HAProxy general file (error pages, custom responses, etc.).

This is a read-only resource automatically created and updated by the controller to expose general files generated from templates. Each HAProxyGeneralFile is owned by a HAProxyCfg resource.

func (*HAProxyGeneralFile) DeepCopy

func (in *HAProxyGeneralFile) DeepCopy() *HAProxyGeneralFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyGeneralFile.

func (*HAProxyGeneralFile) DeepCopyInto

func (in *HAProxyGeneralFile) DeepCopyInto(out *HAProxyGeneralFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyGeneralFile) DeepCopyObject

func (in *HAProxyGeneralFile) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyGeneralFileList

type HAProxyGeneralFileList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyGeneralFile `json:"items"`
}

HAProxyGeneralFileList contains a list of HAProxyGeneralFile.

func (*HAProxyGeneralFileList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyGeneralFileList.

func (*HAProxyGeneralFileList) DeepCopyInto

func (in *HAProxyGeneralFileList) DeepCopyInto(out *HAProxyGeneralFileList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyGeneralFileList) DeepCopyObject

func (in *HAProxyGeneralFileList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyGeneralFileSpec

type HAProxyGeneralFileSpec struct {
	// FileName is the logical name of the file.
	//
	// This corresponds to the key in HAProxyTemplateConfig.spec.files.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	FileName string `json:"fileName"`

	// Path is the file system path where this file is stored.
	//
	// Example: /etc/haproxy/general/503.http
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Content is the file content.
	//
	// This can be any content the HAProxy configuration references,
	// such as custom error pages or response files.
	// +optional
	// +kubebuilder:validation:MinLength=1
	Content string `json:"content,omitempty"`

	// Empty explicitly represents a zero-byte file without omitting its content declaration.
	// +optional
	Empty bool `json:"empty,omitempty"`

	// Checksum is the SHA-256 hash of the file content.
	//
	// Used to detect changes and verify consistency across pods.
	// Format: sha256:<hex-digest>
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Checksum string `json:"checksum"`

	// Compressed indicates the content is zstd+base64 encoded.
	//
	// When true, consumers must decompress before use.
	// +optional
	Compressed bool `json:"compressed,omitempty"`

	// CAFile marks this file as an SSL CA or trust bundle.
	// +optional
	CAFile bool `json:"caFile,omitempty"`
}

HAProxyGeneralFileSpec contains the general file content. +kubebuilder:validation:XValidation:rule="has(self.content) != (has(self.empty) && self.empty)",message="set nonempty content or empty: true" +kubebuilder:validation:XValidation:rule="!has(self.empty) || !self.empty || ((!has(self.compressed) || !self.compressed) && self.checksum == 'sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')",message="empty files must be uncompressed and use the checksum of zero bytes"

func (*HAProxyGeneralFileSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyGeneralFileSpec.

func (*HAProxyGeneralFileSpec) DeepCopyInto

func (in *HAProxyGeneralFileSpec) DeepCopyInto(out *HAProxyGeneralFileSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyGeneralFileStatus

type HAProxyGeneralFileStatus struct {
	// DeployedToPods tracks which HAProxy pods currently have this file.
	//
	// Pods are automatically added when the file is applied and removed when
	// the pod terminates.
	// +optional
	// +listType=map
	// +listMapKey=podName
	DeployedToPods []PodDeploymentStatus `json:"deployedToPods,omitempty"`

	// ObservedGeneration reflects the generation of the spec that was most recently processed.
	//
	// This is used to track whether status is up-to-date with latest spec changes.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions represent the latest available observations of the resource's state.
	//
	// Standard conditions include:
	// - "Synced": File has been successfully applied to all target pods
	// - "Ready": Resource is ready for use
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

HAProxyGeneralFileStatus tracks deployment state to HAProxy pods.

func (*HAProxyGeneralFileStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyGeneralFileStatus.

func (*HAProxyGeneralFileStatus) DeepCopyInto

func (in *HAProxyGeneralFileStatus) DeepCopyInto(out *HAProxyGeneralFileStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyMapFile

type HAProxyMapFile struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyMapFileSpec   `json:"spec,omitempty"`
	Status HAProxyMapFileStatus `json:"status,omitempty"`
}

HAProxyMapFile contains a rendered HAProxy map file.

This is a read-only resource automatically created and updated by the controller to expose map files generated from templates. Each HAProxyMapFile is owned by a HAProxyConfig resource.

func (*HAProxyMapFile) DeepCopy

func (in *HAProxyMapFile) DeepCopy() *HAProxyMapFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyMapFile.

func (*HAProxyMapFile) DeepCopyInto

func (in *HAProxyMapFile) DeepCopyInto(out *HAProxyMapFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyMapFile) DeepCopyObject

func (in *HAProxyMapFile) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyMapFileList

type HAProxyMapFileList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyMapFile `json:"items"`
}

HAProxyMapFileList contains a list of HAProxyMapFile.

func (*HAProxyMapFileList) DeepCopy

func (in *HAProxyMapFileList) DeepCopy() *HAProxyMapFileList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyMapFileList.

func (*HAProxyMapFileList) DeepCopyInto

func (in *HAProxyMapFileList) DeepCopyInto(out *HAProxyMapFileList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyMapFileList) DeepCopyObject

func (in *HAProxyMapFileList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyMapFileSpec

type HAProxyMapFileSpec struct {
	// MapName is the logical name of the map file.
	//
	// This corresponds to the key in HAProxyTemplateConfig.spec.maps.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	MapName string `json:"mapName"`

	// Path is the file system path where this map file is stored.
	//
	// Example: /etc/haproxy/maps/path-prefix.map
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Entries is the map file content in HAProxy map format.
	//
	// Each line typically contains a key-value pair separated by whitespace.
	// Example:
	//   /api backend-api
	//   /web backend-web
	// +optional
	// +kubebuilder:validation:MinLength=1
	Entries string `json:"entries,omitempty"`

	// Empty explicitly represents a zero-byte file without omitting its content declaration.
	// +optional
	Empty bool `json:"empty,omitempty"`

	// Checksum is the SHA-256 hash of the map file entries.
	//
	// Used to detect changes and verify consistency across pods.
	// Format: sha256:<hex-digest>
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Checksum string `json:"checksum"`

	// Compressed indicates the entries are zstd+base64 encoded.
	//
	// When true, consumers must decompress before use.
	// +optional
	Compressed bool `json:"compressed,omitempty"`
}

HAProxyMapFileSpec contains the map file content. +kubebuilder:validation:XValidation:rule="has(self.entries) != (has(self.empty) && self.empty)",message="set nonempty entries or empty: true" +kubebuilder:validation:XValidation:rule="!has(self.empty) || !self.empty || ((!has(self.compressed) || !self.compressed) && self.checksum == 'sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')",message="empty files must be uncompressed and use the checksum of zero bytes"

func (*HAProxyMapFileSpec) DeepCopy

func (in *HAProxyMapFileSpec) DeepCopy() *HAProxyMapFileSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyMapFileSpec.

func (*HAProxyMapFileSpec) DeepCopyInto

func (in *HAProxyMapFileSpec) DeepCopyInto(out *HAProxyMapFileSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyMapFileStatus

type HAProxyMapFileStatus struct {
	// DeployedToPods tracks which HAProxy pods currently have this map file.
	//
	// Pods are automatically added when the map file is applied and removed when
	// the pod terminates.
	// +optional
	// +listType=map
	// +listMapKey=podName
	DeployedToPods []PodDeploymentStatus `json:"deployedToPods,omitempty"`

	// ObservedGeneration reflects the generation of the spec that was most recently processed.
	//
	// This is used to track whether status is up-to-date with latest spec changes.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions represent the latest available observations of the resource's state.
	//
	// Standard conditions include:
	// - "Synced": Map file has been successfully applied to all target pods
	// - "Ready": Resource is ready for use
	// +optional
	// +patchMergeKey=type
	// +patchStrategy=merge
	// +listType=map
	// +listMapKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

HAProxyMapFileStatus tracks deployment state to HAProxy pods.

func (*HAProxyMapFileStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyMapFileStatus.

func (*HAProxyMapFileStatus) DeepCopyInto

func (in *HAProxyMapFileStatus) DeepCopyInto(out *HAProxyMapFileStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyTemplateConfig

type HAProxyTemplateConfig struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyTemplateConfigSpec   `json:"spec,omitempty"`
	Status HAProxyTemplateConfigStatus `json:"status,omitempty"`
}

HAProxyTemplateConfig defines the configuration for the HAProxy Template Ingress Controller.

As a custom resource it provides OpenAPI validation, type safety, and support for embedded validation tests.

func (*HAProxyTemplateConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateConfig.

func (*HAProxyTemplateConfig) DeepCopyInto

func (in *HAProxyTemplateConfig) DeepCopyInto(out *HAProxyTemplateConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyTemplateConfig) DeepCopyObject

func (in *HAProxyTemplateConfig) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyTemplateConfigList

type HAProxyTemplateConfigList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyTemplateConfig `json:"items"`
}

HAProxyTemplateConfigList contains a list of HAProxyTemplateConfig.

func (*HAProxyTemplateConfigList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateConfigList.

func (*HAProxyTemplateConfigList) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyTemplateConfigList) DeepCopyObject

func (in *HAProxyTemplateConfigList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyTemplateConfigSpec

type HAProxyTemplateConfigSpec struct {
	// LibraryRefs pulls in HAProxyTemplateLibrary objects, in merge order.
	//
	// Earlier entries are overridden by later ones, and this object's own
	// inline content wins last — so the object an operator edits is always the
	// override point, with no dependence on ordering.
	//
	// The controller renders only when every reference resolves to an object
	// whose spec.revision equals the revision named here. Otherwise it keeps
	// serving the last-good configuration, because a partially applied set is
	// not safe to render: libraries deliberately override one another, so a
	// missing member silently changes behaviour rather than removing it.
	// +optional
	// +listType=map
	// +listMapKey=name
	LibraryRefs []LibraryRef `json:"libraryRefs,omitempty"`

	// CredentialsSecretRef references the Secret containing the HAPTIC agent credentials.
	//
	// The Secret must contain the following keys, which keep their historical
	// names so a rotation set up against them keeps working:
	//   - dataplane_username: agent username
	//   - dataplane_password: agent password
	//
	// If the namespace is omitted, it defaults to the same namespace as this config resource.
	// +optional
	CredentialsSecretRef SecretReference `json:"credentialsSecretRef,omitempty"`

	// PodSelector identifies which HAProxy pods to configure.
	//
	// Required in the merged config (config.ValidateStructure rejects an empty
	// matchLabels); optional here only because the merged result is what is checked.
	// +optional
	PodSelector PodSelector `json:"podSelector,omitempty"`

	// Controller contains controller-level settings (ports, leader election, etc.).
	// +optional
	Controller ControllerConfig `json:"controller,omitempty"`

	// Logging configures logging behavior.
	// +optional
	Logging LoggingConfig `json:"logging,omitempty"`

	// Dataplane configures how the controller reaches the HAProxy pods and where
	// their files live. The block keeps its name across the agent cutover.
	// +optional
	Dataplane DataplaneConfig `json:"dataplane,omitempty"`

	// TemplatingSettings configures template rendering behavior and custom variables.
	// +optional
	TemplatingSettings TemplatingSettings `json:"templatingSettings,omitempty"`

	// WatchedResourcesIgnoreFields specifies JSONPath expressions for fields
	// to remove from all watched resources to reduce memory usage.
	//
	// Example: ["metadata.managedFields", "metadata.resourceVersion"]
	// +optional
	WatchedResourcesIgnoreFields []string `json:"watchedResourcesIgnoreFields,omitempty"`

	// WatchedResources maps resource type names to their watch configuration.
	//
	// Each key is a user-defined name for the resource type (e.g., "ingresses", "services").
	// This name is used in templates to access the resources.
	//
	// The merged config must declare at least one (config.ValidateStructure);
	// a single object may declare none.
	// +optional
	WatchedResources map[string]WatchedResource `json:"watchedResources,omitempty"`

	// Validators declares pluggable validator sidecars consulted by the
	// controller before publishing rendered configuration. See
	// `docs/site/docs/operations/pluggable-validators.md`
	// for setup; the wire protocol is at
	// `docs/development/validator-protocol.md`.
	//
	// An empty list (the default) disables pluggable validation — the
	// controller keeps performing its built-in validation only.
	// +optional
	// +listType=map
	// +listMapKey=name
	Validators []ValidatorConfig `json:"validators,omitempty"`

	// TemplateSnippets maps snippet names to reusable template fragments.
	//
	// Snippets can be included in other templates using {{ render "name" }}.
	// +kubebuilder:validation:MaxProperties=4096
	// +optional
	TemplateSnippets map[string]TemplateSnippet `json:"templateSnippets,omitempty"`

	// AbsentIncrementalGroups is populated only by offline effective resolution.
	AbsentIncrementalGroups []string `json:"-"`

	// Maps maps map file names to their template definitions.
	//
	// These generate HAProxy map files for backend routing and other features.
	// +optional
	Maps map[string]MapFile `json:"maps,omitempty"`

	// Files maps file names to their template definitions.
	//
	// These generate auxiliary files like custom error pages.
	// +optional
	Files map[string]GeneralFile `json:"files,omitempty"`

	// SSLCertificates maps certificate names to their template definitions.
	//
	// These generate SSL certificate files for HAProxy.
	// +optional
	SSLCertificates map[string]SSLCertificate `json:"sslCertificates,omitempty"`

	// K8sResources maps resource template names to their template
	// definitions. Each entry's rendered output is parsed as one or
	// more Kubernetes resources (multi-doc YAML, separated by `---`)
	// and applied via Server-Side Apply with field manager `haptic`.
	//
	// The controller injects an OwnerReference to the
	// HAProxyTemplateConfig CR (controller=true,
	// blockOwnerDeletion=true) on every applied resource so cascade
	// garbage collection removes them when the CR is deleted (e.g.
	// `helm uninstall`). Resources that disappear from the rendered
	// set across reconciliations are pruned via the
	// `haproxy-haptic.org/managed-by` label the applier injects.
	//
	// Templates have full access to the same engine context as
	// haproxyConfig — `resources`, filters, `templateSnippets`,
	// `fileRegistry`, `extraContext`, etc. — so a k8sResources
	// template can render extension points (`render_glob` patterns)
	// and consume cached state (`shared.ComputeIfAbsent`).
	// +optional
	K8sResources map[string]K8sResource `json:"k8sResources,omitempty"`

	// HAProxyConfig contains the main HAProxy configuration template.
	//
	// Exactly one object in a merged set supplies it (the base library);
	// config.ValidateStructure rejects a merged config whose template is empty.
	// +optional
	HAProxyConfig HAProxyConfig `json:"haproxyConfig,omitempty"`

	// ValidationTests contains embedded validation test definitions.
	//
	// The map key is the test name, which must be unique across the whole
	// merged set: the controller unions tests per source and rejects a name
	// two objects both define, because a silent override would leave one
	// author believing an assertion runs that does not. The reserved
	// `_global` entry is the exception — it is a shared baseline several
	// objects each contribute part of, and its fixtures accumulate.
	//
	// These tests are executed at startup (the load gate), on every live
	// config change, and via the "controller validate" / "preflight" CLI
	// commands before deployment.
	// +optional
	ValidationTests map[string]ValidationTest `json:"validationTests,omitempty"`
}

HAProxyTemplateConfigSpec defines the desired state of HAProxyTemplateConfig.

One object per controller. Bulk template content lives in HAProxyTemplateLibrary objects pulled in through LibraryRefs, so this object stays small enough to read, diff and `kubectl edit`.

The CEL rule below runs in the apiserver at apply time, where it cannot be unreachable the way a webhook can. PodSelector and WatchedResources are required unconditionally, because no referenced library can supply them. HAProxyConfig may come from a library, so it is required only when nothing is referenced. Everything else the controller needs is enforced after the merge by config.ValidateStructure.

+kubebuilder:validation:XValidation:rule="has(self.podSelector) && has(self.watchedResources) && size(self.watchedResources) > 0 && (has(self.haproxyConfig) || (has(self.libraryRefs) && size(self.libraryRefs) > 0))",message="a HAProxyTemplateConfig needs podSelector, at least one watchedResources entry, and haproxyConfig — either inline or supplied by a spec.libraryRefs entry"

func (*HAProxyTemplateConfigSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateConfigSpec.

func (*HAProxyTemplateConfigSpec) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyTemplateConfigStatus

type HAProxyTemplateConfigStatus struct {
	// ObservedGeneration reflects the generation most recently observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// LastValidated is the timestamp of the last successful validation.
	// +optional
	LastValidated *metav1.Time `json:"lastValidated,omitempty"`

	// ValidationStatus indicates the overall validation status.
	// +kubebuilder:validation:Enum=Valid;Invalid;Unknown
	// +optional
	ValidationStatus string `json:"validationStatus,omitempty"`

	// ValidationMessage contains human-readable validation details.
	// +optional
	ValidationMessage string `json:"validationMessage,omitempty"`

	// ValidationErrors contains detailed validation error messages.
	// Each entry includes the template name, error location, and context.
	// +optional
	ValidationErrors []string `json:"validationErrors,omitempty"`

	// Conditions represent the latest available observations of the config's state.
	// +optional
	Conditions []metav1.Condition `json:"conditions,omitempty"`
}

HAProxyTemplateConfigStatus defines the observed state of HAProxyTemplateConfig.

func (*HAProxyTemplateConfigStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateConfigStatus.

func (*HAProxyTemplateConfigStatus) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyTemplateLibrary

type HAProxyTemplateLibrary struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   HAProxyTemplateLibrarySpec   `json:"spec,omitempty"`
	Status HAProxyTemplateLibraryStatus `json:"status,omitempty"`
}

HAProxyTemplateLibrary carries template library content that a HAProxyTemplateConfig pulls in through spec.libraryRefs.

A library is a complete content contributor, not just a bag of snippets: it can define map files, general files, SSL certificates, Kubernetes resources and the main haproxyConfig template as well.

It exists so the bulk of a configuration — templateSnippets and validationTests are ~94% of the rendered bytes — lives outside the object an operator reads and edits, and so a library too large for one object can be split across several without changing how it merges.

It carries content only. A library cannot declare podSelector, watchedResources or dataplane settings, so it can never redefine the controller's operational identity.

func (*HAProxyTemplateLibrary) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateLibrary.

func (*HAProxyTemplateLibrary) DeepCopyInto

func (in *HAProxyTemplateLibrary) DeepCopyInto(out *HAProxyTemplateLibrary)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyTemplateLibrary) DeepCopyObject

func (in *HAProxyTemplateLibrary) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyTemplateLibraryList

type HAProxyTemplateLibraryList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []HAProxyTemplateLibrary `json:"items"`
}

HAProxyTemplateLibraryList contains a list of HAProxyTemplateLibrary.

func (*HAProxyTemplateLibraryList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateLibraryList.

func (*HAProxyTemplateLibraryList) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*HAProxyTemplateLibraryList) DeepCopyObject

func (in *HAProxyTemplateLibraryList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type HAProxyTemplateLibrarySpec

type HAProxyTemplateLibrarySpec struct {
	// Revision identifies this content to the configs that reference it. A
	// referencing spec.libraryRefs entry must carry the same string or the
	// controller holds the last-good configuration rather than rendering a
	// half-applied set.
	//
	// The writer chooses the value and the controller only ever compares it
	// against the reference — it never derives a revision from the content.
	// That is what lets `kubectl edit` change a snippet in place and take
	// effect: the content moves, the revision does not, so the reference still
	// matches. A digest of the content is the convenient source for a
	// generator, because it changes exactly when the content does.
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Revision string `json:"revision"`

	// TemplatingSettings lets a library ship defaults for the template context.
	//
	// Template configuration, not operational identity: the referencing config
	// merges last, so anything an operator sets wins over every library.
	// +optional
	TemplatingSettings TemplatingSettings `json:"templatingSettings,omitempty"`

	// TemplateSnippets maps snippet names to reusable template fragments.
	// +kubebuilder:validation:MaxProperties=4096
	// +optional
	TemplateSnippets map[string]TemplateSnippet `json:"templateSnippets,omitempty"`

	// Maps maps map file names to their template definitions.
	// +optional
	Maps map[string]MapFile `json:"maps,omitempty"`

	// Files maps file names to their template definitions.
	// +optional
	Files map[string]GeneralFile `json:"files,omitempty"`

	// SSLCertificates maps certificate names to their template definitions.
	// +optional
	SSLCertificates map[string]SSLCertificate `json:"sslCertificates,omitempty"`

	// K8sResources maps resource template names to their template definitions.
	// +optional
	K8sResources map[string]K8sResource `json:"k8sResources,omitempty"`

	// HAProxyConfig contains the main HAProxy configuration template.
	//
	// Exactly one member of a merged set supplies it, or the referencing
	// config does.
	// +optional
	HAProxyConfig HAProxyConfig `json:"haproxyConfig,omitempty"`

	// ValidationTests contains embedded validation test definitions.
	//
	// Names must be unique across the merged set: the controller unions tests
	// per source and rejects a name two sources both define, because a silent
	// override would leave one author believing an assertion runs that does
	// not. The reserved `_global` entry accumulates instead.
	// +optional
	ValidationTests map[string]ValidationTest `json:"validationTests,omitempty"`
}

HAProxyTemplateLibrarySpec is the content one snippets object contributes.

func (*HAProxyTemplateLibrarySpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateLibrarySpec.

func (*HAProxyTemplateLibrarySpec) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HAProxyTemplateLibraryStatus

type HAProxyTemplateLibraryStatus struct {
	// ObservedGeneration reflects the generation most recently observed.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions represent the latest available observations.
	// +optional
	Conditions []metav1.Condition `json:"conditions,omitempty"`
}

HAProxyTemplateLibraryStatus reports what the controller observed.

func (*HAProxyTemplateLibraryStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HAProxyTemplateLibraryStatus.

func (*HAProxyTemplateLibraryStatus) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type HTTPResourceFixture

type HTTPResourceFixture struct {
	// URL is the HTTP URL to mock.
	//
	// When http.Fetch() is called with this URL during test execution,
	// the Content field is returned instead of fetching from the network.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	URL string `json:"url"`

	// Content is the mock response body to return.
	//
	// This content is returned when http.Fetch() is called with the
	// matching URL during test execution.
	// +kubebuilder:validation:Required
	Content string `json:"content"`

	// Pending renders the URL as content waiting for acceptance: http.Fetch
	// returns empty content and http.Pending reports true. Content is ignored.
	// +optional
	Pending bool `json:"pending,omitempty"`
}

HTTPResourceFixture defines mock HTTP content for validation tests.

When templates call http.Fetch() for the specified URL, the pre-defined content is returned instead of making an actual HTTP request.

func (*HTTPResourceFixture) DeepCopy

func (in *HTTPResourceFixture) DeepCopy() *HTTPResourceFixture

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPResourceFixture.

func (*HTTPResourceFixture) DeepCopyInto

func (in *HTTPResourceFixture) DeepCopyInto(out *HTTPResourceFixture)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type IncrementalEffect

type IncrementalEffect string

IncrementalEffect identifies a declared query-local side effect. +kubebuilder:validation:Enum=deriveResource;recordEvent;backendPlan;publishValue;statusPatch +kubebuilder:validation:MaxLength=32

const (
	IncrementalEffectDeriveResource IncrementalEffect = "deriveResource"
	IncrementalEffectRecordEvent    IncrementalEffect = "recordEvent"
	IncrementalEffectBackendPlan    IncrementalEffect = "backendPlan"
	IncrementalEffectPublishValue   IncrementalEffect = "publishValue"
	IncrementalEffectStatusPatch    IncrementalEffect = "statusPatch"
)

type IncrementalMode

type IncrementalMode string

IncrementalMode selects an incremental execution protocol.

const (
	IncrementalModeScriggo            IncrementalMode = ""
	IncrementalModeResourceProjection IncrementalMode = "resourceProjection"
)

type IncrementalTemplate

type IncrementalTemplate struct {
	// Mode selects Scriggo execution when empty or exact resource publication
	// when set to resourceProjection. Resource projections emit no rendered text.
	// +kubebuilder:validation:Enum="";resourceProjection
	// +kubebuilder:validation:MaxLength=32
	// +optional
	Mode IncrementalMode `json:"mode,omitempty"`

	// Source names one watchedResources entry.
	// +kubebuilder:validation:MinLength=1
	// +optional
	Source string `json:"source,omitempty"`

	// BindingsTemplate emits a JSON object mapping watched-resource aliases to
	// immutable component props.
	// +kubebuilder:validation:MinLength=1
	// +optional
	BindingsTemplate string `json:"bindingsTemplate,omitempty"`

	// WhenAnyPathExists makes the component empty unless at least one JSONPath
	// exists on its post-derivation source item. [*] selects any array element.
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:Pattern=`^\$?\.?([^.\[\]?*@()]+|\[([0-9]+|\*|'[^']+'|"[^"]+")\])(\.?([^.\[\]?*@()]+|\[([0-9]+|\*|'[^']+'|"[^"]+")\]))*$`
	// +listType=set
	// +optional
	WhenAnyPathExists []string `json:"whenAnyPathExists,omitempty"`

	// Root groups compatible components into one authenticated Scriggo runner.
	// Each member keeps its own bindings, dependencies, effects, and result.
	// +kubebuilder:validation:MinLength=1
	// +optional
	Root string `json:"root,omitempty"`

	// Group evaluates all members before resolving shared contributions.
	// +optional
	Group string `json:"group,omitempty"`

	// Consumes lists publication groups that must complete before this component
	// can select their exact keyed values.
	// +kubebuilder:validation:items:MinLength=1
	// +listType=set
	// +optional
	Consumes []string `json:"consumes,omitempty"`

	// OptionalConsumes lists publication groups that may be absent only when
	// effective-config resolution stripped their optional-resource snippets.
	// +kubebuilder:validation:items:MinLength=1
	// +listType=set
	// +optional
	OptionalConsumes []string `json:"optionalConsumes,omitempty"`

	// Effects declares the query-local side effects this component may emit.
	// +kubebuilder:validation:MaxItems=5
	// +listType=set
	// +optional
	Effects []IncrementalEffect `json:"effects,omitempty"`
}

IncrementalTemplate configures authenticated incremental evaluation. +kubebuilder:validation:XValidation:rule="has(self.source) != has(self.bindingsTemplate)",message="exactly one of source or bindingsTemplate is required" +kubebuilder:validation:XValidation:rule="!has(self.whenAnyPathExists) || !has(self.effects) || !self.effects.exists(effect, effect == 'deriveResource')",message="whenAnyPathExists cannot be combined with deriveResource" +kubebuilder:validation:XValidation:rule="!has(self.mode) || self.mode != 'resourceProjection' || (has(self.bindingsTemplate) && !has(self.source))",message="resourceProjection requires bindingsTemplate and forbids source" +kubebuilder:validation:XValidation:rule="!has(self.mode) || self.mode != 'resourceProjection' || (has(self.effects) && self.effects.size() == 1 && self.effects[0] == 'publishValue')",message="resourceProjection requires exactly the publishValue effect" +kubebuilder:validation:XValidation:rule="!has(self.mode) || self.mode != 'resourceProjection' || (!has(self.whenAnyPathExists) && !has(self.root) && !has(self.consumes) && !has(self.optionalConsumes))",message="resourceProjection forbids whenAnyPathExists, root, consumes, and optionalConsumes"

func (*IncrementalTemplate) DeepCopy

func (in *IncrementalTemplate) DeepCopy() *IncrementalTemplate

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IncrementalTemplate.

func (*IncrementalTemplate) DeepCopyInto

func (in *IncrementalTemplate) DeepCopyInto(out *IncrementalTemplate)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type K8sResource

type K8sResource struct {
	// Template is the template for generating the resource YAML.
	//
	// The rendered output is parsed as one or more Kubernetes
	// resources (separate documents with `---`). Each document must
	// declare `apiVersion`, `kind`, and `metadata.name` (plus
	// `metadata.namespace` for namespaced kinds).
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// PostProcessing defines optional post-processors to apply after rendering.
	//
	// Post-processors run in the order specified and can transform the rendered output.
	// +optional
	PostProcessing []PostProcessorConfig `json:"postProcessing,omitempty"`

	// CreateOnlyFields are dotted field paths this template sets when the
	// object is created and never again, so whoever runs the object owns them
	// afterwards.
	//
	// `spec.replicas` on a workload is the case this exists for: HAProxy
	// routes to whatever pods are there, so the count belongs to an operator
	// draining it or to an autoscaler. Without this the field is re-applied
	// every reconcile, and a deliberate `kubectl scale` is overwritten seconds
	// after it is made. The template's value is the size the object starts at,
	// not the size it keeps.
	//
	// Paths are dotted (`spec.replicas`) and must name a field the template
	// itself sets. A path absent from the rendered object is ignored.
	// +optional
	CreateOnlyFields []string `json:"createOnlyFields,omitempty"`
}

K8sResource defines a template that emits one or more Kubernetes resources via multi-doc YAML.

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (K8sResource)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function - k8sResources section)

func (*K8sResource) DeepCopy

func (in *K8sResource) DeepCopy() *K8sResource

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K8sResource.

func (*K8sResource) DeepCopyInto

func (in *K8sResource) DeepCopyInto(out *K8sResource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LeaderElectionConfig

type LeaderElectionConfig struct {
	// Enabled determines whether leader election is active.
	//
	// If false, the controller assumes it is the sole instance (single-replica mode).
	// Default: true
	// +optional
	Enabled *bool `json:"enabled,omitempty"`

	// LeaseName is the name of the Lease resource used for coordination.
	//
	// Default: haptic-leader
	// +kubebuilder:validation:MinLength=1
	// +optional
	LeaseName string `json:"leaseName,omitempty"`

	// LeaseDuration is the duration that non-leader candidates will wait
	// to force acquire leadership (measured against time of last observed ack).
	//
	// Format: Go duration string (e.g., "15s", "30s")
	// Default: 30s (DefaultLeaderElectionLeaseDuration in pkg/core/config/defaults.go;
	// the Helm chart's values.yaml sets the same value at controller.config.controller.leaderElection.leaseDuration)
	// +optional
	LeaseDuration string `json:"leaseDuration,omitempty"`

	// RenewDeadline is the duration that the acting leader will retry
	// refreshing leadership before giving up.
	//
	// Format: Go duration string (e.g., "20s")
	// Default: 20s (DefaultLeaderElectionRenewDeadline)
	// Must be less than LeaseDuration
	// +optional
	RenewDeadline string `json:"renewDeadline,omitempty"`

	// RetryPeriod is the duration the LeaderElector clients should wait
	// between tries of actions.
	//
	// Format: Go duration string (e.g., "5s")
	// Default: 5s (DefaultLeaderElectionRetryPeriod)
	// Must be less than RenewDeadline
	// +optional
	RetryPeriod string `json:"retryPeriod,omitempty"`
}

LeaderElectionConfig configures leader election for running multiple replicas.

func (*LeaderElectionConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfig.

func (*LeaderElectionConfig) DeepCopyInto

func (in *LeaderElectionConfig) DeepCopyInto(out *LeaderElectionConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LibraryRef

type LibraryRef struct {
	// Name of the HAProxyTemplateLibrary object, in this config's namespace.
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Name string `json:"name"`

	// Revision the referenced object must report in spec.revision.
	//
	// The controller compares the two strings and never recomputes either from
	// the content. A writer that applies both objects together stamps the same
	// value on each, so a half-applied set is visible as a mismatch — while an
	// in-place edit to a snippet's content leaves the revision alone and takes
	// effect immediately.
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Revision string `json:"revision"`
}

LibraryRef names one HAProxyTemplateLibrary object and the revision of it this configuration expects.

func (*LibraryRef) DeepCopy

func (in *LibraryRef) DeepCopy() *LibraryRef

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibraryRef.

func (*LibraryRef) DeepCopyInto

func (in *LibraryRef) DeepCopyInto(out *LibraryRef)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LoggingConfig

type LoggingConfig struct {
	// Level controls the log level.
	//
	// Values: TRACE, DEBUG, INFO, WARN, ERROR (case-insensitive)
	//
	// If not set, the LOG_LEVEL environment variable is used.
	// If neither is set, defaults to INFO.
	// +kubebuilder:validation:Enum=TRACE;DEBUG;INFO;WARN;ERROR;trace;debug;info;warn;error;""
	// +optional
	Level string `json:"level,omitempty"`
}

LoggingConfig configures logging behavior.

func (*LoggingConfig) DeepCopy

func (in *LoggingConfig) DeepCopy() *LoggingConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfig.

func (*LoggingConfig) DeepCopyInto

func (in *LoggingConfig) DeepCopyInto(out *LoggingConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type MapFile

type MapFile struct {
	// Template is the template for generating the map file content.
	//
	// The rendered output should be in HAProxy map file format (key-value pairs).
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// PostProcessing defines optional post-processors to apply after rendering.
	//
	// Post-processors run in the order specified and can transform the rendered output.
	// +optional
	PostProcessing []PostProcessorConfig `json:"postProcessing,omitempty"`

	// Ordered declares whether the position of an entry inside this map file
	// changes what HAProxy does with it.
	//
	// Keep it true for a map read with map_reg, map_sub, map_dom, map_dir or
	// map_end: those are evaluated as a list, first match wins, so an entry
	// inserted in the middle must land in the middle. Set it to false for a
	// map_str, map_beg, map_ip or map_str_int lookup, where a key is found by
	// its own value and a new entry can simply be appended at runtime instead
	// of rewriting the file and reloading.
	// +optional
	// +kubebuilder:default=true
	Ordered *bool `json:"ordered,omitempty"`
}

MapFile defines a HAProxy map file generated from a template.

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (MapFile)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function - maps section)

func (*MapFile) DeepCopy

func (in *MapFile) DeepCopy() *MapFile

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MapFile.

func (*MapFile) DeepCopyInto

func (in *MapFile) DeepCopyInto(out *MapFile)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type PodDeploymentStatus

type PodDeploymentStatus struct {
	// PodName is the name of the HAProxy pod.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	PodName string `json:"podName"`

	// PodUID binds the deployment proof to the Kubernetes pod incarnation.
	// +optional
	PodUID string `json:"podUID,omitempty"`

	// PodRuntimeID binds the deployment proof to the pod's container execution epoch.
	// +optional
	PodRuntimeID string `json:"podRuntimeID,omitempty"`

	// Checksum of the configuration deployed to this pod.
	// +optional
	Checksum string `json:"checksum,omitempty"`

	// AppliedPlanID is the render plan this pod last accepted.
	// +optional
	AppliedPlanID string `json:"appliedPlanID,omitempty"`

	// RunningPlanID is the render plan this pod's running HAProxy serves.
	// +optional
	RunningPlanID string `json:"runningPlanID,omitempty"`

	// WorkerOpsPlanID identifies the configuration after accepted runtime operations.
	// +optional
	WorkerOpsPlanID string `json:"workerOpsPlanID,omitempty"`

	// Mode is how the plan was applied to this pod.
	// +optional
	// +kubebuilder:validation:Enum=runtime;file_only;reload;scheduled;noop;rejected
	Mode string `json:"mode,omitempty"`

	// Reasons explain the apply mode, most significant first.
	// +optional
	// +kubebuilder:validation:MaxItems=8
	Reasons []string `json:"reasons,omitempty"`

	// LastError contains the error message from the most recent failed sync attempt.
	//
	// This field is cleared when a sync succeeds. Combined with ConsecutiveErrors,
	// this helps identify persistent vs transient issues.
	// +optional
	LastError string `json:"lastError,omitempty"`

	// ConsecutiveErrors is the count of consecutive sync failures.
	//
	// This counter increments on each failure and resets to 0 on success.
	// High values indicate persistent problems requiring investigation.
	// +optional
	// +kubebuilder:validation:Minimum=0
	ConsecutiveErrors int `json:"consecutiveErrors,omitempty"`
}

PodDeploymentStatus tracks deployment to a specific pod.

func (*PodDeploymentStatus) DeepCopy

func (in *PodDeploymentStatus) DeepCopy() *PodDeploymentStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDeploymentStatus.

func (*PodDeploymentStatus) DeepCopyInto

func (in *PodDeploymentStatus) DeepCopyInto(out *PodDeploymentStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type PodSelector

type PodSelector struct {
	// MatchLabels are the labels to match HAProxy pods.
	//
	// Example:
	//   app: haproxy
	//   component: loadbalancer
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinProperties=1
	MatchLabels map[string]string `json:"matchLabels"`
}

PodSelector identifies which HAProxy pods to configure.

func (*PodSelector) DeepCopy

func (in *PodSelector) DeepCopy() *PodSelector

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSelector.

func (*PodSelector) DeepCopyInto

func (in *PodSelector) DeepCopyInto(out *PodSelector)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type PostProcessorConfig

type PostProcessorConfig struct {
	// Type specifies the post-processor type (e.g., "regex_replace").
	// +kubebuilder:validation:Required
	Type string `json:"type"`

	// Params contains post-processor-specific parameters.
	//
	// For "regex_replace":
	//   - pattern: Regular expression pattern to match
	//   - replace: Replacement string
	// +kubebuilder:validation:Required
	Params map[string]string `json:"params"`
}

PostProcessorConfig defines a post-processor to apply to rendered template output.

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (PostProcessorConfig)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function)

func (*PostProcessorConfig) DeepCopy

func (in *PostProcessorConfig) DeepCopy() *PostProcessorConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostProcessorConfig.

func (*PostProcessorConfig) DeepCopyInto

func (in *PostProcessorConfig) DeepCopyInto(out *PostProcessorConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ResourceReference

type ResourceReference struct {
	// Kind is the resource type (e.g., HAProxyMapFile, Secret).
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Kind string `json:"kind"`

	// Name is the resource name.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`

	// Namespace is the resource namespace.
	// +optional
	Namespace string `json:"namespace,omitempty"`
}

ResourceReference identifies a related Kubernetes resource.

func (*ResourceReference) DeepCopy

func (in *ResourceReference) DeepCopy() *ResourceReference

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReference.

func (*ResourceReference) DeepCopyInto

func (in *ResourceReference) DeepCopyInto(out *ResourceReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RetainedConfigReference

type RetainedConfigReference struct {
	Name     string `json:"name"`
	UID      string `json:"uid"`
	Checksum string `json:"checksum"`
}

RetainedConfigReference binds a recovery checkpoint to one object incarnation.

func (*RetainedConfigReference) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetainedConfigReference.

func (*RetainedConfigReference) DeepCopyInto

func (in *RetainedConfigReference) DeepCopyInto(out *RetainedConfigReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SSLCertificate

type SSLCertificate struct {
	// Template is the template for generating the certificate content.
	//
	// The rendered output should be in PEM format (certificate + private key).
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// PostProcessing defines optional post-processors to apply after rendering.
	//
	// Post-processors run in the order specified and can transform the rendered output.
	// +optional
	PostProcessing []PostProcessorConfig `json:"postProcessing,omitempty"`
}

SSLCertificate defines an SSL certificate generated from a template.

IMPORTANT: This is a Kubernetes CRD type. When modifying this struct, you must also update:

  • The internal config type: pkg/core/config/types.go (SSLCertificate)
  • The conversion logic: pkg/controller/conversion/converter.go (ConvertSpec function - sslCertificates section)

func (*SSLCertificate) DeepCopy

func (in *SSLCertificate) DeepCopy() *SSLCertificate

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSLCertificate.

func (*SSLCertificate) DeepCopyInto

func (in *SSLCertificate) DeepCopyInto(out *SSLCertificate)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SecretReference

type SecretReference struct {
	// Name is the name of the Secret.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`

	// Namespace is the namespace of the Secret.
	//
	// If empty, defaults to the same namespace as the HAProxyTemplateConfig.
	// +optional
	Namespace string `json:"namespace,omitempty"`
}

SecretReference references a Secret by name and optional namespace.

func (*SecretReference) DeepCopy

func (in *SecretReference) DeepCopy() *SecretReference

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference.

func (*SecretReference) DeepCopyInto

func (in *SecretReference) DeepCopyInto(out *SecretReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ServerAddr

type ServerAddr struct {
	// Address is the server's address — an IP or a hostname.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Address string `json:"address"`

	// Port is the server's port. Omit it for a server line that carries none.
	// +optional
	Port *int64 `json:"port,omitempty"`
}

ServerAddr is one server of a previously deployed backend, as templates see it in currentConfig.ServerIndex.

func (*ServerAddr) DeepCopy

func (in *ServerAddr) DeepCopy() *ServerAddr

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerAddr.

func (*ServerAddr) DeepCopyInto

func (in *ServerAddr) DeepCopyInto(out *ServerAddr)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type TemplateSnippet

type TemplateSnippet struct {
	// Template is the template content.
	//
	// Can be included in other templates using {{ render "snippet_name" }}.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Template string `json:"template"`

	// Requires lists watched-resource names this snippet depends on. When an
	// optional watched resource has no served candidate version, every
	// snippet requiring it is stripped from the effective config at load
	// time. Each entry must name a key of watchedResources.
	// +optional
	Requires []string `json:"requires,omitempty"`

	// Incremental configures authenticated incremental evaluation for this snippet.
	// +optional
	Incremental *IncrementalTemplate `json:"incremental,omitempty"`
}

TemplateSnippet defines a reusable template fragment.

func (*TemplateSnippet) DeepCopy

func (in *TemplateSnippet) DeepCopy() *TemplateSnippet

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSnippet.

func (*TemplateSnippet) DeepCopyInto

func (in *TemplateSnippet) DeepCopyInto(out *TemplateSnippet)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type TemplatingSettings

type TemplatingSettings struct {
	// Engine specifies which template engine to use for rendering.
	//
	// Available engines:
	//   - "scriggo" (default): Go template syntax, high performance rendering
	//
	// Default: scriggo
	// +kubebuilder:validation:Enum=scriggo
	// +optional
	Engine string `json:"engine,omitempty"`

	// ExtraContext provides custom variables that are passed to all templates.
	//
	// This allows users to add arbitrary data to the template context without
	// modifying controller code. Values can be any valid JSON type (string, number,
	// boolean, object, array).
	//
	// Example:
	//   extraContext:
	//     debug:
	//       enabled: true
	//     environment: production
	//     customValue: 42
	//
	// Templates can then reference these as: {{ debug.enabled }}, {{ environment }}, etc.
	// +optional
	// +kubebuilder:validation:Type=object
	// +kubebuilder:pruning:PreserveUnknownFields
	ExtraContext runtime.RawExtension `json:"extraContext,omitempty"`

	// TestExtraContext is the extraContext validationTests render with in place of
	// this config's extraContext, so a deployment's values can't change what a
	// test asserts. Library extraContext defaults apply beneath it.
	// +optional
	// +kubebuilder:validation:Type=object
	// +kubebuilder:pruning:PreserveUnknownFields
	TestExtraContext runtime.RawExtension `json:"testExtraContext,omitempty"`
}

TemplatingSettings configures template rendering behavior.

func (*TemplatingSettings) DeepCopy

func (in *TemplatingSettings) DeepCopy() *TemplatingSettings

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplatingSettings.

func (*TemplatingSettings) DeepCopyInto

func (in *TemplatingSettings) DeepCopyInto(out *TemplatingSettings)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ValidationAssertion

type ValidationAssertion struct {
	// Type is the assertion type.
	//
	// Supported types:
	//   - haproxy_valid: Validates that generated HAProxy config is syntactically valid
	//   - contains: Checks if target contains pattern (regex)
	//   - not_contains: Checks if target does not contain pattern (regex)
	//   - equals: Checks if target equals expected value
	//   - jsonpath: Evaluates JSONPath expression against target
	//   - match_count: Counts how many times pattern matches in target (regex)
	//   - match_order: Validates that patterns appear in specified order
	//   - not_exists: Checks that the render produced no artefact under the target
	//   - deterministic: Verifies that rendering twice produces identical output
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:Enum=haproxy_valid;contains;not_contains;equals;jsonpath;match_count;match_order;not_exists;deterministic
	Type string `json:"type"`

	// Description explains what this assertion validates.
	// +optional
	Description string `json:"description,omitempty"`

	// Target specifies what to validate.
	//
	// Format depends on assertion type:
	//   - haproxy_valid: not used
	//   - contains/not_contains/equals: "haproxy.cfg", "map:<name>", "file:<name>", "cert:<name>"
	//   - jsonpath: the resource to query
	// +optional
	Target string `json:"target,omitempty"`

	// Pattern is the regex pattern for contains/not_contains assertions.
	// +optional
	Pattern string `json:"pattern,omitempty"`

	// Expected is the expected value for equals assertions.
	// +optional
	Expected string `json:"expected,omitempty"`

	// JSONPath is the JSONPath expression for jsonpath assertions.
	// +optional
	JSONPath string `json:"jsonpath,omitempty"`

	// Patterns is a list of regex patterns for match_order assertions.
	// The patterns must appear in the target in the order specified.
	// +optional
	Patterns []string `json:"patterns,omitempty"`
}

ValidationAssertion defines a single validation check.

func (*ValidationAssertion) DeepCopy

func (in *ValidationAssertion) DeepCopy() *ValidationAssertion

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidationAssertion.

func (*ValidationAssertion) DeepCopyInto

func (in *ValidationAssertion) DeepCopyInto(out *ValidationAssertion)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ValidationTest

type ValidationTest struct {
	// UseDeploymentWatchScopes applies configured watch namespaces to this test.
	// Set it on individual tests, not on the shared _global entry.
	// +optional
	UseDeploymentWatchScopes bool `json:"useDeploymentWatchScopes,omitempty"`

	// Description explains what this test validates.
	// +optional
	Description string `json:"description,omitempty"`

	// Fixtures defines the Kubernetes resources to use for this test.
	//
	// Keys are resource type names (matching WatchedResources keys).
	// Values are arrays of resources as raw JSON.
	//
	// Example:
	//   ingresses:
	//     - apiVersion: networking.k8s.io/v1
	//       kind: Ingress
	//       metadata:
	//         name: test-ingress
	//
	// Optional per object so several libraries can each contribute part of the
	// shared `_global` baseline; see Assertions.
	// +optional
	// +kubebuilder:pruning:PreserveUnknownFields
	Fixtures map[string][]runtime.RawExtension `json:"fixtures,omitempty"`

	// HTTPResources defines mock HTTP content for this test.
	//
	// These fixtures are used when templates call http.Fetch() to provide
	// pre-defined content without making actual HTTP requests.
	//
	// Example:
	//   httpResources:
	//     - url: http://blocklist.example.com/list.txt
	//       content: |
	//         blocked-value-1
	//         blocked-value-2
	// +optional
	HTTPResources []HTTPResourceFixture `json:"httpResources,omitempty"`

	// CurrentServers are the servers of a previous deployment, keyed by backend
	// name and then by server name, exposed to templates as
	// `currentConfig.ServerIndex`. Use it to test slot-aware server assignment
	// during rolling deployments.
	//
	// Example:
	//   currentServers:
	//     my-backend:
	//       srv1: {address: 10.0.0.1, port: 8080}
	//       srv2: {address: 10.0.0.2, port: 8080}
	// +optional
	CurrentServers map[string]map[string]ServerAddr `json:"currentServers,omitempty"`

	// CurrentFiles are the currently-deployed general auxiliary files
	// (filename → content), exposed to templates under `currentFiles`. Used to
	// test templates that read their own prior output — e.g. self-rotating TLS
	// session-ticket keys inspecting the current key file's embedded date marker.
	// +optional
	CurrentFiles map[string]string `json:"currentFiles,omitempty"`

	// ExtraContext provides custom variables that override the global extraContext for this test.
	//
	// This allows testing template behavior with different extraContext values without
	// modifying the global configuration.
	//
	// Example:
	//   extraContext:
	//     sanitize_auth_realm: true
	//     debug: true
	// +optional
	// +kubebuilder:validation:Type=object
	// +kubebuilder:pruning:PreserveUnknownFields
	ExtraContext runtime.RawExtension `json:"extraContext,omitempty"`

	// MinHAProxyVersion specifies the minimum HAProxy version required to run this test.
	//
	// When set, the test is skipped if the local HAProxy version is below this threshold.
	// This is useful for tests that use HAProxy features only available in newer versions
	// (e.g., shm-stats-file requires HAProxy 3.3+).
	//
	// Format: "major.minor" (e.g., "3.3")
	// +optional
	MinHAProxyVersion string `json:"minHAProxyVersion,omitempty"`

	// Requires lists watched-resource names this test depends on. When an
	// optional watched resource has no served candidate version, every test
	// requiring it is stripped from the effective config at load time.
	// Each entry must name a key of watchedResources.
	// +optional
	Requires []string `json:"requires,omitempty"`

	// RequiresFields lists schema field paths this test depends on, each in
	// the form "<watchedResourceKey>.<field.path>" (e.g.
	// "httproutes.spec.rules.filters.cors"). When any referenced field is
	// absent from the resolved schema generation of its watched resource,
	// the test is stripped from the effective config at load time. This
	// covers clusters that serve the resource at the same API version as
	// newer releases but with an older schema generation lacking the field.
	// The first dot-segment of each entry must name a key of
	// watchedResources.
	// +optional
	RequiresFields []string `json:"requiresFields,omitempty"`

	// Assertions defines the validation checks to perform.
	//
	// Optional in the schema, required in practice: config.ValidateStructure
	// rejects a merged config whose test declares none. The schema cannot
	// express it because the reserved `_global` entry is a shared baseline
	// rather than a test — the runner never executes its assertions — and
	// several template libraries each contribute part of it, so each of their
	// objects carries an incomplete `_global` that only becomes whole after
	// the merge.
	// +optional
	Assertions []ValidationAssertion `json:"assertions,omitempty"`
}

ValidationTest defines a validation test with fixtures and assertions.

The test name is provided by the map key in ValidationTests.

func (*ValidationTest) DeepCopy

func (in *ValidationTest) DeepCopy() *ValidationTest

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidationTest.

func (*ValidationTest) DeepCopyInto

func (in *ValidationTest) DeepCopyInto(out *ValidationTest)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ValidatorConfig

type ValidatorConfig struct {
	// Name is the operator-facing identifier for this validator.
	//
	// MUST be a valid RFC 1123 label (lowercase alphanumeric and `-`,
	// 1-63 characters). MUST be unique across the validators array.
	// Surfaces in admission denial messages so operators can identify
	// which validator rejected a change.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
	Name string `json:"name"`

	// SocketPath is the absolute filesystem path to the validator's
	// Unix domain socket inside the controller pod.
	//
	// The chart-rendered shared `emptyDir` volume mounts at
	// `/var/run/haptic-validators/`; the conventional path is
	// `/var/run/haptic-validators/<name>.sock`. Custom paths must
	// still resolve inside the controller pod's filesystem.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:Pattern=`^/`
	SocketPath string `json:"socketPath"`

	// Files is a list of glob patterns matched against rendered file
	// paths to decide which files to send to this validator.
	//
	// Glob syntax follows Go's `path/filepath.Match` rules:
	//   - `*` matches any run of non-`/` characters.
	//   - `?` matches any single non-`/` character.
	//   - `[a-z]` matches any character in the range.
	//   - `**` is NOT supported; use multiple entries to cover
	//     directory hierarchies.
	//
	// At least one glob MUST be specified. Paths use the same relative or
	// absolute form emitted by the corresponding file template.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinItems=1
	// +listType=set
	Files []string `json:"files"`

	// DataFiles lists glob patterns for files this validator needs in order
	// to check the files it validates, but must not validate on their own.
	//
	// Every matching file is attached to every request sent to this
	// validator, marked as data. The validator does not parse them; it
	// resolves references from the validated file into them.
	//
	// A WAF ruleset is the motivating case: the validator sidecar runs in
	// the controller pod and cannot read the HAProxy pod's filesystem, so a
	// hub config that `Include`s a ruleset by path can only be checked if
	// the ruleset's content travels with the request.
	//
	// A file matching both `files` and `dataFiles` is treated as data —
	// validating a reference target standalone reports on the wrong thing.
	// +optional
	// +listType=set
	DataFiles []string `json:"dataFiles,omitempty"`

	// TimeoutMs is the per-call deadline, in milliseconds, covering
	// the request-response cycle for one file (connect-or-acquire +
	// write + read).
	//
	// Defaults to 5000 (5 seconds) when omitted. Validator calls
	// exceeding this deadline are surfaced as `result: "error"` so a
	// wedged sidecar does not stall the webhook path indefinitely.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=60000
	TimeoutMs *int32 `json:"timeoutMs,omitempty"`

	// MaxConnections caps the size of the controller's connection
	// pool to this validator's socket. The pool starts small (one
	// idle connection) and grows on contention up to this cap;
	// connections idle past the validator's idle timeout are reaped
	// transparently and reopened on next use.
	//
	// Defaults to 4 when omitted. Setting 1 reproduces a serial
	// client (one validation in flight at a time). Higher values
	// allow more concurrent validations during reconciliation bursts
	// at the cost of file descriptors and validator-side resource
	// pressure.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=32
	MaxConnections *int32 `json:"maxConnections,omitempty"`
}

ValidatorConfig declares one pluggable validator sidecar that the controller consults before rendered configuration is published.

The wire protocol between the controller and a validator sidecar is documented in `docs/development/validator-protocol.md` and is owned by HAPTIC. Reference implementation: `haproxy-spoa-hub --validate-socket <path>` shipped alongside HAPTIC; any conforming implementation may be substituted. The validator program is opaque to HAPTIC — its internal architecture (whether it has plugins, how it dispatches files, how it parses content) is its own concern.

Operators declare zero, one, or many validators. Each one runs in its own sidecar container in the controller pod and shares a Unix domain socket via an emptyDir volume; the chart wires this up automatically when `spec.validators` is non-empty.

Routing: HAPTIC matches each rendered file's path against every validator's `files` glob list. Files that match are sent to that validator over its socket. A file that matches multiple validators' globs is sent to each of them. Files that match no validator's globs are not validated by any sidecar (they still flow through the existing template + HAProxy syntax dry-run).

func (*ValidatorConfig) DeepCopy

func (in *ValidatorConfig) DeepCopy() *ValidatorConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatorConfig.

func (*ValidatorConfig) DeepCopyInto

func (in *ValidatorConfig) DeepCopyInto(out *ValidatorConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type WatchedResource

type WatchedResource struct {
	// APIVersion is the Kubernetes API version (e.g., "networking.k8s.io/v1").
	//
	// Mutually exclusive with apiVersions (exactly one must be set; the
	// controller's config validation enforces this). Equivalent to a
	// one-element apiVersions list.
	// +optional
	APIVersion string `json:"apiVersion,omitempty"`

	// APIVersions is an ordered candidate list of API versions. The
	// controller resolves the entry to the FIRST candidate the apiserver
	// serves and watches that version. Mutually exclusive with apiVersion.
	//
	// Example: ["gateway.networking.k8s.io/v1", "gateway.networking.k8s.io/v1beta1"]
	// +optional
	// +kubebuilder:validation:MinItems=1
	APIVersions []string `json:"apiVersions,omitempty"`

	// Optional marks this resource as non-essential: when NO candidate
	// version is served by the cluster, the watch is dropped and every
	// templateSnippet / validationTest whose requires list names this
	// resource is stripped from the effective config at load time, instead
	// of failing startup.
	// +optional
	Optional bool `json:"optional,omitempty"`

	// Resources is the plural form of the Kubernetes resource type (e.g., "ingresses", "services").
	//
	// This is the name used in RBAC rules and API paths.
	// +kubebuilder:validation:Required
	// +kubebuilder:validation:MinLength=1
	Resources string `json:"resources"`

	// EnableValidationWebhook enables admission webhook validation for this resource.
	//
	// When enabled, the controller will validate resources of this type before they're saved.
	// Default: false
	// +optional
	EnableValidationWebhook bool `json:"enableValidationWebhook,omitempty"`

	// IndexBy specifies JSONPath expressions for extracting index keys.
	//
	// Resources are indexed by these values for O(1) lookup in templates.
	//
	// Examples:
	//   - ["metadata.namespace", "metadata.name"]
	//   - ["metadata.labels['kubernetes.io/service-name']"]
	// +optional
	IndexBy []string `json:"indexBy,omitempty"`

	// LabelSelector filters resources by labels (server-side filtering).
	//
	// Equality-only: comma-separated "key=value" pairs.
	// Example: "app=nginx,environment=production"
	// Parsed with the Kubernetes label-selector grammar. Set-based syntax
	// (e.g. "tier in (frontend,api)", "!disabled", "app!=nginx") is NOT supported
	// and is rejected: the configuration fails to load rather than the selector
	// being dropped, which would silently widen the watch to every object of
	// this kind cluster-wide.
	// +optional
	LabelSelector string `json:"labelSelector,omitempty"`

	// FieldSelector filters resources using client-side JSONPath evaluation.
	// Unlike Kubernetes' native fieldSelector (which only supports limited fields),
	// this supports any JSONPath expression.
	//
	// Format: "field.path=value"
	// Example: "spec.ingressClassName=haproxy-internal"
	// +optional
	FieldSelector string `json:"fieldSelector,omitempty"`

	// Namespaces restricts the watch to these namespaces; unset watches every
	// namespace. The controller needs read access only there, and a template
	// lookup into any other namespace fails the render instead of returning
	// nothing. Requires indexBy to start with metadata.namespace.
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=63
	// +kubebuilder:validation:items:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
	// +listType=set
	// +optional
	Namespaces []string `json:"namespaces,omitempty"`

	// NamespacesSetting names the setting that chose namespaces, such as a
	// Helm value; the error for a lookup outside them quotes it. Defaults to
	// watchedResources.<name>.namespaces.
	// +kubebuilder:validation:MaxLength=253
	// +optional
	NamespacesSetting string `json:"namespacesSetting,omitempty"`

	// Store specifies the storage backend for this resource type.
	//
	// Valid values:
	//   - "full": MemoryStore - keeps all resources in memory (faster, higher memory usage)
	//   - "on-demand": CachedStore - fetches resources on-demand with caching (slower, lower memory usage)
	//
	// Default: "full"
	//
	// Use "on-demand" for large resources accessed infrequently (e.g., Secrets).
	// Use "full" for frequently accessed resources (e.g., Ingress, Service, EndpointSlice).
	// +kubebuilder:validation:Enum=full;on-demand
	// +optional
	Store string `json:"store,omitempty"`

	// DebounceInterval overrides the watcher's refractory window.
	// "0" disables debouncing; default 100ms.
	// +optional
	DebounceInterval string `json:"debounceInterval,omitempty"`

	// IgnoreFields lists JSONPath expressions removed from this resource
	// before it is stored, in addition to watchedResourcesIgnoreFields.
	// `[*]` selects every element of an array. An update that changes only
	// ignored fields is not a change: templates never see it and it
	// triggers no render.
	//
	// Example: ["status.listeners[*].attachedRoutes"]
	// +optional
	IgnoreFields []string `json:"ignoreFields,omitempty"`
}

WatchedResource configures watching for a specific Kubernetes resource type.

func (*WatchedResource) DeepCopy

func (in *WatchedResource) DeepCopy() *WatchedResource

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchedResource.

func (*WatchedResource) DeepCopyInto

func (in *WatchedResource) DeepCopyInto(out *WatchedResource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

Jump to

Keyboard shortcuts

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