feat(go): small api changes;

This commit is contained in:
Vishal Dalwadi
2026-10-04 14:10:37 +05:30
parent a111a859b1
commit 74d91c1fef
4 changed files with 78 additions and 69 deletions
+20 -15
View File
@@ -267,8 +267,8 @@ func (b *networkStatusBuilder) nodeNetworkStatus(node *models.Node) models.Netwo
}
peerStatus := peerNetworkStatus(peerID, metric, b.names)
if relayID := peerRelayNodeID(node, b.nodesByID[peerID]); relayID != "" {
peerStatus.ConnectionType = models.PeerConnectionRelayed
peerStatus.RelayNodeID = relayID
peerStatus.IsRelayed = true
peerStatus.Via = b.nodeRef(relayID)
}
nodeStatus.Peers = append(nodeStatus.Peers, peerStatus)
}
@@ -424,18 +424,25 @@ func relayedEgressPath(routers []egressRouter, preferred, relayID string, toRela
}
func (b *networkStatusBuilder) applyEgressPath(egressStatus *models.NetworkEgressStatus, path egressPath) {
egressStatus.RoutingNodeID = path.routerID
egressStatus.RoutingNodeName = b.names[path.routerID]
egressStatus.RoutingNode = b.nodeRef(path.routerID)
egressStatus.RoutingNodesConnected = path.connectedCnt
egressStatus.Connected = path.connected
egressStatus.LatencyMs = path.latencyMs
egressStatus.PercentUp = path.percentUp
if path.relayID != "" {
egressStatus.ConnectionType = models.PeerConnectionRelayed
egressStatus.RelayNodeID = path.relayID
egressStatus.IsRelayed = true
egressStatus.Via = b.nodeRef(path.relayID)
}
}
// nodeRef returns the ID and host name of a node, or nil for an empty ID.
func (b *networkStatusBuilder) nodeRef(nodeID string) *models.NetworkNodeRef {
if nodeID == "" {
return nil
}
return &models.NetworkNodeRef{ID: nodeID, Name: b.names[nodeID]}
}
// connectivity returns a node's reported links, cached per request.
func (b *networkStatusBuilder) connectivity(nodeID string) map[string]models.Metric {
if c, ok := b.relayConnectivity[nodeID]; ok {
@@ -567,7 +574,6 @@ func (b *networkStatusBuilder) newEgressStatus(e *schema.Egress, routers []egres
Domains: ConfiguredDomainsForEgress(*e),
IsInternet: isInternet,
RoutingNodesTotal: len(routers),
ConnectionType: models.PeerConnectionDirect,
}, true
}
@@ -608,14 +614,13 @@ func peerNetworkStatus(peerID string, metric models.Metric, names map[string]str
name = metric.NodeName
}
return models.NetworkPeerStatus{
PeerID: peerID,
Name: name,
Connected: metric.Connected,
LatencyMs: metric.Latency,
ConnectionType: models.PeerConnectionDirect,
PercentUp: metric.PercentUp,
BytesSent: metric.TotalSent,
BytesReceived: metric.TotalReceived,
PeerID: peerID,
Name: name,
Connected: metric.Connected,
LatencyMs: metric.Latency,
PercentUp: metric.PercentUp,
BytesSent: metric.TotalSent,
BytesReceived: metric.TotalReceived,
}
}
+15 -15
View File
@@ -193,10 +193,10 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
if e.EgressID != "lan" || e.Name != "office" || len(e.Ranges) != 1 || e.Ranges[0] != "10.0.0.0/24" {
t.Fatalf("egress identity = %+v", e)
}
if e.RoutingNodeID != backup.ID.String() || e.RoutingNodesTotal != 2 || e.RoutingNodesConnected != 1 {
t.Fatalf("routing = %s %d/%d, want backup 1/2", e.RoutingNodeID, e.RoutingNodesConnected, e.RoutingNodesTotal)
if e.RoutingNode.ID != backup.ID.String() || e.RoutingNodesTotal != 2 || e.RoutingNodesConnected != 1 {
t.Fatalf("routing = %s %d/%d, want backup 1/2", e.RoutingNode.ID, e.RoutingNodesConnected, e.RoutingNodesTotal)
}
if !e.Connected || e.LatencyMs != 12 || e.PercentUp != 99.5 || e.ConnectionType != models.PeerConnectionDirect {
if !e.Connected || e.LatencyMs != 12 || e.PercentUp != 99.5 || e.IsRelayed {
t.Fatalf("link = %+v", e)
}
})
@@ -213,7 +213,7 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
relayed.IsRelayed, relayed.RelayedBy = true, gw.ID.String()
b := newTestStatusBuilder(eli, NetworkStatusOptions{IncludeEgress: true}, &relayed, primary, backup, gw)
e := b.nodeNetworkStatus(&relayed).Egresses[0]
if e.ConnectionType != models.PeerConnectionRelayed || e.RelayNodeID != gw.ID.String() {
if !e.IsRelayed || (e.Via == nil || e.Via.ID != gw.ID.String()) {
t.Fatalf("link = %+v, want relayed via gateway", e)
}
})
@@ -242,10 +242,10 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
b := newTestStatusBuilder(eli, NetworkStatusOptions{IncludeEgress: true}, &exitClient, primary, backup, exit, gw)
e := b.nodeNetworkStatus(&exitClient).Egresses[0]
if e.ConnectionType != models.PeerConnectionRelayed || e.RelayNodeID != exit.ID.String() {
if !e.IsRelayed || (e.Via == nil || e.Via.ID != exit.ID.String()) {
t.Fatalf("without bypass: link = %+v, want relayed via exit", e)
}
if e.RoutingNodeID != primary.ID.String() || e.RoutingNodesConnected != 2 || !e.Connected ||
if e.RoutingNode.ID != primary.ID.String() || e.RoutingNodesConnected != 2 || !e.Connected ||
e.LatencyMs != 34 || e.PercentUp != 95 {
t.Fatalf("without bypass: path = %+v, want primary via exit at 34ms", e)
}
@@ -255,14 +255,14 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
b = newTestStatusBuilder(bypassing, NetworkStatusOptions{IncludeEgress: true}, &exitClient, primary, backup, exit, gw)
got := b.nodeNetworkStatus(&exitClient)
e = got.Egresses[0]
if e.ConnectionType != models.PeerConnectionDirect || e.RelayNodeID != "" {
if e.IsRelayed || e.Via != nil {
t.Fatalf("with bypass: link = %+v, want direct", e)
}
if e.RoutingNodeID != backup.ID.String() || !e.Connected || e.LatencyMs != 12 {
if e.RoutingNode.ID != backup.ID.String() || !e.Connected || e.LatencyMs != 12 {
t.Fatalf("with bypass: path = %+v, want backup direct at 12ms", e)
}
// The exit itself is still reached directly for internet traffic.
if inet := got.Egresses[1]; !inet.IsInternet || inet.ConnectionType != models.PeerConnectionDirect || inet.LatencyMs != 30 {
if inet := got.Egresses[1]; !inet.IsInternet || inet.IsRelayed || inet.LatencyMs != 30 {
t.Fatalf("with bypass: internet egress = %+v, want direct to exit at 30ms", inet)
}
})
@@ -280,7 +280,7 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
})
b := newTestStatusBuilder(eli, NetworkStatusOptions{IncludeEgress: true}, &autoRelayed, primary, backup, gw)
e := b.nodeNetworkStatus(&autoRelayed).Egresses[0]
if e.RoutingNodeID != backup.ID.String() || e.RoutingNodesConnected != 1 || e.RelayNodeID != gw.ID.String() ||
if e.RoutingNode.ID != backup.ID.String() || e.RoutingNodesConnected != 1 || (e.Via == nil || e.Via.ID != gw.ID.String()) ||
!e.Connected || e.LatencyMs != 14 || e.PercentUp != 90 {
t.Fatalf("path = %+v, want backup via auto-relay at 14ms", e)
}
@@ -304,7 +304,7 @@ func TestNodeNetworkStatusEgresses(t *testing.T) {
if e.EgressID != "inet" || !e.IsInternet || len(e.Ranges) != 1 || e.Ranges[0] != IPv4Network {
t.Fatalf("internet egress identity = %+v", e)
}
if e.RoutingNodeID != exit.ID.String() || !e.Connected || e.LatencyMs != 30 || e.ConnectionType != models.PeerConnectionDirect {
if e.RoutingNode.ID != exit.ID.String() || !e.Connected || e.LatencyMs != 30 || e.IsRelayed {
t.Fatalf("internet egress link = %+v, want direct to exit at 30ms", e)
}
@@ -373,10 +373,10 @@ func TestExtClientNetworkStatusEgresses(t *testing.T) {
for _, e := range got.Egresses {
byID[e.EgressID] = e
}
if e := byID["via-gw"]; e.ConnectionType != models.PeerConnectionDirect || e.LatencyMs != 20 || e.RoutingNodeID != gw.ID.String() {
if e := byID["via-gw"]; e.IsRelayed || e.LatencyMs != 20 || e.RoutingNode.ID != gw.ID.String() {
t.Fatalf("via-gw = %+v, want direct at 20ms", e)
}
if e := byID["via-router"]; e.ConnectionType != models.PeerConnectionRelayed || e.RelayNodeID != gw.ID.String() ||
if e := byID["via-router"]; !e.IsRelayed || (e.Via == nil || e.Via.ID != gw.ID.String()) ||
e.LatencyMs != 23 || e.PercentUp != 90 {
t.Fatalf("via-router = %+v, want relayed via gateway at 23ms", e)
}
@@ -393,8 +393,8 @@ func TestExtClientNetworkStatusEgresses(t *testing.T) {
if got.InternetGatewayNodeID != gw.ID.String() || got.TotalEgresses != 3 {
t.Fatalf("internet gateway = %s, egresses = %d; want %s, 3", got.InternetGatewayNodeID, got.TotalEgresses, gw.ID)
}
if e := got.Egresses[2]; e.EgressID != "inet-gw" || !e.IsInternet || e.RoutingNodeID != gw.ID.String() ||
e.ConnectionType != models.PeerConnectionDirect || e.LatencyMs != 20 {
if e := got.Egresses[2]; e.EgressID != "inet-gw" || !e.IsInternet || e.RoutingNode.ID != gw.ID.String() ||
e.IsRelayed || e.LatencyMs != 20 {
t.Fatalf("internet egress = %+v, want direct to gateway at 20ms", e)
}
+22 -22
View File
@@ -11,10 +11,11 @@ const (
NetworkNodeKindExtClient = NetworkNodeKind("extclient")
)
const (
PeerConnectionDirect = "direct"
PeerConnectionRelayed = "relayed"
)
// NetworkNodeRef identifies a node by ID and name.
type NetworkNodeRef struct {
ID string `json:"id"`
Name string `json:"name"`
}
// NetworkStatusDstType selects which destination details the network status includes.
type NetworkStatusDstType string
@@ -89,27 +90,26 @@ type NetworkEgressStatus struct {
// IsInternet marks the internet egress (exit node) the entry routes all traffic through.
IsInternet bool `json:"is_internet"`
RoutingNodeID string `json:"routing_node_id,omitempty"` // routing node in use: lowest metric among connected routers
RoutingNodeName string `json:"routing_node_name,omitempty"`
RoutingNodesTotal int `json:"routing_nodes_total"`
RoutingNodesConnected int `json:"routing_nodes_connected"`
RoutingNode *NetworkNodeRef `json:"routing_node,omitempty"` // in use: preferred exit, else lowest metric among connected routers
RoutingNodesTotal int `json:"routing_nodes_total"`
RoutingNodesConnected int `json:"routing_nodes_connected"`
Connected bool `json:"connected"`
LatencyMs int64 `json:"latency_ms"`
ConnectionType string `json:"connection_type"` // direct | relayed
RelayNodeID string `json:"relay_node_id,omitempty"` // set when relayed
PercentUp float64 `json:"percent_up"`
Connected bool `json:"connected"`
LatencyMs int64 `json:"latency_ms"`
IsRelayed bool `json:"is_relayed"`
Via *NetworkNodeRef `json:"via,omitempty"` // relay, set when relayed
PercentUp float64 `json:"percent_up"`
}
// NetworkPeerStatus is a node's link to one peer, as reported in its metrics.
type NetworkPeerStatus struct {
PeerID string `json:"peer_id"`
Name string `json:"name"`
Connected bool `json:"connected"`
LatencyMs int64 `json:"latency_ms"`
ConnectionType string `json:"connection_type"` // direct | relayed
RelayNodeID string `json:"relay_node_id,omitempty"` // set when relayed
PercentUp float64 `json:"percent_up"`
BytesSent int64 `json:"bytes_sent"`
BytesReceived int64 `json:"bytes_received"`
PeerID string `json:"peer_id"`
Name string `json:"name"`
Connected bool `json:"connected"`
LatencyMs int64 `json:"latency_ms"`
IsRelayed bool `json:"is_relayed"`
Via *NetworkNodeRef `json:"via,omitempty"` // relay, set when relayed
PercentUp float64 `json:"percent_up"`
BytesSent int64 `json:"bytes_sent"`
BytesReceived int64 `json:"bytes_received"`
}
+21 -17
View File
@@ -1619,9 +1619,6 @@ definitions:
properties:
connected:
type: boolean
connection_type:
description: direct | relayed
type: string
domains:
items:
type: string
@@ -1632,6 +1629,8 @@ definitions:
description: the internet egress (exit node) the entry routes all traffic
through
type: boolean
is_relayed:
type: boolean
latency_ms:
type: integer
name:
@@ -1644,18 +1643,24 @@ definitions:
items:
type: string
type: array
relay_node_id:
description: set when relayed
type: string
routing_node_id:
description: 'routing node in use: lowest metric among connected routers'
type: string
routing_node_name:
type: string
routing_node:
$ref: '#/definitions/models.NetworkNodeRef'
description: 'routing node in use: preferred exit, else lowest metric among
connected routers'
routing_nodes_connected:
type: integer
routing_nodes_total:
type: integer
via:
$ref: '#/definitions/models.NetworkNodeRef'
description: relay, set when relayed
type: object
models.NetworkNodeRef:
properties:
id:
type: string
name:
type: string
type: object
models.NetworkPeerStatus:
properties:
@@ -1665,9 +1670,8 @@ definitions:
type: integer
connected:
type: boolean
connection_type:
description: direct | relayed
type: string
is_relayed:
type: boolean
latency_ms:
type: integer
name:
@@ -1676,9 +1680,9 @@ definitions:
type: string
percent_up:
type: number
relay_node_id:
description: set when relayed
type: string
via:
$ref: '#/definitions/models.NetworkNodeRef'
description: relay, set when relayed
type: object
models.NetworkStatus:
properties: