Documentation
¶
Overview ¶
Package bridge implements the hybrid edge-to-local cloud routing primitives for Idea 46 (devx bridge). It orchestrates kubectl port-forward subprocesses, manages session state, and generates bridge environment variables for devx shell.
Design: All cluster interactions use the kubectl subprocess pattern, consistent with devx's established pattern of wrapping external CLIs (cloudflared, podman, etc.).
Future: dns.go is reserved for Idea 46.1.5 (DNS Proxy) — a lightweight DNS proxy using Go's net package that resolves *.svc.cluster.local to forwarded local ports without requiring elevated permissions.
Index ¶
- Constants
- func CheckInterceptConflict(kubeconfig, kubeCtx, namespace, service string) error
- func ClearSession() error
- func EnvPath() (string, error)
- func GenerateEnvFile(entries []SessionEntry) error
- func GetServiceSelector(kubeconfig, kubeCtx, namespace, service string) (map[string]string, error)
- func IsActive() bool
- func ListContexts(kubeconfig string) ([]string, error)
- func ListServices(kubeconfig, context, namespace string) ([]string, error)
- func LoadEnvVars() (map[string]string, error)
- func RemoveAgent(kubeconfig, kubeCtx, namespace, sessionID string) error
- func ResolveKubeconfig(explicit string) (string, error)
- func RestoreServiceSelector(kubeconfig, kubeCtx string, state *ServiceState) error
- func SaveSession(session *Session) error
- func SessionPath() (string, error)
- func ValidateContext(kubeconfig, context string) error
- func ValidateInterceptable(info *ServiceInfo) error
- func ValidateKubectl() (string, error)
- func ValidateService(kubeconfig, context, namespace, service string) error
- type AgentConfig
- type AgentInfo
- type InterceptEntry
- type PortForward
- func (pf *PortForward) LastError() error
- func (pf *PortForward) LocalAddr() string
- func (pf *PortForward) ResolveLocalPort() (string, error)
- func (pf *PortForward) Start(ctx context.Context) error
- func (pf *PortForward) State() PortForwardState
- func (pf *PortForward) StateChannel() <-chan PortForwardState
- func (pf *PortForward) Stop()
- type PortForwardState
- type ServiceInfo
- type ServicePortSpec
- type ServiceState
- type Session
- type SessionEntry
- type Tunnel
- type TunnelConfig
Constants ¶
const ( // AgentImageDefault is the default agent container image. // Override via --agent-image flag or bridge.agent_image in devx.yaml. AgentImageDefault = "ghcr.io/VitruvianSoftware/devx-bridge-agent:v0.1.0" // AgentControlPort is the Yamux control port inside the agent pod. AgentControlPort = 4200 // AgentHealthPort is the health check port inside the agent pod. AgentHealthPort = 4201 // AgentDefaultDeadline is the default activeDeadlineSeconds for agent Jobs (4 hours). AgentDefaultDeadline = 14400 )
Variables ¶
This section is empty.
Functions ¶
func CheckInterceptConflict ¶
CheckInterceptConflict checks whether the Service already has an active intercept session.
func ClearSession ¶
func ClearSession() error
ClearSession removes the session file and env file from disk.
func GenerateEnvFile ¶
func GenerateEnvFile(entries []SessionEntry) error
GenerateEnvFile creates ~/.devx/bridge.env with BRIDGE_<SERVICE>_URL, BRIDGE_<SERVICE>_HOST, and BRIDGE_<SERVICE>_PORT variables for each active port-forward. This file is consumed by devx shell.
func GetServiceSelector ¶
GetServiceSelector returns the current selector of a Service.
func IsActive ¶
func IsActive() bool
IsActive checks whether a bridge session exists and has entries or intercepts.
func ListContexts ¶
ListContexts returns available kube contexts from the kubeconfig.
func ListServices ¶
ListServices returns the names of services in the given namespace for TUI selection.
func LoadEnvVars ¶
LoadEnvVars reads the bridge env file and returns the key-value pairs. Returns an empty map if the file does not exist.
func RemoveAgent ¶
RemoveAgent deletes the agent Job, ServiceAccount, Role, and RoleBinding.
func ResolveKubeconfig ¶
ResolveKubeconfig returns the absolute path to the kubeconfig file. It checks, in order: explicit path > KUBECONFIG env var > ~/.kube/config.
func RestoreServiceSelector ¶
func RestoreServiceSelector(kubeconfig, kubeCtx string, state *ServiceState) error
RestoreServiceSelector restores the original Service selector and removes the session annotation.
func SaveSession ¶
SaveSession persists the session state to disk.
func SessionPath ¶
SessionPath returns the path to the bridge session file (~/.devx/bridge.json).
func ValidateContext ¶
ValidateContext checks that the specified context exists and the cluster is reachable.
func ValidateInterceptable ¶
func ValidateInterceptable(info *ServiceInfo) error
ValidateInterceptable checks that a Service is safe to intercept.
func ValidateKubectl ¶
ValidateKubectl checks that kubectl is on the PATH and returns its version.
func ValidateService ¶
ValidateService checks that a service exists in the given namespace.
Types ¶
type AgentConfig ¶
type AgentConfig struct {
Kubeconfig string
Context string
Namespace string
TargetService string
InterceptPort int // The specific port being intercepted
ServicePorts []ServicePortSpec // ALL ports on the target Service (for dynamic Pod spec)
OriginalSelector map[string]string // For self-healing: passed to agent via env var
AgentImage string
SessionID string
Deadline int // activeDeadlineSeconds (default: AgentDefaultDeadline)
}
AgentConfig defines the parameters for deploying a bridge agent.
type AgentInfo ¶
type AgentInfo struct {
PodName string
PodIP string
ControlPort int
HealthPort int
SessionID string
}
AgentInfo contains runtime information about a deployed agent.
func DeployAgent ¶
func DeployAgent(cfg AgentConfig) (*AgentInfo, error)
DeployAgent creates the agent Job, ServiceAccount, Role, and RoleBinding in the cluster and waits for the agent to be ready.
type InterceptEntry ¶
type InterceptEntry struct {
Service string `json:"service"`
Namespace string `json:"namespace"`
TargetPort int `json:"target_port"`
LocalPort int `json:"local_port"`
Mode string `json:"mode"` // "steal" or "mirror"
AgentPod string `json:"agent_pod"`
SessionID string `json:"session_id"`
OriginalSelector map[string]string `json:"original_selector"` // for restore on teardown
StartedAt time.Time `json:"started_at"`
Origin string `json:"origin,omitempty"` // "standalone" or "dag" — prevents cross-teardown (Idea 46.3)
}
InterceptEntry represents an active traffic intercept (Idea 46.2).
type PortForward ¶
type PortForward struct {
Service string // K8s service name
Namespace string
RemotePort int
LocalPort int
// contains filtered or unexported fields
}
PortForward manages a single kubectl port-forward subprocess.
func NewPortForward ¶
func NewPortForward(kubeconfig, kubeCtx, namespace, service string, remotePort, localPort int) *PortForward
NewPortForward creates a new port-forward manager.
func (*PortForward) LastError ¶
func (pf *PortForward) LastError() error
LastError returns the last error that caused a retry or failure.
func (*PortForward) LocalAddr ¶
func (pf *PortForward) LocalAddr() string
LocalAddr returns the local address string (e.g. "127.0.0.1:9501").
func (*PortForward) ResolveLocalPort ¶
func (pf *PortForward) ResolveLocalPort() (string, error)
ResolveLocalPort acquires a free local port if LocalPort is 0, or resolves port collisions if the desired port is in use.
func (*PortForward) Start ¶
func (pf *PortForward) Start(ctx context.Context) error
Start launches the kubectl port-forward subprocess. It blocks until the context is cancelled or the port-forward fails after all retries.
func (*PortForward) State ¶
func (pf *PortForward) State() PortForwardState
State returns the current state of this port-forward.
func (*PortForward) StateChannel ¶
func (pf *PortForward) StateChannel() <-chan PortForwardState
StateChannel returns a channel that receives state transitions.
func (*PortForward) Stop ¶
func (pf *PortForward) Stop()
Stop gracefully terminates the port-forward subprocess.
type PortForwardState ¶
type PortForwardState int
PortForwardState represents the health of a single port-forward.
const ( StateStarting PortForwardState = iota StateHealthy StateFailed StateStopped )
func (PortForwardState) String ¶
func (s PortForwardState) String() string
type ServiceInfo ¶
type ServiceInfo struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Type string `json:"type"` // ClusterIP, NodePort, etc.
Selector map[string]string `json:"selector"`
Ports []ServicePortSpec `json:"ports"`
HasMeshSidecar bool `json:"has_mesh_sidecar"`
}
ServiceInfo captures the full spec of a target Service for intercept planning.
func InspectService ¶
func InspectService(kubeconfig, kubeCtx, namespace, service string) (*ServiceInfo, error)
InspectService retrieves the full Service spec and validates it for intercept.
type ServicePortSpec ¶
type ServicePortSpec struct {
Name string `json:"name"` // e.g., "http-api", "metrics" (may be empty)
Port int `json:"port"` // Service port number
TargetPort string `json:"target_port"` // Container port number or name (e.g., "8080" or "http-api")
Protocol string `json:"protocol"` // Must be "TCP" for 46.2
}
ServicePortSpec captures a single port from the target Service for dynamic agent generation.
type ServiceState ¶
type ServiceState struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
OriginalSelector map[string]string `json:"original_selector"`
}
ServiceState captures the original state of a Service before patching (for restore).
func PatchServiceSelector ¶
func PatchServiceSelector(kubeconfig, kubeCtx, namespace, service string, newSelector map[string]string, sessionID string) (*ServiceState, error)
PatchServiceSelector replaces the target Service's selector with the agent pod's labels. Also sets the annotation devx-bridge-session=<sessionID> for conflict detection.
type Session ¶
type Session struct {
Kubeconfig string `json:"kubeconfig"`
Context string `json:"context"`
Entries []SessionEntry `json:"entries"`
Intercepts []InterceptEntry `json:"intercepts,omitempty"` // Idea 46.2
StartedAt time.Time `json:"started_at"`
}
Session represents the full bridge session state persisted to ~/.devx/bridge.json.
func LoadSession ¶
LoadSession reads the session state from disk. Returns nil, nil if the file does not exist.
type SessionEntry ¶
type SessionEntry struct {
Service string `json:"service"`
Namespace string `json:"namespace"`
RemotePort int `json:"remote_port"`
LocalPort int `json:"local_port"`
State string `json:"state"`
PID int `json:"pid,omitempty"`
StartedAt time.Time `json:"started_at"`
Origin string `json:"origin,omitempty"` // "standalone" or "dag" — prevents cross-teardown (Idea 46.3)
}
SessionEntry represents a single active port-forward in the session file.
type Tunnel ¶
type Tunnel struct {
// contains filtered or unexported fields
}
Tunnel manages the kubectl port-forward subprocess and Yamux client session.
func NewTunnel ¶
func NewTunnel(cfg TunnelConfig) *Tunnel
NewTunnel creates a new Tunnel with the given config.
func (*Tunnel) Done ¶
func (t *Tunnel) Done() <-chan struct{}
Done returns a channel that is closed when the tunnel stops accepting streams.