network

package
v1.6.3 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

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

func SelectEndpoint(route *Route, endpoints []provider.Endpoint) *provider.Endpoint

SelectEndpoint picks the endpoint within `endpoints` that should receive traffic for `route`. Selection rules, in priority order:

  1. Exact match on (ServiceName, Port). When the route names a service AND a port, only an endpoint with both fields matching is eligible.
  2. 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.
  3. 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.
  4. 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.

func NewService

func NewService(store Store, router Router, events event.Bus, auth auth.Provider) Service

NewService creates a new network service.

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.

Jump to

Keyboard shortcuts

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