Documentation
¶
Overview ¶
Package routing defines the seam between the workspace lifecycle and how workspace access routes are materialized (ADR-0001). The reconciler knows nothing about HTTPRoutes, gateways, or VPNs — it asks a RouteProvider for access entries and cleans them up on deletion. New access technologies (Tailscale, NetBird-as-access) are added by implementing RouteProvider; provider selection, when more than one exists, will be a per-tenant concern.
Index ¶
- Constants
- func EndpointServiceName(wsd *workspacesv1.WorkspaceDeployment, ep workspacesv1.AccessEndpoint) string
- func HelmReleaseName(wsd *workspacesv1.WorkspaceDeployment) string
- func IsInfraNotReady(err error) bool
- func MeshNamespaceLabels(mode MeshMode, wp WaypointConfig) map[string]string
- func WaypointNameForClusterDeployment(cdName string) string
- func WorkspaceNamespaceName(wsd *workspacesv1.WorkspaceDeployment) string
- type InfraNotReadyError
- type MeshConfig
- type MeshMode
- type OrphanSweeper
- type RouteProvider
- type RouteRequest
- type SweepRequest
- type WaypointConfig
Constants ¶
const ( // LabelWorkspace marks an object (namespace, Service, route) as belonging // to a workspace and identifies which one. On child clusters, Istio mesh // discovery (discoverySelectors) keys off this label; on regional // clusters it identifies provider-created route objects for cleanup. LabelWorkspace = "workspaces.exalsius.ai/workspace" )
Variables ¶
This section is empty.
Functions ¶
func EndpointServiceName ¶
func EndpointServiceName(wsd *workspacesv1.WorkspaceDeployment, ep workspacesv1.AccessEndpoint) string
EndpointServiceName returns the child-cluster Service name for an access endpoint: the explicit per-endpoint serviceName when the class declares one (fixed-name/umbrella charts), otherwise the `<release-name>-<endpoint-name>` convention.
func HelmReleaseName ¶
func HelmReleaseName(wsd *workspacesv1.WorkspaceDeployment) string
HelmReleaseName returns the workspace's Helm release name (the ServiceSet service entry name). Chart Services follow the convention `<release-name>-<endpoint-name>`.
func IsInfraNotReady ¶
IsInfraNotReady reports whether err is (or wraps) an InfraNotReadyError.
func MeshNamespaceLabels ¶
func MeshNamespaceLabels(mode MeshMode, wp WaypointConfig) map[string]string
MeshNamespaceLabels returns the mesh-enrollment labels to stamp on workspace namespaces for the given mode. Empty for MeshModeNone (or an unknown mode, treated as none). In ambient mode, when a waypoint is configured, the waypoint-routing labels are included so the ingress gateway routes through the waypoint to ambient/global services.
func WaypointNameForClusterDeployment ¶ added in v0.11.0
WaypointNameForClusterDeployment returns the name of the per-child waypoint for the given ClusterDeployment (ADR-0005). Each child cluster has a dedicated waypoint named `<cd-name>-waypoint`, present on both the regional cluster and that child; the waypoint name scopes the global service's cross-cluster endpoints to the one hosting child (no fan-out, no relay).
The operator and onboarding must agree on this name without coordination, so it is a pure function of the CD name. If `<cd-name>-waypoint` would exceed the 63-char object-name limit, the CD name is truncated and a short, deterministic hash of the full name is inserted to keep it unique.
func WorkspaceNamespaceName ¶
func WorkspaceNamespaceName(wsd *workspacesv1.WorkspaceDeployment) string
WorkspaceNamespaceName returns the per-workspace namespace. It is the same name on the child cluster (where the workload runs) and on the regional cluster (where the mirror Service lives) — Istio multi-cluster endpoint discovery requires namespace sameness (ADR-0001).
Types ¶
type InfraNotReadyError ¶
type InfraNotReadyError struct {
Reason string
}
InfraNotReadyError signals that the tenant's routing infrastructure (regional cluster topology, gateway, listeners) is missing or not ready — an admin-fixable condition, not a transient provider error. The reconciler surfaces it as a RoutesReady=False condition with reason RoutingInfraNotReady and retries.
func (*InfraNotReadyError) Error ¶
func (e *InfraNotReadyError) Error() string
type MeshConfig ¶ added in v0.11.0
type MeshConfig struct {
// Mode is the data-plane enrollment mode (ambient/sidecar/none).
Mode MeshMode
// WaypointEnabled turns on per-child waypoint routing (ambient only). When
// false, namespaces are enrolled without a waypoint label.
WaypointEnabled bool
// WaypointNamespace is where the per-child waypoint Gateways live (e.g.
// istio-system) on both the regional and child clusters.
WaypointNamespace string
}
MeshConfig captures how the operator enrolls workspace namespaces into the Istio mesh, resolved from manager flags. Unlike a fixed label set, the waypoint label is per-hosting-child (ADR-0005): NamespaceLabels derives the `<cd-name>-waypoint` value for a specific ClusterDeployment.
func (MeshConfig) MirrorNamespaceLabels ¶ added in v0.11.1
func (c MeshConfig) MirrorNamespaceLabels() map[string]string
MirrorNamespaceLabels returns the mesh-enrollment labels to stamp on the regional MIRROR namespace. It carries the data-plane enrollment label so the selector-less mirror Service participates in the ambient mesh as a global service, but NOT the waypoint-routing labels: the per-child waypoint scope is expressed only on the child namespace (ADR-0005), keeping the regional mirror free of a child-specific waypoint reference.
func (MeshConfig) NamespaceLabels ¶ added in v0.11.0
func (c MeshConfig) NamespaceLabels(cdName string) map[string]string
NamespaceLabels returns the mesh-enrollment labels to stamp on the workspace namespace on the CHILD cluster hosting the given ClusterDeployment — the cluster where the workspace pods actually run. In ambient mode with waypoints enabled, the per-child waypoint-routing labels point at that child's dedicated `<cd-name>-waypoint`.
The waypoint labels are intentionally NOT applied to the regional mirror namespace (see MirrorNamespaceLabels): the per-child waypoint scope is asserted on the child namespace alone — the side that owns the real endpoints (ADR-0005).
type MeshMode ¶
type MeshMode string
MeshMode selects how workspace namespaces are enrolled into the Istio mesh. The operator creates the workspace namespaces (child) and mirror namespaces (regional), so it stamps the enrollment label; the value depends on which data-plane mode the mesh runs (ADR-0001).
const ( // MeshModeAmbient enrolls namespaces into the Istio ambient data plane // (ztunnel captures their pods — no sidecar). The default. MeshModeAmbient MeshMode = "ambient" // MeshModeSidecar enrolls namespaces for sidecar injection. MeshModeSidecar MeshMode = "sidecar" // MeshModeNone stamps no enrollment label — the mesh enrolls namespaces // some other way (or routing is being tested without a mesh). MeshModeNone MeshMode = "none" )
type OrphanSweeper ¶
type OrphanSweeper interface {
SweepOrphans(ctx context.Context, req SweepRequest) error
}
OrphanSweeper is an optional RouteProvider extension. Owner references don't cross clusters, so finalizer-driven cleanup is the primary mechanism — the sweep is the label-based backstop that reclaims provider-created objects whose workspace no longer exists. The main orphan source by construction: a child ClusterDeployment deleted BEFORE its workspaces makes CleanupRoutes skip ("teardown owns it") while the mirror objects live on the regional cluster, which outlives the child.
type RouteProvider ¶
type RouteProvider interface {
// EnsureRoutes materializes access for all endpoints of the workspace
// and returns what is reachable. Idempotent: repeat calls with unchanged
// input converge on the same entries. An entry with Ready=false and a
// Message is the per-endpoint failure surface (e.g. pool exhausted);
// returning an error signals a provider-wide transient problem the
// caller should retry.
EnsureRoutes(ctx context.Context, req RouteRequest) ([]workspacesv1.AccessEntry, error)
// CleanupRoutes removes everything EnsureRoutes created for the
// workspace. Idempotent; must tolerate nil req.Endpoints and routes
// that never existed.
CleanupRoutes(ctx context.Context, req RouteRequest) error
}
RouteProvider materializes externally reachable access for workspace endpoints and reports the result as AccessEntry values for WorkspaceDeployment.status.access[].
type RouteRequest ¶
type RouteRequest struct {
// Workspace is the deployment being routed.
Workspace *workspacesv1.WorkspaceDeployment
// Endpoints are the access endpoints declared by the WorkspaceClass.
// May be nil during cleanup when the class is no longer resolvable —
// providers must be able to clean up from workspace identity alone
// (e.g. via labels on the objects they created).
Endpoints []workspacesv1.AccessEndpoint
// ManagementClient reads cluster topology and kubeconfig secrets on the
// management cluster.
ManagementClient client.Client
// Scheme is the management client's scheme, for building per-cluster
// clients.
Scheme *runtime.Scheme
}
RouteRequest carries the resolved context a provider needs to materialize or remove access for one workspace. It deliberately includes the management-cluster client rather than pre-resolved regional/child clients: each provider decides which clusters it needs to touch and resolves them via the cluster topology (KOF labels, kubeconfig secrets).
type SweepRequest ¶
type SweepRequest struct {
// ManagementClient reads cluster topology and kubeconfig secrets on the
// management cluster.
ManagementClient client.Client
// Scheme for building per-cluster clients.
Scheme *runtime.Scheme
// IsActiveWorkspace reports whether a WorkspaceDeployment with the given
// name currently exists (in any namespace — conservative on purpose:
// the sweep must never remove live routes).
IsActiveWorkspace func(name string) bool
}
SweepRequest carries the context for an orphan sweep.
type WaypointConfig ¶
WaypointConfig points workspace namespaces at a shared Istio ambient waypoint. An empty Name disables waypoint enrollment (the labels are omitted).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package gatewayapi implements routing.RouteProvider on top of Gateway API resources on the tenant's regional cluster (ADR-0001).
|
Package gatewayapi implements routing.RouteProvider on top of Gateway API resources on the tenant's regional cluster (ADR-0001). |