events

package
v0.1.0-alpha.9 Latest Latest
Warning

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

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

README

pkg/controller/events

Domain-specific event type definitions for controller coordination.

Overview

This package defines all event types used by the controller for component coordination via the EventBus. Events represent facts about what happened in the system and are immutable after creation.

Separation:

  • pkg/events - Generic pub/sub infrastructure
  • pkg/controller/events - Domain event types (this package)

Installation

import "haptic/pkg/controller/events"

Event Categories

Lifecycle Events
const (
    EventTypeControllerStarted  = "controller.started"
    EventTypeControllerShutdown = "controller.shutdown"
)
  • ControllerStartedEvent - Controller initialization complete
  • ControllerShutdownEvent - Controller shutting down
Configuration Events
const (
    EventTypeConfigParsed             = "config.parsed"
    EventTypeConfigValidationRequest  = "config.validation.request"
    EventTypeConfigValidationResponse = "config.validation.response"
    EventTypeConfigValidated          = "config.validated"
    EventTypeConfigInvalid            = "config.invalid"
)
  • ConfigParsedEvent - ConfigMap parsed successfully
  • ConfigValidationRequest - Scatter-gather validation request
  • ConfigValidationResponse - Validator response
  • ConfigValidatedEvent - All validators passed
  • ConfigInvalidEvent - Validation failed
Resource Events
const (
    EventTypeResourceIndexUpdated = "resource.index.updated"
    EventTypeResourceSyncComplete = "resource.sync.complete"
    EventTypeIndexSynchronized    = "index.synchronized"
)
  • ResourceIndexUpdatedEvent - Resource index changed (add/update/delete)
  • ResourceSyncCompleteEvent - Single resource type synced
  • IndexSynchronizedEvent - All resource types synced
Reconciliation Events
const (
    EventTypeReconciliationTriggered = "reconciliation.triggered"
    EventTypeReconciliationStarted   = "reconciliation.started"
    EventTypeReconciliationCompleted = "reconciliation.completed"
    EventTypeReconciliationFailed    = "reconciliation.failed"
)
  • ReconciliationTriggeredEvent - Reconciliation requested
  • ReconciliationStartedEvent - Reconciliation cycle started
  • ReconciliationCompletedEvent - Reconciliation succeeded
  • ReconciliationFailedEvent - Reconciliation failed
Template Events
const (
    EventTypeTemplateRendered     = "template.rendered"
    EventTypeTemplateRenderFailed = "template.render.failed"
)
  • TemplateRenderedEvent - Template rendering succeeded
  • TemplateRenderFailedEvent - Template rendering failed
Validation Events
const (
    EventTypeValidationStarted   = "validation.started"
    EventTypeValidationCompleted = "validation.completed"
    EventTypeValidationFailed    = "validation.failed"
)
  • ValidationStartedEvent - HAProxy config validation started
  • ValidationCompletedEvent - Validation succeeded
  • ValidationFailedEvent - Validation failed
Deployment Events
const (
    EventTypeDeploymentStarted        = "deployment.started"
    EventTypeInstanceDeployed         = "instance.deployed"
    EventTypeInstanceDeploymentFailed = "instance.deployment.failed"
    EventTypeDeploymentCompleted      = "deployment.completed"
)
  • DeploymentStartedEvent - Deployment to HAProxy pods started
  • InstanceDeployedEvent - Single HAProxy instance deployed
  • InstanceDeploymentFailedEvent - Single instance deployment failed
  • DeploymentCompletedEvent - All instances deployed
HAProxy Pod Events
const (
    EventTypeHAProxyPodsDiscovered = "haproxy.pods.discovered"
    EventTypeHAProxyPodAdded       = "haproxy.pod.added"
    EventTypeHAProxyPodRemoved     = "haproxy.pod.removed"
)
  • HAProxyPodsDiscoveredEvent - HAProxy pods discovered
  • HAProxyPodAddedEvent - New HAProxy pod added
  • HAProxyPodRemovedEvent - HAProxy pod removed

Usage

Publishing Events
import "haptic/pkg/controller/events"

// Create event using constructor (performs defensive copying)
event := events.NewConfigParsedEvent(config, "v1")

// Publish to EventBus
eventBus.Publish(event)
Consuming Events
// Subscribe to EventBus
eventChan := eventBus.Subscribe(100)

for event := range eventChan {
    // Type assertion to specific event
    if parsed, ok := event.(*events.ConfigParsedEvent); ok {
        fmt.Printf("Config version: %s\n", parsed.Version)
        // Process config...
    }
}
Scatter-Gather Pattern
// Create validation request
req := events.NewConfigValidationRequest(config, "v1")

// Send scatter-gather request
result, err := eventBus.Request(ctx, req, events.RequestOptions{
    Timeout:            10 * time.Second,
    ExpectedResponders: []string{"basic", "template", "jsonpath"},
})

if err != nil {
    // Timeout or error
}

// Process responses
for _, resp := range result.Responses {
    if valResp, ok := resp.(*events.ConfigValidationResponse); ok {
        if !valResp.Valid {
            fmt.Printf("Validator %s failed: %v\n", valResp.Validator, valResp.Errors)
        }
    }
}

Event Immutability

Events are immutable after creation to ensure consistency across consumers.

Constructors Perform Defensive Copying
func NewResourceIndexUpdatedEvent(resourceType string, changes []types.ResourceChange) *ResourceIndexUpdatedEvent {
    // Copy slice to prevent external mutations
    changesCopy := make([]types.ResourceChange, len(changes))
    copy(changesCopy, changes)

    return &ResourceIndexUpdatedEvent{
        ResourceType: resourceType,
        Changes:      changesCopy,
    }
}
Consumers Must Not Modify Events
// Good - read-only access
event := <-eventChan
if update, ok := event.(*events.ResourceIndexUpdatedEvent); ok {
    for _, change := range update.Changes {
        processChange(change)  // Read only
    }
}

// Bad - DO NOT MODIFY
if update, ok := event.(*events.ResourceIndexUpdatedEvent); ok {
    update.Changes = append(update.Changes, newChange)  // FORBIDDEN!
}

Adding New Event Types

  1. Define event struct with exported fields
  2. Add EventType constant
  3. Implement EventType() method with pointer receiver
  4. Create constructor with defensive copying
  5. Update commentator to log the event

Example:

// 1. Define struct
type MyNewEvent struct {
    Field string
    Data  []string
}

// 2. Add constant
const EventTypeMyNew = "my.new"

// 3. Implement EventType()
func (e *MyNewEvent) EventType() string {
    return EventTypeMyNew
}

// 4. Create constructor
func NewMyNewEvent(field string, data []string) *MyNewEvent {
    dataCopy := make([]string, len(data))
    copy(dataCopy, data)

    return &MyNewEvent{
        Field: field,
        Data:  dataCopy,
    }
}

Common Event Fields

Most events include:

  • Timestamp - When the event occurred
  • Version - Resource version (for ConfigMap/Secret events)
  • Errors - Error messages (for failure events)

Examples

See:

  • Event publishing: pkg/controller/configloader/
  • Event consumption: pkg/controller/reconciler/
  • Scatter-gather: pkg/controller/validator/coordinator.go
  • Event logging: pkg/controller/commentator/

License

See main repository for license information.

Documentation

Overview

Package events contains all domain event type definitions for the HAPTIC controller.

Event Immutability Contract

Events in this system are intended to be immutable after creation. They represent historical facts about what happened in the system and should not be modified after being published to the EventBus.

To support this immutability contract:

  1. All event types use pointer receivers for their Event interface methods. This avoids copying large structs (200+ bytes) and follows Go best practices.

  2. All event fields are exported to support JSON serialization and idiomatic Go access. This follows industry standards (Kubernetes, NATS) rather than enforcing immutability through unexported fields and getters.

  3. Constructors perform defensive copying of slices and maps to prevent mutations from affecting the published event. Publishers cannot modify events after creation.

  4. Consumers MUST NOT modify event fields. This immutability contract is enforced through: - A custom static analyzer (tools/linters/eventimmutability) that detects parameter mutations - Code review for cases not caught by the analyzer - Team discipline and documentation

This approach balances performance, Go idioms, and practical immutability for an internal project where all consumers are controlled.

Event Categories

Events are organized into separate files by category:

  • lifecycle.go: System startup and shutdown events
  • config.go: ConfigMap/Secret changes and validation events
  • resource.go: Kubernetes resource indexing and synchronization events
  • reconciliation.go: Template rendering and deployment cycle events
  • template.go: Template rendering operation events
  • validation.go: Configuration validation (syntax and semantics) events
  • deployment.go: HAProxy configuration deployment events
  • storage.go: Auxiliary file synchronization events
  • discovery.go: HAProxy pod discovery events
  • credentials.go: Credentials loading and validation events
  • leader.go: Leader election events
  • publishing.go: Config publishing events (including SyncMetadata types)
  • certificate.go: Webhook certificate events
  • webhookobservability.go: Webhook validation observability events
  • http.go: HTTP resource events
  • webhook.go: Scatter-gather request/response events for webhook validation

Index

Constants

View Source
const (
	// Lifecycle event types.
	EventTypeControllerStarted  = "controller.started"
	EventTypeControllerShutdown = "controller.shutdown"

	// Configuration event types.
	EventTypeConfigParsed             = "config.parsed"
	EventTypeConfigValidationRequest  = "config.validation.request"
	EventTypeConfigValidationResponse = "config.validation.response"
	EventTypeConfigValidated          = "config.validated"
	EventTypeConfigInvalid            = "config.invalid"
	EventTypeConfigResourceChanged    = "config.resource.changed"

	// Resource event types.
	EventTypeResourceIndexUpdated = "resource.index.updated"
	EventTypeResourceSyncComplete = "resource.sync.complete"
	EventTypeIndexSynchronized    = "index.synchronized"

	// Reconciliation event types.
	EventTypeReconciliationTriggered = "reconciliation.triggered"
	EventTypeReconciliationStarted   = "reconciliation.started"
	EventTypeReconciliationCompleted = "reconciliation.completed"
	EventTypeReconciliationFailed    = "reconciliation.failed"

	// Template event types.
	EventTypeTemplateRendered     = "template.rendered"
	EventTypeTemplateRenderFailed = "template.render.failed"

	// Validation event types (HAProxy dataplane API validation).
	EventTypeValidationStarted   = "validation.started"
	EventTypeValidationCompleted = "validation.completed"
	EventTypeValidationFailed    = "validation.failed"

	// Validation test event types (embedded validation tests).
	EventTypeValidationTestsStarted   = "validation_tests.started"
	EventTypeValidationTestsCompleted = "validation_tests.completed"
	EventTypeValidationTestsFailed    = "validation_tests.failed"

	// Deployment event types.
	EventTypeDeploymentScheduled      = "deployment.scheduled"
	EventTypeDeploymentStarted        = "deployment.started"
	EventTypeInstanceDeployed         = "instance.deployed"
	EventTypeInstanceDeploymentFailed = "instance.deployment.failed"
	EventTypeDeploymentCompleted      = "deployment.completed"
	EventTypeDriftPreventionTriggered = "drift.prevention.triggered"

	// Storage event types.
	EventTypeStorageSyncStarted   = "storage.sync.started"
	EventTypeStorageSyncCompleted = "storage.sync.completed"
	EventTypeStorageSyncFailed    = "storage.sync.failed"

	// HAProxy pod event types.
	EventTypeHAProxyPodsDiscovered = "haproxy.pods.discovered"
	EventTypeHAProxyPodAdded       = "haproxy.pod.added"
	EventTypeHAProxyPodRemoved     = "haproxy.pod.removed"
	EventTypeHAProxyPodTerminated  = "haproxy.pod.terminated"

	// Config publishing event types.
	EventTypeConfigPublished     = "config.published"
	EventTypeConfigPublishFailed = "config.publish.failed"
	EventTypeConfigAppliedToPod  = "config.applied.to.pod"

	// Credentials event types.
	EventTypeSecretResourceChanged = "secret.resource.changed"
	EventTypeCredentialsUpdated    = "credentials.updated"
	EventTypeCredentialsInvalid    = "credentials.invalid"

	// Webhook certificate event types.
	EventTypeCertResourceChanged = "cert.resource.changed"
	EventTypeCertParsed          = "cert.parsed"

	// Webhook validation event types (observability only).
	// Note: Scatter-gather request/response events are in webhook.go.
	EventTypeWebhookValidationRequest = "webhook.validation.request"
	EventTypeWebhookValidationAllowed = "webhook.validation.allowed"
	EventTypeWebhookValidationDenied  = "webhook.validation.denied"
	EventTypeWebhookValidationError   = "webhook.validation.error"

	// Leader election event types.
	EventTypeLeaderElectionStarted = "leader.election.started"
	EventTypeBecameLeader          = "leader.became"
	EventTypeLostLeadership        = "leader.lost"
	EventTypeNewLeaderObserved     = "leader.observed"

	// HTTP resource event types.
	EventTypeHTTPResourceUpdated  = "http.resource.updated"
	EventTypeHTTPResourceAccepted = "http.resource.accepted"
	EventTypeHTTPResourceRejected = "http.resource.rejected"
)
View Source
const (
	EventTypeWebhookValidationRequestSG  = "webhook.validation.request.sg"  // Scatter-gather request
	EventTypeWebhookValidationResponseSG = "webhook.validation.response.sg" // Scatter-gather response
)

Webhook scatter-gather event type constants. Note: Other webhook events (lifecycle, observability) are defined in types.go.

Variables

This section is empty.

Functions

This section is empty.

Types

type BecameLeaderEvent

type BecameLeaderEvent struct {
	Identity string
	// contains filtered or unexported fields
}

BecameLeaderEvent is published when this replica becomes the leader.

func NewBecameLeaderEvent

func NewBecameLeaderEvent(identity string) *BecameLeaderEvent

NewBecameLeaderEvent creates a new BecameLeaderEvent.

func (*BecameLeaderEvent) EventType

func (e *BecameLeaderEvent) EventType() string

func (*BecameLeaderEvent) Timestamp

func (e *BecameLeaderEvent) Timestamp() time.Time

type CertParsedEvent

type CertParsedEvent struct {
	CertPEM []byte
	KeyPEM  []byte
	Version string // Secret resourceVersion
	// contains filtered or unexported fields
}

CertParsedEvent is published when webhook certificates are successfully extracted and parsed.

The controller will use these certificates to initialize the webhook server.

func NewCertParsedEvent

func NewCertParsedEvent(certPEM, keyPEM []byte, version string) *CertParsedEvent

NewCertParsedEvent creates a new CertParsedEvent.

func (*CertParsedEvent) EventType

func (e *CertParsedEvent) EventType() string

func (*CertParsedEvent) Timestamp

func (e *CertParsedEvent) Timestamp() time.Time

type CertResourceChangedEvent

type CertResourceChangedEvent struct {
	Resource interface{} // *unstructured.Unstructured
	// contains filtered or unexported fields
}

CertResourceChangedEvent is published when the webhook certificate Secret changes.

This event is published by the resource watcher when the Secret resource is created, updated, or modified.

func NewCertResourceChangedEvent

func NewCertResourceChangedEvent(resource interface{}) *CertResourceChangedEvent

NewCertResourceChangedEvent creates a new CertResourceChangedEvent.

func (*CertResourceChangedEvent) EventType

func (e *CertResourceChangedEvent) EventType() string

func (*CertResourceChangedEvent) Timestamp

func (e *CertResourceChangedEvent) Timestamp() time.Time

type ConfigAppliedToPodEvent

type ConfigAppliedToPodEvent struct {
	RuntimeConfigName      string
	RuntimeConfigNamespace string
	PodName                string
	PodNamespace           string
	Checksum               string

	// IsDriftCheck indicates whether this was a drift prevention check (GET-only)
	// or an actual sync operation (POST/PUT/DELETE).
	//
	// True:  Drift check - no actual changes were made, just verified config is current
	// False: Actual sync - configuration was written to HAProxy
	IsDriftCheck bool

	// SyncMetadata contains detailed information about the sync operation.
	// Only populated for actual syncs (IsDriftCheck=false).
	SyncMetadata *SyncMetadata
	// contains filtered or unexported fields
}

ConfigAppliedToPodEvent is published after configuration is successfully applied to an HAProxy pod.

This triggers updating the deployment status in runtime config resources.

func NewConfigAppliedToPodEvent

func NewConfigAppliedToPodEvent(runtimeConfigName, runtimeConfigNamespace, podName, podNamespace, checksum string, isDriftCheck bool, syncMetadata *SyncMetadata) *ConfigAppliedToPodEvent

NewConfigAppliedToPodEvent creates a new ConfigAppliedToPodEvent.

func (*ConfigAppliedToPodEvent) EventType

func (e *ConfigAppliedToPodEvent) EventType() string

func (*ConfigAppliedToPodEvent) Timestamp

func (e *ConfigAppliedToPodEvent) Timestamp() time.Time

type ConfigInvalidEvent

type ConfigInvalidEvent struct {
	Version string

	// TemplateConfig is the original HAProxyTemplateConfig CRD.
	// Type: interface{} to avoid circular dependencies.
	// Used by status updater to set validation errors on the CRD status.
	TemplateConfig interface{}

	// ValidationErrors maps validator names to their error messages.
	ValidationErrors map[string][]string
	// contains filtered or unexported fields
}

ConfigInvalidEvent is published when config validation fails.

The controller will continue running with the previous valid config and wait. for the next ConfigMap update.

func NewConfigInvalidEvent

func NewConfigInvalidEvent(version string, templateConfig interface{}, validationErrors map[string][]string) *ConfigInvalidEvent

NewConfigInvalidEvent creates a new ConfigInvalidEvent. Performs defensive copy of the validation errors map and its slice values.

func (*ConfigInvalidEvent) EventType

func (e *ConfigInvalidEvent) EventType() string

func (*ConfigInvalidEvent) Timestamp

func (e *ConfigInvalidEvent) Timestamp() time.Time

type ConfigParsedEvent

type ConfigParsedEvent struct {
	// Config contains the parsed configuration.
	// Type: interface{} to avoid circular dependencies.
	// Consumers should type-assert to their expected config type.
	Config interface{}

	// TemplateConfig is the original HAProxyTemplateConfig CRD.
	// Type: interface{} to avoid circular dependencies.
	// Needed by ConfigPublisher to extract Kubernetes metadata (name, namespace, UID).
	TemplateConfig interface{}

	// Version is the resourceVersion of the ConfigMap.
	Version string

	// SecretVersion is the resourceVersion of the credentials Secret.
	SecretVersion string
	// contains filtered or unexported fields
}

ConfigParsedEvent is published when the configuration ConfigMap/Secret has been. successfully parsed into a Config structure.

This event does not mean the config is valid - only that it could be parsed. Validation occurs in a subsequent step.

func NewConfigParsedEvent

func NewConfigParsedEvent(config, templateConfig interface{}, version, secretVersion string) *ConfigParsedEvent

NewConfigParsedEvent creates a new ConfigParsedEvent.

func (*ConfigParsedEvent) EventType

func (e *ConfigParsedEvent) EventType() string

func (*ConfigParsedEvent) Timestamp

func (e *ConfigParsedEvent) Timestamp() time.Time

type ConfigPublishFailedEvent

type ConfigPublishFailedEvent struct {
	Error string
	// contains filtered or unexported fields
}

ConfigPublishFailedEvent is published when runtime configuration publishing fails.

This is logged but does not affect controller operation.

func NewConfigPublishFailedEvent

func NewConfigPublishFailedEvent(err error) *ConfigPublishFailedEvent

NewConfigPublishFailedEvent creates a new ConfigPublishFailedEvent.

func (*ConfigPublishFailedEvent) EventType

func (e *ConfigPublishFailedEvent) EventType() string

func (*ConfigPublishFailedEvent) Timestamp

func (e *ConfigPublishFailedEvent) Timestamp() time.Time

type ConfigPublishedEvent

type ConfigPublishedEvent struct {
	RuntimeConfigName      string
	RuntimeConfigNamespace string
	MapFileCount           int
	SecretCount            int
	// contains filtered or unexported fields
}

ConfigPublishedEvent is published after runtime configuration resources are created/updated.

This is a non-critical event - publishing failures do not affect controller operation.

func NewConfigPublishedEvent

func NewConfigPublishedEvent(runtimeConfigName, runtimeConfigNamespace string, mapFileCount, secretCount int) *ConfigPublishedEvent

NewConfigPublishedEvent creates a new ConfigPublishedEvent.

func (*ConfigPublishedEvent) EventType

func (e *ConfigPublishedEvent) EventType() string

func (*ConfigPublishedEvent) Timestamp

func (e *ConfigPublishedEvent) Timestamp() time.Time

type ConfigResourceChangedEvent

type ConfigResourceChangedEvent struct {
	// Resource contains the raw ConfigMap resource.
	// Type: interface{} to avoid circular dependencies.
	// Consumers should type-assert to *unstructured.Unstructured or *corev1.ConfigMap.
	Resource interface{}
	// contains filtered or unexported fields
}

ConfigResourceChangedEvent is published when the ConfigMap resource is added, updated, or deleted.

This is a low-level event published directly by the SingleWatcher callback in the controller package. The ConfigLoaderComponent subscribes to this event and handles parsing.

func NewConfigResourceChangedEvent

func NewConfigResourceChangedEvent(resource interface{}) *ConfigResourceChangedEvent

NewConfigResourceChangedEvent creates a new ConfigResourceChangedEvent.

func (*ConfigResourceChangedEvent) EventType

func (e *ConfigResourceChangedEvent) EventType() string

func (*ConfigResourceChangedEvent) Timestamp

func (e *ConfigResourceChangedEvent) Timestamp() time.Time

type ConfigValidatedEvent

type ConfigValidatedEvent struct {
	Config interface{}

	// TemplateConfig is the original HAProxyTemplateConfig CRD.
	// Type: interface{} to avoid circular dependencies.
	// Needed by ConfigPublisher to extract Kubernetes metadata (name, namespace, UID).
	TemplateConfig interface{}

	Version       string
	SecretVersion string
	// contains filtered or unexported fields
}

ConfigValidatedEvent is published when all validators have confirmed the config is valid.

After receiving this event, the controller proceeds to start resource watchers. with the validated configuration.

func NewConfigValidatedEvent

func NewConfigValidatedEvent(config, templateConfig interface{}, version, secretVersion string) *ConfigValidatedEvent

NewConfigValidatedEvent creates a new ConfigValidatedEvent.

func (*ConfigValidatedEvent) EventType

func (e *ConfigValidatedEvent) EventType() string

func (*ConfigValidatedEvent) Timestamp

func (e *ConfigValidatedEvent) Timestamp() time.Time

type ConfigValidationRequest

type ConfigValidationRequest struct {

	// Config contains the configuration to validate.
	Config interface{}

	// Version is the resourceVersion being validated.
	Version string
	// contains filtered or unexported fields
}

ConfigValidationRequest is published to request validation of a parsed config.

This is a Request event used in the scatter-gather pattern. Multiple validators (basic, template, jsonpath) will respond with ConfigValidationResponse events.

func NewConfigValidationRequest

func NewConfigValidationRequest(config interface{}, version string) *ConfigValidationRequest

NewConfigValidationRequest creates a new ConfigValidationRequest.

func (*ConfigValidationRequest) EventType

func (e *ConfigValidationRequest) EventType() string

func (*ConfigValidationRequest) RequestID

func (e *ConfigValidationRequest) RequestID() string

func (*ConfigValidationRequest) Timestamp

func (e *ConfigValidationRequest) Timestamp() time.Time

type ConfigValidationResponse

type ConfigValidationResponse struct {

	// ValidatorName identifies which validator produced this response (basic, template, jsonpath).
	ValidatorName string

	// Valid is true if this validator found no errors.
	Valid bool

	// Errors contains validation error messages, empty if Valid is true.
	Errors []string
	// contains filtered or unexported fields
}

ConfigValidationResponse is sent by validators in response to ConfigValidationRequest.

This is a Response event used in the scatter-gather pattern. The ValidationCoordinator collects all responses and determines if the config is valid overall.

func NewConfigValidationResponse

func NewConfigValidationResponse(requestID, validatorName string, valid bool, errors []string) *ConfigValidationResponse

NewConfigValidationResponse creates a new ConfigValidationResponse. Performs defensive copy of the errors slice.

func (*ConfigValidationResponse) EventType

func (e *ConfigValidationResponse) EventType() string

func (*ConfigValidationResponse) RequestID

func (e *ConfigValidationResponse) RequestID() string

func (*ConfigValidationResponse) Responder

func (e *ConfigValidationResponse) Responder() string

func (*ConfigValidationResponse) Timestamp

func (e *ConfigValidationResponse) Timestamp() time.Time

type ControllerShutdownEvent

type ControllerShutdownEvent struct {
	Reason string
	// contains filtered or unexported fields
}

ControllerShutdownEvent is published when the controller is shutting down gracefully.

func NewControllerShutdownEvent

func NewControllerShutdownEvent(reason string) *ControllerShutdownEvent

NewControllerShutdownEvent creates a new ControllerShutdownEvent.

func (*ControllerShutdownEvent) EventType

func (e *ControllerShutdownEvent) EventType() string

func (*ControllerShutdownEvent) Timestamp

func (e *ControllerShutdownEvent) Timestamp() time.Time

type ControllerStartedEvent

type ControllerStartedEvent struct {
	ConfigVersion string
	SecretVersion string
	// contains filtered or unexported fields
}

ControllerStartedEvent is published when the controller has completed startup. and all components are ready to process events.

func NewControllerStartedEvent

func NewControllerStartedEvent(configVersion, secretVersion string) *ControllerStartedEvent

NewControllerStartedEvent creates a new ControllerStartedEvent.

func (*ControllerStartedEvent) EventType

func (e *ControllerStartedEvent) EventType() string

func (*ControllerStartedEvent) Timestamp

func (e *ControllerStartedEvent) Timestamp() time.Time

type CorrelatedEvent

type CorrelatedEvent interface {
	// EventID returns a unique identifier for this specific event.
	// Each event instance has its own unique EventID.
	// This is used as the CausationID for downstream events.
	EventID() string

	// CorrelationID returns a unique identifier that links related events.
	// All events in the same reconciliation cycle share the same correlation ID.
	// Returns empty string if correlation is not set.
	CorrelationID() string

	// CausationID returns the EventID of the event that triggered this one.
	// This enables building causal chains for debugging.
	// Returns empty string if causation is not set.
	CausationID() string
}

CorrelatedEvent is an interface for events that support correlation tracking.

Events that implement this interface can be linked together to trace causal chains through the reconciliation pipeline. This enables:

  • Querying all events for a specific reconciliation cycle
  • Building event graphs for debugging
  • Measuring end-to-end latency for pipelines
  • OpenTelemetry integration

Not all events need to implement this interface. It's optional and primarily useful for events in the reconciliation pipeline.

type Correlation

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

Correlation holds event ID, correlation ID, and causation ID for event tracing.

This struct is embedded in event types that need correlation support. It's designed to be optional - events can work without correlation, and consumers can check for empty IDs.

The IDs serve different purposes:

  • eventID: Unique identifier for THIS specific event instance
  • correlationID: Shared ID linking all events in a reconciliation cycle
  • causationID: The eventID of the event that triggered this one

func NewCorrelation

func NewCorrelation(opts ...CorrelationOption) Correlation

NewCorrelation creates a Correlation struct from the provided options. This factory always generates a unique eventID for the event.

This function only mutates a local variable (which is allowed), ensuring events are fully initialized in their struct literals.

func (*Correlation) CausationID

func (c *Correlation) CausationID() string

CausationID returns the causation ID, or empty string if not set.

func (*Correlation) CorrelationID

func (c *Correlation) CorrelationID() string

CorrelationID returns the correlation ID, or empty string if not set.

func (*Correlation) EventID

func (c *Correlation) EventID() string

EventID returns the unique identifier for this specific event.

type CorrelationOption

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

CorrelationOption holds data for setting correlation on events. This is a data struct rather than a closure to ensure events are fully initialized in their struct literals without post-creation mutation.

func PropagateCorrelation

func PropagateCorrelation(source interface{}) CorrelationOption

PropagateCorrelation extracts correlation context from a source event and returns a CorrelationOption that can be applied to a new event. If the source event doesn't implement CorrelatedEvent, returns an empty option.

The correlation ID is copied from the source event (maintaining pipeline identity). The causation ID is set to the source event's EventID (creating causal chain).

Example:

func handleEvent(sourceEvent Event) {
    newEvent := events.NewTemplateRenderedEvent(...,
        events.PropagateCorrelation(sourceEvent))
}

func WithCorrelation

func WithCorrelation(correlationID, causationID string) CorrelationOption

WithCorrelation sets both correlation and causation IDs on an event. Use this when propagating correlation context from a triggering event.

Example:

triggeredEvent := events.NewReconciliationTriggeredEvent("config_change")
renderedEvent := events.NewTemplateRenderedEvent(...,
    events.WithCorrelation(triggeredEvent.CorrelationID(), triggeredEvent.EventID()))

func WithNewCorrelation

func WithNewCorrelation() CorrelationOption

WithNewCorrelation generates a new correlation ID and sets it on an event. Use this at the start of a new pipeline (e.g., ReconciliationTriggeredEvent).

Example:

event := events.NewReconciliationTriggeredEvent("config_change",
    events.WithNewCorrelation())

type CredentialsInvalidEvent

type CredentialsInvalidEvent struct {
	SecretVersion string
	Error         string
	// contains filtered or unexported fields
}

CredentialsInvalidEvent is published when credential loading or validation fails.

The controller will continue running with the previous valid credentials and wait. for the next Secret update.

func NewCredentialsInvalidEvent

func NewCredentialsInvalidEvent(secretVersion, errMsg string) *CredentialsInvalidEvent

NewCredentialsInvalidEvent creates a new CredentialsInvalidEvent.

func (*CredentialsInvalidEvent) EventType

func (e *CredentialsInvalidEvent) EventType() string

func (*CredentialsInvalidEvent) Timestamp

func (e *CredentialsInvalidEvent) Timestamp() time.Time

type CredentialsUpdatedEvent

type CredentialsUpdatedEvent struct {
	// Credentials contains the validated credentials.
	// Type: interface{} to avoid circular dependencies.
	// Consumers should type-assert to their expected credentials type.
	Credentials interface{}

	// SecretVersion is the resourceVersion of the Secret.
	SecretVersion string
	// contains filtered or unexported fields
}

CredentialsUpdatedEvent is published when credentials have been successfully. loaded and validated from the Secret.

func NewCredentialsUpdatedEvent

func NewCredentialsUpdatedEvent(credentials interface{}, secretVersion string) *CredentialsUpdatedEvent

NewCredentialsUpdatedEvent creates a new CredentialsUpdatedEvent.

func (*CredentialsUpdatedEvent) EventType

func (e *CredentialsUpdatedEvent) EventType() string

func (*CredentialsUpdatedEvent) Timestamp

func (e *CredentialsUpdatedEvent) Timestamp() time.Time

type DeploymentCompletedEvent

type DeploymentCompletedEvent struct {
	Total              int   // Total number of instances
	Succeeded          int   // Number of successful deployments
	Failed             int   // Number of failed deployments
	DurationMs         int64 // Total deployment duration in milliseconds
	ReloadsTriggered   int   // Count of instances that triggered HAProxy reload
	TotalAPIOperations int   // Sum of API operations across all instances

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

DeploymentCompletedEvent is published when deployment to all HAProxy instances completes.

This event propagates the correlation ID from DeploymentStartedEvent.

func NewDeploymentCompletedEvent

func NewDeploymentCompletedEvent(result DeploymentResult, opts ...CorrelationOption) *DeploymentCompletedEvent

NewDeploymentCompletedEvent creates a new DeploymentCompletedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewDeploymentCompletedEvent(events.DeploymentResult{
    Total:              len(endpoints),
    Succeeded:          successCount,
    Failed:             failureCount,
    DurationMs:         totalDurationMs,
    ReloadsTriggered:   reloads,
    TotalAPIOperations: ops,
}, events.PropagateCorrelation(startedEvent))

func (*DeploymentCompletedEvent) EventType

func (e *DeploymentCompletedEvent) EventType() string

func (*DeploymentCompletedEvent) Timestamp

func (e *DeploymentCompletedEvent) Timestamp() time.Time

type DeploymentResult

type DeploymentResult struct {
	Total              int   // Total number of instances
	Succeeded          int   // Number of successful deployments
	Failed             int   // Number of failed deployments
	DurationMs         int64 // Total deployment duration in milliseconds
	ReloadsTriggered   int   // Count of instances that triggered HAProxy reload
	TotalAPIOperations int   // Sum of API operations across all instances
}

DeploymentResult contains the outcome of a deployment operation. Used with NewDeploymentCompletedEvent for cleaner parameter passing.

type DeploymentScheduledEvent

type DeploymentScheduledEvent struct {
	// Config is the rendered HAProxy configuration to deploy.
	Config string

	// AuxiliaryFiles contains all rendered auxiliary files.
	// Type: interface{} to avoid circular dependencies with pkg/dataplane.
	// Consumers should type-assert to *dataplane.AuxiliaryFiles.
	AuxiliaryFiles interface{}

	// Endpoints is the list of HAProxy endpoints to deploy to.
	Endpoints []interface{}

	// RuntimeConfigName is the name of the HAProxyCfg resource.
	// Used for publishing ConfigAppliedToPodEvent after successful deployment.
	RuntimeConfigName string

	// RuntimeConfigNamespace is the namespace of the HAProxyCfg resource.
	// Used for publishing ConfigAppliedToPodEvent after successful deployment.
	RuntimeConfigNamespace string

	// Reason describes why this deployment was scheduled.
	// Examples: "config_validation", "pod_discovery", "drift_prevention"
	Reason string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

DeploymentScheduledEvent is published when the deployment scheduler has decided. to execute a deployment. This event contains all necessary data for the deployer to execute the deployment without maintaining state.

Published by: DeploymentScheduler. Consumed by: Deployer component.

This event propagates the correlation ID from ValidationCompletedEvent.

func NewDeploymentScheduledEvent

func NewDeploymentScheduledEvent(config string, auxFiles interface{}, endpoints []interface{}, runtimeConfigName, runtimeConfigNamespace, reason string, opts ...CorrelationOption) *DeploymentScheduledEvent

NewDeploymentScheduledEvent creates a new DeploymentScheduledEvent. Performs defensive copy of endpoints slice.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewDeploymentScheduledEvent(config, auxFiles, endpoints, name, ns, reason,
    events.PropagateCorrelation(validationEvent))

func (*DeploymentScheduledEvent) EventType

func (e *DeploymentScheduledEvent) EventType() string

func (*DeploymentScheduledEvent) Timestamp

func (e *DeploymentScheduledEvent) Timestamp() time.Time

type DeploymentStartedEvent

type DeploymentStartedEvent struct {
	Endpoints []interface{}

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

DeploymentStartedEvent is published when deployment to HAProxy instances begins.

This event propagates the correlation ID from DeploymentScheduledEvent.

func NewDeploymentStartedEvent

func NewDeploymentStartedEvent(endpoints []interface{}, opts ...CorrelationOption) *DeploymentStartedEvent

NewDeploymentStartedEvent creates a new DeploymentStartedEvent. Performs defensive copy of the endpoints slice.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewDeploymentStartedEvent(endpoints,
    events.PropagateCorrelation(scheduledEvent))

func (*DeploymentStartedEvent) EventType

func (e *DeploymentStartedEvent) EventType() string

func (*DeploymentStartedEvent) Timestamp

func (e *DeploymentStartedEvent) Timestamp() time.Time

type DriftPreventionTriggeredEvent

type DriftPreventionTriggeredEvent struct {
	// TimeSinceLastDeployment is the duration since the last deployment completed.
	TimeSinceLastDeployment time.Duration
	// contains filtered or unexported fields
}

DriftPreventionTriggeredEvent is published when the drift prevention monitor. detects that no deployment has occurred within the configured interval and triggers a deployment to prevent configuration drift.

Published by: DriftPreventionMonitor. Consumed by: DeploymentScheduler (which then schedules a deployment).

func NewDriftPreventionTriggeredEvent

func NewDriftPreventionTriggeredEvent(timeSinceLast time.Duration) *DriftPreventionTriggeredEvent

NewDriftPreventionTriggeredEvent creates a new DriftPreventionTriggeredEvent.

func (*DriftPreventionTriggeredEvent) EventType

func (e *DriftPreventionTriggeredEvent) EventType() string

func (*DriftPreventionTriggeredEvent) Timestamp

func (e *DriftPreventionTriggeredEvent) Timestamp() time.Time

type HAProxyPodAddedEvent

type HAProxyPodAddedEvent struct {
	Endpoint interface{}
	// contains filtered or unexported fields
}

HAProxyPodAddedEvent is published when a new HAProxy pod is discovered.

func NewHAProxyPodAddedEvent

func NewHAProxyPodAddedEvent(endpoint interface{}) *HAProxyPodAddedEvent

NewHAProxyPodAddedEvent creates a new HAProxyPodAddedEvent.

func (*HAProxyPodAddedEvent) EventType

func (e *HAProxyPodAddedEvent) EventType() string

func (*HAProxyPodAddedEvent) Timestamp

func (e *HAProxyPodAddedEvent) Timestamp() time.Time

type HAProxyPodRemovedEvent

type HAProxyPodRemovedEvent struct {
	Endpoint interface{}
	// contains filtered or unexported fields
}

HAProxyPodRemovedEvent is published when an HAProxy pod is removed.

func NewHAProxyPodRemovedEvent

func NewHAProxyPodRemovedEvent(endpoint interface{}) *HAProxyPodRemovedEvent

NewHAProxyPodRemovedEvent creates a new HAProxyPodRemovedEvent.

func (*HAProxyPodRemovedEvent) EventType

func (e *HAProxyPodRemovedEvent) EventType() string

func (*HAProxyPodRemovedEvent) Timestamp

func (e *HAProxyPodRemovedEvent) Timestamp() time.Time

type HAProxyPodTerminatedEvent

type HAProxyPodTerminatedEvent struct {
	PodName      string
	PodNamespace string
	// contains filtered or unexported fields
}

HAProxyPodTerminatedEvent is published when an HAProxy pod terminates.

This triggers cleanup of the pod from all runtime config status fields.

func NewHAProxyPodTerminatedEvent

func NewHAProxyPodTerminatedEvent(podName, podNamespace string) *HAProxyPodTerminatedEvent

NewHAProxyPodTerminatedEvent creates a new HAProxyPodTerminatedEvent.

func (*HAProxyPodTerminatedEvent) EventType

func (e *HAProxyPodTerminatedEvent) EventType() string

func (*HAProxyPodTerminatedEvent) Timestamp

func (e *HAProxyPodTerminatedEvent) Timestamp() time.Time

type HAProxyPodsDiscoveredEvent

type HAProxyPodsDiscoveredEvent struct {
	// Endpoints is the list of discovered HAProxy Dataplane API endpoints.
	Endpoints []interface{}
	Count     int
	// contains filtered or unexported fields
}

HAProxyPodsDiscoveredEvent is published when HAProxy pods are discovered or updated.

func NewHAProxyPodsDiscoveredEvent

func NewHAProxyPodsDiscoveredEvent(endpoints []interface{}, count int) *HAProxyPodsDiscoveredEvent

NewHAProxyPodsDiscoveredEvent creates a new HAProxyPodsDiscoveredEvent. Performs defensive copy of the endpoints slice.

func (*HAProxyPodsDiscoveredEvent) EventType

func (e *HAProxyPodsDiscoveredEvent) EventType() string

func (*HAProxyPodsDiscoveredEvent) Timestamp

func (e *HAProxyPodsDiscoveredEvent) Timestamp() time.Time

type HTTPResourceAcceptedEvent

type HTTPResourceAcceptedEvent struct {
	URL             string // The URL whose content was accepted
	ContentChecksum string // SHA256 checksum of accepted content
	ContentSize     int    // Size of accepted content in bytes
	// contains filtered or unexported fields
}

HTTPResourceAcceptedEvent is published when pending HTTP content passes validation. The content has been promoted from "pending" to "accepted" state.

func NewHTTPResourceAcceptedEvent

func NewHTTPResourceAcceptedEvent(url, checksum string, size int) *HTTPResourceAcceptedEvent

NewHTTPResourceAcceptedEvent creates a new HTTPResourceAcceptedEvent.

func (*HTTPResourceAcceptedEvent) EventType

func (e *HTTPResourceAcceptedEvent) EventType() string

func (*HTTPResourceAcceptedEvent) Timestamp

func (e *HTTPResourceAcceptedEvent) Timestamp() time.Time

type HTTPResourceRejectedEvent

type HTTPResourceRejectedEvent struct {
	URL             string // The URL whose content was rejected
	ContentChecksum string // SHA256 checksum of rejected content
	Reason          string // Why the content was rejected
	// contains filtered or unexported fields
}

HTTPResourceRejectedEvent is published when pending HTTP content fails validation. The old accepted content remains in use.

func NewHTTPResourceRejectedEvent

func NewHTTPResourceRejectedEvent(url, checksum, reason string) *HTTPResourceRejectedEvent

NewHTTPResourceRejectedEvent creates a new HTTPResourceRejectedEvent.

func (*HTTPResourceRejectedEvent) EventType

func (e *HTTPResourceRejectedEvent) EventType() string

func (*HTTPResourceRejectedEvent) Timestamp

func (e *HTTPResourceRejectedEvent) Timestamp() time.Time

type HTTPResourceUpdatedEvent

type HTTPResourceUpdatedEvent struct {
	URL             string // The URL that was refreshed
	ContentChecksum string // SHA256 checksum of new content
	ContentSize     int    // Size of new content in bytes
	// contains filtered or unexported fields
}

HTTPResourceUpdatedEvent is published when HTTP resource content has changed. This triggers a reconciliation cycle with the new content as "pending". The content must pass validation before being promoted to "accepted".

func NewHTTPResourceUpdatedEvent

func NewHTTPResourceUpdatedEvent(url, checksum string, size int) *HTTPResourceUpdatedEvent

NewHTTPResourceUpdatedEvent creates a new HTTPResourceUpdatedEvent.

func (*HTTPResourceUpdatedEvent) EventType

func (e *HTTPResourceUpdatedEvent) EventType() string

func (*HTTPResourceUpdatedEvent) Timestamp

func (e *HTTPResourceUpdatedEvent) Timestamp() time.Time

type IndexSynchronizedEvent

type IndexSynchronizedEvent struct {
	// ResourceCounts maps resource types to their counts.
	ResourceCounts map[string]int
	// contains filtered or unexported fields
}

IndexSynchronizedEvent is published when all resource watchers have completed. their initial sync and the system has a complete view of all resources.

This is a critical milestone - the controller waits for this event before. starting reconciliation to ensure it has complete data.

func NewIndexSynchronizedEvent

func NewIndexSynchronizedEvent(resourceCounts map[string]int) *IndexSynchronizedEvent

NewIndexSynchronizedEvent creates a new IndexSynchronizedEvent. Performs defensive copy of the resource counts map.

func (*IndexSynchronizedEvent) EventType

func (e *IndexSynchronizedEvent) EventType() string

func (*IndexSynchronizedEvent) Timestamp

func (e *IndexSynchronizedEvent) Timestamp() time.Time

type InstanceDeployedEvent

type InstanceDeployedEvent struct {
	Endpoint       interface{} // The HAProxy endpoint that was deployed to
	DurationMs     int64
	ReloadRequired bool // Whether this deployment required an HAProxy reload

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

InstanceDeployedEvent is published when deployment to a single HAProxy instance succeeds.

This event propagates the correlation ID from DeploymentStartedEvent.

func NewInstanceDeployedEvent

func NewInstanceDeployedEvent(endpoint interface{}, durationMs int64, reloadRequired bool, opts ...CorrelationOption) *InstanceDeployedEvent

NewInstanceDeployedEvent creates a new InstanceDeployedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewInstanceDeployedEvent(endpoint, durationMs, reloadRequired,
    events.PropagateCorrelation(startedEvent))

func (*InstanceDeployedEvent) EventType

func (e *InstanceDeployedEvent) EventType() string

func (*InstanceDeployedEvent) Timestamp

func (e *InstanceDeployedEvent) Timestamp() time.Time

type InstanceDeploymentFailedEvent

type InstanceDeploymentFailedEvent struct {
	Endpoint  interface{}
	Error     string
	Retryable bool // Whether this failure is retryable

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

InstanceDeploymentFailedEvent is published when deployment to a single HAProxy instance fails.

This event propagates the correlation ID from DeploymentStartedEvent.

func NewInstanceDeploymentFailedEvent

func NewInstanceDeploymentFailedEvent(endpoint interface{}, err string, retryable bool, opts ...CorrelationOption) *InstanceDeploymentFailedEvent

NewInstanceDeploymentFailedEvent creates a new InstanceDeploymentFailedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewInstanceDeploymentFailedEvent(endpoint, err, retryable,
    events.PropagateCorrelation(startedEvent))

func (*InstanceDeploymentFailedEvent) EventType

func (e *InstanceDeploymentFailedEvent) EventType() string

func (*InstanceDeploymentFailedEvent) Timestamp

func (e *InstanceDeploymentFailedEvent) Timestamp() time.Time

type LeaderElectionStartedEvent

type LeaderElectionStartedEvent struct {
	Identity       string
	LeaseName      string
	LeaseNamespace string
	// contains filtered or unexported fields
}

LeaderElectionStartedEvent is published when leader election is initiated.

func NewLeaderElectionStartedEvent

func NewLeaderElectionStartedEvent(identity, leaseName, leaseNamespace string) *LeaderElectionStartedEvent

NewLeaderElectionStartedEvent creates a new LeaderElectionStartedEvent.

func (*LeaderElectionStartedEvent) EventType

func (e *LeaderElectionStartedEvent) EventType() string

func (*LeaderElectionStartedEvent) Timestamp

func (e *LeaderElectionStartedEvent) Timestamp() time.Time

type LostLeadershipEvent

type LostLeadershipEvent struct {
	Identity string
	Reason   string // graceful_shutdown, lease_expired, etc.
	// contains filtered or unexported fields
}

LostLeadershipEvent is published when this replica loses leadership.

func NewLostLeadershipEvent

func NewLostLeadershipEvent(identity, reason string) *LostLeadershipEvent

NewLostLeadershipEvent creates a new LostLeadershipEvent.

func (*LostLeadershipEvent) EventType

func (e *LostLeadershipEvent) EventType() string

func (*LostLeadershipEvent) Timestamp

func (e *LostLeadershipEvent) Timestamp() time.Time

type NewLeaderObservedEvent

type NewLeaderObservedEvent struct {
	NewLeaderIdentity string
	IsSelf            bool // true if this replica is the new leader
	// contains filtered or unexported fields
}

NewLeaderObservedEvent is published when a new leader is observed.

func NewNewLeaderObservedEvent

func NewNewLeaderObservedEvent(newLeaderIdentity string, isSelf bool) *NewLeaderObservedEvent

NewNewLeaderObservedEvent creates a new NewLeaderObservedEvent.

func (*NewLeaderObservedEvent) EventType

func (e *NewLeaderObservedEvent) EventType() string

func (*NewLeaderObservedEvent) Timestamp

func (e *NewLeaderObservedEvent) Timestamp() time.Time

type OperationCounts

type OperationCounts struct {
	TotalAPIOperations int
	BackendsAdded      int
	BackendsRemoved    int
	BackendsModified   int
	ServersAdded       int
	ServersRemoved     int
	ServersModified    int
	FrontendsAdded     int
	FrontendsRemoved   int
	FrontendsModified  int
}

OperationCounts provides statistics about sync operations.

type ReconciliationCompletedEvent

type ReconciliationCompletedEvent struct {
	DurationMs int64

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ReconciliationCompletedEvent is published when a reconciliation cycle completes successfully.

This event propagates the correlation ID from the reconciliation chain.

func NewReconciliationCompletedEvent

func NewReconciliationCompletedEvent(durationMs int64, opts ...CorrelationOption) *ReconciliationCompletedEvent

NewReconciliationCompletedEvent creates a new ReconciliationCompletedEvent.

Use WithCorrelation() to propagate correlation from the pipeline:

event := events.NewReconciliationCompletedEvent(durationMs,
    events.WithCorrelation(correlationID, causationID))

func (*ReconciliationCompletedEvent) EventType

func (e *ReconciliationCompletedEvent) EventType() string

func (*ReconciliationCompletedEvent) Timestamp

func (e *ReconciliationCompletedEvent) Timestamp() time.Time

type ReconciliationFailedEvent

type ReconciliationFailedEvent struct {
	Error string
	Phase string // Which phase failed: "render", "validate", "deploy"

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ReconciliationFailedEvent is published when a reconciliation cycle fails.

This event propagates the correlation ID from the reconciliation chain.

func NewReconciliationFailedEvent

func NewReconciliationFailedEvent(err, phase string, opts ...CorrelationOption) *ReconciliationFailedEvent

NewReconciliationFailedEvent creates a new ReconciliationFailedEvent.

Use WithCorrelation() to propagate correlation from the pipeline:

event := events.NewReconciliationFailedEvent(err, phase,
    events.WithCorrelation(correlationID, causationID))

func (*ReconciliationFailedEvent) EventType

func (e *ReconciliationFailedEvent) EventType() string

func (*ReconciliationFailedEvent) Timestamp

func (e *ReconciliationFailedEvent) Timestamp() time.Time

type ReconciliationStartedEvent

type ReconciliationStartedEvent struct {
	// Trigger describes what triggered this reconciliation.
	Trigger string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ReconciliationStartedEvent is published when the Executor begins a reconciliation cycle.

This event propagates the correlation ID from ReconciliationTriggeredEvent.

func NewReconciliationStartedEvent

func NewReconciliationStartedEvent(trigger string, opts ...CorrelationOption) *ReconciliationStartedEvent

NewReconciliationStartedEvent creates a new ReconciliationStartedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewReconciliationStartedEvent(trigger,
    events.PropagateCorrelation(triggeredEvent))

func (*ReconciliationStartedEvent) EventType

func (e *ReconciliationStartedEvent) EventType() string

func (*ReconciliationStartedEvent) Timestamp

func (e *ReconciliationStartedEvent) Timestamp() time.Time

type ReconciliationTriggeredEvent

type ReconciliationTriggeredEvent struct {
	// Reason describes why reconciliation was triggered.
	// Examples: "debounce_timer", "config_change", "manual_trigger"
	Reason string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ReconciliationTriggeredEvent is published when a reconciliation cycle should start.

This event is typically published by the Reconciler after the debounce timer. expires, or immediately for config changes.

This event starts a new correlation chain. Downstream events (TemplateRenderedEvent, ValidationCompletedEvent, DeploymentScheduledEvent, etc.) should propagate the correlation ID to enable end-to-end tracing.

func NewReconciliationTriggeredEvent

func NewReconciliationTriggeredEvent(reason string, opts ...CorrelationOption) *ReconciliationTriggeredEvent

NewReconciliationTriggeredEvent creates a new ReconciliationTriggeredEvent.

Use WithNewCorrelation() to start a new correlation chain:

event := events.NewReconciliationTriggeredEvent("config_change",
    events.WithNewCorrelation())

func (*ReconciliationTriggeredEvent) EventType

func (e *ReconciliationTriggeredEvent) EventType() string

func (*ReconciliationTriggeredEvent) Timestamp

func (e *ReconciliationTriggeredEvent) Timestamp() time.Time

type ResourceIndexUpdatedEvent

type ResourceIndexUpdatedEvent struct {
	// ResourceTypeName identifies the resource type from config (e.g., "ingresses", "services").
	ResourceTypeName string

	// ChangeStats provides detailed change statistics including Created, Modified, Deleted counts
	// and whether this event occurred during initial sync.
	ChangeStats types.ChangeStats
	// contains filtered or unexported fields
}

ResourceIndexUpdatedEvent is published when a watched Kubernetes resource. has been added, updated, or deleted in the local index.

func NewResourceIndexUpdatedEvent

func NewResourceIndexUpdatedEvent(resourceTypeName string, changeStats types.ChangeStats) *ResourceIndexUpdatedEvent

NewResourceIndexUpdatedEvent creates a new ResourceIndexUpdatedEvent. Performs a value copy of ChangeStats (it's a small struct with no pointers).

func (*ResourceIndexUpdatedEvent) EventType

func (e *ResourceIndexUpdatedEvent) EventType() string

func (*ResourceIndexUpdatedEvent) Timestamp

func (e *ResourceIndexUpdatedEvent) Timestamp() time.Time

type ResourceSyncCompleteEvent

type ResourceSyncCompleteEvent struct {
	// ResourceTypeName identifies the resource type from config (e.g., "ingresses").
	ResourceTypeName string

	// InitialCount is the number of resources loaded during initial sync.
	InitialCount int
	// contains filtered or unexported fields
}

ResourceSyncCompleteEvent is published when a resource watcher has completed. its initial sync with the Kubernetes API.

func NewResourceSyncCompleteEvent

func NewResourceSyncCompleteEvent(resourceTypeName string, initialCount int) *ResourceSyncCompleteEvent

NewResourceSyncCompleteEvent creates a new ResourceSyncCompleteEvent.

func (*ResourceSyncCompleteEvent) EventType

func (e *ResourceSyncCompleteEvent) EventType() string

func (*ResourceSyncCompleteEvent) Timestamp

func (e *ResourceSyncCompleteEvent) Timestamp() time.Time

type SecretResourceChangedEvent

type SecretResourceChangedEvent struct {
	// Resource contains the raw Secret resource.
	// Type: interface{} to avoid circular dependencies.
	// Consumers should type-assert to *unstructured.Unstructured or *corev1.Secret.
	Resource interface{}
	// contains filtered or unexported fields
}

SecretResourceChangedEvent is published when the Secret resource is added, updated, or deleted.

This is a low-level event published directly by the SingleWatcher callback in the controller package. The CredentialsLoaderComponent subscribes to this event and handles parsing.

func NewSecretResourceChangedEvent

func NewSecretResourceChangedEvent(resource interface{}) *SecretResourceChangedEvent

NewSecretResourceChangedEvent creates a new SecretResourceChangedEvent.

func (*SecretResourceChangedEvent) EventType

func (e *SecretResourceChangedEvent) EventType() string

func (*SecretResourceChangedEvent) Timestamp

func (e *SecretResourceChangedEvent) Timestamp() time.Time

type StorageSyncCompletedEvent

type StorageSyncCompletedEvent struct {
	Phase string

	// Stats contains sync statistics.
	// Type: interface{} to avoid circular dependencies.
	Stats interface{}

	DurationMs int64
	// contains filtered or unexported fields
}

StorageSyncCompletedEvent is published when auxiliary file synchronization completes.

func NewStorageSyncCompletedEvent

func NewStorageSyncCompletedEvent(phase string, stats interface{}, durationMs int64) *StorageSyncCompletedEvent

NewStorageSyncCompletedEvent creates a new StorageSyncCompletedEvent.

func (*StorageSyncCompletedEvent) EventType

func (e *StorageSyncCompletedEvent) EventType() string

func (*StorageSyncCompletedEvent) Timestamp

func (e *StorageSyncCompletedEvent) Timestamp() time.Time

type StorageSyncFailedEvent

type StorageSyncFailedEvent struct {
	Phase string
	Error string
	// contains filtered or unexported fields
}

StorageSyncFailedEvent is published when auxiliary file synchronization fails.

func NewStorageSyncFailedEvent

func NewStorageSyncFailedEvent(phase, err string) *StorageSyncFailedEvent

NewStorageSyncFailedEvent creates a new StorageSyncFailedEvent.

func (*StorageSyncFailedEvent) EventType

func (e *StorageSyncFailedEvent) EventType() string

func (*StorageSyncFailedEvent) Timestamp

func (e *StorageSyncFailedEvent) Timestamp() time.Time

type StorageSyncStartedEvent

type StorageSyncStartedEvent struct {
	// Phase describes which sync phase: "pre-config", "config", "post-config"
	Phase     string
	Endpoints []interface{}
	// contains filtered or unexported fields
}

StorageSyncStartedEvent is published when auxiliary file synchronization begins.

func NewStorageSyncStartedEvent

func NewStorageSyncStartedEvent(phase string, endpoints []interface{}) *StorageSyncStartedEvent

NewStorageSyncStartedEvent creates a new StorageSyncStartedEvent. Performs defensive copy of the endpoints slice.

func (*StorageSyncStartedEvent) EventType

func (e *StorageSyncStartedEvent) EventType() string

func (*StorageSyncStartedEvent) Timestamp

func (e *StorageSyncStartedEvent) Timestamp() time.Time

type SyncMetadata

type SyncMetadata struct {
	// ReloadTriggered indicates whether HAProxy was reloaded during this sync.
	// Reloads occur for structural changes via transaction API (status 202).
	// Runtime-only changes don't trigger reloads (status 200).
	ReloadTriggered bool

	// ReloadID is the reload identifier from HAProxy dataplane API.
	// Only populated when ReloadTriggered is true.
	ReloadID string

	// SyncDuration is how long the sync operation took.
	SyncDuration time.Duration

	// VersionConflictRetries is the number of retries due to version conflicts.
	// HAProxy's dataplane API uses optimistic concurrency control.
	VersionConflictRetries int

	// FallbackUsed indicates whether incremental sync failed and a full
	// raw configuration push was used instead.
	FallbackUsed bool

	// OperationCounts provides a breakdown of operations performed.
	OperationCounts OperationCounts

	// Error contains the error message if sync failed.
	// Empty string indicates success.
	Error string
}

SyncMetadata contains detailed information about a sync operation.

type TemplateRenderFailedEvent

type TemplateRenderFailedEvent struct {
	// TemplateName is the name of the template that failed to render.
	TemplateName string

	// Error is the error message.
	Error string

	// StackTrace provides additional debugging context.
	StackTrace string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

TemplateRenderFailedEvent is published when template rendering fails.

This event propagates the correlation ID from ReconciliationTriggeredEvent.

func NewTemplateRenderFailedEvent

func NewTemplateRenderFailedEvent(templateName, err, stackTrace string, opts ...CorrelationOption) *TemplateRenderFailedEvent

NewTemplateRenderFailedEvent creates a new TemplateRenderFailedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewTemplateRenderFailedEvent(name, err, stackTrace,
    events.PropagateCorrelation(triggeredEvent))

func (*TemplateRenderFailedEvent) EventType

func (e *TemplateRenderFailedEvent) EventType() string

func (*TemplateRenderFailedEvent) Timestamp

func (e *TemplateRenderFailedEvent) Timestamp() time.Time

type TemplateRenderedEvent

type TemplateRenderedEvent struct {
	// HAProxyConfig is the rendered main HAProxy configuration for production deployment.
	// Contains absolute paths like /etc/haproxy/maps/host.map for HAProxy pods.
	HAProxyConfig string

	// ValidationHAProxyConfig is the rendered configuration for controller validation.
	// Contains temp directory paths matching ValidationPaths for isolated validation.
	ValidationHAProxyConfig string

	// ValidationPaths specifies temp directories where auxiliary files should be written for validation.
	// Type: interface{} to avoid circular dependencies with pkg/dataplane.
	// Consumers should type-assert to dataplane.ValidationPaths.
	ValidationPaths interface{}

	// AuxiliaryFiles contains all rendered auxiliary files (maps, certificates, general files)
	// for production deployment. Uses accepted HTTP content only.
	// Type: interface{} to avoid circular dependencies with pkg/dataplane.
	// Consumers should type-assert to *dataplane.AuxiliaryFiles.
	AuxiliaryFiles interface{}

	// ValidationAuxiliaryFiles contains auxiliary files for validation.
	// Uses pending HTTP content if available (for testing new content before promotion).
	// Type: interface{} to avoid circular dependencies with pkg/dataplane.
	// Consumers should type-assert to *dataplane.AuxiliaryFiles.
	ValidationAuxiliaryFiles interface{}

	// Metrics for observability
	ConfigBytes           int   // Size of HAProxyConfig (production)
	ValidationConfigBytes int   // Size of ValidationHAProxyConfig
	AuxiliaryFileCount    int   // Number of auxiliary files
	DurationMs            int64 // Total rendering duration (both configs)

	// TriggerReason is the reason that triggered this reconciliation.
	// Propagated from ReconciliationTriggeredEvent.Reason.
	// Examples: "config_change", "debounce_timer", "drift_prevention"
	// Used by downstream components (e.g., DeploymentScheduler) to determine fallback behavior.
	TriggerReason string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

TemplateRenderedEvent is published when template rendering completes successfully.

This event carries two versions of the rendered HAProxy configuration: - Production version with absolute paths for deployment to HAProxy pods - Validation version with temp directory paths for controller validation

Both configurations are rendered from the same templates but with different PathResolver instances.

The event also carries two versions of auxiliary files: - Production version with accepted HTTP content only (for deployment) - Validation version with pending HTTP content (for testing new content before promotion).

This event propagates the correlation ID from ReconciliationTriggeredEvent.

func NewTemplateRenderedEvent

func NewTemplateRenderedEvent(
	haproxyConfig string,
	validationHAProxyConfig string,
	validationPaths interface{},
	auxiliaryFiles interface{},
	validationAuxiliaryFiles interface{},
	auxFileCount int,
	durationMs int64,
	triggerReason string,
	opts ...CorrelationOption,
) *TemplateRenderedEvent

NewTemplateRenderedEvent creates a new TemplateRenderedEvent. Performs defensive copy of the haproxyConfig strings.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewTemplateRenderedEvent(..., triggerReason,
    events.PropagateCorrelation(triggeredEvent))

func (*TemplateRenderedEvent) EventType

func (e *TemplateRenderedEvent) EventType() string

func (*TemplateRenderedEvent) GetAuxiliaryFiles

func (e *TemplateRenderedEvent) GetAuxiliaryFiles() (*dataplane.AuxiliaryFiles, bool)

GetAuxiliaryFiles returns AuxiliaryFiles with proper type. Returns nil, false if the type assertion fails.

This method provides type-safe access to the AuxiliaryFiles field, avoiding the need for manual type assertions in consumer code.

func (*TemplateRenderedEvent) GetValidationAuxiliaryFiles

func (e *TemplateRenderedEvent) GetValidationAuxiliaryFiles() (*dataplane.AuxiliaryFiles, bool)

GetValidationAuxiliaryFiles returns ValidationAuxiliaryFiles with proper type. Returns nil, false if the type assertion fails.

This method provides type-safe access to the ValidationAuxiliaryFiles field, avoiding the need for manual type assertions in consumer code.

func (*TemplateRenderedEvent) GetValidationPaths

func (e *TemplateRenderedEvent) GetValidationPaths() (*dataplane.ValidationPaths, bool)

GetValidationPaths returns ValidationPaths with proper type. Returns nil, false if the type assertion fails.

This method provides type-safe access to the ValidationPaths field, avoiding the need for manual type assertions in consumer code.

func (*TemplateRenderedEvent) Timestamp

func (e *TemplateRenderedEvent) Timestamp() time.Time

type ValidationCompletedEvent

type ValidationCompletedEvent struct {
	Warnings   []string // Non-fatal warnings from HAProxy validation
	DurationMs int64

	// TriggerReason is the reason that triggered this reconciliation.
	// Propagated from TemplateRenderedEvent.TriggerReason.
	// Examples: "config_change", "debounce_timer", "drift_prevention"
	// Used by DeploymentScheduler to determine fallback behavior on validation failure.
	TriggerReason string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ValidationCompletedEvent is published when local configuration validation succeeds.

Validation is performed locally using the HAProxy binary. Endpoints are not involved.

This event propagates the correlation ID from ValidationStartedEvent.

func NewValidationCompletedEvent

func NewValidationCompletedEvent(warnings []string, durationMs int64, triggerReason string, opts ...CorrelationOption) *ValidationCompletedEvent

NewValidationCompletedEvent creates a new ValidationCompletedEvent. Performs defensive copy of the warnings slice.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewValidationCompletedEvent(warnings, durationMs, triggerReason,
    events.PropagateCorrelation(startedEvent))

func (*ValidationCompletedEvent) EventType

func (e *ValidationCompletedEvent) EventType() string

func (*ValidationCompletedEvent) Timestamp

func (e *ValidationCompletedEvent) Timestamp() time.Time

type ValidationFailedEvent

type ValidationFailedEvent struct {
	Errors     []string // Validation errors from HAProxy
	DurationMs int64

	// TriggerReason is the reason that triggered this reconciliation.
	// Propagated from TemplateRenderedEvent.TriggerReason.
	// Examples: "config_change", "debounce_timer", "drift_prevention"
	// Used by DeploymentScheduler to determine fallback behavior (deploy cached config on drift prevention).
	TriggerReason string

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ValidationFailedEvent is published when local configuration validation fails.

Validation is performed locally using the HAProxy binary. Endpoints are not involved.

This event propagates the correlation ID from ValidationStartedEvent.

func NewValidationFailedEvent

func NewValidationFailedEvent(errors []string, durationMs int64, triggerReason string, opts ...CorrelationOption) *ValidationFailedEvent

NewValidationFailedEvent creates a new ValidationFailedEvent. Performs defensive copy of the errors slice.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewValidationFailedEvent(errors, durationMs, triggerReason,
    events.PropagateCorrelation(startedEvent))

func (*ValidationFailedEvent) EventType

func (e *ValidationFailedEvent) EventType() string

func (*ValidationFailedEvent) Timestamp

func (e *ValidationFailedEvent) Timestamp() time.Time

type ValidationStartedEvent

type ValidationStartedEvent struct {

	// Correlation embeds correlation tracking for event tracing.
	Correlation
	// contains filtered or unexported fields
}

ValidationStartedEvent is published when local configuration validation begins.

Validation is performed locally using the HAProxy binary to check configuration syntax. It does not involve HAProxy endpoints - those are only used later for deployment.

This event propagates the correlation ID from TemplateRenderedEvent.

func NewValidationStartedEvent

func NewValidationStartedEvent(opts ...CorrelationOption) *ValidationStartedEvent

NewValidationStartedEvent creates a new ValidationStartedEvent.

Use PropagateCorrelation() to propagate correlation from the triggering event:

event := events.NewValidationStartedEvent(
    events.PropagateCorrelation(renderedEvent))

func (*ValidationStartedEvent) EventType

func (e *ValidationStartedEvent) EventType() string

func (*ValidationStartedEvent) Timestamp

func (e *ValidationStartedEvent) Timestamp() time.Time

type ValidationTestsCompletedEvent

type ValidationTestsCompletedEvent struct {
	TotalTests  int   // Total number of tests executed
	PassedTests int   // Number of tests that passed
	FailedTests int   // Number of tests that failed
	DurationMs  int64 // Time taken to execute all tests
	// contains filtered or unexported fields
}

ValidationTestsCompletedEvent is published when all validation tests finish execution.

This event is published regardless of whether tests passed or failed.

func NewValidationTestsCompletedEvent

func NewValidationTestsCompletedEvent(total, passed, failed int, durationMs int64) *ValidationTestsCompletedEvent

NewValidationTestsCompletedEvent creates a new ValidationTestsCompletedEvent.

func (*ValidationTestsCompletedEvent) EventType

func (e *ValidationTestsCompletedEvent) EventType() string

func (*ValidationTestsCompletedEvent) Timestamp

func (e *ValidationTestsCompletedEvent) Timestamp() time.Time

type ValidationTestsFailedEvent

type ValidationTestsFailedEvent struct {
	FailedTests []string // Names of tests that failed
	// contains filtered or unexported fields
}

ValidationTestsFailedEvent is published when validation tests fail during webhook validation.

This event is only published during webhook validation when tests fail and admission is denied.

func NewValidationTestsFailedEvent

func NewValidationTestsFailedEvent(failedTests []string) *ValidationTestsFailedEvent

NewValidationTestsFailedEvent creates a new ValidationTestsFailedEvent. Performs defensive copy of the failed tests slice.

func (*ValidationTestsFailedEvent) EventType

func (e *ValidationTestsFailedEvent) EventType() string

func (*ValidationTestsFailedEvent) Timestamp

func (e *ValidationTestsFailedEvent) Timestamp() time.Time

type ValidationTestsStartedEvent

type ValidationTestsStartedEvent struct {
	TestCount int // Number of tests to execute
	// contains filtered or unexported fields
}

ValidationTestsStartedEvent is published when embedded validation tests begin execution.

This is used for both CLI validation and webhook validation.

func NewValidationTestsStartedEvent

func NewValidationTestsStartedEvent(testCount int) *ValidationTestsStartedEvent

NewValidationTestsStartedEvent creates a new ValidationTestsStartedEvent.

func (*ValidationTestsStartedEvent) EventType

func (e *ValidationTestsStartedEvent) EventType() string

func (*ValidationTestsStartedEvent) Timestamp

func (e *ValidationTestsStartedEvent) Timestamp() time.Time

type WebhookValidationAllowedEvent

type WebhookValidationAllowedEvent struct {
	RequestUID string
	Kind       string
	Name       string
	Namespace  string
	// contains filtered or unexported fields
}

WebhookValidationAllowedEvent is published when a resource is admitted.

func NewWebhookValidationAllowedEvent

func NewWebhookValidationAllowedEvent(requestUID, kind, name, namespace string) *WebhookValidationAllowedEvent

NewWebhookValidationAllowedEvent creates a new WebhookValidationAllowedEvent.

func (*WebhookValidationAllowedEvent) EventType

func (e *WebhookValidationAllowedEvent) EventType() string

func (*WebhookValidationAllowedEvent) Timestamp

func (e *WebhookValidationAllowedEvent) Timestamp() time.Time

type WebhookValidationDeniedEvent

type WebhookValidationDeniedEvent struct {
	RequestUID string
	Kind       string
	Name       string
	Namespace  string
	Reason     string
	// contains filtered or unexported fields
}

WebhookValidationDeniedEvent is published when a resource is denied.

func NewWebhookValidationDeniedEvent

func NewWebhookValidationDeniedEvent(requestUID, kind, name, namespace, reason string) *WebhookValidationDeniedEvent

NewWebhookValidationDeniedEvent creates a new WebhookValidationDeniedEvent.

func (*WebhookValidationDeniedEvent) EventType

func (e *WebhookValidationDeniedEvent) EventType() string

func (*WebhookValidationDeniedEvent) Timestamp

func (e *WebhookValidationDeniedEvent) Timestamp() time.Time

type WebhookValidationErrorEvent

type WebhookValidationErrorEvent struct {
	RequestUID string
	Kind       string
	Error      string
	// contains filtered or unexported fields
}

WebhookValidationErrorEvent is published when validation encounters an error.

func NewWebhookValidationErrorEvent

func NewWebhookValidationErrorEvent(requestUID, kind, errorMsg string) *WebhookValidationErrorEvent

NewWebhookValidationErrorEvent creates a new WebhookValidationErrorEvent.

func (*WebhookValidationErrorEvent) EventType

func (e *WebhookValidationErrorEvent) EventType() string

func (*WebhookValidationErrorEvent) Timestamp

func (e *WebhookValidationErrorEvent) Timestamp() time.Time

type WebhookValidationRequest

type WebhookValidationRequest struct {
	// ID uniquely identifies this validation request for response correlation.
	// Generated by webhook component using UUID.
	ID string

	// GVK identifies the resource type in "group/version.Kind" format.
	// Examples: "networking.k8s.io/v1.Ingress", "v1.ConfigMap"
	GVK string

	// Namespace is the Kubernetes namespace of the resource.
	// Empty for cluster-scoped resources.
	Namespace string

	// Name is the Kubernetes name of the resource.
	// May be empty for CREATE operations using generateName.
	Name string

	// Object is the full resource object from the AdmissionRequest.
	// Typically map[string]interface{} parsed from JSON.
	Object interface{}

	// Operation indicates the admission operation type.
	// Values: "CREATE", "UPDATE", "DELETE"
	Operation string
	// contains filtered or unexported fields
}

WebhookValidationRequest is published by the webhook component via scatter-gather to request validation from all registered validators.

This event uses the scatter-gather pattern (EventBus.Request()) where multiple validator components (BasicValidator, DryRunValidator, etc.) respond with WebhookValidationResponse events.

Contract:

  • Published by: pkg/controller/webhook (validator.go)
  • Consumed by: All validator components (basic, dryrun, etc.)
  • Response: WebhookValidationResponse (one per validator)
  • Timing: Synchronous with admission request (< 5s timeout)

func NewWebhookValidationRequest

func NewWebhookValidationRequest(gvk, namespace, name string, obj interface{}, operation string) *WebhookValidationRequest

NewWebhookValidationRequest creates a new webhook validation request.

Parameters:

  • gvk: Resource Group/Version.Kind (e.g., "networking.k8s.io/v1.Ingress")
  • namespace: Resource namespace (empty for cluster-scoped)
  • name: Resource name
  • obj: Full resource object from admission request
  • operation: "CREATE", "UPDATE", or "DELETE"

Returns:

  • Immutable WebhookValidationRequest with unique ID

func (*WebhookValidationRequest) EventType

func (e *WebhookValidationRequest) EventType() string

EventType implements the Event interface.

func (*WebhookValidationRequest) RequestID

func (e *WebhookValidationRequest) RequestID() string

RequestID implements the Request interface for scatter-gather pattern.

func (*WebhookValidationRequest) Timestamp

func (e *WebhookValidationRequest) Timestamp() time.Time

Timestamp implements the Event interface.

type WebhookValidationRequestEvent

type WebhookValidationRequestEvent struct {
	RequestUID string
	Kind       string
	Name       string
	Namespace  string
	Operation  string
	// contains filtered or unexported fields
}

WebhookValidationRequestEvent is published when an admission request is received.

func NewWebhookValidationRequestEvent

func NewWebhookValidationRequestEvent(requestUID, kind, name, namespace, operation string) *WebhookValidationRequestEvent

NewWebhookValidationRequestEvent creates a new WebhookValidationRequestEvent.

func (*WebhookValidationRequestEvent) EventType

func (e *WebhookValidationRequestEvent) EventType() string

func (*WebhookValidationRequestEvent) Timestamp

func (e *WebhookValidationRequestEvent) Timestamp() time.Time

type WebhookValidationResponse

type WebhookValidationResponse struct {
	// ValidatorID identifies which validator produced this response.
	// Examples: "basic", "dryrun"
	ValidatorID string

	// Allowed indicates whether this validator allows the resource.
	// false = deny, true = allow
	Allowed bool

	// Reason provides a human-readable explanation for denial.
	// Empty if Allowed is true.
	// Shown to user in kubectl output if resource is denied.
	Reason string
	// contains filtered or unexported fields
}

WebhookValidationResponse is published by validator components in response to a WebhookValidationRequest.

Each validator (BasicValidator, DryRunValidator, etc.) publishes exactly one response per request. The webhook component aggregates all responses using AND logic: all validators must allow for the resource to be admitted.

Contract:

  • Published by: Validator components (basic, dryrun, etc.)
  • Consumed by: pkg/controller/webhook (via EventBus.Request() result)
  • Timing: Must respond within 5s timeout
  • Logic: ANY deny = overall deny, ALL allow = overall allow

func NewWebhookValidationResponse

func NewWebhookValidationResponse(requestID, validatorID string, allowed bool, reason string) *WebhookValidationResponse

NewWebhookValidationResponse creates a new webhook validation response.

Parameters:

  • requestID: ID from the corresponding WebhookValidationRequest
  • validatorID: Identifier for this validator (e.g., "basic", "dryrun")
  • allowed: Whether this validator allows the resource
  • reason: Human-readable denial reason (empty if allowed)

Returns:

  • Immutable WebhookValidationResponse

func (*WebhookValidationResponse) EventType

func (e *WebhookValidationResponse) EventType() string

EventType implements the Event interface.

func (*WebhookValidationResponse) RequestID

func (e *WebhookValidationResponse) RequestID() string

RequestID implements the Response interface for scatter-gather pattern.

func (*WebhookValidationResponse) Responder

func (e *WebhookValidationResponse) Responder() string

Responder implements the Response interface for scatter-gather pattern.

func (*WebhookValidationResponse) Timestamp

func (e *WebhookValidationResponse) Timestamp() time.Time

Timestamp implements the Event interface.

Jump to

Keyboard shortcuts

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