diff --git a/model_utils.go b/model_utils.go index 0f582c9..be68cec 100644 --- a/model_utils.go +++ b/model_utils.go @@ -77,22 +77,26 @@ func parceConnectionsToGraphicalModel() { switch { case segmentType == clientNT: - interfID := fmt.Sprintf("int-c--%s--%s", connectionID, node.Data.ID) - nodeMap[interfID] = makeInterface(interfID, node.Data.ID, getInterfaceLabelFromMetrics(segment, clientInterface)) + interfName := getInterfaceLabelFromMetrics(segment, clientInterface) + interfID := fmt.Sprintf("int-c--%s--%s--%s", connectionID, node.Data.ID, interfName) + nodeMap[interfID] = makeInterface(interfID, node.Data.ID, interfName) previousInterfaceID = interfID case segmentType == endpointNT: - interfID := fmt.Sprintf("int-s--%s--%s", connectionID, node.Data.ID) - nodeMap[interfID] = makeInterface(interfID, node.Data.ID, getInterfaceLabelFromMetrics(segment, serverInterface)) + interfName := getInterfaceLabelFromMetrics(segment, serverInterface) + interfID := fmt.Sprintf("int-s--%s--%s--%s", connectionID, node.Data.ID, interfName) + nodeMap[interfID] = makeInterface(interfID, node.Data.ID, interfName) if previousInterfaceID != "" { edges = addEdge(edges, previousInterfaceID, interfID, interfaceConnection, healthy) } previousInterfaceID = interfID case segmentType == forwarderNT: - interfEID := fmt.Sprintf("int-s--%s--%s", connectionID, node.Data.ID) - nodeMap[interfEID] = makeInterface(interfEID, node.Data.ID, getInterfaceLabelFromMetrics(segment, serverInterface)) + interfEName := getInterfaceLabelFromMetrics(segment, serverInterface) + interfEID := fmt.Sprintf("int-s--%s--%s--%s", connectionID, node.Data.ID, interfEName) + nodeMap[interfEID] = makeInterface(interfEID, node.Data.ID, interfEName) edges = addEdge(edges, previousInterfaceID, interfEID, interfaceConnection, healthy) - interfCID := fmt.Sprintf("int-c--%s--%s", connectionID, node.Data.ID) - nodeMap[interfCID] = makeInterface(interfCID, node.Data.ID, getInterfaceLabelFromMetrics(segment, clientInterface)) + interfCName := getInterfaceLabelFromMetrics(segment, clientInterface) + interfCID := fmt.Sprintf("int-c--%s--%s--%s", connectionID, node.Data.ID, interfCName) + nodeMap[interfCID] = makeInterface(interfCID, node.Data.ID, interfCName) edges = addEdge(edges, interfEID, interfCID, interfaceCrossConnection, healthy) previousInterfaceID = interfCID // TODO Aggregate statistics for the Overview page diff --git a/model_utils_test.go b/model_utils_test.go index 7233796..1a91c2c 100644 --- a/model_utils_test.go +++ b/model_utils_test.go @@ -31,11 +31,17 @@ func Test_Interface_Order(t *testing.T) { goleak.VerifyNone(t) }) - nsmgrAddr := "10.244.1.4:5001" - nscName := "alpine-0a9d9aa7" - fwd1Name := "forwarder-vpp-t2jgb" - fwd2Name := "forwarder-vpp-9dxwt" - nseName := "nse-kernel-zz6m5" + const nsmgrAddr = "10.244.1.4:5001" + const nscName = "alpine-0a9d9aa7" + const cifNscName = "KERNEL/nsm-1" + const fwd1Name = "forwarder-vpp-t2jgb" + const cifFwd1Name = "WIREGUARD TUNNEL/wg0" + const sifFwd1Name = "VIRTIO/tun0" + const fwd2Name = "forwarder-vpp-9dxwt" + const cifFwd2Name = "VIRTIO/tun0" + const sifFwd2Name = "WIREGUARD TUNNEL/wg0" + const nseName = "nse-kernel-zz6m5" + const sifNseName = "KERNEL/kernel2ip2-ff6c" connection := &networkservice.Connection{ NetworkService: "kernel2ip2kernel", @@ -45,7 +51,7 @@ func Test_Interface_Order(t *testing.T) { Name: nscName, Id: "alpine-0a9d9aa7-0", Metrics: map[string]string{ - "client_interface": "KERNEL/nsm-1", + "client_interface": cifNscName, }, }, { @@ -56,8 +62,8 @@ func Test_Interface_Order(t *testing.T) { Name: fwd1Name, Id: "23456", Metrics: map[string]string{ - "client_interface": "WIREGUARD TUNNEL/wg0", - "server_interface": "VIRTIO/tun0", + "client_interface": cifFwd1Name, + "server_interface": sifFwd1Name, }, }, { @@ -68,15 +74,15 @@ func Test_Interface_Order(t *testing.T) { Name: fwd2Name, Id: "45678", Metrics: map[string]string{ - "client_interface": "VIRTIO/tun0", - "server_interface": "WIREGUARD TUNNEL/wg0", + "client_interface": cifFwd2Name, + "server_interface": sifFwd2Name, }, }, { Name: nseName, Id: "56789", Metrics: map[string]string{ - "server_interface": "KERNEL/kernel2ip2-ff6c", + "server_interface": sifNseName, }, }, }, @@ -92,28 +98,28 @@ func Test_Interface_Order(t *testing.T) { require.Equal(t, 5, len(storageData.Edges)) // Connection 1 (client-forwarder1) - source1 := fmt.Sprintf("int-c--%s--%s", connectionID, nscName) - target1 := fmt.Sprintf("int-s--%s--%s", connectionID, fwd1Name) + source1 := fmt.Sprintf("int-c--%s--%s--%s", connectionID, nscName, cifNscName) + target1 := fmt.Sprintf("int-s--%s--%s--%s", connectionID, fwd1Name, sifFwd1Name) require.Equal(t, source1, storageData.Edges[0].Data.Source) require.Equal(t, target1, storageData.Edges[0].Data.Target) // Connection 2 (forwarder1 internal interface cross connection) - source2 := fmt.Sprintf("int-s--%s--%s", connectionID, fwd1Name) - target2 := fmt.Sprintf("int-c--%s--%s", connectionID, fwd1Name) + source2 := fmt.Sprintf("int-s--%s--%s--%s", connectionID, fwd1Name, sifFwd1Name) + target2 := fmt.Sprintf("int-c--%s--%s--%s", connectionID, fwd1Name, cifFwd1Name) require.Equal(t, source2, storageData.Edges[1].Data.Source) require.Equal(t, target2, storageData.Edges[1].Data.Target) // Connection 3 (forwarder1-forwarder2) - source3 := fmt.Sprintf("int-c--%s--%s", connectionID, fwd1Name) - target3 := fmt.Sprintf("int-s--%s--%s", connectionID, fwd2Name) + source3 := fmt.Sprintf("int-c--%s--%s--%s", connectionID, fwd1Name, cifFwd1Name) + target3 := fmt.Sprintf("int-s--%s--%s--%s", connectionID, fwd2Name, sifFwd2Name) require.Equal(t, source3, storageData.Edges[2].Data.Source) require.Equal(t, target3, storageData.Edges[2].Data.Target) // Connection 4 (forwarder2 internal interface cross connection) - source4 := fmt.Sprintf("int-s--%s--%s", connectionID, fwd2Name) - target4 := fmt.Sprintf("int-c--%s--%s", connectionID, fwd2Name) + source4 := fmt.Sprintf("int-s--%s--%s--%s", connectionID, fwd2Name, sifFwd2Name) + target4 := fmt.Sprintf("int-c--%s--%s--%s", connectionID, fwd2Name, cifFwd2Name) require.Equal(t, source4, storageData.Edges[3].Data.Source) require.Equal(t, target4, storageData.Edges[3].Data.Target) // Connection 5 (forwarder2-endpoint) - source5 := fmt.Sprintf("int-c--%s--%s", connectionID, fwd2Name) - target5 := fmt.Sprintf("int-s--%s--%s", connectionID, nseName) + source5 := fmt.Sprintf("int-c--%s--%s--%s", connectionID, fwd2Name, cifFwd2Name) + target5 := fmt.Sprintf("int-s--%s--%s--%s", connectionID, nseName, sifNseName) require.Equal(t, source5, storageData.Edges[4].Data.Source) require.Equal(t, target5, storageData.Edges[4].Data.Target) @@ -121,8 +127,140 @@ func Test_Interface_Order(t *testing.T) { connections.Delete(connectionID) managerConnections.Delete(nsmgrAddr) nsmgrs.Delete(nsmgrAddr) +} + +func Test_NSE_To_NSE_Connection(t *testing.T) { + t.Cleanup(func() { + goleak.VerifyNone(t) + }) + + const nsmgrAddr = "10.244.1.5:5001" + + connection := &networkservice.Connection{ + NetworkService: "ns1", + Path: &networkservice.Path{ + PathSegments: []*networkservice.PathSegment{ + { + Name: "nse-vl3-vpp-9ln7f", + Id: "12345", + Metrics: map[string]string{ + "server_interface": "MEMIF/memif2670642822/2", + }, + }, + { + Name: "nsmgr-j6x6m", + Id: "23456", + }, + { + Name: "forwarder-vpp-zpg6b", + Id: "34567", + Metrics: map[string]string{ + "client_interface": "WIREGUARD TUNNEL/wg1", + "server_interface": "MEMIF/memif2670642822/0", + }, + }, + { + Name: "nsmgr-rp4rr", + Id: "45678", + }, + { + Name: "forwarder-vpp-s7sw5", + Id: "56789", + Metrics: map[string]string{ + "client_interface": "MEMIF/memif2670642822/0", + "server_interface": "WIREGUARD TUNNEL/wg1", + }, + }, + { + Name: "nse-vl3-vpp-gcf6j", + Id: "67890", + Metrics: map[string]string{ + "server_interface": "MEMIF/memif2670642822/1", + }, + }, + }, + }, + } + connectionID := generateConnectionID(connection) + + connections.Store(connectionID, connection) + addManagerConnection(nsmgrAddr, connectionID) parceConnectionsToGraphicalModel() - require.Equal(t, 0, len(storageData.Nodes)) - require.Equal(t, 0, len(storageData.Edges)) + // 14: 1 cluster + 1 ns + 2 nse + 2 mgr + 2 fwd + 6 if + require.Equal(t, 14, len(storageData.Nodes)) + require.Equal(t, 5, len(storageData.Edges)) + + // Check that all connections have sources and targets + for _, edge := range storageData.Edges { + require.NotEmpty(t, edge.Data.Source) + require.NotEmpty(t, edge.Data.Target) + } + + // Cleanup + connections.Delete(connectionID) + managerConnections.Delete(nsmgrAddr) + nsmgrs.Delete(nsmgrAddr) +} + +func Test_Looped_NSE_To_NSE_Connection(t *testing.T) { + t.Cleanup(func() { + goleak.VerifyNone(t) + }) + + const nsmgrAddr = "10.244.1.6:5001" + + connection := &networkservice.Connection{ + NetworkService: "ns2", + Path: &networkservice.Path{ + PathSegments: []*networkservice.PathSegment{ + { + Name: "nse-vl3-vpp-gcf6j", + Id: "12345", + Metrics: map[string]string{ + "server_interface": "MEMIF/memif2670642822/2", + }, + }, + { + Name: "nsmgr-rp4rr", + Id: "23456", + }, + { + Name: "forwarder-vpp-s7sw5", + Id: "34567", + Metrics: map[string]string{ + "client_interface": "MEMIF/memif3519870697/0", + "server_interface": "VIRTIO/tun0", + }, + }, + { + Name: "nse-vl3-vpp-gcf6j", + Id: "12345", + Metrics: map[string]string{ + "server_interface": "MEMIF/memif2670642822/1", + }, + }, + }, + }, + } + connectionID := generateConnectionID(connection) + + connections.Store(connectionID, connection) + addManagerConnection(nsmgrAddr, connectionID) + parceConnectionsToGraphicalModel() + + // 9: 1 cluster + 1 ns + 1 nse + 1 mgr + 1 fwd + 4 if + require.Equal(t, 9, len(storageData.Nodes)) + require.Equal(t, 3, len(storageData.Edges)) + + // Check that all connections have sources and targets + for _, edge := range storageData.Edges { + require.NotEmpty(t, edge.Data.Source) + require.NotEmpty(t, edge.Data.Target) + } + + // Cleanup + connections.Delete(connectionID) + managerConnections.Delete(nsmgrAddr) + nsmgrs.Delete(nsmgrAddr) }