context

package
v0.1.0-alpha.6 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package context provides wrapper types for clean separation between raw API types and processing logic. Based on Envoy Gateway's GatewayContext and ListenerContext patterns, aligned with cfgate's composable CRD architecture.

The package provides four primary context types, each wrapping a cfgate CRD or Gateway API resource with computed state and helper methods:

  • TunnelContext: Wraps CloudflareTunnel with resolved account ID and clients
  • DNSContext: Wraps CloudflareDNS with resolved tunnel reference and zones
  • AccessPolicyContext: Wraps CloudflareAccessPolicy with resolved targets
  • RouteContext: Wraps HTTPRoute/TCPRoute/UDPRoute/GRPCRoute with origin config

Context wrappers serve multiple purposes:

  • Cache computed values to avoid repeated calculation in reconcile loops
  • Provide type-safe access to resolved references
  • Encapsulate validation logic for cross-resource relationships
  • Capture partial resolution errors without failing the entire operation

TunnelContext

TunnelContext wraps CloudflareTunnel with resolved Cloudflare credentials:

tc := context.NewTunnelContext(tunnel, accountID, client)
accountID := tc.AccountID()
client := tc.TunnelClient()

Note: DNS management is handled separately by CloudflareDNS CRD. TunnelContext is tunnel-only and does not manage DNS records.

DNSContext

DNSContext wraps CloudflareDNS with resolved tunnel (or external target) and zone configuration:

dc, err := context.NewDNSContext(ctx, dns, k8sClient, dnsClient)
if err != nil {
    // Handle tunnel resolution error
}
tunnelDomain := dc.TunnelDomain()
shouldDelete := dc.ShouldDeleteOnResourceRemoval()

DNSContext supports both tunnelRef and externalTarget modes. When using tunnelRef, it validates the tunnel exists and has a domain ready in status.

AccessPolicyContext

AccessPolicyContext wraps CloudflareAccessPolicy with resolved targetRefs:

apc := context.NewAccessPolicyContext(ctx, policy, k8sClient)
if apc.HasFailedTargets() {
    // Handle resolution failures
}
hostnames, err := apc.ExtractHostnames(ctx, k8sClient)

Target resolution includes ReferenceGrant checking for cross-namespace references. Errors are captured per-target in TargetInfo.Error to allow partial resolution.

RouteContext

RouteContext provides a unified interface for all Gateway API route types:

rc := context.NewRouteContext(httpRoute)
hostnames := rc.GetHostnames()
config := rc.OriginConfig()

For TCPRoute and UDPRoute, hostnames come from the cfgate.io/hostname annotation since Gateway API has no spec.hostnames field for L4 routes.

Builder Functions

Builder functions create fully-initialized contexts from NamespacedName refs:

tc, err := context.BuildTunnelContext(ctx, k8sClient, cfClient, ref, accountID)
dc, err := context.BuildDNSContext(ctx, k8sClient, dnsClient, ref)
apc, err := context.BuildAccessPolicyContext(ctx, k8sClient, ref)
rc, err := context.BuildRouteContext(ctx, k8sClient, "HTTPRoute", ref)

Builder functions return nil (not error) when the target resource is not found, allowing callers to distinguish between "not found" and "error".

TargetInfo

TargetInfo represents a resolved policy target with resolution status:

type TargetInfo struct {
    Kind        string   // HTTPRoute, Gateway, etc.
    Namespace   string
    Name        string
    Resolved    bool
    SectionName *string  // Optional listener/rule selector
    Error       error    // Resolution error (nil if successful)
}

TargetInfo captures partial resolution results. A target may fail to resolve due to not being found or lacking a ReferenceGrant, but other targets in the same policy can still succeed.

Logging

Context constructors use logr with named logger hierarchy:

ctrl.Log.WithName("context").WithName("tunnel")
ctrl.Log.WithName("context").WithName("dns")
ctrl.Log.WithName("context").WithName("accesspolicy")
ctrl.Log.WithName("context").WithName("route")

Debug-level (V(1)) logs are emitted for resolution results and config parsing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessPolicyContext

type AccessPolicyContext struct {
	// Embedded policy resource
	*cfgatev1alpha1.CloudflareAccessPolicy
	// contains filtered or unexported fields
}

AccessPolicyContext wraps CloudflareAccessPolicy with resolved targets and helper methods for reconciliation.

func BuildAccessPolicyContext

func BuildAccessPolicyContext(
	ctx context.Context,
	k8sClient client.Client,
	ref types.NamespacedName,
) (*AccessPolicyContext, error)

BuildAccessPolicyContext creates an AccessPolicyContext with full initialization.

func NewAccessPolicyContext

func NewAccessPolicyContext(
	ctx context.Context,
	policy *cfgatev1alpha1.CloudflareAccessPolicy,
	k8sClient client.Client,
) *AccessPolicyContext

NewAccessPolicyContext creates an AccessPolicyContext with resolved targets. Target resolution errors are captured in TargetInfo.Error (partial resolution).

func (*AccessPolicyContext) AllTargetsResolved

func (apc *AccessPolicyContext) AllTargetsResolved() bool

AllTargetsResolved returns true if all targets resolved successfully.

func (*AccessPolicyContext) ExtractHostnames

func (apc *AccessPolicyContext) ExtractHostnames(
	ctx context.Context,
	k8sClient client.Client,
) ([]string, error)

ExtractHostnames extracts unique hostnames from resolved HTTPRoute/GRPCRoute targets.

func (*AccessPolicyContext) FailedTargets

func (apc *AccessPolicyContext) FailedTargets() []TargetInfo

FailedTargets returns targets that failed to resolve.

func (*AccessPolicyContext) GetTargetRefs

GetTargetRefs returns all target references (merged from targetRef and targetRefs).

func (*AccessPolicyContext) HasCrossNamespaceTargets

func (apc *AccessPolicyContext) HasCrossNamespaceTargets() bool

HasCrossNamespaceTargets returns true if any targets are in different namespace.

func (*AccessPolicyContext) HasFailedTargets

func (apc *AccessPolicyContext) HasFailedTargets() bool

HasFailedTargets returns true if any target failed to resolve.

func (*AccessPolicyContext) RequiresMTLS

func (apc *AccessPolicyContext) RequiresMTLS() bool

RequiresMTLS returns true if mTLS is configured and enabled.

func (*AccessPolicyContext) RequiresServiceTokens

func (apc *AccessPolicyContext) RequiresServiceTokens() bool

RequiresServiceTokens returns true if service tokens are configured.

func (*AccessPolicyContext) ResolvedTargets

func (apc *AccessPolicyContext) ResolvedTargets() []TargetInfo

ResolvedTargets returns all resolved target info.

func (*AccessPolicyContext) SuccessfullyResolvedTargets

func (apc *AccessPolicyContext) SuccessfullyResolvedTargets() []TargetInfo

SuccessfullyResolvedTargets returns only targets that resolved without error.

type DNSContext

type DNSContext struct {
	// Embedded DNS resource
	*cfgatev1alpha1.CloudflareDNS
	// contains filtered or unexported fields
}

DNSContext wraps CloudflareDNS with resolved dependencies. It provides a clean interface for the DNSReconciler to manage DNS records independent of the tunnel reconciler.

func BuildDNSContext

func BuildDNSContext(
	ctx context.Context,
	k8sClient client.Client,
	dnsClient *cloudflare.DNSService,
	ref types.NamespacedName,
) (*DNSContext, error)

BuildDNSContext creates a DNSContext with resolved tunnel and zones. Returns nil if DNS resource not found.

func NewDNSContext

func NewDNSContext(
	ctx context.Context,
	dns *cfgatev1alpha1.CloudflareDNS,
	k8sClient client.Client,
	dnsClient *cloudflare.DNSService,
) (*DNSContext, error)

NewDNSContext creates a DNSContext with resolved tunnel and zones. Returns error if the tunnel cannot be resolved (when tunnelRef is specified).

func (*DNSContext) DNSClient

func (dc *DNSContext) DNSClient() *cloudflare.DNSService

DNSClient returns the DNS API client.

func (*DNSContext) GetAnnotationFilter

func (dc *DNSContext) GetAnnotationFilter() string

GetAnnotationFilter returns the annotation filter for route selection.

func (*DNSContext) GetCommentTemplate

func (dc *DNSContext) GetCommentTemplate() string

GetCommentTemplate returns the comment template for ownership.

func (*DNSContext) GetDefaultProxied

func (dc *DNSContext) GetDefaultProxied() bool

GetDefaultProxied returns the default proxied setting.

func (*DNSContext) GetDefaultTTL

func (dc *DNSContext) GetDefaultTTL() int32

GetDefaultTTL returns the default TTL (1 for auto, or explicit value).

func (*DNSContext) GetExplicitHostnames

func (dc *DNSContext) GetExplicitHostnames() []cfgatev1alpha1.DNSExplicitHostname

GetExplicitHostnames returns explicitly configured hostnames.

func (*DNSContext) GetOwnerID

func (dc *DNSContext) GetOwnerID() string

GetOwnerID returns the owner identifier for TXT records. Defaults to namespace/name if not explicitly configured.

func (*DNSContext) GetOwnershipPrefix

func (dc *DNSContext) GetOwnershipPrefix() string

GetOwnershipPrefix returns the TXT ownership record prefix.

func (*DNSContext) GetPolicy

func (dc *DNSContext) GetPolicy() cfgatev1alpha1.DNSPolicy

GetPolicy returns the DNS policy (defaults to sync).

func (*DNSContext) GetZoneID

func (dc *DNSContext) GetZoneID(zoneName string) string

GetZoneID returns the zone ID for a zone name. Returns empty string if not resolved.

func (*DNSContext) HasExternalTarget

func (dc *DNSContext) HasExternalTarget() bool

HasExternalTarget returns true if this DNS context uses an external target.

func (*DNSContext) HasGatewayRoutesEnabled

func (dc *DNSContext) HasGatewayRoutesEnabled() bool

HasGatewayRoutesEnabled returns true if Gateway API routes are a hostname source.

func (*DNSContext) HasTunnelRef

func (dc *DNSContext) HasTunnelRef() bool

HasTunnelRef returns true if this DNS context uses a tunnel reference.

func (*DNSContext) OnlyDeleteManaged

func (dc *DNSContext) OnlyDeleteManaged() bool

OnlyDeleteManaged returns true if only cfgate-managed records should be cleaned up. nil defaults to true (only managed by default).

func (*DNSContext) ResolvedTunnel

func (dc *DNSContext) ResolvedTunnel() *cfgatev1alpha1.CloudflareTunnel

ResolvedTunnel returns the resolved CloudflareTunnel (nil if using externalTarget).

func (*DNSContext) ResolvedZones

func (dc *DNSContext) ResolvedZones() map[string]string

ResolvedZones returns the zone name to ID mapping. IDs may be empty if not pre-configured and not yet resolved.

func (*DNSContext) SetResolvedZoneID

func (dc *DNSContext) SetResolvedZoneID(zoneName, zoneID string)

SetResolvedZoneID updates the zone ID after API lookup.

func (*DNSContext) ShouldCreateTXTRecords

func (dc *DNSContext) ShouldCreateTXTRecords() bool

ShouldCreateTXTRecords returns true if TXT ownership tracking is enabled.

func (*DNSContext) ShouldDeleteOnResourceRemoval

func (dc *DNSContext) ShouldDeleteOnResourceRemoval() bool

ShouldDeleteOnResourceRemoval returns true if records should be deleted when CloudflareDNS is deleted. nil defaults to true (delete by default).

func (*DNSContext) ShouldDeleteOnRouteRemoval

func (dc *DNSContext) ShouldDeleteOnRouteRemoval() bool

ShouldDeleteOnRouteRemoval returns true if records should be deleted when routes are removed. nil defaults to true (delete by default).

func (*DNSContext) ShouldUseCommentOwnership

func (dc *DNSContext) ShouldUseCommentOwnership() bool

ShouldUseCommentOwnership returns true if comment-based ownership is enabled.

func (*DNSContext) TunnelDomain

func (dc *DNSContext) TunnelDomain() string

TunnelDomain returns the tunnel's CNAME target domain (e.g., {tunnelId}.cfargotunnel.com) or the external target value.

func (*DNSContext) TunnelName

func (dc *DNSContext) TunnelName() string

TunnelName returns the tunnel's name (empty if using externalTarget).

func (*DNSContext) TunnelNamespacedName

func (dc *DNSContext) TunnelNamespacedName() types.NamespacedName

TunnelNamespacedName returns the tunnel's namespaced name. Returns empty NamespacedName if using externalTarget.

func (*DNSContext) ZoneForHostname

func (dc *DNSContext) ZoneForHostname(hostname string) (string, bool)

ZoneForHostname returns the matching zone for a hostname. Uses suffix matching against configured zones.

type OriginConfig

type OriginConfig struct {
	Protocol  string        // http, https, tcp, udp
	SSLVerify bool          // whether to verify TLS certificates
	Timeout   time.Duration // connection timeout
	Hostname  string        // For TCPRoute/UDPRoute (from annotation)
}

OriginConfig holds parsed origin annotations.

type PolicyRef

type PolicyRef struct {
	Namespace string
	Name      string
	Kind      string // CloudflareAccessPolicy, etc.
}

PolicyRef identifies an attached policy.

type RouteContext

type RouteContext struct {
	// Kind of route (HTTPRoute, TCPRoute, UDPRoute, GRPCRoute)
	Kind string

	// Route is the underlying route object (use type switch to access)
	Route client.Object

	// Namespace and Name for convenience
	Namespace string
	Name      string
	// contains filtered or unexported fields
}

RouteContext wraps any route type with attached policies and computed state.

func BuildRouteContext

func BuildRouteContext(
	ctx context.Context,
	k8sClient client.Client,
	kind string,
	ref types.NamespacedName,
) (*RouteContext, error)

BuildRouteContext creates a RouteContext for any route type.

func NewRouteContext

func NewRouteContext(route client.Object) *RouteContext

NewRouteContext creates a RouteContext for any route type.

func (*RouteContext) AddAttachedPolicy

func (rc *RouteContext) AddAttachedPolicy(ref PolicyRef)

AddAttachedPolicy adds a policy reference.

func (*RouteContext) AttachedPolicies

func (rc *RouteContext) AttachedPolicies() []PolicyRef

AttachedPolicies returns policies attached to this route.

func (*RouteContext) GetAccessPolicyAnnotation

func (rc *RouteContext) GetAccessPolicyAnnotation() string

GetAccessPolicyAnnotation returns the access-policy annotation value.

func (*RouteContext) GetHostnames

func (rc *RouteContext) GetHostnames() []string

GetHostnames extracts hostnames from the route. Returns annotation hostname for TCP/UDP routes, spec.hostnames for HTTP/GRPC.

func (*RouteContext) HasAccessPolicyAnnotation

func (rc *RouteContext) HasAccessPolicyAnnotation() bool

HasAccessPolicyAnnotation returns true if access-policy annotation is set.

func (*RouteContext) OriginConfig

func (rc *RouteContext) OriginConfig() *OriginConfig

OriginConfig returns parsed origin configuration.

type TargetInfo

type TargetInfo struct {
	// Kind of the target resource (HTTPRoute, Gateway, etc.)
	Kind string

	// Namespace of the target resource
	Namespace string

	// Name of the target resource
	Name string

	// Resolved indicates if the target was successfully resolved
	Resolved bool

	// SectionName targets specific listener (Gateway) or rule (Route)
	SectionName *string

	// Error contains the resolution error (nil if Resolved=true)
	Error error
}

TargetInfo holds information about a resolved policy target.

func (*TargetInfo) IsGRPCRoute

func (ti *TargetInfo) IsGRPCRoute() bool

IsGRPCRoute returns true if target is a GRPCRoute.

func (*TargetInfo) IsGateway

func (ti *TargetInfo) IsGateway() bool

IsGateway returns true if target is a Gateway.

func (*TargetInfo) IsHTTPRoute

func (ti *TargetInfo) IsHTTPRoute() bool

IsHTTPRoute returns true if target is an HTTPRoute.

func (*TargetInfo) IsTCPRoute

func (ti *TargetInfo) IsTCPRoute() bool

IsTCPRoute returns true if target is a TCPRoute.

func (*TargetInfo) IsUDPRoute

func (ti *TargetInfo) IsUDPRoute() bool

IsUDPRoute returns true if target is a UDPRoute.

func (*TargetInfo) NamespacedName

func (ti *TargetInfo) NamespacedName() types.NamespacedName

NamespacedName returns the namespaced name for k8s lookups.

func (*TargetInfo) String

func (ti *TargetInfo) String() string

String returns a human-readable representation.

type TunnelContext

type TunnelContext struct {
	// Embedded tunnel resource
	*cfgatev1alpha1.CloudflareTunnel
	// contains filtered or unexported fields
}

TunnelContext wraps CloudflareTunnel with computed state and helper methods. It provides a clean interface for reconcilers to work with tunnels without repeatedly computing derived values.

Note: DNS management is handled separately by CloudflareDNS CRD. TunnelContext is tunnel-only and does not manage DNS records.

func BuildTunnelContext

func BuildTunnelContext(
	ctx context.Context,
	k8sClient client.Client,
	cfClient cloudflare.Client,
	ref types.NamespacedName,
	accountID string,
) (*TunnelContext, error)

BuildTunnelContext creates a TunnelContext with full initialization. Returns nil and logs warning if tunnel not found.

Note: DNS is handled separately by CloudflareDNS CRD and its reconciler.

func NewTunnelContext

func NewTunnelContext(
	tunnel *cfgatev1alpha1.CloudflareTunnel,
	accountID string,
	tunnelClient cloudflare.Client,
) *TunnelContext

NewTunnelContext creates a TunnelContext with resolved clients. Returns error if credentials cannot be resolved.

func (*TunnelContext) AccountID

func (tc *TunnelContext) AccountID() string

AccountID returns the resolved Cloudflare account ID.

func (*TunnelContext) TunnelClient

func (tc *TunnelContext) TunnelClient() cloudflare.Client

TunnelClient returns the tunnel API client.

Jump to

Keyboard shortcuts

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