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 WorkspaceNamespaceName(wsd *workspacesv1.WorkspaceDeployment) string
- type InfraNotReadyError
- 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 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 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). |