Documentation
¶
Overview ¶
Package dataplane provides a simple, high-level API for synchronizing HAProxy configurations via the Dataplane API.
The library handles all complexity internally:
- Fetches current configuration from the Dataplane API
- Parses both current and desired configurations
- Generates fine-grained operations to transform current → desired
- Executes operations with automatic retry on version conflicts (409 errors)
- Falls back to raw config push on non-recoverable errors
- Returns detailed results including applied changes and reload information
Basic Usage (Recommended) ¶
For production use, create a Client to reuse connections across multiple operations:
endpoint := dataplane.Endpoint{
URL: "http://haproxy:5555/v2",
Username: "admin",
Password: "secret",
}
// Create client once, reuse for multiple operations
client, err := dataplane.NewClient(context.Background(), endpoint)
if err != nil {
slog.Error("failed to create client", "error", err)
os.Exit(1)
}
defer client.Close()
desiredConfig := `
global
daemon
defaults
mode http
timeout client 30s
timeout server 30s
timeout connect 5s
backend web
balance roundrobin
server srv1 192.168.1.10:80 check
`
result, err := client.Sync(ctx, desiredConfig, nil, nil)
if err != nil {
slog.Error("sync failed", "error", err)
os.Exit(1)
}
fmt.Printf("Applied %d operations\n", len(result.AppliedOperations))
if result.ReloadTriggered {
fmt.Printf("HAProxy reloaded (ID: %s)\n", result.ReloadID)
}
Simple One-Off Operations ¶
For quick scripts, use the convenience functions (creates client internally):
result, err := dataplane.Sync(ctx, endpoint, desiredConfig, nil, nil)
Custom Options ¶
Configure sync behavior with options:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
opts := &dataplane.SyncOptions{
MaxRetries: 5, // Retry 409 conflicts up to 5 times
Timeout: 3 * time.Minute, // Overall timeout
ContinueOnError: false, // Stop on first error
FallbackToRaw: true, // Fall back to raw push on errors
}
result, err := client.Sync(ctx, desiredConfig, nil, opts)
Dry Run ¶
Preview changes without applying them:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
diff, err := client.DryRun(ctx, desiredConfig)
if err != nil {
slog.Error("dry run failed", "error", err)
os.Exit(1)
}
fmt.Printf("Would apply %d operations:\n", len(diff.PlannedOperations))
for _, op := range diff.PlannedOperations {
fmt.Printf(" - %s\n", op.Description)
}
Diff Only ¶
Get detailed diff information:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
diff, err := client.Diff(ctx, desiredConfig)
if err != nil {
slog.Error("diff failed", "error", err)
os.Exit(1)
}
fmt.Printf("Backends added: %v\n", diff.Details.BackendsAdded)
fmt.Printf("Servers modified: %d\n", len(diff.Details.ServersModified))
Error Handling ¶
The library provides detailed, actionable error messages:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
result, err := client.Sync(ctx, desiredConfig, nil, nil)
if err != nil {
var syncErr *dataplane.SyncError
if errors.As(err, &syncErr) {
fmt.Printf("Stage: %s\n", syncErr.Stage)
fmt.Printf("Error: %s\n", syncErr.Message)
for _, hint := range syncErr.Hints {
fmt.Printf(" Hint: %s\n", hint)
}
}
}
Index ¶
- func SimplifyRenderingError(err error) string
- func SimplifyValidationError(err error) string
- func ValidateConfiguration(mainConfig string, auxFiles *AuxiliaryFiles, paths *ValidationPaths, ...) error
- type AppliedOperation
- type AuxiliaryFiles
- type Capabilities
- type Client
- func (c *Client) Close() error
- func (c *Client) Diff(ctx context.Context, desiredConfig string) (*DiffResult, error)
- func (c *Client) DryRun(ctx context.Context, desiredConfig string) (*DiffResult, error)
- func (c *Client) Sync(ctx context.Context, desiredConfig string, auxFiles *AuxiliaryFiles, ...) (*SyncResult, error)
- type ConfigParser
- type ConflictError
- type ConnectionError
- type DiffDetails
- type DiffResult
- type Endpoint
- type FallbackError
- type OperationError
- type ParseError
- type PathConfig
- type PlannedOperation
- type ResolvedPaths
- type SyncError
- func NewConflictError(retries int, expectedVersion int64, actualVersion string) *SyncError
- func NewConnectionError(endpoint string, cause error) *SyncError
- func NewFallbackError(originalErr, fallbackCause error) *SyncError
- func NewOperationError(opType, section, resource string, cause error) *SyncError
- func NewParseError(configType, configSnippet string, cause error) *SyncError
- func NewValidationError(message string, cause error) *SyncError
- type SyncOptions
- type SyncResult
- type ValidationError
- type ValidationPaths
- type Version
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SimplifyRenderingError ¶
SimplifyRenderingError extracts meaningful error messages from template rendering failures.
Handles template-level validation errors from the fail() function which are buried in the template engine's execution stack trace.
Input format:
"failed to render haproxy.cfg: failed to render template 'haproxy.cfg': unable to execute template: ... invalid call to function 'fail': <message>"
Output: "<message>" (the user-provided error message from fail() call)
If the error doesn't match this pattern (e.g., syntax errors, missing variables), returns the original error string.
func SimplifyValidationError ¶
SimplifyValidationError parses HAProxy validation errors and extracts the key information for user-friendly error messages.
Handles two types of validation errors:
Schema validation errors - OpenAPI spec violations: Input: "schema validation failed: configuration violates API schema constraints: ... Error at "/field": constraint" Output: "field constraint (got value)"
Semantic validation errors - HAProxy binary validation failures: Input: "semantic validation failed: configuration has semantic errors: haproxy validation failed: <context>" Output: "<context>" (preserves parseHAProxyError output with context lines)
Returns original error string if parsing fails.
func ValidateConfiguration ¶
func ValidateConfiguration(mainConfig string, auxFiles *AuxiliaryFiles, paths *ValidationPaths, version *Version, skipDNSValidation bool) error
ValidateConfiguration performs three-phase HAProxy configuration validation.
Phase 1: Syntax validation using client-native parser Phase 1.5: API schema validation using OpenAPI spec (patterns, formats, required fields) Phase 2: Semantic validation using haproxy binary (-c flag)
The validation writes files to the directories specified in paths. Callers must ensure that paths are isolated (e.g., per-worker temp directories) to allow parallel execution.
Parameters:
- mainConfig: The rendered HAProxy configuration (haproxy.cfg content)
- auxFiles: All auxiliary files (maps, certificates, general files)
- paths: Filesystem paths for validation (must be isolated for parallel execution)
- version: HAProxy/DataPlane API version for schema selection (nil uses default v3.0)
- skipDNSValidation: If true, adds -dr flag to skip DNS resolution failures. Use true for runtime validation (permissive, prevents blocking when DNS fails) and false for webhook validation (strict, catches DNS issues before resource admission).
Returns:
- nil if validation succeeds
- ValidationError with phase information if validation fails
Types ¶
type AppliedOperation ¶
type AppliedOperation struct {
// Type is the operation type: "create", "update", or "delete"
Type string
// Section is the configuration section: "backend", "server", "frontend", "acl", "http-rule", etc.
Section string
// Resource is the resource name or identifier (e.g., backend name, server name)
Resource string
// Description is a human-readable description of what was changed
Description string
}
AppliedOperation represents a single applied configuration change.
type AuxiliaryFiles ¶
type AuxiliaryFiles struct {
// GeneralFiles contains general-purpose files (error pages, custom response files, etc.)
GeneralFiles []auxiliaryfiles.GeneralFile
// SSLCertificates contains SSL certificates to sync to HAProxy SSL storage
SSLCertificates []auxiliaryfiles.SSLCertificate
// MapFiles contains map files for backend routing and other map-based features
MapFiles []auxiliaryfiles.MapFile
// CRTListFiles contains crt-list files for SSL certificate lists with per-certificate options
CRTListFiles []auxiliaryfiles.CRTListFile
}
AuxiliaryFiles contains files to synchronize before configuration changes. These files are synced in two phases:
- Phase 1 (pre-config): Creates and updates are applied before config sync
- Phase 2 (post-config): Deletes are applied after successful config sync
func DefaultAuxiliaryFiles ¶
func DefaultAuxiliaryFiles() *AuxiliaryFiles
DefaultAuxiliaryFiles returns an empty auxiliary files struct.
type Capabilities ¶
type Capabilities = client.Capabilities
Capabilities defines which features are available for a given HAProxy/DataPlane API version. This type is re-exported from pkg/dataplane/client for convenience.
func CapabilitiesFromVersion ¶
func CapabilitiesFromVersion(v *Version) Capabilities
CapabilitiesFromVersion computes capabilities based on a HAProxy version. This is used for local HAProxy binary detection (haproxy -v).
Capability thresholds (verified against OpenAPI specs):
- SupportsCrtList: v3.2+ (CRT-list storage endpoint)
- SupportsMapStorage: v3.0+ (Map file storage endpoint)
- SupportsGeneralStorage: v3.0+ (General file storage)
- SupportsSslCaFiles: v3.2+ (SSL CA file runtime endpoint)
- SupportsSslCrlFiles: v3.2+ (SSL CRL file runtime endpoint)
- SupportsLogProfiles: v3.1+ (Log profiles configuration endpoint)
- SupportsTraces: v3.1+ (Traces configuration endpoint)
- SupportsAcmeProviders: v3.2+ (ACME provider configuration endpoint)
- SupportsQUIC: v3.0+ (QUIC/HTTP3 configuration options)
- SupportsQUICInitialRules: v3.1+ (QUIC initial rules endpoints)
- SupportsHTTP2: v3.0+ (HTTP/2 configuration)
- SupportsRuntimeMaps: v3.0+ (Runtime map operations)
- SupportsRuntimeServers: v3.0+ (Runtime server operations)
type Client ¶
type Client struct {
// Endpoint contains connection information
Endpoint Endpoint
// contains filtered or unexported fields
}
Client manages a persistent connection to the HAProxy Dataplane API. It reuses connections for multiple operations, making it efficient for repeated sync operations.
For simple one-off operations, use the package-level convenience functions (Sync, DryRun, Diff) which create a client internally.
For production use with multiple operations, create a Client explicitly:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
// Reuse client for multiple operations
result1, err := client.Sync(ctx, config1, auxFiles1, opts)
result2, err := client.Sync(ctx, config2, auxFiles2, opts)
func NewClient ¶
NewClient creates a new Client for the given endpoint. The client reuses connections for multiple operations.
Example:
endpoint := dataplane.Endpoint{
URL: "http://haproxy:5555/v2",
Username: "admin",
Password: "secret",
}
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}
defer client.Close()
result, err := client.Sync(ctx, desiredConfig, nil, nil)
func (*Client) Close ¶
Close cleans up client resources. Currently a no-op, but provided for future resource cleanup needs.
func (*Client) Diff ¶
Diff compares the current and desired configurations and returns detailed differences.
This is an alias for DryRun - both methods perform the same operation. Use whichever name makes more sense in your context.
Parameters:
- ctx: Context for cancellation and timeout
- desiredConfig: The desired HAProxy configuration as a string
Returns:
- *DiffResult: Detailed information about differences
- error: Error if comparison fails
Example:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
diff, err := client.Diff(ctx, desiredConfig)
if err != nil {
return fmt.Errorf("diff failed: %w", err)
}
fmt.Printf("Backends added: %v\n", diff.Details.BackendsAdded)
fmt.Printf("Backends modified: %v\n", diff.Details.BackendsModified)
fmt.Printf("Servers deleted: %d total\n", len(diff.Details.ServersDeleted))
func (*Client) DryRun ¶
DryRun previews what changes would be applied without actually applying them.
This method performs all the same steps as Sync except for the actual application:
- Fetches the current configuration from the Dataplane API
- Parses both current and desired configurations
- Compares them to generate a list of planned operations
- Returns the diff without executing any operations
This is useful for:
- Previewing changes before applying them
- Validating configurations
- Understanding what would change
Parameters:
- ctx: Context for cancellation and timeout
- desiredConfig: The desired HAProxy configuration as a string
Returns:
- *DiffResult: Detailed information about planned changes
- error: Error if comparison fails
Example:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
diff, err := client.DryRun(ctx, desiredConfig)
if err != nil {
return fmt.Errorf("dry run failed: %w", err)
}
if diff.HasChanges {
fmt.Printf("Would apply %d operations:\n", len(diff.PlannedOperations))
for _, op := range diff.PlannedOperations {
fmt.Printf(" - %s %s %s\n", op.Type, op.Section, op.Resource)
}
}
func (*Client) Sync ¶
func (c *Client) Sync(ctx context.Context, desiredConfig string, auxFiles *AuxiliaryFiles, opts *SyncOptions) (*SyncResult, error)
Sync synchronizes the desired HAProxy configuration using this client.
This method:
- Fetches the current configuration from the Dataplane API
- Parses both current and desired configurations
- Compares them to generate fine-grained operations
- Executes operations with automatic retry on 409 version conflicts
- Falls back to raw config push on non-recoverable errors (if enabled)
- Returns detailed results including applied changes and reload information
Parameters:
- ctx: Context for cancellation and timeout
- desiredConfig: The desired HAProxy configuration as a string
- auxFiles: Auxiliary files to sync (use nil for defaults)
- opts: Sync options (use nil for defaults)
Returns:
- *SyncResult: Detailed information about the sync operation
- error: Detailed error with actionable hints if the sync fails
Example:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
result, err := client.Sync(ctx, desiredConfig, nil, nil)
if err != nil {
return fmt.Errorf("sync failed: %w", err)
}
fmt.Printf("Applied %d operations in %v\n", len(result.AppliedOperations), result.Duration)
type ConfigParser ¶
type ConfigParser interface {
ParseFromString(config string) (*parserconfig.StructuredConfig, error)
}
ConfigParser defines the interface for HAProxy configuration parsing. Both CE (parser.Parser) and EE (enterprise.Parser) parsers implement this interface.
type ConflictError ¶
type ConflictError struct {
// Retries is the number of retry attempts made
Retries int
// ExpectedVersion is the version we tried to use
ExpectedVersion int64
// ActualVersion is the version that exists on the server
ActualVersion string
}
ConflictError represents unresolved version conflicts after exhausting retries.
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
Error implements the error interface.
type ConnectionError ¶
type ConnectionError struct {
// Endpoint is the URL that failed to connect
Endpoint string
// Cause is the underlying connection error
Cause error
}
ConnectionError represents a failure to connect to the Dataplane API.
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
Error implements the error interface.
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
Unwrap returns the underlying cause for error unwrapping.
type DiffDetails ¶
type DiffDetails struct {
// Total operation counts
TotalOperations int
Creates int
Updates int
Deletes int
// Global and defaults changes
GlobalChanged bool
DefaultsChanged bool
// Frontend changes
FrontendsAdded []string
FrontendsModified []string
FrontendsDeleted []string
// Backend changes
BackendsAdded []string
BackendsModified []string
BackendsDeleted []string
// Server changes (map of backend -> server names)
ServersAdded map[string][]string
ServersModified map[string][]string
ServersDeleted map[string][]string
// ACL changes (map of parent resource -> ACL names)
ACLsAdded map[string][]string
ACLsModified map[string][]string
ACLsDeleted map[string][]string
// HTTP rule changes (map of parent resource -> count)
HTTPRulesAdded map[string]int
HTTPRulesModified map[string]int
HTTPRulesDeleted map[string]int
}
DiffDetails contains detailed diff information about configuration changes.
func NewDiffDetails ¶
func NewDiffDetails() DiffDetails
NewDiffDetails creates an empty DiffDetails with initialized maps.
func (*DiffDetails) String ¶
func (d *DiffDetails) String() string
String returns a human-readable summary of the diff details.
type DiffResult ¶
type DiffResult struct {
// HasChanges indicates whether any differences were detected
HasChanges bool
// PlannedOperations contains structured information about operations that would be executed
PlannedOperations []PlannedOperation
// Details contains detailed diff information
Details DiffDetails
}
DiffResult contains comparison results without applying changes.
func Diff ¶
Diff compares the current and desired configurations and returns detailed differences.
This is a convenience function that creates a client internally for one-off operations. This is an alias for DryRun. For production use with multiple operations, create a Client explicitly.
Parameters:
- ctx: Context for cancellation and timeout
- endpoint: Dataplane API connection information
- desiredConfig: The desired HAProxy configuration as a string
Returns:
- *DiffResult: Detailed information about differences
- error: Error if comparison fails
func DryRun ¶
DryRun previews what changes would be applied without actually applying them.
This is a convenience function that creates a client internally for one-off operations. For production use with multiple operations, create a Client explicitly.
Parameters:
- ctx: Context for cancellation and timeout
- endpoint: Dataplane API connection information
- desiredConfig: The desired HAProxy configuration as a string
Returns:
- *DiffResult: Detailed information about planned changes
- error: Error if comparison fails
func (*DiffResult) String ¶
func (r *DiffResult) String() string
String returns a human-readable summary of the diff result.
type Endpoint ¶
type Endpoint struct {
// URL is the Dataplane API endpoint (e.g., "http://haproxy:5555/v2")
URL string
// Username for basic authentication
Username string
// Password for basic authentication
Password string
// PodName is the Kubernetes pod name (for observability)
PodName string
// PodNamespace is the Kubernetes pod namespace (for observability)
PodNamespace string
// Version info (cached after discovery admission, avoids redundant /v3/info calls)
// Zero values indicate version not yet detected.
DetectedMajorVersion int // Major version (e.g., 3)
DetectedMinorVersion int // Minor version (e.g., 2)
DetectedFullVersion string // Full version string (e.g., "v3.2.6 87ad0bcf")
}
Endpoint represents HAProxy Dataplane API connection information.
func (*Endpoint) HasCachedVersion ¶
HasCachedVersion returns true if version info has been cached on this endpoint.
type FallbackError ¶
type FallbackError struct {
// OriginalError is the error that triggered the fallback
OriginalError error
// FallbackCause is the error that occurred during fallback
FallbackCause error
}
FallbackError represents a failure during raw config fallback.
func (*FallbackError) Error ¶
func (e *FallbackError) Error() string
Error implements the error interface.
func (*FallbackError) Unwrap ¶
func (e *FallbackError) Unwrap() error
Unwrap returns the fallback cause for error unwrapping.
type OperationError ¶
type OperationError struct {
// OperationType is "create", "update", or "delete"
OperationType string
// Section is the configuration section (e.g., "backend", "server")
Section string
// Resource is the resource identifier (e.g., backend name, server name)
Resource string
// Cause is the underlying error
Cause error
}
OperationError represents a failure of a specific configuration operation.
func (*OperationError) Error ¶
func (e *OperationError) Error() string
Error implements the error interface.
func (*OperationError) Unwrap ¶
func (e *OperationError) Unwrap() error
Unwrap returns the underlying cause for error unwrapping.
type ParseError ¶
type ParseError struct {
// ConfigType indicates which config failed: "current" or "desired"
ConfigType string
// ConfigSnippet contains the first 200 characters of the problematic config
ConfigSnippet string
// Line indicates the approximate line number where parsing failed (if available)
Line int
// Cause is the underlying parsing error
Cause error
}
ParseError represents a configuration parsing failure.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
Error implements the error interface.
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
Unwrap returns the underlying cause for error unwrapping.
type PathConfig ¶
type PathConfig struct {
// MapsDir is the base path for HAProxy map files (e.g., /etc/haproxy/maps).
MapsDir string
// SSLDir is the base path for HAProxy SSL certificates (e.g., /etc/haproxy/ssl).
SSLDir string
// GeneralDir is the base path for HAProxy general files (e.g., /etc/haproxy/general).
GeneralDir string
// ConfigFile is the path to the HAProxy configuration file (e.g., /tmp/haproxy.cfg).
// Only used in validation contexts; can be empty for production paths.
ConfigFile string
}
PathConfig contains the base directory configuration for HAProxy auxiliary files. These are the raw filesystem paths before capability-based resolution.
type PlannedOperation ¶
type PlannedOperation struct {
// Type is the operation type: "create", "update", or "delete"
Type string
// Section is the configuration section: "backend", "server", "frontend", "acl", "http-rule", etc.
Section string
// Resource is the resource name or identifier
Resource string
// Description is a human-readable description of what would be changed
Description string
// Priority indicates execution order (lower = earlier for creates, higher = earlier for deletes)
Priority int
}
PlannedOperation represents an operation that would be executed.
type ResolvedPaths ¶
type ResolvedPaths struct {
// MapsDir is the resolved path for HAProxy map files.
MapsDir string
// SSLDir is the resolved path for HAProxy SSL certificates.
SSLDir string
// CRTListDir is the resolved path for CRT-list files.
// When SupportsCrtList is true (HAProxy >= 3.2), this equals SSLDir.
// When SupportsCrtList is false (HAProxy < 3.2), this equals GeneralDir.
CRTListDir string
// GeneralDir is the resolved path for HAProxy general files.
GeneralDir string
// ConfigFile is the path to the HAProxy configuration file.
ConfigFile string
}
ResolvedPaths contains capability-aware resolved paths for HAProxy auxiliary files. This is the result of applying capability-based resolution to a PathConfig.
The key difference from PathConfig is that CRTListDir is computed based on HAProxy capabilities - it may fall back to GeneralDir if CRT-list storage is not supported (HAProxy < 3.2).
func ResolvePaths ¶
func ResolvePaths(base PathConfig, capabilities Capabilities) *ResolvedPaths
ResolvePaths applies capability-based path resolution to base paths. This is the SINGLE SOURCE OF TRUTH for all capability-dependent path logic.
Currently handles:
- CRT-list fallback: HAProxy < 3.2 doesn't support crt-list storage, so CRT-list files are stored in the general directory instead.
Future capability-dependent paths should be added here to ensure consistent resolution across all components.
func (*ResolvedPaths) ToValidationPaths ¶
func (r *ResolvedPaths) ToValidationPaths() *ValidationPaths
ToValidationPaths converts ResolvedPaths to ValidationPaths. Use this when you need ValidationPaths for HAProxy configuration validation.
type SyncError ¶
type SyncError struct {
// Stage indicates where the failure occurred:
// "connect", "fetch", "parse-current", "parse-desired", "compare", "apply", "commit", "fallback"
Stage string
// Message provides a detailed error description
Message string
// Cause is the underlying error that caused the failure
Cause error
// Hints provides actionable suggestions for fixing the problem
Hints []string
}
SyncError represents a synchronization failure with actionable context. It provides detailed information about what stage failed and suggestions for how to fix the problem.
func NewConflictError ¶
NewConflictError creates a ConflictError.
func NewConnectionError ¶
NewConnectionError creates a ConnectionError.
func NewFallbackError ¶
NewFallbackError creates a FallbackError.
func NewOperationError ¶
NewOperationError creates an OperationError.
func NewParseError ¶
NewParseError creates a ParseError.
func NewValidationError ¶
NewValidationError creates a ValidationError.
type SyncOptions ¶
type SyncOptions struct {
// MaxRetries for 409 version conflict errors (default: 3)
// These are always retried as they're recoverable errors.
MaxRetries int
// Timeout for the entire sync operation (default: 2 minutes)
Timeout time.Duration
// ContinueOnError continues applying operations even if some fail (default: false)
// When false, the first error stops execution.
ContinueOnError bool
// FallbackToRaw enables automatic fallback to raw config push on non-409 errors (default: true)
// When enabled, if fine-grained sync fails with non-recoverable errors,
// the library automatically falls back to pushing the complete raw configuration.
FallbackToRaw bool
// VerifyReload enables async reload verification after sync (default: true)
// When true, polls the reload status endpoint until succeeded/failed/timeout.
// Disable for dry-run or when reload verification is not needed.
VerifyReload bool
// ReloadVerificationTimeout is the maximum time to wait for reload verification (default: 10s)
// This should be set higher than the DataPlane API's reload-delay setting.
// Only used when VerifyReload is true.
ReloadVerificationTimeout time.Duration
}
SyncOptions configures synchronization behavior.
func DefaultSyncOptions ¶
func DefaultSyncOptions() *SyncOptions
DefaultSyncOptions returns sensible default sync options.
func DryRunOptions ¶
func DryRunOptions() *SyncOptions
DryRunOptions returns options configured for dry-run mode.
type SyncResult ¶
type SyncResult struct {
// Success indicates whether the sync completed successfully
Success bool
// AppliedOperations contains structured information about operations that were applied
AppliedOperations []AppliedOperation
// ReloadTriggered indicates whether a HAProxy reload was triggered
// true when commit status is 202, false when 200
ReloadTriggered bool
// ReloadID is the reload identifier from the Reload-ID response header
// Only set when ReloadTriggered is true
ReloadID string
// ReloadVerified indicates whether the reload was verified as successful.
// Only set when VerifyReload option is enabled and ReloadTriggered is true.
ReloadVerified bool
// ReloadVerificationError contains an error message if reload verification failed.
// This includes timeout errors or explicit reload failures from HAProxy.
ReloadVerificationError string
// FallbackToRaw indicates whether we had to fall back to raw config push
// This happens when fine-grained sync encounters non-recoverable errors
FallbackToRaw bool
// Duration of the sync operation
Duration time.Duration
// Retries indicates how many times operations were retried (for 409 conflicts)
Retries int
// Details contains detailed diff information
// This field is always populated, even when FallbackToRaw is true
Details DiffDetails
// Message provides additional context about the result
Message string
}
SyncResult contains detailed information about a sync operation.
func Sync ¶
func Sync(ctx context.Context, endpoint *Endpoint, desiredConfig string, auxFiles *AuxiliaryFiles, opts *SyncOptions) (*SyncResult, error)
Sync synchronizes the desired HAProxy configuration to the dataplane endpoint.
This is a convenience function that creates a client internally for one-off operations. For production use with multiple operations, create a Client explicitly to reuse connections:
client, err := dataplane.NewClient(ctx, endpoint)
if err != nil {
return err
}
defer client.Close()
result, err := client.Sync(ctx, desiredConfig, auxFiles, opts)
Parameters:
- ctx: Context for cancellation and timeout
- endpoint: Dataplane API connection information
- desiredConfig: The desired HAProxy configuration as a string
- auxFiles: Auxiliary files to sync (use nil for defaults)
- opts: Sync options (use nil for defaults)
Returns:
- *SyncResult: Detailed information about the sync operation
- error: Detailed error with actionable hints if the sync fails
func (*SyncResult) String ¶
func (r *SyncResult) String() string
String returns a human-readable summary of the sync result.
type ValidationError ¶
type ValidationError struct {
// Phase indicates which validation phase failed: "syntax" or "semantic"
Phase string
// Message is the validation error message
Message string
// Cause is the underlying error
Cause error
}
ValidationError represents semantic validation failure from HAProxy.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap returns the underlying error for error unwrapping.
type ValidationPaths ¶
type ValidationPaths struct {
MapsDir string
SSLCertsDir string
CRTListDir string // Directory for CRT-list files (may differ from SSLCertsDir on HAProxy < 3.2)
GeneralStorageDir string
ConfigFile string
}
ValidationPaths holds the filesystem paths for HAProxy validation. These paths must match the HAProxy Dataplane API server's resource configuration.
type Version ¶
Version represents HAProxy or DataPlane API version with major.minor components. Only major and minor are used for compatibility comparison.
func DetectLocalVersion ¶
DetectLocalVersion runs "haproxy -v" and returns the local HAProxy version. Returns an error if haproxy is not found or version cannot be parsed.
func ParseHAProxyVersionOutput ¶
ParseHAProxyVersionOutput parses the output of "haproxy -v" command. Expected format: "HAProxy version 3.2.9 2025/11/21 - https://haproxy.org/\n..." Returns extracted major.minor version.
func VersionFromAPIInfo ¶
func VersionFromAPIInfo(info *client.VersionInfo) (*Version, error)
VersionFromAPIInfo converts client.VersionInfo (from /v3/info) to Version. The API version string format is "vX.Y.Z commit" (e.g., "v3.2.6 87ad0bcf").
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package auxiliaryfiles provides functionality for synchronizing auxiliary files (general files, SSL certificates, map files, crt-lists) with the HAProxy Dataplane API.
|
Package auxiliaryfiles provides functionality for synchronizing auxiliary files (general files, SSL certificates, map files, crt-lists) with the HAProxy Dataplane API. |
|
Package client provides a high-level wrapper around the generated HAProxy Dataplane API client.
|
Package client provides a high-level wrapper around the generated HAProxy Dataplane API client. |
|
enterprise
Package enterprise provides client operations for HAProxy Enterprise-only DataPlane API endpoints.
|
Package enterprise provides client operations for HAProxy Enterprise-only DataPlane API endpoints. |
|
Package comparator provides comparison functions for HAProxy Enterprise Edition sections.
|
Package comparator provides comparison functions for HAProxy Enterprise Edition sections. |
|
sections
Package sections provides factory functions for creating HAProxy configuration operations.
|
Package sections provides factory functions for creating HAProxy configuration operations. |
|
sections/executors
Package executors provides pre-built executor functions for HAProxy configuration operations.
|
Package executors provides pre-built executor functions for HAProxy configuration operations. |
|
Package parser provides HAProxy configuration parsing using client-native library.
|
Package parser provides HAProxy configuration parsing using client-native library. |
|
enterprise
Package enterprise provides HAProxy Enterprise Edition configuration parsing.
|
Package enterprise provides HAProxy Enterprise Edition configuration parsing. |
|
enterprise/directives
Package types provides parser implementations for HAProxy Enterprise Edition section-specific directives.
|
Package types provides parser implementations for HAProxy Enterprise Edition section-specific directives. |
|
enterprise/parsers
Package parsers provides wrapper parsers for HAProxy Enterprise Edition directives.
|
Package parsers provides wrapper parsers for HAProxy Enterprise Edition directives. |
|
parserconfig
Package parserconfig provides canonical configuration types for HAProxy parsing.
|
Package parserconfig provides canonical configuration types for HAProxy parsing. |
|
Package synchronizer provides configuration synchronization between desired state and HAProxy via the Dataplane API.
|
Package synchronizer provides configuration synchronization between desired state and HAProxy via the Dataplane API. |