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 ¶
- type AccessPolicyContext
- func (apc *AccessPolicyContext) AllTargetsResolved() bool
- func (apc *AccessPolicyContext) ExtractHostnames(ctx context.Context, k8sClient client.Client) ([]string, error)
- func (apc *AccessPolicyContext) FailedTargets() []TargetInfo
- func (apc *AccessPolicyContext) GetTargetRefs() []cfgatev1alpha1.PolicyTargetReference
- func (apc *AccessPolicyContext) HasCrossNamespaceTargets() bool
- func (apc *AccessPolicyContext) HasFailedTargets() bool
- func (apc *AccessPolicyContext) RequiresMTLS() bool
- func (apc *AccessPolicyContext) RequiresServiceTokens() bool
- func (apc *AccessPolicyContext) ResolvedTargets() []TargetInfo
- func (apc *AccessPolicyContext) SuccessfullyResolvedTargets() []TargetInfo
- type DNSContext
- func (dc *DNSContext) DNSClient() *cloudflare.DNSService
- func (dc *DNSContext) GetAnnotationFilter() string
- func (dc *DNSContext) GetCommentTemplate() string
- func (dc *DNSContext) GetDefaultProxied() bool
- func (dc *DNSContext) GetDefaultTTL() int32
- func (dc *DNSContext) GetExplicitHostnames() []cfgatev1alpha1.DNSExplicitHostname
- func (dc *DNSContext) GetOwnerID() string
- func (dc *DNSContext) GetOwnershipPrefix() string
- func (dc *DNSContext) GetPolicy() cfgatev1alpha1.DNSPolicy
- func (dc *DNSContext) GetZoneID(zoneName string) string
- func (dc *DNSContext) HasExternalTarget() bool
- func (dc *DNSContext) HasGatewayRoutesEnabled() bool
- func (dc *DNSContext) HasTunnelRef() bool
- func (dc *DNSContext) OnlyDeleteManaged() bool
- func (dc *DNSContext) ResolvedTunnel() *cfgatev1alpha1.CloudflareTunnel
- func (dc *DNSContext) ResolvedZones() map[string]string
- func (dc *DNSContext) SetResolvedZoneID(zoneName, zoneID string)
- func (dc *DNSContext) ShouldCreateTXTRecords() bool
- func (dc *DNSContext) ShouldDeleteOnResourceRemoval() bool
- func (dc *DNSContext) ShouldDeleteOnRouteRemoval() bool
- func (dc *DNSContext) ShouldUseCommentOwnership() bool
- func (dc *DNSContext) TunnelDomain() string
- func (dc *DNSContext) TunnelName() string
- func (dc *DNSContext) TunnelNamespacedName() types.NamespacedName
- func (dc *DNSContext) ZoneForHostname(hostname string) (string, bool)
- type OriginConfig
- type PolicyRef
- type RouteContext
- func (rc *RouteContext) AddAttachedPolicy(ref PolicyRef)
- func (rc *RouteContext) AttachedPolicies() []PolicyRef
- func (rc *RouteContext) GetAccessPolicyAnnotation() string
- func (rc *RouteContext) GetHostnames() []string
- func (rc *RouteContext) HasAccessPolicyAnnotation() bool
- func (rc *RouteContext) OriginConfig() *OriginConfig
- type TargetInfo
- type TunnelContext
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 ¶
func (apc *AccessPolicyContext) GetTargetRefs() []cfgatev1alpha1.PolicyTargetReference
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 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.