Documentation
¶
Overview ¶
Package gatewayapi contains the edge proxy's Gateway API controller: it watches Gateway API HTTPRoutes, TCPRoutes, and TLSRoutes attached to a Gateway of the aether GatewayClass and projects them into the edge data plane (proposal 018 — north-south). It is the edge's only routing API (the VirtualHost CRD was retired); routing is direct-to-pod mTLS.
Index ¶
Constants ¶
const ( // LabelEdgeGateway is the label applied to per-Gateway LoadBalancer Services for // GC (value = "<namespace>.<name>"). The edge reconciler lists Services with this // label to find stale per-Gateway Services and delete them when their Gateway is // gone. LabelEdgeGateway = "aether.io/edge-gateway" // AnnotationMetalLBLoadBalancerIPs is the MetalLB annotation that pins a // LoadBalancer Service to a specific IP from the MetalLB pool. AnnotationMetalLBLoadBalancerIPs = "metallb.universe.tf/loadBalancerIPs" )
const AnnotationGatewayHTTPRedirect = "gateway.aether.io/http-redirect"
AnnotationGatewayHTTPRedirect is a Gateway annotation that opts a plain-HTTP listener into HTTP→HTTPS redirect behaviour. When set to "true" on a Gateway of the aether GatewayClass, the edge emits a 301-redirect listener on the Gateway's HTTP port instead of serving routes directly.
Default absent / "false" → the HTTP listener serves its attached HTTPRoutes (no redirect). Operators MUST set this annotation on any Gateway whose HTTP listener should redirect to HTTPS (e.g. the production api.palermo.dev edge Gateway). The aether chart sets it automatically when edge.tls.enabled is true.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Reconciler ¶
type Reconciler struct {
client.Client
// APIReader is an uncached reader (mgr.GetAPIReader) used to fetch the
// cluster-scoped GatewayClass for status (a cached Get on a cluster-scoped
// resource can miss before its informer has synced and return NotFound).
APIReader client.Reader
// Sink receives the projected virtual hosts/certs and L4 routes (the snapshot cache).
Sink RouteSink
// Namespace is the edge's own namespace. It is used as the default namespace
// for the TLS Secret provider's cert lookups and as the namespace of the edge
// LoadBalancer Service (EdgeServiceName) from which the published Gateway
// status.addresses is resolved; Gateways/Routes are listed and reconciled
// CLUSTER-WIDE (namespace-agnostic), so this field does not scope the
// route/Gateway lists.
Namespace string
// EdgeServiceName is the name of the edge's own LoadBalancer Service (in
// Namespace). Its status.loadBalancer.ingress address is published as every
// class-aether Gateway's status.addresses (proposal 021 Phase 1 — the shared
// edge address), and is used as the base name for per-Gateway Services in Phase 2.
// Empty disables address publication.
EdgeServiceName string
// GatewayClassName is the GatewayClass whose Gateways this edge serves.
GatewayClassName string
// Secrets resolves Gateway listener TLS cert material; nil disables TLS.
Secrets *secret.Registry
// MeshDomain is the mesh DNS domain used to build TCP cluster names.
MeshDomain string
Log *slog.Logger
}
Reconciler watches Gateway API HTTPRoutes, TCPRoutes, and TLSRoutes (and the Gateways/Secrets they depend on) CLUSTER-WIDE and projects, on any change, the complete virtual-host and L4 route sets into the cache. Level-based: each reconcile re-lists, so adds/updates/deletes converge without delta tracking — the same model as the VirtualHost reconciler. It is namespace-agnostic: a Gateway of our class in any namespace is reconciled and gets status, which is what the upstream conformance suite (running in its own namespaces) requires.
func (*Reconciler) Reconcile ¶
Reconcile re-lists our Gateways and the HTTPRoutes, TCPRoutes, and TLSRoutes attached to them, resolves each Gateway listener's TLS cert, and replaces the cache's virtual-host and L4 route sets.
func (*Reconciler) SetupWithManager ¶
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager registers the reconciler to watch HTTPRoutes, TCPRoutes, TLSRoutes, Gateways and (when TLS is enabled) Secrets — any change re-projects the whole set.
The reconciler runs on EVERY edge replica (NeedLeaderElection=false). The edge is a multi-replica Deployment; each replica hosts its own xDS server that serves a co-located Envoy. Per-Gateway Envoy listeners are injected into the replica's own SnapshotCache via SetEdgeGateways — a call that only the leader's reconciler would make if leader-only. The follower's Envoy would then see no listeners on the allocated internal ports, causing "connection refused" for ~50% of connections (those kube-proxy routes to the follower pod). Running the reconciler on all replicas ensures each pod's SnapshotCache is updated and its co-located Envoy receives the correct per-Gateway listener set.
K8s resource writes (per-Gateway Service create/update, Gateway status patches) are safe under concurrent reconciliation: the CreateOrUpdate pattern is idempotent, and status patches use server-side apply / optimistic concurrency (the controller-runtime client retries on 409 Conflict).
type RouteSink ¶
type RouteSink interface {
SetVirtualHosts(vhosts []cache.VirtualHost)
SetEdgeTLSSecrets(ctx context.Context, certs map[string]cache.EdgeTLSCert) error
SetEdgeTCPRoutes(routes []proxy.EdgeL4TCPRoute)
SetEdgeTLSRoutes(routes []proxy.EdgeL4TLSRoute)
// SetEdgeHTTPRedirect controls whether the HTTP-port listener 301-redirects
// to https (true) or serves routes directly (false). The reconciler sets this
// on every reconcile based on whether any Gateway in the current set carries
// the gateway.aether.io/http-redirect: "true" annotation.
SetEdgeHTTPRedirect(enabled bool)
// SetEdgeGateways replaces the per-Gateway routing set (proposal 021 Phase 2).
// When non-empty, the snapshot emits per-Gateway listeners and route configs
// (one per Gateway, bound on allocated internal ports) instead of the shared
// Phase 1 listeners. When empty, falls back to Phase 1 behavior.
SetEdgeGateways(gateways []cache.EdgeGatewayEntry)
// HasRegistryService reports whether the named service is currently known to
// the mesh registry (namespace-blind, bare service name). Used by the
// backend-existence check to distinguish mesh/registry services (which need
// no k8s Service object in the route namespace) from k8s-only Services.
// Returns false when the registry does not implement ServiceCatalog or no
// registry has been configured (safe default = not a registry service).
HasRegistryService(name string) bool
}
RouteSink receives the projected virtual hosts, TLS certs, and L4 routes (the snapshot cache).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package attachment holds the edge Gateway API controller's route→listener attachment resolution: parentRef matching, allowedRoutes (namespaces/kinds) admission, ReferenceGrant-gated backendRef admission, and listener/route hostname intersection.
|
Package attachment holds the edge Gateway API controller's route→listener attachment resolution: parentRef matching, allowedRoutes (namespaces/kinds) admission, ReferenceGrant-gated backendRef admission, and listener/route hostname intersection. |