Documentation
¶
Overview ¶
Package network manages routing, custom domains, TLS certificates, and service discovery for ctrlplane instances. It defines the Router interface for pluggable traffic routing implementations.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SelectEndpoint ¶ added in v1.5.1
SelectEndpoint picks the endpoint within `endpoints` that should receive traffic for `route`. Selection rules, in priority order:
- Exact match on (ServiceName, Port). When the route names a service AND a port, only an endpoint with both fields matching is eligible.
- ServiceName match on any port. When the route names a service but the listed port doesn't match a published endpoint, fall through to any endpoint owned by that service.
- Port match on any service. When the route doesn't name a service (legacy single-service routes), pick the first endpoint publishing the right port.
- First endpoint as a last resort. Single-endpoint instances and legacy routes that don't specify a port still resolve to "the obvious one".
Returns nil when `endpoints` is empty.
Types ¶
type AddDomainRequest ¶
type AddDomainRequest struct {
InstanceID id.ID `json:"instance_id" validate:"required"`
Hostname string `json:"hostname" validate:"required,fqdn"`
TLSEnabled bool `json:"tls_enabled"`
}
AddDomainRequest holds the parameters for adding a custom domain.
type AddRouteRequest ¶
type AddRouteRequest struct {
InstanceID id.ID `json:"instance_id" validate:"required"`
ServiceName string `json:"service_name,omitempty"`
Path string `json:"path" validate:"required"`
Port int `json:"port" validate:"required"`
Protocol string `default:"http" json:"protocol"`
Weight int `default:"100" json:"weight"`
StripPrefix bool `json:"strip_prefix,omitempty"`
RewriteRedirects bool `json:"rewrite_redirects,omitempty"`
RewriteCookiePath bool `json:"rewrite_cookie_path,omitempty"`
UpstreamOrigin string `json:"upstream_origin,omitempty"`
TLSVerify *bool `json:"tls_verify,omitempty"`
Hostname string `json:"hostname,omitempty"`
}
AddRouteRequest holds the parameters for creating a traffic route.
ServiceName optionally targets a specific service inside a multi-service instance — leave empty to route to the instance's Main service (the default for single-service workloads).
Hostname optionally scopes the route to a single host — leave empty to answer on every host the gateway listener serves.
type Certificate ¶
type Certificate struct {
ctrlplane.Entity
DomainID id.ID `db:"domain_id" json:"domain_id"`
TenantID string `db:"tenant_id" json:"tenant_id"`
Issuer string `db:"issuer" json:"issuer"`
ExpiresAt time.Time `db:"expires_at" json:"expires_at"`
AutoRenew bool `db:"auto_renew" json:"auto_renew"`
}
Certificate holds TLS certificate state.
type Domain ¶
type Domain struct {
ctrlplane.Entity
TenantID string `db:"tenant_id" json:"tenant_id"`
InstanceID id.ID `db:"instance_id" json:"instance_id"`
Hostname string `db:"hostname" json:"hostname"`
Verified bool `db:"verified" json:"verified"`
TLSEnabled bool `db:"tls_enabled" json:"tls_enabled"`
CertExpiry *time.Time `db:"cert_expiry" json:"cert_expiry,omitempty"`
DNSTarget string `db:"dns_target" json:"dns_target"`
VerifyToken string `db:"verify_token" json:"verify_token"`
}
Domain represents a custom domain bound to an instance.
type GatewayRouter ¶ added in v1.3.0
type GatewayRouter interface {
Router
// SyncRoutes synchronises all routes for a datacenter with the gateway.
SyncRoutes(ctx context.Context, datacenterID id.ID) error
// SetBackendHealth marks an instance backend as healthy or unhealthy.
SetBackendHealth(ctx context.Context, instanceID id.ID, healthy bool) error
// GetGatewayStatus returns the current operational status of the gateway.
GetGatewayStatus(ctx context.Context) (*GatewayStatus, error)
}
GatewayRouter extends Router with datacenter-aware gateway operations. Implement this interface for cross-datacenter traffic management. Phase 2: a Forge extension will provide the concrete implementation.
type GatewayStatus ¶ added in v1.3.0
type GatewayStatus struct {
Healthy bool `json:"healthy"`
ActiveRoutes int `json:"active_routes"`
ActiveDomains int `json:"active_domains"`
Metadata map[string]string `json:"metadata,omitempty"`
}
GatewayStatus describes the operational state of a gateway.
type Route ¶
type Route struct {
ctrlplane.Entity
TenantID string `db:"tenant_id" json:"tenant_id"`
InstanceID id.ID `db:"instance_id" json:"instance_id"`
ServiceName string `db:"service_name" json:"service_name,omitempty"`
Path string `db:"path" json:"path"`
Port int `db:"port" json:"port"`
Protocol string `db:"protocol" json:"protocol"`
Weight int `db:"weight" json:"weight"`
// StripPrefix drops the route's Path prefix before the request
// reaches the backend. It doubles as the route's path mode for
// proxying: the annotation emitter maps true to octopus's "strip"
// and false to "passthrough". Keeping one field here means the two
// can never disagree.
StripPrefix bool `db:"strip_prefix" json:"strip_prefix"`
// Proxy-mode fields. Octopus reads these off the emitted HTTPRoute
// to decide how far it rewrites a proxied response. They only take
// effect once the route is in proxy mode, which the emitter decides;
// a route with all of them at their zero value proxies as before.
//
// RewriteRedirects re-adds a stripped prefix to Location headers so
// a backend mounted at "/" doesn't send browsers outside the
// gateway prefix. RewriteCookiePath does the same for Set-Cookie
// Path attributes.
RewriteRedirects bool `db:"rewrite_redirects" json:"rewrite_redirects,omitempty"`
RewriteCookiePath bool `db:"rewrite_cookie_path" json:"rewrite_cookie_path,omitempty"`
// UpstreamOrigin overrides the backend address with an absolute
// scheme://host[:port], for routes that proxy somewhere outside the
// cluster. TLSVerify controls certificate verification against that
// origin and is meaningless without it. TLSVerify defaults to true;
// AddRoute treats an unset AddRouteRequest.TLSVerify as true so a
// caller can never silently disable verification by omission.
// UpdateRoute holds the matching invariant from the other side: an
// empty UpstreamOrigin always implies TLSVerify, because clearing
// the origin resets verification.
UpstreamOrigin string `db:"upstream_origin" json:"upstream_origin,omitempty"`
TLSVerify bool `db:"tls_verify" json:"tls_verify"`
// Hostname, when set, scopes the route to a single host (the
// workspace's API hostname). The OctopusRouter uses it as the
// Gateway API HTTPRoute's `hostnames` entry so per-workspace path
// routes don't collide on the shared *.api wildcard listener.
// Empty means the route answers on every host the listener serves.
Hostname string `db:"hostname" json:"hostname,omitempty"`
}
Route maps traffic from an endpoint to an instance. ServiceName optionally targets a specific service inside a multi-service instance — empty resolves to the instance's Main service so single- service workloads keep working without explicit configuration.
type Router ¶
type Router interface {
// AddRoute configures a route to an instance.
AddRoute(ctx context.Context, route *Route) error
// RemoveRoute removes a route.
RemoveRoute(ctx context.Context, routeID id.ID) error
// UpdateRoute modifies an existing route.
UpdateRoute(ctx context.Context, route *Route) error
// AddDomain configures a custom domain.
AddDomain(ctx context.Context, domain *Domain) error
// RemoveDomain removes a custom domain.
RemoveDomain(ctx context.Context, domainID id.ID) error
// ProvisionCert obtains or renews a TLS certificate.
ProvisionCert(ctx context.Context, domain *Domain) (*Certificate, error)
}
Router abstracts traffic routing implementation. Implement for your load balancer or ingress controller.
type Service ¶
type Service interface {
// AddDomain registers a custom domain for an instance.
AddDomain(ctx context.Context, req AddDomainRequest) (*Domain, error)
// VerifyDomain confirms DNS ownership of a domain.
VerifyDomain(ctx context.Context, domainID id.ID) (*Domain, error)
// RemoveDomain removes a custom domain.
RemoveDomain(ctx context.Context, domainID id.ID) error
// ListDomains returns all domains for an instance.
ListDomains(ctx context.Context, instanceID id.ID) ([]Domain, error)
// AddRoute creates a traffic route to an instance.
AddRoute(ctx context.Context, req AddRouteRequest) (*Route, error)
// UpdateRoute modifies an existing route.
UpdateRoute(ctx context.Context, routeID id.ID, req UpdateRouteRequest) (*Route, error)
// RemoveRoute removes a traffic route.
RemoveRoute(ctx context.Context, routeID id.ID) error
// ListRoutes returns all routes for an instance.
ListRoutes(ctx context.Context, instanceID id.ID) ([]Route, error)
// ProvisionCert obtains or renews a TLS certificate for a domain.
ProvisionCert(ctx context.Context, domainID id.ID) (*Certificate, error)
// ListCerts returns all certificates for an instance.
ListCerts(ctx context.Context, instanceID id.ID) ([]Certificate, error)
}
Service manages domains, routes, and certificates for instances.
type Store ¶
type Store interface {
// InsertDomain persists a new domain.
InsertDomain(ctx context.Context, domain *Domain) error
// GetDomain retrieves a domain by ID.
GetDomain(ctx context.Context, tenantID string, domainID id.ID) (*Domain, error)
// GetDomainByHostname retrieves a domain by its hostname.
GetDomainByHostname(ctx context.Context, hostname string) (*Domain, error)
// ListDomains returns all domains for an instance.
ListDomains(ctx context.Context, tenantID string, instanceID id.ID) ([]Domain, error)
// UpdateDomain persists changes to a domain.
UpdateDomain(ctx context.Context, domain *Domain) error
// DeleteDomain removes a domain.
DeleteDomain(ctx context.Context, tenantID string, domainID id.ID) error
// InsertRoute persists a new route.
InsertRoute(ctx context.Context, route *Route) error
// GetRoute retrieves a route by ID.
GetRoute(ctx context.Context, tenantID string, routeID id.ID) (*Route, error)
// ListRoutes returns all routes for an instance.
ListRoutes(ctx context.Context, tenantID string, instanceID id.ID) ([]Route, error)
// UpdateRoute persists changes to a route.
UpdateRoute(ctx context.Context, route *Route) error
// DeleteRoute removes a route.
DeleteRoute(ctx context.Context, tenantID string, routeID id.ID) error
// InsertCertificate persists a new certificate.
InsertCertificate(ctx context.Context, cert *Certificate) error
// GetCertificate retrieves a certificate by ID.
GetCertificate(ctx context.Context, tenantID string, certID id.ID) (*Certificate, error)
// ListCertificates returns all certificates for an instance.
ListCertificates(ctx context.Context, tenantID string, instanceID id.ID) ([]Certificate, error)
// UpdateCertificate persists changes to a certificate.
UpdateCertificate(ctx context.Context, cert *Certificate) error
// DeleteCertificate removes a certificate.
DeleteCertificate(ctx context.Context, tenantID string, certID id.ID) error
// CountDomainsByTenant returns the number of domains for a tenant.
CountDomainsByTenant(ctx context.Context, tenantID string) (int, error)
}
Store is the persistence interface for domains, routes, and certificates.
type UpdateRouteRequest ¶
type UpdateRouteRequest struct {
ServiceName *string `json:"service_name,omitempty"`
Hostname *string `json:"hostname,omitempty"`
Path *string `json:"path,omitempty"`
Weight *int `json:"weight,omitempty"`
StripPrefix *bool `json:"strip_prefix,omitempty"`
RewriteRedirects *bool `json:"rewrite_redirects,omitempty"`
RewriteCookiePath *bool `json:"rewrite_cookie_path,omitempty"`
UpstreamOrigin *string `json:"upstream_origin,omitempty"`
TLSVerify *bool `json:"tls_verify,omitempty"`
}
UpdateRouteRequest holds the parameters for modifying a route. Every field is a pointer so an omitted key leaves the stored value alone.
The proxy fields mirror AddRouteRequest. UpstreamOrigin is a *string rather than a string so a caller can tell "leave it" (nil) apart from "clear it and go back to the in-cluster backend" (pointer to "").
Clearing the origin also resets TLSVerify to true, even against an explicit tls_verify=false in the same request. Verification can be turned off again once a new origin is set.