Documentation
¶
Index ¶
- Constants
- Variables
- func AdvertisedEdgeCommands() []stringdeprecated
- func AvailableManagerMTLSCAPath(cfg *Config) (string, error)
- func BuildHopByHopHeaders(respHeader http.Header) map[string]struct{}
- func BuildManagerServerTLSConfig(cfg *Config) (*tls.Config, error)
- func BuildWebSocketHeaders(c *echo.Context, accessToken *string) http.Header
- func ClearDefaultRegistry(registry *TunnelRegistry)
- func CopyBodyWithFlush(w http.ResponseWriter, body io.Reader) error
- func CopyRequestHeaders(from, to http.Header)
- func CopyResponseHeaders(from, to http.Header, hop map[string]struct{})
- func DefaultTunnelAcquireTimeout() time.Duration
- func DoRequest(ctx context.Context, envID, method, path string, body []byte) (int, []byte, error)
- func EnsureAgentMTLSAssets(ctx context.Context, cfg *Config) error
- func GeneratedManagerClientMTLSCertPath(cfg *Config, envID string) (string, error)
- func GetActiveTunnel(envID string) mo.Option[*AgentTunnel]
- func GetTunnelRuntimeState(envID string) mo.Option[*TunnelRuntimeState]
- func HTTPToWebSocketURL(url string) string
- func HasActiveTunnel(envID string) bool
- func IsInternalTunnelRequest(ctx context.Context) bool
- func NewManagerHTTPClient(cfg *Config, timeout time.Duration) (*http.Client, error)
- func NormalizeEdgeMTLSMode(value string) string
- func NormalizeEdgeTransport(value string) string
- func PrepareManagerMTLSAssetsWithContext(ctx context.Context, cfg *Config) error
- func ProxyHTTPRequest(c *echo.Context, tunnel *AgentTunnel, targetPath string) errordeprecated
- func ProxyRequest(ctx context.Context, tunnel *AgentTunnel, method, path, query string, ...) (int, map[string]string, []byte, error)
- func ProxyWebSocketRequest(c *echo.Context, tunnel *AgentTunnel, targetPath string, ...) errordeprecated
- func PublishEventToManager(ctx context.Context, event *TunnelEvent) error
- func RequestTunnelAndWait(ctx context.Context, envID string, demandTTL, timeout time.Duration) mo.Option[*AgentTunnel]
- func ResolveEdgeCommandName(method, requestPath string, stream bool) mo.Option[string]
- func SetAgentToken(req *http.Request, accessToken *string)
- func SetAuthHeader(req *http.Request, c *echo.Context)
- func SetDefaultRegistry(registry *TunnelRegistry)
- func SetForwardedHeaders(req *http.Request, clientIP, host string)
- func StartTunnelClient(ctx context.Context, cfg *Config, handler http.Handler) (func(context.Context) error, error)
- func TouchTunnelDemand(envID string, ttl time.Duration) time.Time
- func UseGRPCEdgeTransport(cfg *Config) bool
- func UsePollEdgeTransport(cfg *Config) bool
- func UseWebSocketEdgeTransport(cfg *Config) bool
- func ValidateAgentMTLSConfig(cfg *Config) error
- func ValidateEdgeCommand(commandName, method, requestPath string, stream bool) booldeprecated
- func ValidateManagerMTLSConfig(cfg *Config) error
- func WaitForActiveTunnel(ctx context.Context, envID string, timeout time.Duration) mo.Option[*AgentTunnel]
- type AgentTunnel
- type CommandClientdeprecated
- func NewCommandClient() *CommandClientdeprecated
- type CommandRequestdeprecated
- type CommandResultdeprecated
- type Config
- type EnrollmentCallback
- type EnvironmentNameResolver
- type EnvironmentResolver
- type EventCallback
- type GRPCAgentTunnelConn
- func (t *GRPCAgentTunnelConn) Close() error
- func (t *GRPCAgentTunnelConn) IsClosed() bool
- func (t *GRPCAgentTunnelConn) IsExpectedReceiveError(err error) bool
- func (t *GRPCAgentTunnelConn) Receive() (*TunnelMessage, error)
- func (t *GRPCAgentTunnelConn) Send(msg *TunnelMessage) error
- func (t *GRPCAgentTunnelConn) Transport() string
- type GRPCManagerTunnelConn
- func (t *GRPCManagerTunnelConn) Close() error
- func (t *GRPCManagerTunnelConn) IsClosed() bool
- func (t *GRPCManagerTunnelConn) IsExpectedReceiveError(err error) bool
- func (t *GRPCManagerTunnelConn) Receive() (*TunnelMessage, error)
- func (t *GRPCManagerTunnelConn) Send(msg *TunnelMessage) error
- func (t *GRPCManagerTunnelConn) Transport() string
- type GeneratedMTLSAssets
- type GeneratedMTLSFile
- type PendingRequestdeprecated
- type PollRuntimeRegistry
- type PollRuntimeState
- type StatusUpdateCallback
- type TunnelClient
- type TunnelConn
- type TunnelConnection
- type TunnelDemandRegistry
- type TunnelEvent
- type TunnelMessage
- type TunnelMessageType
- type TunnelMetadataSnapshot
- type TunnelPollRequest
- type TunnelPollResponse
- type TunnelRegistry
- func (r *TunnelRegistry) Active(envID string) mo.Option[*AgentTunnel]
- func (r *TunnelRegistry) CleanupStale(ctx context.Context, maxAge time.Duration) []*AgentTunnel
- func (r *TunnelRegistry) Get(envID string) mo.Option[*AgentTunnel]
- func (r *TunnelRegistry) ObserveAgents(meter metric.Meter) (metric.Registration, error)
- func (r *TunnelRegistry) Register(envID string, tunnel *AgentTunnel)
- func (r *TunnelRegistry) RegisterSession(ctx context.Context, tunnel *AgentTunnel, staleAfter time.Duration) (bool, bool, string, error)
- func (r *TunnelRegistry) Stop(ctx context.Context) error
- func (r *TunnelRegistry) Unregister(envID string)
- func (r *TunnelRegistry) UnregisterCurrent(ctx context.Context, envID string, current *AgentTunnel) (bool, bool)
- func (r *TunnelRegistry) WaitForActive(ctx context.Context, envID string, timeout time.Duration) mo.Option[*AgentTunnel]
- type TunnelRuntimeState
- type TunnelServer
- func (s *TunnelServer) Connect(...) error
- func (s *TunnelServer) GRPCServerOptions() []grpc.ServerOption
- func (s *TunnelServer) HandleConnect(c *echo.Context) error
- func (s *TunnelServer) HandleMTLSEnroll(c *echo.Context) error
- func (s *TunnelServer) HandlePoll(c *echo.Context) error
- func (s *TunnelServer) StartCleanupLoop(ctx context.Context)
- func (s *TunnelServer) WaitForCleanupDone()
Constants ¶
const ( // DefaultHeartbeatInterval is how often the client sends heartbeats DefaultHeartbeatInterval = 30 * time.Second // DefaultWriteTimeout is the timeout for write operations DefaultWriteTimeout = 10 * time.Second // DefaultRequestTimeout is the timeout for executing local requests DefaultRequestTimeout = 5 * time.Minute // DefaultGRPCRegistrationTimeout bounds how long the agent waits for the // manager to acknowledge tunnel registration on any transport. DefaultGRPCRegistrationTimeout = 10 * time.Second // DefaultWebSocketPreferenceTTL keeps websocket as the preferred transport // for a short period after a successful auto-mode fallback. DefaultWebSocketPreferenceTTL = 2 * time.Minute )
const ( // EdgeDataPlaneMux and EdgeDataPlaneLegacy name the negotiated data plane in runtime state. EdgeDataPlaneMux = "mux" EdgeDataPlaneLegacy = "legacy" // MuxAgentBaseURL is the synthetic origin for requests a manager sends through a multiplexed tunnel. MuxAgentBaseURL = "http://agent.edge.arcane.internal" // ProxyResponseHeaderTimeout is generous because proxied operations such as deploys can run for minutes before responding. ProxyResponseHeaderTimeout = 30 * time.Minute )
const ( // DefaultTunnelPollInterval is how often poll-mode agents should check in. DefaultTunnelPollInterval = 2 * time.Second // DefaultPollRuntimeTTL is the minimum time a poll check-in stays fresh for runtime status. DefaultPollRuntimeTTL = 6 * time.Second // DefaultTunnelDemandTTL keeps a touched environment's tunnel required; it exceeds the 2m health // interval so health checks keep idle poll-mode tunnels open instead of flapping. DefaultTunnelDemandTTL = 5 * time.Minute // TunnelStatusIdle indicates that no reverse tunnel is currently needed. TunnelStatusIdle = "IDLE" // TunnelStatusRequired indicates that the manager needs the agent to open a tunnel. TunnelStatusRequired = "REQUIRED" // TunnelStatusActive indicates that the manager still needs the tunnel and it is already open. TunnelStatusActive = "ACTIVE" )
const ( DefaultProxyTimeout = 5 * time.Minute DefaultTunnelAcquirePollEvery = 100 * time.Millisecond )
const ( HeaderAPIKey = "X-Api-Key" // #nosec G101: header name, not a credential HeaderAuthorization = "Authorization" HeaderCookie = "Cookie" HeaderAgentToken = "X-Arcane-Agent-Token" // #nosec G101: header name, not a credential HeaderUpgrade = "Upgrade" HeaderConnection = "Connection" ConnectionUpgradeToken = "upgrade" )
const ( // EdgeTransportAuto prefers gRPC and falls back to WebSocket automatically. EdgeTransportAuto = "auto" // EdgeTransportWebSocket forces WebSocket tunnel transport. EdgeTransportWebSocket = "websocket" // EdgeTransportGRPC forces gRPC transport without WebSocket fallback. EdgeTransportGRPC = "grpc" // EdgeTransportPoll uses an HTTP polling control plane with the existing // websocket tunnel as an on-demand data plane. EdgeTransportPoll = "poll" // EdgeMTLSModeDisabled disables edge tunnel mTLS. EdgeMTLSModeDisabled = "disabled" // EdgeMTLSModeOptional enables edge tunnel mTLS when certificates are configured. EdgeMTLSModeOptional = "optional" // EdgeMTLSModeRequired requires a verified client certificate on edge tunnel endpoints // when Arcane terminates TLS; external TLS terminators must enforce mTLS before proxying. EdgeMTLSModeRequired = "required" )
const ( // TunnelEventTypeNotificationDispatch marks an event carrying a notification dispatch request in MetadataJSON; // tunnel-connected agents lack manager HTTP config, so dispatch rides the event channel (#3002). TunnelEventTypeNotificationDispatch = "notification.dispatch" )
const ( // TunnelStaleTimeout is how long before a tunnel is considered stale. TunnelStaleTimeout = 2 * time.Minute )
Variables ¶
var DefaultCommandClient = NewCommandClient()
Deprecated: legacy edge message protocol; remove in v3.
var ErrNoActiveAgentTunnel = errors.New("no active edge agent tunnel")
ErrNoActiveAgentTunnel is returned when no active agent tunnel exists for outbound event sync.
var ( // ErrTunnelConnectionClosed is returned by Send and Receive on every transport once the connection is closed. ErrTunnelConnectionClosed = errors.New("edge tunnel connection is closed") )
Functions ¶
func AdvertisedEdgeCommands
deprecated
func AdvertisedEdgeCommands() []string
AdvertisedEdgeCommands lists every allowlisted command name once.
Deprecated: legacy edge message protocol; remove in v3.
func AvailableManagerMTLSCAPath ¶ added in v2.8.0
AvailableManagerMTLSCAPath resolves an existing manager CA certificate.
func BuildHopByHopHeaders ¶
func BuildManagerServerTLSConfig ¶
BuildManagerServerTLSConfig returns the manager TLS configuration needed to support optional edge mTLS on the shared Arcane listener.
func BuildWebSocketHeaders ¶
BuildWebSocketHeaders constructs a header set for proxying WebSocket requests to a remote environment, forwarding authentication in the same way as HTTP proxying.
func ClearDefaultRegistry ¶ added in v2.7.0
func ClearDefaultRegistry(registry *TunnelRegistry)
ClearDefaultRegistry replaces registry only when it is still the active default.
func CopyBodyWithFlush ¶
func CopyBodyWithFlush(w http.ResponseWriter, body io.Reader) error
CopyBodyWithFlush streams body to w, flushing after each write when supported. It returns the first error other than io.EOF, so a response cut short upstream is not mistaken for a complete one.
func CopyRequestHeaders ¶
func CopyResponseHeaders ¶
func DefaultTunnelAcquireTimeout ¶
DefaultTunnelAcquireTimeout returns a poll-aware wait timeout for acquiring an on-demand edge tunnel.
func DoRequest ¶
DoRequest performs a service-level HTTP request through an edge tunnel and returns the status and body.
func EnsureAgentMTLSAssets ¶
EnsureAgentMTLSAssets downloads manager-generated client certificates when edge mTLS is enabled without configured client cert/key files, and renews them before they expire.
func GeneratedManagerClientMTLSCertPath ¶
GeneratedManagerClientMTLSCertPath returns the manager-side generated client certificate path for an environment.
func GetActiveTunnel ¶
func GetActiveTunnel(envID string) mo.Option[*AgentTunnel]
GetActiveTunnel returns the active tunnel for an environment in the default registry, if one exists.
func GetTunnelRuntimeState ¶
func GetTunnelRuntimeState(envID string) mo.Option[*TunnelRuntimeState]
GetTunnelRuntimeState returns live metadata for an active tunnel.
func HTTPToWebSocketURL ¶
HTTPToWebSocketURL converts an HTTP(S) URL to WS(S).
func HasActiveTunnel ¶
HasActiveTunnel checks if an environment has an active edge tunnel
func IsInternalTunnelRequest ¶
IsInternalTunnelRequest reports whether a request is dispatched by the legacy in-process tunnel client, which skips request logging. Only the legacy edge message protocol sets it; remove in v3.
func NewManagerHTTPClient ¶
NewManagerHTTPClient creates an HTTP client for agent-to-manager requests, applying edge TLS settings when the manager URL uses HTTPS.
func NormalizeEdgeMTLSMode ¶
NormalizeEdgeMTLSMode normalizes edge mTLS config and defaults to disabled.
func NormalizeEdgeTransport ¶
NormalizeEdgeTransport normalizes transport config and defaults to auto-negotiation.
func PrepareManagerMTLSAssetsWithContext ¶
PrepareManagerMTLSAssetsWithContext generates the manager CA when edge mTLS is enabled and no explicit manager CA file is configured.
func ProxyHTTPRequest
deprecated
func ProxyHTTPRequest(c *echo.Context, tunnel *AgentTunnel, targetPath string) error
ProxyHTTPRequest proxies an echo request through a legacy tunnel.
Deprecated: legacy edge message protocol; remove in v3.
func ProxyRequest ¶
func ProxyRequest(ctx context.Context, tunnel *AgentTunnel, method, path, query string, headers map[string]string, body []byte) (int, map[string]string, []byte, error)
ProxyRequest sends an HTTP request through an edge tunnel and returns the response status, headers, and body.
func ProxyWebSocketRequest
deprecated
func ProxyWebSocketRequest(c *echo.Context, tunnel *AgentTunnel, targetPath string, checkOrigin func(*http.Request) bool) error
ProxyWebSocketRequest proxies a WebSocket upgrade through a legacy edge tunnel. checkOrigin must be the local WebSocket Origin validator: the session cookie is already validated, so any Origin would allow cross-site terminals.
Deprecated: legacy edge message protocol; remove in v3.
func PublishEventToManager ¶
func PublishEventToManager(ctx context.Context, event *TunnelEvent) error
PublishEventToManager sends an event from the active agent tunnel to the manager.
func RequestTunnelAndWait ¶
func RequestTunnelAndWait(ctx context.Context, envID string, demandTTL, timeout time.Duration) mo.Option[*AgentTunnel]
RequestTunnelAndWait marks an edge environment as needed and waits for the agent to establish a live tunnel.
func ResolveEdgeCommandName ¶
ResolveEdgeCommandName returns the edge command for a request, or None when the allowlist does not cover it.
func SetAgentToken ¶
func SetDefaultRegistry ¶
func SetDefaultRegistry(registry *TunnelRegistry)
SetDefaultRegistry replaces the process-wide default tunnel registry.
func SetForwardedHeaders ¶
func StartTunnelClient ¶ added in v2.7.0
func StartTunnelClient(ctx context.Context, cfg *Config, handler http.Handler) (func(context.Context) error, error)
StartTunnelClient starts the tunnel client with an owned background worker.
func TouchTunnelDemand ¶
TouchTunnelDemand marks an edge environment as requiring an on-demand tunnel.
func UseGRPCEdgeTransport ¶
UseGRPCEdgeTransport reports whether gRPC managed tunnel mode should be attempted.
func UsePollEdgeTransport ¶
UsePollEdgeTransport reports whether the Portainer-style polling control plane should be used.
func UseWebSocketEdgeTransport ¶
UseWebSocketEdgeTransport reports whether websocket managed tunnel mode is allowed.
func ValidateAgentMTLSConfig ¶
ValidateAgentMTLSConfig validates the edge agent TLS configuration before the reverse tunnel client starts.
func ValidateEdgeCommand
deprecated
func ValidateManagerMTLSConfig ¶
ValidateManagerMTLSConfig validates a configured manager CA file. An empty CA file is allowed because PrepareManagerMTLSAssetsWithContext generates one.
func WaitForActiveTunnel ¶
func WaitForActiveTunnel(ctx context.Context, envID string, timeout time.Duration) mo.Option[*AgentTunnel]
WaitForActiveTunnel waits for an environment to establish a live tunnel in the default registry.
Types ¶
type AgentTunnel ¶
type AgentTunnel struct {
EnvironmentID string
Conn TunnelConnection
// Deprecated: legacy edge message protocol; remove in v3.
Pending sync.Map // map[string]*PendingRequest
ConnectedAt time.Time
LastHeartbeat time.Time
SessionID string
AgentInstance string
Transport string
SecurityMode string
Capabilities []string
State string
DisconnectErr string
// contains filtered or unexported fields
}
AgentTunnel represents an active tunnel connection from an edge agent
func NewAgentTunnelWithConn ¶
func NewAgentTunnelWithConn(envID string, conn TunnelConnection) *AgentTunnel
NewAgentTunnelWithConn creates a new agent tunnel from a transport-agnostic connection.
func (*AgentTunnel) CloseWithReason ¶
func (t *AgentTunnel) CloseWithReason(reason string) error
CloseWithReason closes the tunnel connection and records the disconnect reason. Pass "" when there is no reason to record.
func (*AgentTunnel) GetLastHeartbeat ¶
func (t *AgentTunnel) GetLastHeartbeat() time.Time
GetLastHeartbeat returns the last heartbeat time
func (*AgentTunnel) HTTPClient ¶ added in v2.16.0
func (t *AgentTunnel) HTTPClient() mo.Option[*http.Client]
HTTPClient returns the client for a tunnel that negotiated the multiplexed data plane. Requests use MuxAgentBaseURL as their origin and are served by the agent's own router.
func (*AgentTunnel) MetadataSnapshot ¶ added in v2.6.0
func (t *AgentTunnel) MetadataSnapshot() TunnelMetadataSnapshot
MetadataSnapshot returns the tunnel's mutable metadata under one read lock, so readers never race heartbeat, registration, or close writers.
func (*AgentTunnel) UpdateHeartbeat ¶
func (t *AgentTunnel) UpdateHeartbeat()
UpdateHeartbeat updates the last heartbeat timestamp
type CommandClient
deprecated
type CommandClient struct{}
Deprecated: legacy edge message protocol; remove in v3.
func NewCommandClient
deprecated
func NewCommandClient() *CommandClient
Deprecated: legacy edge message protocol; remove in v3.
func (*CommandClient) Execute
deprecated
func (c *CommandClient) Execute(ctx context.Context, tunnel *AgentTunnel, req *CommandRequest) (result *CommandResult, err error)
Deprecated: legacy edge message protocol; remove in v3.
func (*CommandClient) OpenStream
deprecated
func (c *CommandClient) OpenStream(ctx context.Context, tunnel *AgentTunnel, req *CommandRequest) error
Deprecated: legacy edge message protocol; remove in v3.
type CommandRequest
deprecated
type CommandRequest struct {
ID string
Command string
Method string
Path string
Query string
Headers map[string]string
Body []byte
TimeoutMillis int64
// Output, when set, receives the response as it streams in; CommandResult.Body is then nil.
Output http.ResponseWriter
}
Deprecated: legacy edge message protocol; remove in v3.
type CommandResult
deprecated
type Config ¶
type Config struct {
EdgeAgent bool
EdgeTransport string
EdgeReconnectInterval int
EdgeMTLSMode string
EdgeMTLSCAFile string
EdgeMTLSCertFile string
EdgeMTLSKeyFile string
EdgeMTLSServerName string
EdgeMTLSAssetsDir string
AppURL string
ManagerApiUrl string
AgentToken string
Port string
Listen string
// EdgeMuxDisabled keeps the legacy message protocol; remove in v3 with it.
EdgeMuxDisabled bool
}
Config contains the public edge-tunnel runtime settings needed by pkg/libarcane/edge.
type EnrollmentCallback ¶
type EnrollmentCallback func(ctx context.Context, environmentID, remoteAddr string, certIssued, caGenerated, reenrolled bool)
EnrollmentCallback is called after a successful manager-side edge mTLS enrollment. reenrolled is true when the environment had already enrolled before the cooldown.
type EnvironmentNameResolver ¶
type EnvironmentNameResolver func(ctx context.Context, environmentID string) (environmentName string, err error)
EnvironmentNameResolver resolves a display name for an environment ID.
type EnvironmentResolver ¶
EnvironmentResolver resolves an agent token to an environment ID.
type EventCallback ¶
type EventCallback func(ctx context.Context, environmentID string, event *TunnelEvent) error
EventCallback is called when an edge agent publishes an event.
type GRPCAgentTunnelConn ¶
type GRPCAgentTunnelConn struct {
// contains filtered or unexported fields
}
GRPCAgentTunnelConn wraps the agent-side gRPC tunnel stream.
func NewGRPCAgentTunnelConn ¶
func NewGRPCAgentTunnelConn(stream grpcAgentStream, cancelFns ...context.CancelFunc) *GRPCAgentTunnelConn
NewGRPCAgentTunnelConn creates an agent-side gRPC tunnel wrapper.
func (*GRPCAgentTunnelConn) Close ¶
func (t *GRPCAgentTunnelConn) Close() error
Close half-closes the send stream before cancelling, so the manager sees a clean io.EOF instead of codes.Canceled.
func (*GRPCAgentTunnelConn) IsClosed ¶
func (t *GRPCAgentTunnelConn) IsClosed() bool
IsClosed returns whether the stream is closed.
func (*GRPCAgentTunnelConn) IsExpectedReceiveError ¶
func (t *GRPCAgentTunnelConn) IsExpectedReceiveError(err error) bool
IsExpectedReceiveError returns true for expected gRPC stream shutdown errors.
func (*GRPCAgentTunnelConn) Receive ¶
func (t *GRPCAgentTunnelConn) Receive() (*TunnelMessage, error)
Receive receives a manager->agent tunnel message from gRPC.
func (*GRPCAgentTunnelConn) Send ¶
func (t *GRPCAgentTunnelConn) Send(msg *TunnelMessage) error
Send sends a legacy agent->manager tunnel message over gRPC.
func (*GRPCAgentTunnelConn) Transport ¶ added in v2.6.0
func (t *GRPCAgentTunnelConn) Transport() string
Transport identifies the underlying tunnel transport.
type GRPCManagerTunnelConn ¶
type GRPCManagerTunnelConn struct {
// contains filtered or unexported fields
}
GRPCManagerTunnelConn wraps the manager-side gRPC tunnel stream.
func NewGRPCManagerTunnelConn ¶
func NewGRPCManagerTunnelConn(stream grpcManagerStream) *GRPCManagerTunnelConn
NewGRPCManagerTunnelConn creates a manager-side gRPC tunnel wrapper. A nil stream yields a connection whose Send and Receive report ErrTunnelConnectionClosed.
func (*GRPCManagerTunnelConn) Close ¶
func (t *GRPCManagerTunnelConn) Close() error
Close marks the stream closed on manager side.
func (*GRPCManagerTunnelConn) IsClosed ¶
func (t *GRPCManagerTunnelConn) IsClosed() bool
IsClosed returns whether the stream is closed.
func (*GRPCManagerTunnelConn) IsExpectedReceiveError ¶
func (t *GRPCManagerTunnelConn) IsExpectedReceiveError(err error) bool
IsExpectedReceiveError returns true for expected gRPC stream shutdown errors.
func (*GRPCManagerTunnelConn) Receive ¶
func (t *GRPCManagerTunnelConn) Receive() (*TunnelMessage, error)
Receive receives an agent->manager tunnel message from gRPC.
func (*GRPCManagerTunnelConn) Send ¶
func (t *GRPCManagerTunnelConn) Send(msg *TunnelMessage) error
Send sends a legacy manager->agent tunnel message over gRPC.
func (*GRPCManagerTunnelConn) Transport ¶ added in v2.6.0
func (t *GRPCManagerTunnelConn) Transport() string
Transport identifies the underlying tunnel transport.
type GeneratedMTLSAssets ¶
type GeneratedMTLSAssets struct {
Files []GeneratedMTLSFile `json:"files"`
HostDirHint string `json:"hostDirHint"`
CertIssued bool `json:"-"`
CAGenerated bool `json:"-"`
Reenrolled bool `json:"-"`
}
GeneratedMTLSAssets contains manager-generated edge client certificates and snippet metadata.
func GenerateManagerClientMTLSAssetsWithContext ¶
func GenerateManagerClientMTLSAssetsWithContext(ctx context.Context, cfg *Config, envID, envName string) (*GeneratedMTLSAssets, error)
GenerateManagerClientMTLSAssetsWithContext ensures the generated CA and the environment's client certificate, reusing a client certificate that is still valid for the environment's identity.
type GeneratedMTLSFile ¶
type GeneratedMTLSFile struct {
Name string `json:"name"`
Content string `json:"content"`
ContainerPath string `json:"containerPath"`
Permissions string `json:"permissions"`
}
GeneratedMTLSFile describes a generated file that should be copied to the edge agent host.
type PendingRequest
deprecated
type PendingRequest struct {
ResponseCh chan *TunnelMessage
// contains filtered or unexported fields
}
PendingRequest tracks an in-flight request waiting for response.
Deprecated: legacy edge message protocol; remove in v3.
type PollRuntimeRegistry ¶
type PollRuntimeRegistry struct {
// contains filtered or unexported fields
}
PollRuntimeRegistry tracks recent poll check-ins from edge agents.
func GetPollRuntimeRegistry ¶
func GetPollRuntimeRegistry() *PollRuntimeRegistry
GetPollRuntimeRegistry returns the process-wide poll runtime registry.
func NewPollRuntimeRegistry ¶
func NewPollRuntimeRegistry() *PollRuntimeRegistry
NewPollRuntimeRegistry creates a new poll runtime registry.
func (*PollRuntimeRegistry) Get ¶
func (r *PollRuntimeRegistry) Get(envID string, now time.Time) mo.Option[PollRuntimeState]
Get returns the most recent poll runtime state if it is still fresh.
func (*PollRuntimeRegistry) Update ¶
func (r *PollRuntimeRegistry) Update(envID string, interval time.Duration, now time.Time) PollRuntimeState
Update records a poll check-in for an environment.
type PollRuntimeState ¶
PollRuntimeState describes the most recent poll-based control-plane activity observed for an edge environment.
type StatusUpdateCallback ¶
StatusUpdateCallback is called when an edge agent connects or disconnects. The connected parameter is true on connect, false on disconnect.
type TunnelClient ¶
type TunnelClient struct {
// contains filtered or unexported fields
}
TunnelClient represents the agent-side tunnel client
func NewTunnelClient ¶
func NewTunnelClient(cfg *Config, handler http.Handler) *TunnelClient
NewTunnelClient creates a new tunnel client
func (*TunnelClient) StartWithErrorChan ¶
func (c *TunnelClient) StartWithErrorChan(ctx context.Context, errCh chan error)
StartWithErrorChan runs the tunnel client and optionally emits connection errors.
type TunnelConn ¶
type TunnelConn struct {
// contains filtered or unexported fields
}
TunnelConn wraps a WebSocket connection with send/receive helpers.
func NewTunnelConn ¶
func NewTunnelConn(conn *websocket.Conn) *TunnelConn
NewTunnelConn creates a new WebSocket tunnel connection wrapper.
func (*TunnelConn) Close ¶
func (t *TunnelConn) Close() error
Close closes the WebSocket tunnel connection, sending a close frame on the first call so the peer observes a normal closure instead of 1006.
func (*TunnelConn) IsClosed ¶
func (t *TunnelConn) IsClosed() bool
IsClosed returns whether the connection is closed.
func (*TunnelConn) IsExpectedReceiveError ¶
func (t *TunnelConn) IsExpectedReceiveError(err error) bool
IsExpectedReceiveError returns true for normal WebSocket close/teardown errors.
func (*TunnelConn) Receive ¶
func (t *TunnelConn) Receive() (*TunnelMessage, error)
Receive receives a legacy tunnel message from the WebSocket connection.
func (*TunnelConn) Send ¶
func (t *TunnelConn) Send(msg *TunnelMessage) error
Send sends a legacy tunnel message over the WebSocket connection.
func (*TunnelConn) Transport ¶ added in v2.6.0
func (t *TunnelConn) Transport() string
Transport identifies the underlying tunnel transport.
type TunnelConnection ¶
type TunnelConnection interface {
Send(msg *TunnelMessage) error
Receive() (*TunnelMessage, error)
IsExpectedReceiveError(err error) bool
Close() error
IsClosed() bool
Transport() string
}
TunnelConnection is the transport contract shared by WebSocket and gRPC wrappers.
type TunnelDemandRegistry ¶
type TunnelDemandRegistry struct {
// contains filtered or unexported fields
}
TunnelDemandRegistry tracks short-lived tunnel demand on the manager side.
func GetDemandRegistry ¶
func GetDemandRegistry() *TunnelDemandRegistry
GetDemandRegistry returns the process-wide tunnel demand registry.
func NewTunnelDemandRegistry ¶
func NewTunnelDemandRegistry() *TunnelDemandRegistry
NewTunnelDemandRegistry creates a new tunnel demand registry.
func (*TunnelDemandRegistry) DesiredStatus ¶
func (r *TunnelDemandRegistry) DesiredStatus(envID string, hasActiveTunnel bool, now time.Time) string
DesiredStatus returns the desired manager-side tunnel state for an environment.
type TunnelEvent ¶
type TunnelEvent struct {
Type string `json:"type"`
Severity string `json:"severity,omitempty"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
ResourceType string `json:"resource_type,omitempty"`
ResourceID string `json:"resource_id,omitempty"`
ResourceName string `json:"resource_name,omitempty"`
UserID string `json:"user_id,omitempty"`
Username string `json:"username,omitempty"`
MetadataJSON []byte `json:"metadata_json,omitempty"`
}
TunnelEvent is an event payload sent from an agent to the manager.
type TunnelMessage ¶
type TunnelMessage struct {
Headers map[string]string `json:"headers,omitempty"` // HTTP headers
Event *TunnelEvent `json:"event,omitempty"` // Agent event payload
Metadata map[string]string `json:"metadata,omitempty"` // Correlation and audit metadata
ID string `json:"id"` // Unique request/stream ID
Type TunnelMessageType `json:"type"` // Message type
Method string `json:"method,omitempty"` // HTTP method for requests
Path string `json:"path,omitempty"` // Request path
Query string `json:"query,omitempty"` // Query string
AgentToken string `json:"agent_token,omitempty"` // Register request token
EnvironmentID string `json:"environment_id,omitempty"` // Manager-resolved environment ID
Error string `json:"error,omitempty"` // Error field for register response
Command string `json:"command,omitempty"` // Typed command name
SessionID string `json:"session_id,omitempty"` // Manager-issued session identifier
ResumeSession string `json:"resume_session,omitempty"` // Previous session being resumed
AgentInstance string `json:"agent_instance,omitempty"` // Stable agent runtime identity
SecurityMode string `json:"security_mode,omitempty"` // token, mtls, etc.
Body []byte `json:"body,omitempty"` // Request/response body
Capabilities []string `json:"capabilities,omitempty"` // Agent advertised capabilities
WSMessageType int `json:"ws_message_type,omitempty"` // WebSocket message type
Status int `json:"status,omitempty"` // HTTP status for responses
TimeoutMillis int64 `json:"timeout_millis,omitempty"` // Command timeout
Sequence int64 `json:"sequence,omitempty"` // Chunk sequence number
Credit int64 `json:"credit,omitempty"` // Command output bytes the manager consumed
Accepted bool `json:"accepted,omitempty"` // Registration accepted
DrainPrevious bool `json:"drain_previous,omitempty"` // Replace previous session
Streaming bool `json:"streaming,omitempty"` // Response used chunked output
EOF bool `json:"eof,omitempty"` // Final chunk indicator
}
TunnelMessage represents a transport-agnostic edge tunnel message. Only register and register_response survive the mux data plane; every other type is the legacy edge message protocol and goes in v3.
type TunnelMessageType ¶
type TunnelMessageType string
TunnelMessageType represents the type of message sent over the tunnel.
const ( // MessageTypeRegister is the first message sent by the agent on gRPC transport. MessageTypeRegister TunnelMessageType = "register" // MessageTypeRegisterResponse is sent by manager after register validation. MessageTypeRegisterResponse TunnelMessageType = "register_response" // MessageTypeRequest is sent from manager to agent to initiate a request. MessageTypeRequest TunnelMessageType = "request" // MessageTypeResponse is sent from agent to manager with the response. MessageTypeResponse TunnelMessageType = "response" // MessageTypeHeartbeat is sent by agents to keep the connection alive. MessageTypeHeartbeat TunnelMessageType = "heartbeat" // MessageTypeHeartbeatAck is sent by manager to acknowledge a heartbeat. MessageTypeHeartbeatAck TunnelMessageType = "heartbeat_ack" // MessageTypeStreamData is sent for streaming responses (logs, stats). MessageTypeStreamData TunnelMessageType = "stream_data" // MessageTypeStreamEnd indicates end of a stream. MessageTypeStreamEnd TunnelMessageType = "stream_end" // MessageTypeWebSocketStart starts a WebSocket stream for logs/stats. MessageTypeWebSocketStart TunnelMessageType = "ws_start" // MessageTypeWebSocketData is a WebSocket message in either direction. MessageTypeWebSocketData TunnelMessageType = "ws_data" // MessageTypeWebSocketClose closes a WebSocket stream. MessageTypeWebSocketClose TunnelMessageType = "ws_close" // MessageTypeEvent carries an event emitted by an agent to the manager. MessageTypeEvent TunnelMessageType = "event" // MessageTypeCommandRequest sends a typed edge command from manager to agent. MessageTypeCommandRequest TunnelMessageType = "command_request" // MessageTypeCommandAck acknowledges a command was accepted by the agent. MessageTypeCommandAck TunnelMessageType = "command_ack" // MessageTypeCommandOutput carries chunked command output from agent to manager. MessageTypeCommandOutput TunnelMessageType = "command_output" // MessageTypeCommandComplete indicates final command completion. MessageTypeCommandComplete TunnelMessageType = "command_complete" // MessageTypeFileChunk carries chunked request or response payload data. MessageTypeFileChunk TunnelMessageType = "file_chunk" // MessageTypeStreamOpen opens a command-backed stream. MessageTypeStreamOpen TunnelMessageType = "stream_open" // MessageTypeStreamClose closes a command-backed stream. MessageTypeStreamClose TunnelMessageType = "stream_close" // MessageTypeCancelRequest requests cancellation of an in-flight command. MessageTypeCancelRequest TunnelMessageType = "cancel_request" // MessageTypeCommandCredit returns flow-control credit for consumed command output. MessageTypeCommandCredit TunnelMessageType = "command_credit" )
type TunnelMetadataSnapshot ¶ added in v2.6.0
type TunnelMetadataSnapshot struct {
ConnectedAt time.Time
LastHeartbeat time.Time
SessionID string
AgentInstance string
SecurityMode string
Capabilities []string
State string
}
TunnelMetadataSnapshot is a consistent copy of a tunnel's mutable metadata.
type TunnelPollRequest ¶
type TunnelPollRequest struct {
Transport string `json:"transport,omitempty"`
Connected bool `json:"connected,omitempty"`
}
TunnelPollRequest is a forward-compatible control-plane check-in request.
type TunnelPollResponse ¶
type TunnelPollResponse struct {
Status string `json:"status"`
PollIntervalSeconds int `json:"pollIntervalSeconds"`
ActiveTransport string `json:"activeTransport,omitempty"`
Connected bool `json:"connected,omitempty"`
}
TunnelPollResponse is a forward-compatible control-plane response.
type TunnelRegistry ¶
type TunnelRegistry struct {
// contains filtered or unexported fields
}
TunnelRegistry manages active edge agent tunnel connections
func GetRegistry ¶
func GetRegistry() *TunnelRegistry
GetRegistry returns the global tunnel registry
func NewTunnelRegistry ¶
func NewTunnelRegistry() *TunnelRegistry
NewTunnelRegistry creates a new tunnel registry
func (*TunnelRegistry) Active ¶ added in v2.16.0
func (r *TunnelRegistry) Active(envID string) mo.Option[*AgentTunnel]
Active returns the environment's tunnel when its connection is still open.
func (*TunnelRegistry) CleanupStale ¶
func (r *TunnelRegistry) CleanupStale(ctx context.Context, maxAge time.Duration) []*AgentTunnel
CleanupStale removes tunnels that haven't had a heartbeat within the given duration.
func (*TunnelRegistry) Get ¶
func (r *TunnelRegistry) Get(envID string) mo.Option[*AgentTunnel]
Get retrieves a tunnel by environment ID
func (*TunnelRegistry) ObserveAgents ¶ added in v2.16.0
func (r *TunnelRegistry) ObserveAgents(meter metric.Meter) (metric.Registration, error)
ObserveAgents reports connected edge agents by transport through the arcane.edge.agents gauge. Poll-mode agents count as "poll" while their check-ins are fresh and no tunnel is open.
func (*TunnelRegistry) Register ¶
func (r *TunnelRegistry) Register(envID string, tunnel *AgentTunnel)
Register adds a tunnel to the registry, closing any existing tunnel for the same env
func (*TunnelRegistry) RegisterSession ¶
func (r *TunnelRegistry) RegisterSession(ctx context.Context, tunnel *AgentTunnel, staleAfter time.Duration) (bool, bool, string, error)
RegisterSession adds a tunnel with duplicate-session handling.
func (*TunnelRegistry) Stop ¶ added in v2.7.0
func (r *TunnelRegistry) Stop(ctx context.Context) error
Stop drains registry mutations and closes active tunnels.
func (*TunnelRegistry) Unregister ¶
func (r *TunnelRegistry) Unregister(envID string)
Unregister removes a tunnel from the registry
func (*TunnelRegistry) UnregisterCurrent ¶
func (r *TunnelRegistry) UnregisterCurrent(ctx context.Context, envID string, current *AgentTunnel) (bool, bool)
UnregisterCurrent removes the environment's tunnel only if it is still current. It reports whether it was removed and whether another live session already replaced it.
func (*TunnelRegistry) WaitForActive ¶ added in v2.16.0
func (r *TunnelRegistry) WaitForActive(ctx context.Context, envID string, timeout time.Duration) mo.Option[*AgentTunnel]
WaitForActive polls until the environment has an open tunnel or timeout elapses.
type TunnelRuntimeState ¶
type TunnelRuntimeState struct {
// DataPlane is EdgeDataPlaneMux or EdgeDataPlaneLegacy.
DataPlane string
// RoundTripTime is the last keepalive round trip; only multiplexed tunnels measure it.
RoundTripTime *time.Duration
// OpenStreams counts open mux streams (including pooled idle ones) or pending legacy requests.
OpenStreams int
Transport string
ConnectedAt *time.Time
LastHeartbeat *time.Time
SessionID string
AgentInstance string
SecurityMode string
Capabilities []string
State string
}
TunnelRuntimeState describes the live, in-memory state of an active edge tunnel.
type TunnelServer ¶
type TunnelServer struct {
// Config holds the edge runtime settings; set it before serving.
Config *Config
// NameResolver, when set, names environments in generated mTLS assets.
NameResolver EnvironmentNameResolver
// EventCallback, when set, receives agent events.
EventCallback EventCallback
// EnrollmentCallback, when set, runs after a successful edge mTLS enrollment.
EnrollmentCallback EnrollmentCallback
// contains filtered or unexported fields
}
TunnelServer handles incoming edge agent connections on the manager side.
func NewTunnelServerWithRegistry ¶
func NewTunnelServerWithRegistry(registry *TunnelRegistry, resolver EnvironmentResolver, statusCallback StatusUpdateCallback) *TunnelServer
NewTunnelServerWithRegistry creates a new tunnel server using an injected tunnel registry.
func (*TunnelServer) Connect ¶
func (s *TunnelServer) Connect(stream grpc.BidiStreamingServer[tunnelpb.AgentMessage, tunnelpb.ManagerMessage]) error
Connect is the gRPC bidi stream handler for edge agent connections.
func (*TunnelServer) GRPCServerOptions ¶
func (s *TunnelServer) GRPCServerOptions() []grpc.ServerOption
GRPCServerOptions returns the receive limit and stream interceptors for the tunnel service. It is served through ServeHTTP, so transport keepalive options belong on net/http.
func (*TunnelServer) HandleConnect ¶
func (s *TunnelServer) HandleConnect(c *echo.Context) error
HandleConnect is the WebSocket handler for edge agent connections. This is registered at /api/tunnel/connect.
func (*TunnelServer) HandleMTLSEnroll ¶
func (s *TunnelServer) HandleMTLSEnroll(c *echo.Context) error
HandleMTLSEnroll returns manager-generated edge client certificates for the calling environment. The response contains private keys, so response-body logging must stay disabled here.
func (*TunnelServer) HandlePoll ¶
func (s *TunnelServer) HandlePoll(c *echo.Context) error
HandlePoll is the HTTP control-plane endpoint used by poll-mode agents.
func (*TunnelServer) StartCleanupLoop ¶
func (s *TunnelServer) StartCleanupLoop(ctx context.Context)
StartCleanupLoop periodically cleans up stale tunnels.
func (*TunnelServer) WaitForCleanupDone ¶
func (s *TunnelServer) WaitForCleanupDone()
WaitForCleanupDone blocks until the cleanup loop has stopped.