Documentation
¶
Overview ¶
Package common provides shared utilities for controllers in the simplified 3-layer architecture. Controllers can directly call Cloudflare API using the APIClientFactory.
Package common provides shared utilities for controllers in the simplified 3-layer architecture.
Architecture Overview ¶
The new architecture simplifies the operator from 6 layers to 3 layers:
Old: CRD → Controller → Service → SyncState → SyncController → CF API New: CRD → Controller → CF API
Key Components ¶
- APIClientFactory: Creates and manages Cloudflare API clients
- Requeue utilities: Standard intervals and backoff for reconciliation
- Re-exports from parent controller package: Status, Finalizer, Event, Deletion utilities
Usage Pattern ¶
Controllers should follow this pattern:
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
obj := &v1alpha2.MyResource{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// Handle deletion
if !obj.DeletionTimestamp.IsZero() {
return r.handleDeletion(ctx, obj)
}
// Get API client
apiResult, err := r.APIFactory.GetClient(ctx, common.APIClientOptions{
CloudflareDetails: &obj.Spec.Cloudflare,
Namespace: obj.Namespace,
StatusAccountID: obj.Status.AccountID,
})
if err != nil {
return r.setErrorStatus(ctx, obj, err)
}
// Ensure finalizer
if added, err := controller.EnsureFinalizer(ctx, r.Client, obj, FinalizerName); err != nil {
return ctrl.Result{}, err
} else if added {
return ctrl.Result{Requeue: true}, nil
}
// Direct API call
result, err := apiResult.API.SomeOperation(ctx, ...)
if err != nil {
return r.setErrorStatus(ctx, obj, err)
}
// Direct status write (no intermediate layer!)
return r.setSuccessStatus(ctx, obj, result)
}
Benefits ¶
- Simpler data flow: One CRD → One controller → Direct API call
- No intermediate SyncState: Status written directly to original CRD
- Independent polling: Each controller has its own Informer, no interference
- Less code: ~13,000 lines removed (service + sync layers)
- Easier debugging: Direct data path, no need to correlate multiple resources
Index ¶
- Constants
- Variables
- func IsFailure(stage string) bool
- func IsInProgress(stage string) bool
- func IsSuccess(stage string) bool
- func IsTerminal(stage string) bool
- func NoRequeue() ctrl.Result
- func RequeueForError(err error, retryCount int) ctrl.Result
- func RequeueLong() ctrl.Result
- func RequeueMedium() ctrl.Result
- func RequeueResult(after time.Duration) ctrl.Result
- func RequeueShort() ctrl.Result
- func RequeueVeryLong() ctrl.Result
- func RequeueWithBackoff(baseDelay time.Duration, retryCount int, maxDelay time.Duration) ctrl.Result
- func SetOperatorNamespace(ns string)
- func ShouldRequeueForError(err error) bool
- type APIClientFactory
- type APIClientOptions
- type APIClientResult
Constants ¶
const ( // RequeueIntervalShort is used for quick retries after transient errors. RequeueIntervalShort = 10 * time.Second // RequeueIntervalMedium is used for polling in-progress operations. RequeueIntervalMedium = 30 * time.Second // RequeueIntervalLong is used for rate limit backoff or long-running operations. RequeueIntervalLong = 1 * time.Minute // RequeueIntervalVeryLong is used for permanent errors that might recover. RequeueIntervalVeryLong = 5 * time.Minute // PollingIntervalDeployment is used for polling deployment status. PollingIntervalDeployment = 30 * time.Second // PollingIntervalDNS is used for polling DNS propagation. PollingIntervalDNS = 1 * time.Minute )
Standard requeue intervals for controllers.
Variables ¶
var OperatorNamespace = "cloudflare-operator-system"
OperatorNamespace is the namespace where the operator runs. This is used for cluster-scoped resources that need to look up secrets.
Functions ¶
func IsInProgress ¶
IsInProgress checks if the stage indicates an in-progress deployment. This is used to determine if polling should continue.
func IsTerminal ¶
IsTerminal checks if the stage indicates a terminal state. Terminal states don't require further polling.
func RequeueForError ¶
RequeueForError returns an appropriate requeue result based on the error type. It uses exponential backoff for transient errors.
func RequeueMedium ¶
RequeueMedium returns a result for medium-term retry.
func RequeueResult ¶
RequeueResult returns a ctrl.Result for requeuing after the specified duration.
func RequeueVeryLong ¶
RequeueVeryLong returns a result for very long retry.
func RequeueWithBackoff ¶
func RequeueWithBackoff(baseDelay time.Duration, retryCount int, maxDelay time.Duration) ctrl.Result
RequeueWithBackoff returns a result with exponential backoff delay.
func SetOperatorNamespace ¶
func SetOperatorNamespace(ns string)
SetOperatorNamespace sets the operator namespace. This should be called during operator initialization.
func ShouldRequeueForError ¶
ShouldRequeueForError returns true if the error warrants a requeue. Permanent errors (NotFound, Auth, Validation) return false.
Types ¶
type APIClientFactory ¶
type APIClientFactory struct {
// contains filtered or unexported fields
}
APIClientFactory creates and caches Cloudflare API clients. It provides a simple interface for controllers to get API clients without dealing with credentials resolution complexity.
func NewAPIClientFactory ¶
func NewAPIClientFactory(c client.Client, log logr.Logger) *APIClientFactory
NewAPIClientFactory creates a new APIClientFactory.
func (*APIClientFactory) GetClient ¶
func (f *APIClientFactory) GetClient(ctx context.Context, opts APIClientOptions) (*APIClientResult, error)
GetClient returns a Cloudflare API client based on the provided options. It resolves credentials and creates or reuses a cached client.
func (*APIClientFactory) GetClientForCredentials ¶
func (f *APIClientFactory) GetClientForCredentials(ctx context.Context, credentialsName string) (*APIClientResult, error)
GetClientForCredentials returns a Cloudflare API client for the given CloudflareCredentials name. This is a simplified version for resources that only need credentials name.
type APIClientOptions ¶
type APIClientOptions struct {
// CloudflareDetails contains the Cloudflare configuration from the resource spec.
// Used for resources with full CloudflareDetails (Tunnel, PagesProject, etc.)
CloudflareDetails *networkingv1alpha2.CloudflareDetails
// CredentialsRef is a simple reference to CloudflareCredentials.
// Used for resources with simplified credentials (R2Bucket, etc.)
CredentialsRef *networkingv1alpha2.CredentialsReference
// Namespace is the namespace for resolving legacy inline secrets.
// For cluster-scoped resources, leave empty or use OperatorNamespace.
Namespace string
// AccountID override from status (already validated).
StatusAccountID string
// ZoneID override from status (already validated).
StatusZoneID string
}
APIClientOptions contains options for getting an API client.
type APIClientResult ¶
type APIClientResult struct {
// API is the Cloudflare API client.
API *cf.API
// AccountID is the resolved Cloudflare account ID.
AccountID string
// ZoneID is the resolved Cloudflare zone ID (may be empty).
ZoneID string
// Domain is the resolved Cloudflare domain (may be empty).
Domain string
// CredentialsName is the name of the CloudflareCredentials used.
CredentialsName string
}
APIClientResult contains the API client and resolved metadata.