controller

package
v1.23.2 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultFailureThreshold is the number of consecutive API failures that open the circuit.
	DefaultFailureThreshold = 5
	// DefaultCooldownPeriod is the time to wait after the circuit opens before probing.
	DefaultCooldownPeriod = 5 * time.Minute
)
View Source
const (
	// TypeReady indicates that the resource is ready for use
	TypeReady = "Ready"
	// TypeSynced indicates that the last sync to UptimeRobot succeeded
	TypeSynced = "Synced"
	// TypeError indicates that the last reconciliation encountered an error
	TypeError = "Error"
	// TypeDeleting indicates that the resource is being deleted (moved from finalizer.go to avoid duplication)
	TypeDeleting = "Deleting"
)

Standard condition types for all CRDs

View Source
const (
	// ReasonReconcileSuccess indicates successful reconciliation
	ReasonReconcileSuccess = "ReconcileSuccess"
	// ReasonReconcileError indicates reconciliation error
	ReasonReconcileError = "ReconcileError"
	// ReasonReconcileDegraded indicates reconciliation completed but some
	// auxiliary data could not be fetched (e.g. upstream list endpoint failed).
	ReasonReconcileDegraded = "ReconcileDegraded"
	// ReasonSyncSuccess indicates successful sync to UptimeRobot
	ReasonSyncSuccess = "SyncSuccess"
	// ReasonSyncError indicates sync error to UptimeRobot
	ReasonSyncError = "SyncError"
	// ReasonSyncSkipped indicates sync was intentionally skipped
	ReasonSyncSkipped = "SyncSkipped"
	// ReasonAPIError indicates UptimeRobot API error
	ReasonAPIError = "APIError"
	// ReasonSecretNotFound indicates secret not found
	ReasonSecretNotFound = "SecretNotFound"
	// ReasonDependencyNotReady indicates a referenced dependency is not ready yet
	ReasonDependencyNotReady = "DependencyNotReady"
	// ReasonCircuitBreakerOpen indicates reconciliation is paused while the API
	// circuit breaker is open.
	ReasonCircuitBreakerOpen = "CircuitBreakerOpen"
	// ReasonCircuitBreakerBlocked indicates reconciliation is paused while the API
	// circuit breaker is blocking calls in a non-open state (for example,
	// half-open while a probe is already in flight).
	ReasonCircuitBreakerBlocked = "CircuitBreakerBlocked"
	// ReasonValidationFailed indicates the resource spec failed a controller-side
	// validation check that should normally be caught by the CRD validating webhook.
	ReasonValidationFailed = "ValidationFailed"
)

Standard condition reasons

View Source
const (
	// SkipCleanupAnnotation allows users to force-skip cleanup if API is permanently down
	SkipCleanupAnnotation = "uptimerobot.com/skip-cleanup"
	// CleanupStartTimeAnnotation tracks when cleanup first started
	CleanupStartTimeAnnotation = "uptimerobot.com/cleanup-start-time"
	// DefaultCleanupTimeout is the maximum duration to attempt cleanup before forcing finalizer removal
	DefaultCleanupTimeout = 10 * time.Minute
)
View Source
const (
	// ReasonCleanupStarted indicates cleanup has started
	ReasonCleanupStarted = "CleanupStarted"
	// ReasonCleanupInProgress indicates cleanup is in progress with retries
	ReasonCleanupInProgress = "CleanupInProgress"
	// ReasonCleanupSuccess indicates cleanup completed successfully
	ReasonCleanupSuccess = "CleanupSuccess"
	// ReasonCleanupSkipped indicates cleanup was skipped due to annotation
	ReasonCleanupSkipped = "CleanupSkipped"
	// ReasonCleanupTimeout indicates cleanup timed out and finalizer was force-removed
	ReasonCleanupTimeout = "CleanupTimeout"
	// ReasonCleanupError indicates cleanup failed with an error
	ReasonCleanupError = "CleanupError"
)

Standard deletion condition reasons

View Source
const (
	// BackoffInitialDelay is the initial delay for exponential backoff (5 seconds)
	BackoffInitialDelay = 5 * time.Second
	// BackoffMaxDelay is the maximum delay between retries (5 minutes)
	BackoffMaxDelay = 5 * time.Minute
	// BackoffJitterFraction is the fraction of delay to use for jitter (0.15 = 15%)
	BackoffJitterFraction = 0.15

	// SyncJitterFraction is the fraction of jitter added to periodic sync intervals (±10%).
	// This spreads reconciliations evenly across the sync window to avoid burst API traffic.
	SyncJitterFraction = 0.10

	// AnnotationRetryCount tracks the number of retry attempts for a resource
	AnnotationRetryCount = "uptimerobot.com/retry-count"
)
View Source
const (
	// AdoptIDAnnotation is used to specify an existing monitor ID to adopt
	AdoptIDAnnotation = "uptimerobot.com/adopt-id"
)

Variables

View Source
var (
	ErrKeyNotFound = errors.New("secret key not found")
	ErrEmptyKey    = errors.New("secret key value is empty")
)
View Source
var (
	ErrNoDefaultAccount       = errors.New("no default account")
	ErrMultipleDefaultAccount = errors.New("more than 1 default account found")
)
View Source
var (
	ErrNoDefaultContact       = errors.New("no default contact")
	ErrMultipleDefaultContact = errors.New("more than 1 default contact found")
)
View Source
var (
	ErrContactMissingID = errors.New("contact missing ID")
	ErrSecretMissingKey = errors.New("secret missing key")
)
View Source
var ClusterResourceNamespace = "uptime-robot-system"

DefaultCircuitBreaker is the package-level circuit breaker shared by all controllers.

View Source
var IngressAnnotationPrefix = "uptimerobot.com/"

Functions

func AddSyncJitter added in v1.22.0

func AddSyncJitter(d time.Duration) time.Duration

AddSyncJitter adds ±10% random jitter to a periodic sync interval. This spreads reconciliations evenly across the sync window, preventing burst API traffic when many resources share the same syncInterval. Example: 24h ± 2.4h = requeue between 21.6h and 26.4h.

func CalculateRequeueDelay added in v1.19.0

func CalculateRequeueDelay(attempt int) time.Duration

CalculateRequeueDelay calculates exponential backoff delay with jitter. The delay follows the pattern: baseDelay * 2^attempt For example with baseDelay=5s: 5s, 10s, 20s, 40s, 80s, capped at 5m Jitter of ±15% is added to prevent thundering herd across resources.

func GetAccount

func GetAccount(ctx context.Context, c client.Client, account *uptimerobotv1.Account, name string) error

func GetApiKey

func GetApiKey(ctx context.Context, c client.Client, account *uptimerobotv1.Account) (string, error)

func GetContact

func GetContact(ctx context.Context, c client.Client, contact *uptimerobotv1.Contact, name string) error

func GetRetryCount added in v1.19.0

func GetRetryCount(annotations map[string]string) int

GetRetryCount extracts the retry count from resource annotations. Returns 0 if the annotation is not present or invalid.

func HandleReconcileError added in v1.19.0

func HandleReconcileError(err error, retryCount int) (ctrl.Result, error)

HandleReconcileError processes an error from reconciliation and returns the appropriate ctrl.Result and error to return from Reconcile(). For transient errors, it returns RequeueAfter with exponential backoff. For permanent errors, it returns the error directly without requeue. For nil errors (success), it resets retry count and returns no error.

func IncrementRetryCount added in v1.19.0

func IncrementRetryCount(annotations map[string]string) map[string]string

IncrementRetryCount increments the retry count annotation. If annotations map is nil, it creates a new one.

func InitializeCleanupTracking added in v1.13.1

func InitializeCleanupTracking(ctx context.Context, k8sClient client.Client, obj client.Object) error

InitializeCleanupTracking sets the cleanup start time annotation if not already set

func IsPermanentError added in v1.19.0

func IsPermanentError(err error) bool

IsPermanentError checks if an error is permanent and should not be retried. Permanent errors include: - 400 Bad Request (validation errors) - 401 Unauthorized (invalid API key) - 403 Forbidden (insufficient permissions) - 404 Not Found (when not during adoption/lookup) - Validation errors (missing fields, invalid values)

func IsTransientError added in v1.19.0

func IsTransientError(err error) bool

IsTransientError checks if an error should trigger exponential backoff retry. Transient errors include: - 5xx server errors (500, 502, 503, 504) - 429 Too Many Requests - Network timeouts - Connection errors (refused, reset, broken pipe) - EOF errors during request/response

func ResetRetryCount added in v1.19.0

func ResetRetryCount(annotations map[string]string)

ResetRetryCount removes the retry count annotation.

func SetCondition added in v1.10.0

func SetCondition(conditions *[]metav1.Condition, conditionType string, status metav1.ConditionStatus, reason, message string, observedGeneration int64)

SetCondition sets or updates a condition in the conditions list

func SetDeletingCondition added in v1.13.1

func SetDeletingCondition(conditions *[]metav1.Condition, reason, message string, observedGeneration int64)

SetDeletingCondition sets the Deleting condition

func SetErrorCondition added in v1.10.0

func SetErrorCondition(conditions *[]metav1.Condition, hasError bool, reason, message string, observedGeneration int64)

SetErrorCondition sets the Error condition

func SetReadyCondition added in v1.10.0

func SetReadyCondition(conditions *[]metav1.Condition, ready bool, reason, message string, observedGeneration int64)

SetReadyCondition sets the Ready condition

func SetSyncedCondition added in v1.10.0

func SetSyncedCondition(conditions *[]metav1.Condition, synced bool, reason, message string, observedGeneration int64)

SetSyncedCondition sets the Synced condition

Types

type AccountReconciler

type AccountReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

AccountReconciler reconciles a Account object

func (*AccountReconciler) Reconcile

func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.2/pkg/reconcile

func (*AccountReconciler) SetupWithManager

func (r *AccountReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type CircuitBreaker added in v1.22.0

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

CircuitBreaker implements per-account API protection. It tracks consecutive API failures keyed by account name. After reaching failureThreshold consecutive failures the circuit opens and API calls are skipped. After cooldownPeriod the circuit transitions to HalfOpen so a single probe call can test whether the API has recovered. Thread-safe.

func NewCircuitBreaker added in v1.22.0

func NewCircuitBreaker(failureThreshold int, cooldownPeriod time.Duration) *CircuitBreaker

NewCircuitBreaker returns a CircuitBreaker with the given thresholds. Invalid inputs are clamped to defaults: failureThreshold must be >= 1, cooldownPeriod must be > 0.

func (*CircuitBreaker) Allow added in v1.22.0

func (cb *CircuitBreaker) Allow(accountKey string) bool

Allow returns true when a reconciliation should proceed with an API call. Returns false when the circuit is not allowing traffic (Open, or HalfOpen with a probe already in flight). In HalfOpen exactly one probe call is allowed through; all subsequent callers are blocked until RecordSuccess or RecordFailure is called.

func (*CircuitBreaker) ConsecutiveFailures added in v1.22.0

func (cb *CircuitBreaker) ConsecutiveFailures(accountKey string) int

ConsecutiveFailures returns the current consecutive failure count for an account key.

func (*CircuitBreaker) CooldownPeriod added in v1.22.0

func (cb *CircuitBreaker) CooldownPeriod() time.Duration

CooldownPeriod returns the configured cooldown duration. cooldownPeriod is immutable after construction so no lock is needed.

func (*CircuitBreaker) RecordFailure added in v1.22.0

func (cb *CircuitBreaker) RecordFailure(accountKey string) bool

RecordFailure increments the consecutive failure counter. If the circuit is HalfOpen (probe failed), it immediately reopens. If the counter reaches failureThreshold from Closed, the circuit opens. Returns true if the circuit transitioned to Open on this call.

func (*CircuitBreaker) RecordSuccess added in v1.22.0

func (cb *CircuitBreaker) RecordSuccess(accountKey string) bool

RecordSuccess closes the circuit and resets the failure counter. Returns true if the circuit transitioned from Open or HalfOpen to Closed (i.e. recovery just completed).

func (*CircuitBreaker) Remove added in v1.22.0

func (cb *CircuitBreaker) Remove(accountKey string)

Remove deletes the circuit entry for accountKey, freeing memory for accounts that no longer exist.

func (*CircuitBreaker) State added in v1.22.0

func (cb *CircuitBreaker) State(accountKey string) CircuitState

State returns the current CircuitState for accountKey. NOTE: this may transition Open → HalfOpen after the cooldown elapses. Allow() performs the same promotion.

type CircuitState added in v1.22.0

type CircuitState int

CircuitState represents the operational state of a circuit breaker.

const (
	// CircuitClosed is the normal operating state — API calls proceed as usual.
	// Explicit values are load-bearing: they map directly to the
	// uptimerobot_circuit_breaker_state Prometheus gauge.
	CircuitClosed CircuitState = 0
	// CircuitOpen means too many consecutive failures occurred; API calls are skipped.
	CircuitOpen CircuitState = 1
	// CircuitHalfOpen is the probe state — one call is allowed to test recovery.
	CircuitHalfOpen CircuitState = 2
)

func (CircuitState) String added in v1.22.0

func (s CircuitState) String() string

String returns a human-readable label for the circuit state.

type CleanupFunc added in v1.13.1

type CleanupFunc func(ctx context.Context) error

CleanupFunc is a function that performs the actual cleanup operation

type CleanupOptions added in v1.13.1

type CleanupOptions struct {
	// Object is the resource being deleted
	Object client.Object
	// Conditions is the status conditions array to update
	Conditions *[]metav1.Condition
	// ObservedGeneration is the current observed generation
	ObservedGeneration int64
	// Recorder is used to emit events
	Recorder record.EventRecorder
	// CleanupTimeout is the maximum duration to attempt cleanup
	CleanupTimeout time.Duration
	// CleanupFunc performs the actual cleanup operation
	CleanupFunc CleanupFunc
}

CleanupOptions configures cleanup behavior

type CleanupResult added in v1.13.1

type CleanupResult struct {
	// Success indicates if cleanup completed successfully
	Success bool
	// ForceRemove indicates the finalizer should be removed regardless of success
	ForceRemove bool
	// RequeueAfter is the duration to wait before retrying (if not successful and not force-removed)
	RequeueAfter time.Duration
	// Message is a human-readable status message
	Message string
}

CleanupResult represents the outcome of a cleanup attempt

func HandleFinalizerCleanup added in v1.13.1

func HandleFinalizerCleanup(ctx context.Context, opts CleanupOptions) (CleanupResult, error)

HandleFinalizerCleanup implements retry and timeout logic for finalizer cleanup

type ContactReconciler

type ContactReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

ContactReconciler reconciles a Contact object

func (*ContactReconciler) Reconcile

func (r *ContactReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.2/pkg/reconcile

func (*ContactReconciler) SetupWithManager

func (r *ContactReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type IngressReconciler

type IngressReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

IngressReconciler reconciles a Ingress object

func (*IngressReconciler) Reconcile

func (r *IngressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.2/pkg/reconcile

func (*IngressReconciler) SetupWithManager

func (r *IngressReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type IntegrationAccountReferencer added in v1.22.7

type IntegrationAccountReferencer interface {
	GetAccountRef() corev1.LocalObjectReference
}

IntegrationAccountReferencer is satisfied by any integration CRD that references a parent Account. It lets the Account reconciler enqueue an Account when one of its integration children changes without each integration needing a bespoke mapper.

To bridge a new integration CRD:

  1. Add a GetAccountRef() corev1.LocalObjectReference method on the CRD type.
  2. Add a .Watches(&NewIntegration{}, handler.EnqueueRequestsFromMapFunc(r.mapIntegrationToAccount)) line in AccountReconciler.SetupWithManager.
  3. Append the integration's UptimeRobot API type string to uptimerobot.BridgedIntegrationTypes so it is surfaced in Account status and resolvable via Contact friendly-name lookup.

The interface lives here (not in the api package) because controller-gen's deepcopy generator cannot process interface types in api/v1alpha1.

type MaintenanceWindowReconciler added in v1.5.0

type MaintenanceWindowReconciler struct {
	client.Client
	APIReader client.Reader
	Scheme    *runtime.Scheme
	Recorder  record.EventRecorder
}

MaintenanceWindowReconciler reconciles a MaintenanceWindow object

func (*MaintenanceWindowReconciler) Reconcile added in v1.5.0

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

func (*MaintenanceWindowReconciler) SetupWithManager added in v1.5.0

func (r *MaintenanceWindowReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type MonitorGroupReconciler added in v1.6.0

type MonitorGroupReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

MonitorGroupReconciler orchestrates MonitorGroup lifecycle

func (*MonitorGroupReconciler) Reconcile added in v1.6.0

func (r *MonitorGroupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile implements the reconciliation loop

func (*MonitorGroupReconciler) SetupWithManager added in v1.6.0

func (r *MonitorGroupReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager configures the controller with manager

type MonitorReconciler

type MonitorReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

MonitorReconciler reconciles a Monitor object

func (*MonitorReconciler) Reconcile

func (r *MonitorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.2/pkg/reconcile

func (*MonitorReconciler) SetupWithManager

func (r *MonitorReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type SlackIntegrationReconciler added in v1.8.0

type SlackIntegrationReconciler struct {
	client.Client
	Scheme   *runtime.Scheme
	Recorder record.EventRecorder
}

SlackIntegrationReconciler reconciles a SlackIntegration object.

func (*SlackIntegrationReconciler) Reconcile added in v1.8.0

Reconcile reconciles SlackIntegration resources to UptimeRobot integrations.

func (*SlackIntegrationReconciler) SetupWithManager added in v1.8.0

func (r *SlackIntegrationReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

Jump to

Keyboard shortcuts

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