gamma

package
v0.0.0-...-84176c5 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 44 Imported by: 0

Documentation

Overview

Package gamma contains the node agent's GAMMA controller: it watches Gateway API HTTPRoutes and GRPCRoutes attached to a Service (parentRef kind=Service) — plus the ReferenceGrants that authorise cross-namespace backendRefs and the HTTPFilter extensions those rules attach (proposal 025) — and projects their L7 rules into the node proxy's routing (proposal 018, Phase 2 — east-west). The projection feeds BOTH route paths the proxy serves: the outbound per-service listeners and the transparent-capture listener's cap_http virtual hosts. Routing and mTLS are unchanged; the routes add canary/header/timeout vocabulary to a path the proxy already serves.

Index

Constants

View Source
const JudgedConditionType = "gateway.aether.io/PodPortsJudged"

JudgedConditionType is the condition, on aether's own parent status of a route, that carries what the pods behind the route's user-Service ports serve, as judged by a node that holds them. Its message is data (encodeJudgements); it is always True.

Variables

This section is empty.

Functions

This section is empty.

Types

type PodPorts

type PodPorts interface {
	// PodPortClasses returns the class of every port of service
	// ("<ns>/<name>") as this node's tables serve it, and whether the node
	// knows the service's ports at all. known is false when it holds no row
	// of the service: then nothing is known here, and this node judges
	// nothing of it. What another node that does hold it judged is in the
	// route's status (judged.go), and is what this node then goes by.
	PodPortClasses(ctx context.Context, service string) (classes map[uint32]registryv1.PortProtocol, known bool)
}

PodPorts answers, for a route's status, what the pods of a service declare their ports to be. The node agent's implementation is the snapshot cache itself (cache.SnapshotCache.PodPortClasses): the class of each port as the node's route tables are built from it, derived ONCE, by one function, from the registry rows the node holds.

It exists for the Services the mesh did not generate. A generated Service carries the answer on its own ports (the registrar derived them from the registry). A user's Service says only that a port exists and which pod port is behind it; whether the pods serve that port as HTTP is their declaration. The data plane answers 500 for a backendRef whose target port they declare raw TCP, or do not declare, and a status that said ResolvedRefs=True for such a reference was a table and a status built from different facts. They are the same facts now, including where pods disagree: the table takes the class most pods declare, and so does this.

It costs no registry read. (It was one per protocol and service, and a protocol the service has no row under fell back to a listing of the whole mesh, from every node, on every reconcile.)

type Reconciler

type Reconciler struct {
	client.Client

	// APIReader reads the API directly, without a cache. Used only to read
	// the EndpointSlices of a route-named Service whose targetPort is a name
	// (resolveNamedTargetPorts). Nil disables that resolution.
	APIReader client.Reader

	// PodPorts says what the pods of a user's Service declare, for a route's
	// status (podports.go). Nil: such a port is reported as not checked.
	PodPorts PodPorts
	// PodPortsChanged delivers an event each time what PodPorts answers has
	// changed (the cache's OnPodPortsChanged): every route's status is then
	// judged again. Nil: the status follows only what the reconciler watches.
	PodPortsChanged <-chan event.GenericEvent

	// Sink receives the projected per-service rules (the snapshot cache).
	Sink RouteSink
	// MeshDomain resolves a backend Service to its data-plane cluster name.
	MeshDomain string
	Log        *slog.Logger

	// Now is the clock of the status writer's back-off; nil is time.Now.
	Now func() time.Time

	// After runs f after d; nil is time.AfterFunc. It is the timer that keeps
	// a held-back status's wait when a reconcile ends in an error (wakeIn).
	After func(d time.Duration, f func())
	// contains filtered or unexported fields
}

Reconciler watches HTTPRoutes (parentRef=Service) cluster-wide and projects, on any change, the complete service→rules map into the cache. Level-based: each reconcile re-lists, so adds/updates/deletes converge without delta tracking.

Phase 2 treats every Service-parented HTTPRoute as a producer route (applies to all clients of that service); per-namespace consumer overrides are a follow-up.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context, _ reconcile.Request) (reconcile.Result, error)

Reconcile re-lists every HTTPRoute and GRPCRoute, keeps those attached to a Service, and replaces the cache's per-service rule set.

func (*Reconciler) SetupWithManager

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

SetupWithManager registers the reconciler to watch HTTPRoutes and GRPCRoutes. Both feed the same per-service rule map; any change re-lists both (level-based), so a single fixed request enqueued for either type is enough.

type RouteSink

type RouteSink interface {
	SetServiceRoutes(routes map[string][]proxy.GammaRoute)
	// SetServiceChainFilters receives the service-wide ALWAYS-ON extension filters
	// (proposal 025 M4 CHAIN scope), keyed by "<ns>/<svc>": at most one per service,
	// from a CHAIN-scope HTTPFilter with a same-namespace Service targetRef. Enabled
	// at the service's capture vhost.
	SetServiceChainFilters(filters map[string]proxy.ExtensionFilter)
	// SetServiceInboundFilters receives the destination-side (INBOUND scope, 027 M3)
	// filters, keyed by "<ns>/<svc>": enabled on the target service's own pods'
	// inbound listeners. At most one per service.
	SetServiceInboundFilters(filters map[string]proxy.ExtensionFilter)
	// SetRouteTargetPorts receives the real Service port(s) of each route target
	// (proposal 023 M2), keyed by the same "<ns>/<svc>" route-target key as
	// SetServiceRoutes. Sourced from the HTTPRoute/GRPCRoute parentRef port; lets the
	// cap_http vhost host-match a client dialing the target's REAL port.
	SetRouteTargetPorts(ports map[string][]uint32)
	// SetServicePortMaps receives the port map of every Service a route names
	// as its parent or as a backend and that the registrar did not generate
	// (proposal 043, "A Service is a port map"), keyed "<ns>/<svc>": Service
	// port -> the pod port its targetPort names, 0 when the targetPort is a
	// name. A route's ports are ports of the SERVICE; the mesh resolves them
	// to pod ports through this.
	SetServicePortMaps(portMaps map[string]map[uint32]uint32)
}

RouteSink receives the projected per-service GAMMA rules (the snapshot cache).

Jump to

Keyboard shortcuts

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