180 lines
7.2 KiB
Go
180 lines
7.2 KiB
Go
package vpnruntime
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
DefaultFabricTunnelPoolID = "ipv4-egress"
|
|
DefaultFabricTunnelServiceKind = "ipv4-tunnel"
|
|
DefaultFabricTunnelClass = "vpn_packets"
|
|
DefaultFabricTunnelRole = "ipv4-egress"
|
|
DefaultFabricTunnelDataPlane = "fabric_quic_streams"
|
|
DefaultFabricTransportOwner = "fabric_farm"
|
|
DefaultFabricRouteVisibility = "opaque_to_service"
|
|
|
|
FabricServiceTunnelSchemaVersion = "rap.fabric_service_tunnel.v1"
|
|
FabricServiceTrafficControl = "control"
|
|
FabricServiceTrafficDNS = "dns"
|
|
FabricServiceTrafficInteractive = "interactive"
|
|
FabricServiceTrafficReliable = "reliable"
|
|
FabricServiceTrafficBulk = "bulk"
|
|
FabricServiceTrafficDroppable = "droppable"
|
|
DefaultFabricServiceStreamShards = 8
|
|
)
|
|
|
|
type FabricServiceTunnel struct {
|
|
TunnelID string `json:"tunnel_id"`
|
|
PoolID string `json:"pool_id"`
|
|
ServiceID string `json:"service_id"`
|
|
LocalServiceID string `json:"local_service_id"`
|
|
RemoteServiceID string `json:"remote_service_id"`
|
|
ServiceKind string `json:"service_kind"`
|
|
ServiceClass string `json:"service_class"`
|
|
ServiceRole string `json:"service_role"`
|
|
RouteLeaseID string `json:"route_lease_id,omitempty"`
|
|
RouteGeneration string `json:"route_generation,omitempty"`
|
|
|
|
DataPlane string `json:"data_plane,omitempty"`
|
|
TransportOwner string `json:"transport_owner,omitempty"`
|
|
RouteVisibility string `json:"route_visibility,omitempty"`
|
|
TrafficClasses []string `json:"traffic_classes,omitempty"`
|
|
StreamShards int `json:"stream_shards,omitempty"`
|
|
}
|
|
|
|
type FabricServiceTunnelDefaults struct {
|
|
PoolID string
|
|
ServiceKind string
|
|
ServiceClass string
|
|
ServiceRole string
|
|
DataPlane string
|
|
TransportOwner string
|
|
RouteVisibility string
|
|
TrafficClasses []string
|
|
StreamShards int
|
|
}
|
|
|
|
func NormalizeServiceTunnel(tunnel FabricServiceTunnel, fallbackID string) FabricServiceTunnel {
|
|
return NormalizeServiceTunnelWithDefaults(tunnel, fallbackID, DefaultVPNServiceTunnelDefaults())
|
|
}
|
|
|
|
func NormalizeServiceTunnelWithDefaults(tunnel FabricServiceTunnel, fallbackID string, defaults FabricServiceTunnelDefaults) FabricServiceTunnel {
|
|
defaults = normalizeServiceTunnelDefaults(defaults)
|
|
tunnel.TunnelID = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.TunnelID, fallbackID))
|
|
tunnel.PoolID = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.PoolID, defaults.PoolID))
|
|
tunnel.ServiceID = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.ServiceID, "svc-"+tunnel.TunnelID))
|
|
tunnel.LocalServiceID = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.LocalServiceID, "svc-local-"+tunnel.TunnelID))
|
|
tunnel.RemoteServiceID = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.RemoteServiceID, "svc-remote-"+tunnel.TunnelID))
|
|
tunnel.ServiceKind = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.ServiceKind, defaults.ServiceKind))
|
|
tunnel.ServiceClass = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.ServiceClass, defaults.ServiceClass))
|
|
tunnel.ServiceRole = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.ServiceRole, defaults.ServiceRole))
|
|
tunnel.DataPlane = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.DataPlane, defaults.DataPlane))
|
|
tunnel.TransportOwner = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.TransportOwner, defaults.TransportOwner))
|
|
tunnel.RouteVisibility = strings.TrimSpace(firstNonEmptyTunnelString(tunnel.RouteVisibility, defaults.RouteVisibility))
|
|
tunnel.TrafficClasses = normalizeTunnelTrafficClasses(tunnel.TrafficClasses, defaults.TrafficClasses)
|
|
if tunnel.StreamShards <= 0 {
|
|
tunnel.StreamShards = defaults.StreamShards
|
|
}
|
|
return tunnel
|
|
}
|
|
|
|
func (t FabricServiceTunnel) Snapshot() map[string]any {
|
|
t = NormalizeServiceTunnelWithDefaults(t, t.TunnelID, FabricServiceTunnelDefaults{
|
|
PoolID: t.PoolID,
|
|
ServiceKind: t.ServiceKind,
|
|
ServiceClass: t.ServiceClass,
|
|
ServiceRole: t.ServiceRole,
|
|
DataPlane: t.DataPlane,
|
|
TransportOwner: t.TransportOwner,
|
|
RouteVisibility: t.RouteVisibility,
|
|
TrafficClasses: t.TrafficClasses,
|
|
StreamShards: t.StreamShards,
|
|
})
|
|
return map[string]any{
|
|
"schema_version": FabricServiceTunnelSchemaVersion,
|
|
"tunnel_id": t.TunnelID,
|
|
"pool_id": t.PoolID,
|
|
"service_id": t.ServiceID,
|
|
"local_service_id": t.LocalServiceID,
|
|
"remote_service_id": t.RemoteServiceID,
|
|
"service_kind": t.ServiceKind,
|
|
"service_class": t.ServiceClass,
|
|
"service_role": t.ServiceRole,
|
|
"route_lease_id": t.RouteLeaseID,
|
|
"route_generation": t.RouteGeneration,
|
|
"data_plane": t.DataPlane,
|
|
"transport_owner": t.TransportOwner,
|
|
"route_visibility": t.RouteVisibility,
|
|
"traffic_classes": append([]string(nil), t.TrafficClasses...),
|
|
"stream_shards": t.StreamShards,
|
|
"selected_node_known": false,
|
|
}
|
|
}
|
|
|
|
func DefaultVPNServiceTunnelDefaults() FabricServiceTunnelDefaults {
|
|
return FabricServiceTunnelDefaults{
|
|
PoolID: DefaultFabricTunnelPoolID,
|
|
ServiceKind: DefaultFabricTunnelServiceKind,
|
|
ServiceClass: DefaultFabricTunnelClass,
|
|
ServiceRole: DefaultFabricTunnelRole,
|
|
DataPlane: DefaultFabricTunnelDataPlane,
|
|
TransportOwner: DefaultFabricTransportOwner,
|
|
RouteVisibility: DefaultFabricRouteVisibility,
|
|
TrafficClasses: []string{
|
|
FabricServiceTrafficControl,
|
|
FabricServiceTrafficDNS,
|
|
FabricServiceTrafficInteractive,
|
|
FabricServiceTrafficReliable,
|
|
FabricServiceTrafficBulk,
|
|
FabricServiceTrafficDroppable,
|
|
},
|
|
StreamShards: DefaultFabricServiceStreamShards,
|
|
}
|
|
}
|
|
|
|
func normalizeServiceTunnelDefaults(defaults FabricServiceTunnelDefaults) FabricServiceTunnelDefaults {
|
|
fallback := DefaultVPNServiceTunnelDefaults()
|
|
defaults.PoolID = firstNonEmptyTunnelString(defaults.PoolID, fallback.PoolID)
|
|
defaults.ServiceKind = firstNonEmptyTunnelString(defaults.ServiceKind, fallback.ServiceKind)
|
|
defaults.ServiceClass = firstNonEmptyTunnelString(defaults.ServiceClass, fallback.ServiceClass)
|
|
defaults.ServiceRole = firstNonEmptyTunnelString(defaults.ServiceRole, fallback.ServiceRole)
|
|
defaults.DataPlane = firstNonEmptyTunnelString(defaults.DataPlane, fallback.DataPlane)
|
|
defaults.TransportOwner = firstNonEmptyTunnelString(defaults.TransportOwner, fallback.TransportOwner)
|
|
defaults.RouteVisibility = firstNonEmptyTunnelString(defaults.RouteVisibility, fallback.RouteVisibility)
|
|
defaults.TrafficClasses = normalizeTunnelTrafficClasses(defaults.TrafficClasses, fallback.TrafficClasses)
|
|
if defaults.StreamShards <= 0 {
|
|
defaults.StreamShards = fallback.StreamShards
|
|
}
|
|
return defaults
|
|
}
|
|
|
|
func normalizeTunnelTrafficClasses(values []string, fallback []string) []string {
|
|
if len(values) == 0 {
|
|
return append([]string(nil), fallback...)
|
|
}
|
|
out := make([]string, 0, len(values))
|
|
seen := map[string]struct{}{}
|
|
for _, value := range values {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[value]; ok {
|
|
continue
|
|
}
|
|
seen[value] = struct{}{}
|
|
out = append(out, value)
|
|
}
|
|
if len(out) == 0 {
|
|
return append([]string(nil), fallback...)
|
|
}
|
|
return out
|
|
}
|
|
|
|
func firstNonEmptyTunnelString(values ...string) string {
|
|
for _, value := range values {
|
|
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
|
return trimmed
|
|
}
|
|
}
|
|
return ""
|
|
}
|