diff --git a/app/api_topology_test.go b/app/api_topology_test.go index 04a6173468..7b4f58f23f 100644 --- a/app/api_topology_test.go +++ b/app/api_topology_test.go @@ -167,7 +167,7 @@ func TestAPITopologyWebsocket(t *testing.T) { if err := decoder.Decode(&d); err != nil { t.Fatalf("JSON parse error: %s", err) } - equals(t, 7, len(d.Add)) + equals(t, 8, len(d.Add)) equals(t, 0, len(d.Update)) equals(t, 0, len(d.Remove)) } diff --git a/integration/config.sh b/integration/config.sh index 53710077ff..5e6b693647 100644 --- a/integration/config.sh +++ b/integration/config.sh @@ -67,7 +67,6 @@ has_connection() { local timeout="${5:-60}" local from_id=$(node_id "${view}" "${host}" "${from}") local to_id=$(node_id "${view}" "${host}" "${to}") - for i in $(seq $timeout); do local nodes="$(curl -s http://$host:4040/api/topology/${view}?system=show)" local edge=$(echo "$nodes" | jq -r ".nodes[\"$from_id\"].adjacency | contains([\"$to_id\"])" 2>/dev/null) diff --git a/render/expected/expected.go b/render/expected/expected.go index 70a9dcccf7..ca20539250 100644 --- a/render/expected/expected.go +++ b/render/expected/expected.go @@ -45,10 +45,11 @@ var ( }, } } - theInternetNode = func(adjacent string) render.RenderableNode { + theIncomingInternetNode = func(adjacent string) render.RenderableNode { return render.RenderableNode{ - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, + ID: render.IncomingInternetID, + LabelMajor: render.InboundMajor, + LabelMinor: render.RequestsMinor, Pseudo: true, Shape: cloud, Node: report.MakeNode().WithAdjacent(adjacent), @@ -58,6 +59,15 @@ var ( }, } } + theOutgoingInternetNode = render.RenderableNode{ + ID: render.OutgoingInternetID, + LabelMajor: render.OutboundMajor, + LabelMinor: render.RequestsMinor, + Pseudo: true, + Shape: cloud, + Node: report.MakeNode(), + EdgeMetadata: report.EdgeMetadata{}, + } ClientProcess1ID = render.MakeProcessID(fixture.ClientHostID, fixture.Client1PID) ClientProcess2ID = render.MakeProcessID(fixture.ClientHostID, fixture.Client2PID) ServerProcessID = render.MakeProcessID(fixture.ServerHostID, fixture.ServerPID) @@ -110,12 +120,13 @@ var ( Rank: fixture.NonContainerName, Pseudo: false, Shape: square, - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - unknownPseudoNode1ID: unknownPseudoNode1(ServerProcessID), - unknownPseudoNode2ID: unknownPseudoNode2(ServerProcessID), - render.TheInternetID: theInternetNode(ServerProcessID), + unknownPseudoNode1ID: unknownPseudoNode1(ServerProcessID), + unknownPseudoNode2ID: unknownPseudoNode2(ServerProcessID), + render.IncomingInternetID: theIncomingInternetNode(ServerProcessID), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ServerProcessRenderedID = render.MakeProcessID(fixture.ServerHostID, fixture.ServerPID) @@ -169,12 +180,13 @@ var ( Children: report.MakeNodeSet( fixture.Report.Process.Nodes[fixture.NonContainerProcessNodeID], ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - unknownPseudoNode1ID: unknownPseudoNode1(fixture.ServerName), - unknownPseudoNode2ID: unknownPseudoNode2(fixture.ServerName), - render.TheInternetID: theInternetNode(fixture.ServerName), + unknownPseudoNode1ID: unknownPseudoNode1(fixture.ServerName), + unknownPseudoNode2ID: unknownPseudoNode2(fixture.ServerName), + render.IncomingInternetID: theIncomingInternetNode(fixture.ServerName), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ServerContainerRenderedID = render.MakeContainerID(fixture.ServerContainerID) @@ -227,10 +239,11 @@ var ( Children: report.MakeNodeSet( fixture.Report.Process.Nodes[fixture.NonContainerProcessNodeID], ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: theInternetNode(ServerContainerRenderedID), + render.IncomingInternetID: theIncomingInternetNode(ServerContainerRenderedID), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ClientContainerImageRenderedName = render.MakeContainerImageID(fixture.ClientContainerImageName) @@ -285,10 +298,11 @@ var ( Children: report.MakeNodeSet( fixture.Report.Process.Nodes[fixture.NonContainerProcessNodeID], ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: theInternetNode(ServerContainerImageRenderedName), + render.IncomingInternetID: theIncomingInternetNode(ServerContainerImageRenderedName), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ServerHostRenderedID = render.MakeHostID(fixture.ServerHostID) @@ -352,9 +366,10 @@ var ( Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: { - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, + render.IncomingInternetID: { + ID: render.IncomingInternetID, + LabelMajor: render.InboundMajor, + LabelMinor: render.RequestsMinor, Pseudo: true, Shape: cloud, Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), @@ -416,20 +431,11 @@ var ( Children: report.MakeNodeSet( fixture.Report.Process.Nodes[fixture.NonContainerProcessNodeID], ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: { - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, - Pseudo: true, - Shape: cloud, - Node: report.MakeNode().WithAdjacent(ServerPodRenderedID), - EdgeMetadata: report.EdgeMetadata{ - EgressPacketCount: newu64(60), - EgressByteCount: newu64(600), - }, - }, + render.IncomingInternetID: theIncomingInternetNode(ServerPodRenderedID), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ServiceRenderedID = render.MakeServiceID("ping/pongservice") @@ -473,20 +479,11 @@ var ( Children: report.MakeNodeSet( fixture.Report.Process.Nodes[fixture.NonContainerProcessNodeID], ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: { - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, - Pseudo: true, - Shape: cloud, - Node: report.MakeNode().WithAdjacent(ServiceRenderedID), - EdgeMetadata: report.EdgeMetadata{ - EgressPacketCount: newu64(60), - EgressByteCount: newu64(600), - }, - }, + render.IncomingInternetID: theIncomingInternetNode(ServiceRenderedID), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() ) diff --git a/render/mapping.go b/render/mapping.go index 6bdd0745a9..5f0f24381e 100644 --- a/render/mapping.go +++ b/render/mapping.go @@ -20,8 +20,12 @@ const ( UncontainedID = "uncontained" UncontainedMajor = "Uncontained" - TheInternetID = "theinternet" - TheInternetMajor = "The Internet" + TheInternetID = "theinternet" + IncomingInternetID = "in-" + TheInternetID + OutgoingInternetID = "out-" + TheInternetID + InboundMajor = "Inbound" + OutboundMajor = "Outbound" + RequestsMinor = "Requests" ContainersKey = "containers" ipsKey = "ips" @@ -40,9 +44,19 @@ const ( type MapFunc func(RenderableNode, report.Networks) RenderableNodes func theInternetNode(m RenderableNode) RenderableNode { - r := newDerivedPseudoNode(TheInternetID, TheInternetMajor, m) - r.Shape = Cloud - return r + node := newDerivedPseudoNode("", "", m) + node.Shape = Cloud + // emit one internet node for incoming, one for outgoing + if len(m.Adjacency) > 0 { + node.ID = IncomingInternetID + node.LabelMajor = InboundMajor + node.LabelMinor = RequestsMinor + } else { + node.ID = OutgoingInternetID + node.LabelMajor = OutboundMajor + node.LabelMinor = RequestsMinor + } + return node } // MapEndpointIdentity maps an endpoint topology node to a single endpoint @@ -258,7 +272,7 @@ func MapAddressIdentity(m RenderableNode, local report.Networks) RenderableNodes if !hasHostID { // If the addr is not in a network local to this report, we emit an // internet node - if !local.Contains(net.ParseIP(addr)) { + if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { return RenderableNodes{TheInternetID: theInternetNode(m)} } @@ -381,8 +395,8 @@ func MapIP2Container(n RenderableNode, _ report.Networks) RenderableNodes { return RenderableNodes{} } - // Propogate the internet pseudo node. - if n.ID == TheInternetID { + // Propogate the internet pseudo node + if strings.HasSuffix(n.ID, TheInternetID) { return RenderableNodes{n.ID: n} } @@ -440,7 +454,7 @@ func MapEndpoint2Process(n RenderableNode, _ report.Networks) RenderableNodes { // must be merged with a container graph to get that info. func MapProcess2Container(n RenderableNode, _ report.Networks) RenderableNodes { // Propogate the internet pseudo node - if n.ID == TheInternetID { + if strings.HasSuffix(n.ID, TheInternetID) { return RenderableNodes{n.ID: n} } diff --git a/render/short_lived_connections_test.go b/render/short_lived_connections_test.go index e3efd476b9..9adf6ce4ef 100644 --- a/render/short_lived_connections_test.go +++ b/render/short_lived_connections_test.go @@ -70,9 +70,10 @@ var ( } want = (render.RenderableNodes{ - render.TheInternetID: { - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, + render.IncomingInternetID: { + ID: render.IncomingInternetID, + LabelMajor: render.InboundMajor, + LabelMinor: render.RequestsMinor, Pseudo: true, Shape: "cloud", Node: report.MakeNode().WithAdjacent(render.MakeContainerID(containerID)),