Gate fabric session endpoint through node config

This commit is contained in:
2026-05-16 00:29:54 +03:00
parent 85c61a474f
commit c2418e5ff2
13 changed files with 66 additions and 1 deletions
@@ -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) {