Documentation
¶
Overview ¶
Package common provides base infrastructure for Sync Controllers. Sync Controllers are responsible for: - Watching CloudflareSyncState resources - Aggregating configuration from multiple sources - Debouncing rapid changes - Syncing to Cloudflare API with incremental detection - Updating SyncState status
Index ¶
- Constants
- func ComputeConfigHash(config interface{}) (string, error)
- func ComputeConfigHashDeterministic(config interface{}) (string, error)
- func CreateAPIClient(ctx context.Context, c client.Client, syncState *v1alpha2.CloudflareSyncState) (*cf.API, error)
- func ExtractFirstSourceConfig[T any](syncState *v1alpha2.CloudflareSyncState) (*T, error)
- func FilterSourcesByKind(sources []v1alpha2.ConfigSource, kinds ...string) []v1alpha2.ConfigSource
- func GeneratePendingID(resourceName string) string
- func HandleNotFoundOnUpdate(err error) bool
- func HashChanged(previous, current string) bool
- func IsPendingID(cloudflareID string) bool
- func MustComputeHash(config interface{}) string
- func ParseSourceConfig[T any](source *v1alpha2.ConfigSource) (*T, error)
- func PredicateForResourceType(resourceType v1alpha2.SyncResourceType) predicate.Predicate
- func RequeueAfterError(_ error) time.Duration
- func RequeueAfterSuccess() time.Duration
- func RequireAccountID(syncState *v1alpha2.CloudflareSyncState) (string, error)
- func RequireZoneID(syncState *v1alpha2.CloudflareSyncState) (string, error)
- func UpdateCloudflareID(ctx context.Context, c client.Client, syncState *v1alpha2.CloudflareSyncState, ...)
- type BaseSyncController
- func (c *BaseSyncController) GetSyncState(ctx context.Context, name string) (*v1alpha2.CloudflareSyncState, error)
- func (c *BaseSyncController) SetSyncStatus(ctx context.Context, syncState *v1alpha2.CloudflareSyncState, ...) error
- func (*BaseSyncController) ShouldSync(syncState *v1alpha2.CloudflareSyncState, newHash string) bool
- func (*BaseSyncController) StoreAggregatedConfig(syncState *v1alpha2.CloudflareSyncState, config interface{}) error
- func (c *BaseSyncController) UpdateSyncStatus(ctx context.Context, syncState *v1alpha2.CloudflareSyncState, ...) error
- type Debouncer
- func (d *Debouncer) Cancel(key string) bool
- func (d *Debouncer) Debounce(key string, fn func())
- func (d *Debouncer) DebounceRequest(key string, req ctrl.Request, enqueue func(ctrl.Request)) bool
- func (d *Debouncer) Flush()
- func (d *Debouncer) GetDelay() time.Duration
- func (d *Debouncer) IsPending(key string) bool
- func (d *Debouncer) PendingCount() int
- type SyncError
- type SyncResult
Constants ¶
const DefaultDebounceDelay = 500 * time.Millisecond
DefaultDebounceDelay is the default delay before executing debounced operations. This allows multiple rapid changes to be coalesced into a single API call.
const PendingIDPrefix = "pending-"
PendingIDPrefix is the prefix used for Cloudflare IDs that haven't been created yet. When a SyncState is first created, the CloudflareID is set to "pending-<resource-name>" to indicate that the resource needs to be created in Cloudflare.
Variables ¶
This section is empty.
Functions ¶
func ComputeConfigHash ¶
ComputeConfigHash computes a SHA256 hash of the given configuration. The hash is used to detect changes and avoid unnecessary API calls. Returns a hex-encoded string of the hash.
func ComputeConfigHashDeterministic ¶
ComputeConfigHashDeterministic computes a deterministic hash by normalizing the JSON. This handles cases where map iteration order differs.
func CreateAPIClient ¶
func CreateAPIClient( ctx context.Context, c client.Client, syncState *v1alpha2.CloudflareSyncState, ) (*cf.API, error)
CreateAPIClient creates a Cloudflare API client from the credentials reference in a SyncState. This is the standard pattern used by all Sync Controllers.
func ExtractFirstSourceConfig ¶
func ExtractFirstSourceConfig[T any](syncState *v1alpha2.CloudflareSyncState) (*T, error)
ExtractFirstSourceConfig extracts configuration from the first source in a SyncState. This is the standard pattern for 1:1 mapping resources (DNS, Gateway, Device, etc.) where each Kubernetes resource maps to exactly one Cloudflare resource.
Returns an error if: - No sources are present - JSON unmarshaling fails - Configuration is empty/nil
func FilterSourcesByKind ¶
func FilterSourcesByKind(sources []v1alpha2.ConfigSource, kinds ...string) []v1alpha2.ConfigSource
FilterSourcesByKind returns sources matching the specified kinds.
func GeneratePendingID ¶
GeneratePendingID creates a pending ID for a new resource. The resource name is appended to distinguish between multiple pending resources.
func HandleNotFoundOnUpdate ¶
HandleNotFoundOnUpdate is a helper for the common pattern where an update fails because the resource was deleted externally. It returns true if the error indicates the resource was not found, allowing the caller to recreate it.
func HashChanged ¶
HashChanged compares two hashes and returns true if they differ. An empty previous hash always indicates a change.
func IsPendingID ¶
IsPendingID checks if the given Cloudflare ID indicates a resource that hasn't been created yet. Resources start with a pending ID and are updated with the real Cloudflare ID after successful creation.
func MustComputeHash ¶
func MustComputeHash(config interface{}) string
MustComputeHash computes a hash, panicking on error. Only use this for known-good configurations during initialization.
func ParseSourceConfig ¶
func ParseSourceConfig[T any](source *v1alpha2.ConfigSource) (*T, error)
ParseSourceConfig parses a source's configuration into the target struct. This is a helper for Sync Controllers to extract typed configuration.
func PredicateForResourceType ¶
func PredicateForResourceType(resourceType v1alpha2.SyncResourceType) predicate.Predicate
PredicateForResourceType creates a predicate that filters CloudflareSyncState events by resource type. This is the standard predicate used by all Sync Controllers to ensure they only process SyncStates of their specific type.
Usage:
ctrl.NewControllerManagedBy(mgr).
For(&v1alpha2.CloudflareSyncState{}).
WithEventFilter(common.PredicateForResourceType(v1alpha2.SyncResourceDNSRecord)).
Complete(r)
func RequeueAfterError ¶
RequeueAfterError returns a requeue duration appropriate for the error type. Permanent errors get longer delays, transient errors get shorter delays.
func RequeueAfterSuccess ¶
RequeueAfterSuccess returns a requeue duration for periodic refresh. Most syncs don't need periodic refresh (they're event-driven), so this returns 0.
func RequireAccountID ¶
func RequireAccountID(syncState *v1alpha2.CloudflareSyncState) (string, error)
RequireAccountID validates that the SyncState has an AccountID specified. This is required for account-scoped resources (Gateway, Device, Access, etc.).
func RequireZoneID ¶
func RequireZoneID(syncState *v1alpha2.CloudflareSyncState) (string, error)
RequireZoneID validates that the SyncState has a ZoneID specified. This is required for zone-scoped resources (DNS, Ruleset, etc.).
func UpdateCloudflareID ¶
func UpdateCloudflareID( ctx context.Context, c client.Client, syncState *v1alpha2.CloudflareSyncState, newID string, )
UpdateCloudflareID updates the CloudflareID in the SyncState spec. This is called after successfully creating a resource in Cloudflare to record the actual ID. Errors are logged but not returned since this is a non-fatal operation that will be corrected on the next reconcile.
Types ¶
type BaseSyncController ¶
BaseSyncController provides common functionality for all Sync Controllers. Each resource type (Tunnel, DNS, Access, etc.) extends this with specific aggregation and sync logic.
func NewBaseSyncController ¶
func NewBaseSyncController(c client.Client) *BaseSyncController
NewBaseSyncController creates a new BaseSyncController
func NewBaseSyncControllerWithDelay ¶
func NewBaseSyncControllerWithDelay(c client.Client, delay time.Duration) *BaseSyncController
NewBaseSyncControllerWithDelay creates a BaseSyncController with custom debounce delay
func (*BaseSyncController) GetSyncState ¶
func (c *BaseSyncController) GetSyncState(ctx context.Context, name string) (*v1alpha2.CloudflareSyncState, error)
GetSyncState retrieves a CloudflareSyncState by name
func (*BaseSyncController) SetSyncStatus ¶
func (c *BaseSyncController) SetSyncStatus( ctx context.Context, syncState *v1alpha2.CloudflareSyncState, status v1alpha2.SyncStatus, ) error
SetSyncStatus updates the SyncState status to the specified state. This is a convenience method for setting just the status without result.
func (*BaseSyncController) ShouldSync ¶
func (*BaseSyncController) ShouldSync(syncState *v1alpha2.CloudflareSyncState, newHash string) bool
ShouldSync determines if a sync is needed by comparing config hashes. Returns true if the configuration has changed since the last sync.
func (*BaseSyncController) StoreAggregatedConfig ¶
func (*BaseSyncController) StoreAggregatedConfig( syncState *v1alpha2.CloudflareSyncState, config interface{}, ) error
StoreAggregatedConfig stores the aggregated configuration in the SyncState status. This is useful for debugging and observability.
func (*BaseSyncController) UpdateSyncStatus ¶
func (c *BaseSyncController) UpdateSyncStatus( ctx context.Context, syncState *v1alpha2.CloudflareSyncState, status v1alpha2.SyncStatus, result *SyncResult, syncErr error, ) error
UpdateSyncStatus updates the SyncState status with the sync result. It handles both success and error cases, setting appropriate conditions.
type Debouncer ¶
type Debouncer struct {
// contains filtered or unexported fields
}
Debouncer coalesces multiple events into a single operation. When an event occurs, it waits for the delay period. If another event occurs during this period, the timer resets. The operation only executes when no new events occur within the delay period.
This is useful for: - Reducing Cloudflare API calls when multiple resources change rapidly - Handling bulk operations (e.g., creating multiple Ingresses) - Avoiding rate limiting from the Cloudflare API
func NewDebouncer ¶
NewDebouncer creates a new Debouncer with the specified delay. Use DefaultDebounceDelay for the standard 500ms delay.
func (*Debouncer) Cancel ¶
Cancel cancels a pending debounced operation. Returns true if an operation was cancelled, false if none was pending.
func (*Debouncer) Debounce ¶
Debounce schedules a function to be called after the delay. If called again with the same key before the delay expires, the timer is reset and only the latest function will be called.
The key should uniquely identify the operation (e.g., SyncState name).
func (*Debouncer) DebounceRequest ¶
DebounceRequest schedules a reconciliation request after the delay. Returns true if a new debounce was scheduled, false if one was already pending.
func (*Debouncer) Flush ¶
func (d *Debouncer) Flush()
Flush immediately executes all pending operations. This is useful during shutdown or testing.
func (*Debouncer) PendingCount ¶
PendingCount returns the number of pending debounced operations.
type SyncError ¶
type SyncError struct {
Op string // Operation that failed (e.g., "aggregate", "sync", "updateStatus")
Err error // Underlying error
Retries int // Number of retries attempted
}
SyncError wraps an error with additional sync context
type SyncResult ¶
type SyncResult struct {
// ConfigVersion is the version returned by Cloudflare after update
ConfigVersion int
// ConfigHash is the hash of the synced configuration
ConfigHash string
}
SyncResult contains the result of a successful sync operation