Gate fabric session endpoint through node config
This commit is contained in:
@@ -203,6 +203,7 @@ func runInstallLinux(ctx context.Context, args []string) error {
|
||||
fs.BoolVar(&cfg.RuntimeConfig.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", true), "Enable synthetic mesh runtime.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshFabricSessionEnabled, "mesh-fabric-session-enabled", getenvBool("RAP_MESH_FABRIC_SESSION_ENABLED", false), "Enable authenticated fabric session WebSocket endpoint.")
|
||||
fs.StringVar(&cfg.RuntimeConfig.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ":19131"), "Synthetic mesh HTTP listen address.")
|
||||
fs.StringVar(&cfg.RuntimeConfig.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
|
||||
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
|
||||
@@ -284,6 +285,7 @@ func runInstallWindows(ctx context.Context, args []string) error {
|
||||
fs.BoolVar(&cfg.RuntimeConfig.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", true), "Enable synthetic mesh runtime.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
|
||||
fs.BoolVar(&cfg.RuntimeConfig.MeshFabricSessionEnabled, "mesh-fabric-session-enabled", getenvBool("RAP_MESH_FABRIC_SESSION_ENABLED", false), "Enable authenticated fabric session WebSocket endpoint.")
|
||||
fs.StringVar(&cfg.RuntimeConfig.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ":19131"), "Synthetic mesh HTTP listen address.")
|
||||
fs.StringVar(&cfg.RuntimeConfig.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", "auto"), "Mesh listen port behavior: manual, auto, or disabled.")
|
||||
fs.IntVar(&cfg.RuntimeConfig.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 19131), "First port used when mesh listen port mode is auto.")
|
||||
@@ -771,6 +773,7 @@ func parseInstall(args []string) (installCommandConfig, error) {
|
||||
fs.BoolVar(&cfg.WorkloadSupervisionEnabled, "workload-supervision-enabled", getenvBool("RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable node-agent workload status reporting.")
|
||||
fs.BoolVar(&cfg.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getenvBool("RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", false), "Enable synthetic mesh runtime.")
|
||||
fs.BoolVar(&cfg.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getenvBool("RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production forwarding gate; runtime still fail-closed if unavailable.")
|
||||
fs.BoolVar(&cfg.MeshFabricSessionEnabled, "mesh-fabric-session-enabled", getenvBool("RAP_MESH_FABRIC_SESSION_ENABLED", false), "Enable authenticated fabric session WebSocket endpoint.")
|
||||
fs.StringVar(&cfg.MeshListenAddr, "mesh-listen-addr", getenv("RAP_MESH_LISTEN_ADDR", ""), "Synthetic mesh HTTP listen address inside container.")
|
||||
fs.StringVar(&cfg.MeshListenPortMode, "mesh-listen-port-mode", getenv("RAP_MESH_LISTEN_PORT_MODE", ""), "Mesh listen port behavior: manual, auto, or disabled.")
|
||||
fs.IntVar(&cfg.MeshListenAutoPortStart, "mesh-listen-auto-port-start", getenvInt("RAP_MESH_LISTEN_AUTO_PORT_START", 0), "First port used when mesh listen port mode is auto.")
|
||||
|
||||
@@ -755,6 +755,15 @@ func startSyntheticMeshEndpoint(ctx context.Context, _ context.CancelFunc, cfg c
|
||||
}
|
||||
log.Printf("fabric_service_channel_access_event=%s", string(payload))
|
||||
},
|
||||
FabricSessionEnabled: cfg.MeshFabricSessionEnabled,
|
||||
FabricSessionLogger: func(entry mesh.FabricSessionEventLogEntry) {
|
||||
payload, err := json.Marshal(entry)
|
||||
if err != nil {
|
||||
log.Printf("fabric session event marshal failed: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("fabric_session_event=%s", string(payload))
|
||||
},
|
||||
RemoteWorkspaceFrameSink: remoteWorkspaceFrameSink,
|
||||
ProductionRoutes: routes,
|
||||
VPNPacketIngress: vpnFabricIngress,
|
||||
@@ -1639,6 +1648,15 @@ func applyRefreshedSyntheticMeshConfig(ctx context.Context, cfg config.Config, i
|
||||
}
|
||||
log.Printf("fabric_service_channel_access_event=%s", string(payload))
|
||||
},
|
||||
FabricSessionEnabled: cfg.MeshFabricSessionEnabled,
|
||||
FabricSessionLogger: func(entry mesh.FabricSessionEventLogEntry) {
|
||||
payload, err := json.Marshal(entry)
|
||||
if err != nil {
|
||||
log.Printf("fabric session event marshal failed: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("fabric_session_event=%s", string(payload))
|
||||
},
|
||||
RemoteWorkspaceFrameSink: meshState.RemoteWorkspaceFrameSink,
|
||||
ProductionRoutes: loadedConfig.Routes,
|
||||
VPNPacketIngress: vpnFabricIngress,
|
||||
@@ -2447,6 +2465,21 @@ func heartbeatPayload(cfg config.Config, identity state.Identity, meshState *syn
|
||||
if cfg.MeshProductionForwardingEnabled || (meshState != nil && meshState.ProductionForwardingEnabled) {
|
||||
payload.Capabilities["mesh_production_forwarding"] = true
|
||||
}
|
||||
if cfg.MeshFabricSessionEnabled {
|
||||
payload.Metadata["fabric_session_endpoint_report"] = map[string]any{
|
||||
"schema_version": "rap.fabric_session_endpoint_report.v1",
|
||||
"enabled": true,
|
||||
"transport": "websocket_binary_frames",
|
||||
"path": "/mesh/v1/fabric/session/ws",
|
||||
"auth": "rap_fsn_token_with_optional_signed_authority",
|
||||
"protocol": "rap.fabric_data_session.v1",
|
||||
"service_neutral": true,
|
||||
"traffic_isolation": "logical_streams",
|
||||
"observed_at": observedAt.UTC().Format(time.RFC3339Nano),
|
||||
}
|
||||
payload.Capabilities["fabric_session_websocket_endpoint"] = true
|
||||
payload.Capabilities["fabric_data_session_v1"] = true
|
||||
}
|
||||
if meshState != nil && meshState.ConfigLoadError != "" {
|
||||
payload.HealthStatus = "warning"
|
||||
}
|
||||
|
||||
@@ -634,6 +634,7 @@ func TestHeartbeatPayloadIncludesMeshEndpointReport(t *testing.T) {
|
||||
MeshRegion: "eu",
|
||||
MeshSyntheticRuntimeEnabled: true,
|
||||
MeshProductionForwardingEnabled: true,
|
||||
MeshFabricSessionEnabled: true,
|
||||
}, state.Identity{
|
||||
ClusterID: "cluster-1",
|
||||
NodeID: "node-a",
|
||||
@@ -652,6 +653,12 @@ func TestHeartbeatPayloadIncludesMeshEndpointReport(t *testing.T) {
|
||||
if payload.Capabilities["mesh_dynamic_endpoint_reporting"] != true {
|
||||
t.Fatalf("dynamic endpoint capability missing: %+v", payload.Capabilities)
|
||||
}
|
||||
if payload.Capabilities["fabric_session_websocket_endpoint"] != true || payload.Capabilities["fabric_data_session_v1"] != true {
|
||||
t.Fatalf("fabric session capabilities missing: %+v", payload.Capabilities)
|
||||
}
|
||||
if report, ok := payload.Metadata["fabric_session_endpoint_report"].(map[string]any); !ok || report["path"] != "/mesh/v1/fabric/session/ws" {
|
||||
t.Fatalf("fabric session endpoint report missing: %+v", payload.Metadata)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeartbeatPayloadReportsMeshListenerFailureWithoutKillingHeartbeat(t *testing.T) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/state"
|
||||
)
|
||||
|
||||
const Version = "0.2.279-vpnperf"
|
||||
const Version = "0.2.280-fabricsession"
|
||||
|
||||
func EnrollmentPayload(clusterID, joinToken string, identity state.Identity) client.EnrollRequest {
|
||||
return client.EnrollRequest{
|
||||
@@ -37,6 +37,8 @@ func EnrollmentPayload(clusterID, joinToken string, identity state.Identity) cli
|
||||
"vpn_fabric_packet_transport": true,
|
||||
"vpn_local_gateway_shortcut": false,
|
||||
"vpn_farm_owned_dataplane": true,
|
||||
"fabric_data_session_v1": true,
|
||||
"fabric_session_websocket_smoke": true,
|
||||
"vpn_backend_relay_fallback": false,
|
||||
"fabric_service_channel_required": true,
|
||||
"external_backend_entry_proxy": true,
|
||||
@@ -64,6 +66,8 @@ func HeartbeatPayload() client.HeartbeatRequest {
|
||||
"vpn_fabric_packet_transport": true,
|
||||
"vpn_local_gateway_shortcut": false,
|
||||
"vpn_farm_owned_dataplane": true,
|
||||
"fabric_data_session_v1": true,
|
||||
"fabric_session_websocket_smoke": true,
|
||||
"vpn_backend_relay_fallback": false,
|
||||
"fabric_service_channel_required": true,
|
||||
"external_backend_entry_proxy": true,
|
||||
|
||||
@@ -26,6 +26,7 @@ type Config struct {
|
||||
EnrollmentPollTimeout time.Duration
|
||||
MeshSyntheticRuntimeEnabled bool
|
||||
MeshProductionForwardingEnabled bool
|
||||
MeshFabricSessionEnabled bool
|
||||
MeshProductionObservationSinkCapacity int
|
||||
MeshListenAddr string
|
||||
MeshListenPortMode string
|
||||
@@ -63,6 +64,7 @@ func Load(args []string, env map[string]string) (Config, error) {
|
||||
fs.BoolVar(&cfg.WorkloadSupervisionEnabled, "workload-supervision-enabled", getEnvBool(env, "RAP_WORKLOAD_SUPERVISION_ENABLED", false), "Enable desired workload polling and status reporting. Disabled by default while service runtime is not implemented.")
|
||||
fs.BoolVar(&cfg.MeshSyntheticRuntimeEnabled, "mesh-synthetic-runtime-enabled", getEnvBool(env, "RAP_MESH_SYNTHETIC_RUNTIME_ENABLED", false), "Enable C17A synthetic fabric probe runtime. Disabled by default.")
|
||||
fs.BoolVar(&cfg.MeshProductionForwardingEnabled, "mesh-production-forwarding-enabled", getEnvBool(env, "RAP_MESH_PRODUCTION_FORWARDING_ENABLED", false), "Enable production fabric-control direct next-hop forwarding gate. Disabled by default.")
|
||||
fs.BoolVar(&cfg.MeshFabricSessionEnabled, "mesh-fabric-session-enabled", getEnvBool(env, "RAP_MESH_FABRIC_SESSION_ENABLED", false), "Enable authenticated fabric session WebSocket endpoint. Disabled by default.")
|
||||
fs.IntVar(&cfg.MeshProductionObservationSinkCapacity, "mesh-production-observation-sink-capacity", getEnvSignedInt(env, "RAP_MESH_PRODUCTION_OBSERVATION_SINK_CAPACITY", 0), "Bounded local metadata-only production envelope observation sink capacity. Disabled when 0.")
|
||||
fs.StringVar(&cfg.MeshListenAddr, "mesh-listen-addr", getEnv(env, "RAP_MESH_LISTEN_ADDR", ""), "Listen address for disabled-by-default C17E synthetic mesh HTTP endpoint.")
|
||||
fs.StringVar(&cfg.MeshListenPortMode, "mesh-listen-port-mode", getEnv(env, "RAP_MESH_LISTEN_PORT_MODE", "manual"), "Mesh listen port behavior: manual, auto, or disabled.")
|
||||
|
||||
@@ -20,6 +20,7 @@ func TestLoadConfigFromEnvAndArgs(t *testing.T) {
|
||||
"RAP_ENROLLMENT_POLL_TIMEOUT_SECONDS": "30",
|
||||
"RAP_MESH_SYNTHETIC_RUNTIME_ENABLED": "true",
|
||||
"RAP_MESH_PRODUCTION_FORWARDING_ENABLED": "true",
|
||||
"RAP_MESH_FABRIC_SESSION_ENABLED": "true",
|
||||
"RAP_MESH_PRODUCTION_OBSERVATION_SINK_CAPACITY": "5",
|
||||
"RAP_MESH_LISTEN_ADDR": "127.0.0.1:19001",
|
||||
"RAP_MESH_LISTEN_PORT_MODE": "auto",
|
||||
@@ -66,6 +67,9 @@ func TestLoadConfigFromEnvAndArgs(t *testing.T) {
|
||||
if !cfg.MeshProductionForwardingEnabled {
|
||||
t.Fatal("MeshProductionForwardingEnabled = false, want true")
|
||||
}
|
||||
if !cfg.MeshFabricSessionEnabled {
|
||||
t.Fatal("MeshFabricSessionEnabled = false, want true")
|
||||
}
|
||||
if cfg.MeshProductionObservationSinkCapacity != 5 {
|
||||
t.Fatalf("MeshProductionObservationSinkCapacity = %d, want 5", cfg.MeshProductionObservationSinkCapacity)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ type RuntimeConfig struct {
|
||||
WorkloadSupervisionEnabled bool
|
||||
MeshSyntheticRuntimeEnabled bool
|
||||
MeshProductionForwardingEnabled bool
|
||||
MeshFabricSessionEnabled bool
|
||||
MeshListenAddr string
|
||||
MeshListenPortMode string
|
||||
MeshListenAutoPortStart int
|
||||
|
||||
@@ -264,6 +264,7 @@ func NodeAgentEnvWithStateDir(cfg RuntimeConfig, stateDir string) []string {
|
||||
"RAP_WORKLOAD_SUPERVISION_ENABLED=" + boolString(cfg.WorkloadSupervisionEnabled),
|
||||
"RAP_MESH_SYNTHETIC_RUNTIME_ENABLED=" + boolString(cfg.MeshSyntheticRuntimeEnabled),
|
||||
"RAP_MESH_PRODUCTION_FORWARDING_ENABLED=" + boolString(cfg.MeshProductionForwardingEnabled),
|
||||
"RAP_MESH_FABRIC_SESSION_ENABLED=" + boolString(cfg.MeshFabricSessionEnabled),
|
||||
}
|
||||
if cfg.JoinToken != "" {
|
||||
env = append(env, "RAP_JOIN_TOKEN="+cfg.JoinToken)
|
||||
|
||||
@@ -72,6 +72,7 @@ func LinuxInstallConfigFromProfile(profile LinuxInstallProfile) LinuxInstallConf
|
||||
WorkloadSupervisionEnabled: profile.WorkloadSupervisionEnabled,
|
||||
MeshSyntheticRuntimeEnabled: profile.MeshSyntheticRuntimeEnabled,
|
||||
MeshProductionForwardingEnabled: profile.MeshProductionForwardingEnabled,
|
||||
MeshFabricSessionEnabled: profile.MeshFabricSessionEnabled,
|
||||
MeshListenAddr: profile.MeshListenAddr,
|
||||
MeshListenPortMode: profile.MeshListenPortMode,
|
||||
MeshListenAutoPortStart: profile.MeshListenAutoPortStart,
|
||||
|
||||
@@ -30,6 +30,7 @@ type DockerInstallProfile struct {
|
||||
WorkloadSupervisionEnabled bool `json:"workload_supervision_enabled"`
|
||||
MeshSyntheticRuntimeEnabled bool `json:"mesh_synthetic_runtime_enabled"`
|
||||
MeshProductionForwardingEnabled bool `json:"mesh_production_forwarding_enabled"`
|
||||
MeshFabricSessionEnabled bool `json:"mesh_fabric_session_enabled"`
|
||||
MeshListenAddr string `json:"mesh_listen_addr"`
|
||||
MeshListenPortMode string `json:"mesh_listen_port_mode"`
|
||||
MeshListenAutoPortStart int `json:"mesh_listen_auto_port_start"`
|
||||
@@ -72,6 +73,7 @@ type WindowsInstallProfile struct {
|
||||
WorkloadSupervisionEnabled bool `json:"workload_supervision_enabled"`
|
||||
MeshSyntheticRuntimeEnabled bool `json:"mesh_synthetic_runtime_enabled"`
|
||||
MeshProductionForwardingEnabled bool `json:"mesh_production_forwarding_enabled"`
|
||||
MeshFabricSessionEnabled bool `json:"mesh_fabric_session_enabled"`
|
||||
MeshListenAddr string `json:"mesh_listen_addr"`
|
||||
MeshListenPortMode string `json:"mesh_listen_port_mode"`
|
||||
MeshListenAutoPortStart int `json:"mesh_listen_auto_port_start"`
|
||||
@@ -104,6 +106,7 @@ type LinuxInstallProfile struct {
|
||||
WorkloadSupervisionEnabled bool `json:"workload_supervision_enabled"`
|
||||
MeshSyntheticRuntimeEnabled bool `json:"mesh_synthetic_runtime_enabled"`
|
||||
MeshProductionForwardingEnabled bool `json:"mesh_production_forwarding_enabled"`
|
||||
MeshFabricSessionEnabled bool `json:"mesh_fabric_session_enabled"`
|
||||
MeshListenAddr string `json:"mesh_listen_addr"`
|
||||
MeshListenPortMode string `json:"mesh_listen_port_mode"`
|
||||
MeshListenAutoPortStart int `json:"mesh_listen_auto_port_start"`
|
||||
@@ -281,6 +284,7 @@ func RuntimeConfigFromProfile(profile DockerInstallProfile) RuntimeConfig {
|
||||
WorkloadSupervisionEnabled: profile.WorkloadSupervisionEnabled,
|
||||
MeshSyntheticRuntimeEnabled: profile.MeshSyntheticRuntimeEnabled,
|
||||
MeshProductionForwardingEnabled: profile.MeshProductionForwardingEnabled,
|
||||
MeshFabricSessionEnabled: profile.MeshFabricSessionEnabled,
|
||||
MeshListenAddr: profile.MeshListenAddr,
|
||||
MeshListenPortMode: profile.MeshListenPortMode,
|
||||
MeshListenAutoPortStart: profile.MeshListenAutoPortStart,
|
||||
|
||||
@@ -594,6 +594,7 @@ func (m DockerManager) runtimeConfigFromContainer(ctx context.Context, runner Co
|
||||
WorkloadSupervisionEnabled: parseBool(env["RAP_WORKLOAD_SUPERVISION_ENABLED"]),
|
||||
MeshSyntheticRuntimeEnabled: true,
|
||||
MeshProductionForwardingEnabled: parseBool(env["RAP_MESH_PRODUCTION_FORWARDING_ENABLED"]),
|
||||
MeshFabricSessionEnabled: parseBool(env["RAP_MESH_FABRIC_SESSION_ENABLED"]),
|
||||
MeshListenAddr: env["RAP_MESH_LISTEN_ADDR"],
|
||||
MeshListenPortMode: env["RAP_MESH_LISTEN_PORT_MODE"],
|
||||
MeshListenAutoPortStart: parseInt(env["RAP_MESH_LISTEN_AUTO_PORT_START"]),
|
||||
|
||||
@@ -66,6 +66,7 @@ func WindowsInstallConfigFromProfile(profile WindowsInstallProfile) WindowsInsta
|
||||
WorkloadSupervisionEnabled: profile.WorkloadSupervisionEnabled,
|
||||
MeshSyntheticRuntimeEnabled: profile.MeshSyntheticRuntimeEnabled,
|
||||
MeshProductionForwardingEnabled: profile.MeshProductionForwardingEnabled,
|
||||
MeshFabricSessionEnabled: profile.MeshFabricSessionEnabled,
|
||||
MeshListenAddr: profile.MeshListenAddr,
|
||||
MeshListenPortMode: profile.MeshListenPortMode,
|
||||
MeshListenAutoPortStart: profile.MeshListenAutoPortStart,
|
||||
|
||||
@@ -260,6 +260,9 @@ Status: started with a transport-neutral `io.Reader`/`io.Writer` frame loop,
|
||||
WebSocket frame adapter in `agents/rap-node-agent/internal/fabricproto`, and a
|
||||
gated/authenticated mesh smoke endpoint/client at `/mesh/v1/fabric/session/ws`.
|
||||
`rap-host-agent fabric-session-smoke` provides the first operator smoke command.
|
||||
Node-agent exposes the endpoint only when `RAP_MESH_FABRIC_SESSION_ENABLED` /
|
||||
`-mesh-fabric-session-enabled` is set, and reports the enabled endpoint in
|
||||
heartbeat metadata.
|
||||
|
||||
Deliverables:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user