diff --git a/app/api_topology_test.go b/app/api_topology_test.go index b81f75661f..f6f4f91dc5 100644 --- a/app/api_topology_test.go +++ b/app/api_topology_test.go @@ -167,7 +167,7 @@ func TestAPITopologyWebsocket(t *testing.T) { if err := json.Unmarshal(p, &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/300_internet_edge_test.sh b/integration/300_internet_edge_test.sh index 3e5b07a1b9..0181ff8ac8 100755 --- a/integration/300_internet_edge_test.sh +++ b/integration/300_internet_edge_test.sh @@ -25,8 +25,8 @@ do_connections& wait_for_containers $HOST1 60 nginx "The Internet" has_container $HOST1 nginx -has_container $HOST1 "The Internet" -has_connection $HOST1 "The Internet" nginx +has_container_id $HOST1 'in-theinternet' +has_connection $HOST1 'in-theinternet' $(container_id $1 nginx) kill %do_connections diff --git a/integration/310_container_to_container_edge_test.sh b/integration/310_container_to_container_edge_test.sh index ec19d8ca91..ff71212f76 100755 --- a/integration/310_container_to_container_edge_test.sh +++ b/integration/310_container_to_container_edge_test.sh @@ -16,6 +16,6 @@ wait_for_containers $HOST1 60 nginx client has_container $HOST1 nginx has_container $HOST1 client -has_connection $HOST1 client nginx +has_connection $HOST1 $(container_id $HOST1 client) $(container_id $HOST1 nginx) scope_end_suite diff --git a/integration/320_container_edge_cross_host_2_test.sh b/integration/320_container_edge_cross_host_2_test.sh index b13cd097c4..2ce5eae774 100755 --- a/integration/320_container_edge_cross_host_2_test.sh +++ b/integration/320_container_edge_cross_host_2_test.sh @@ -21,7 +21,7 @@ sleep 30 # need to allow the scopes to poll dns, resolve the other app ids, and check() { has_container $1 nginx has_container $1 client - has_connection $1 client nginx + has_connection $1 $(container_id $1 client) $(container_id $1 nginx) } check $HOST1 diff --git a/integration/config.sh b/integration/config.sh index 3c674a206d..05d637ea51 100644 --- a/integration/config.sh +++ b/integration/config.sh @@ -40,6 +40,13 @@ has_container() { assert "curl -s http://$host:4040/api/topology/containers?system=show | jq -r '[.nodes[] | select(.label_major == \"$name\")] | length'" $count } +has_container_id() { + local host=$1 + local id=$2 + local count=${3:-1} + assert "curl -s http://$host:4040/api/topology/containers?system=show | jq -r '[.nodes[] | select(.id == \"$id\")] | length'" $count +} + scope_end_suite() { end_suite for host in $HOSTS; do @@ -56,11 +63,9 @@ container_id() { # this checks we have an edge from container 1 to container 2 has_connection() { local host="$1" - local from="$2" - local to="$3" + local from_id="$2" + local to_id="$3" local timeout="${4:-60}" - local from_id=$(container_id "$host" "$from") - local to_id=$(container_id "$host" "$to") for i in $(seq $timeout); do local containers="$(curl -s http://$host:4040/api/topology/containers?system=show)" diff --git a/render/expected/expected.go b/render/expected/expected.go index 3616e60709..e74dc6940f 100644 --- a/render/expected/expected.go +++ b/render/expected/expected.go @@ -44,10 +44,11 @@ var ( ), } } - theInternetNode = func(adjacent string) render.RenderableNode { + theIncomingInternetNode = func(adjacent string) render.RenderableNode { return render.RenderableNode{ - ID: render.TheInternetID, + ID: render.IncomingInternetID, LabelMajor: render.TheInternetMajor, + LabelMinor: render.Incoming, Pseudo: true, Node: report.MakeNode().WithAdjacent(adjacent), EdgeMetadata: report.EdgeMetadata{ @@ -56,10 +57,20 @@ var ( }, Origins: report.MakeIDList( test.RandomClientNodeID, - test.GoogleEndpointNodeID, ), } } + theOutgoingInternetNode = render.RenderableNode{ + ID: render.OutgoingInternetID, + LabelMajor: render.TheInternetMajor, + LabelMinor: render.Outgoing, + Pseudo: true, + Node: report.MakeNode(), + EdgeMetadata: report.EdgeMetadata{}, + Origins: report.MakeIDList( + test.GoogleEndpointNodeID, + ), + } ClientProcess1ID = render.MakeProcessID(test.ClientHostID, test.Client1PID) ClientProcess2ID = render.MakeProcessID(test.ClientHostID, test.Client2PID) ServerProcessID = render.MakeProcessID(test.ServerHostID, test.ServerPID) @@ -128,12 +139,13 @@ var ( test.ServerHostNodeID, test.NonContainerNodeID, ), - 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() RenderedProcessNames = (render.RenderableNodes{ @@ -184,12 +196,13 @@ var ( test.ServerHostNodeID, test.NonContainerNodeID, ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - unknownPseudoNode1ID: unknownPseudoNode1("apache"), - unknownPseudoNode2ID: unknownPseudoNode2("apache"), - render.TheInternetID: theInternetNode("apache"), + unknownPseudoNode1ID: unknownPseudoNode1("apache"), + unknownPseudoNode2ID: unknownPseudoNode2("apache"), + render.IncomingInternetID: theIncomingInternetNode("apache"), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() RenderedContainers = (render.RenderableNodes{ @@ -244,10 +257,11 @@ var ( test.ServerHostNodeID, test.NonContainerNodeID, ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, }, - render.TheInternetID: theInternetNode(test.ServerContainerID), + render.IncomingInternetID: theIncomingInternetNode(test.ServerContainerID), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() RenderedContainerImages = (render.RenderableNodes{ @@ -301,72 +315,11 @@ var ( test.NonContainerProcessNodeID, test.ServerHostNodeID, ), - Node: report.MakeNode().WithAdjacent(render.TheInternetID), - EdgeMetadata: report.EdgeMetadata{}, - }, - render.TheInternetID: theInternetNode(test.ServerContainerImageName), - }).Prune() - - ServerHostRenderedID = render.MakeHostID(test.ServerHostID) - ClientHostRenderedID = render.MakeHostID(test.ClientHostID) - pseudoHostID1 = render.MakePseudoNodeID(test.UnknownClient1IP, test.ServerIP) - pseudoHostID2 = render.MakePseudoNodeID(test.UnknownClient3IP, test.ServerIP) - - RenderedHosts = (render.RenderableNodes{ - ServerHostRenderedID: { - ID: ServerHostRenderedID, - LabelMajor: "server", // before first . - LabelMinor: "hostname.com", // after first . - Rank: "hostname.com", - Pseudo: false, - Origins: report.MakeIDList( - test.ServerHostNodeID, - test.ServerAddressNodeID, - ), - Node: report.MakeNode(), - EdgeMetadata: report.EdgeMetadata{ - MaxConnCountTCP: newu64(3), - }, - }, - ClientHostRenderedID: { - ID: ClientHostRenderedID, - LabelMajor: "client", // before first . - LabelMinor: "hostname.com", // after first . - Rank: "hostname.com", - Pseudo: false, - Origins: report.MakeIDList( - test.ClientHostNodeID, - test.ClientAddressNodeID, - ), - Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), - EdgeMetadata: report.EdgeMetadata{ - MaxConnCountTCP: newu64(3), - }, - }, - pseudoHostID1: { - ID: pseudoHostID1, - LabelMajor: test.UnknownClient1IP, - Pseudo: true, - Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), + Node: report.MakeNode().WithAdjacent(render.OutgoingInternetID), EdgeMetadata: report.EdgeMetadata{}, - Origins: report.MakeIDList(test.UnknownAddress1NodeID, test.UnknownAddress2NodeID), - }, - pseudoHostID2: { - ID: pseudoHostID2, - LabelMajor: test.UnknownClient3IP, - Pseudo: true, - Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), - EdgeMetadata: report.EdgeMetadata{}, - Origins: report.MakeIDList(test.UnknownAddress3NodeID), - }, - render.TheInternetID: { - ID: render.TheInternetID, - LabelMajor: render.TheInternetMajor, - Pseudo: true, - Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), - EdgeMetadata: report.EdgeMetadata{}, - Origins: report.MakeIDList(test.RandomAddressNodeID), }, + render.IncomingInternetID: theIncomingInternetNode(test.ServerContainerImageName), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() RenderedPods = (render.RenderableNodes{ @@ -423,23 +376,11 @@ var ( test.NonContainerProcessNodeID, test.NonContainerNodeID, ), - 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, - Node: report.MakeNode().WithAdjacent("ping/pong-b"), - EdgeMetadata: report.EdgeMetadata{ - EgressPacketCount: newu64(60), - EgressByteCount: newu64(600), - }, - Origins: report.MakeIDList( - test.RandomClientNodeID, - test.GoogleEndpointNodeID, - ), - }, + render.IncomingInternetID: theIncomingInternetNode("ping/pong-b"), + render.OutgoingInternetID: theOutgoingInternetNode, }).Prune() RenderedPodServices = (render.RenderableNodes{ @@ -485,22 +426,73 @@ var ( test.NonContainerProcessNodeID, test.NonContainerNodeID, ), - 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, - Node: report.MakeNode().WithAdjacent(test.ServiceID), + render.IncomingInternetID: theIncomingInternetNode(test.ServiceID), + render.OutgoingInternetID: theOutgoingInternetNode, + }).Prune() + + ServerHostRenderedID = render.MakeHostID(test.ServerHostID) + ClientHostRenderedID = render.MakeHostID(test.ClientHostID) + pseudoHostID1 = render.MakePseudoNodeID(test.UnknownClient1IP, test.ServerIP) + pseudoHostID2 = render.MakePseudoNodeID(test.UnknownClient3IP, test.ServerIP) + + RenderedHosts = (render.RenderableNodes{ + ServerHostRenderedID: { + ID: ServerHostRenderedID, + LabelMajor: "server", // before first . + LabelMinor: "hostname.com", // after first . + Rank: "hostname.com", + Pseudo: false, + Origins: report.MakeIDList( + test.ServerHostNodeID, + test.ServerAddressNodeID, + ), + Node: report.MakeNode(), EdgeMetadata: report.EdgeMetadata{ - EgressPacketCount: newu64(60), - EgressByteCount: newu64(600), + MaxConnCountTCP: newu64(3), }, + }, + ClientHostRenderedID: { + ID: ClientHostRenderedID, + LabelMajor: "client", // before first . + LabelMinor: "hostname.com", // after first . + Rank: "hostname.com", + Pseudo: false, Origins: report.MakeIDList( - test.RandomClientNodeID, - test.GoogleEndpointNodeID, + test.ClientHostNodeID, + test.ClientAddressNodeID, ), + Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), + EdgeMetadata: report.EdgeMetadata{ + MaxConnCountTCP: newu64(3), + }, + }, + pseudoHostID1: { + ID: pseudoHostID1, + LabelMajor: test.UnknownClient1IP, + Pseudo: true, + Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), + EdgeMetadata: report.EdgeMetadata{}, + Origins: report.MakeIDList(test.UnknownAddress1NodeID, test.UnknownAddress2NodeID), + }, + pseudoHostID2: { + ID: pseudoHostID2, + LabelMajor: test.UnknownClient3IP, + Pseudo: true, + Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), + EdgeMetadata: report.EdgeMetadata{}, + Origins: report.MakeIDList(test.UnknownAddress3NodeID), + }, + render.IncomingInternetID: { + ID: render.IncomingInternetID, + LabelMajor: render.TheInternetMajor, + LabelMinor: render.Incoming, + Pseudo: true, + Node: report.MakeNode().WithAdjacent(ServerHostRenderedID), + EdgeMetadata: report.EdgeMetadata{}, + Origins: report.MakeIDList(test.RandomAddressNodeID), }, }).Prune() ) diff --git a/render/mapping.go b/render/mapping.go index b31cfeb353..bf060f0a94 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 + TheInternetMajor = "The Internet" + Incoming = "Incoming" + Outgoing = "Outgoing" containersKey = "containers" podsKey = "pods" @@ -37,6 +41,19 @@ const ( // If the output is empty, the node shall be omitted from the rendered topology. type MapFunc func(RenderableNode, report.Networks) RenderableNodes +func generateInternetNodeFor(m RenderableNode) RenderableNodes { + node := newDerivedPseudoNode("", TheInternetMajor, m) + // emit one internet node for incoming, one for outgoing + if len(m.Adjacency) > 0 { + node.ID = IncomingInternetID + node.LabelMinor = Incoming + } else { + node.ID = OutgoingInternetID + node.LabelMinor = Outgoing + } + return RenderableNodes{node.ID: node} +} + // MapEndpointIdentity maps an endpoint topology node to a single endpoint // renderable node. As it is only ever run on endpoint topology nodes, we // expect that certain keys are present. @@ -62,16 +79,7 @@ func MapEndpointIdentity(m RenderableNode, local report.Networks) RenderableNode // If the dstNodeAddr is not in a network local to this report, we emit an // internet node if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { - node := newDerivedPseudoNode(TheInternetID, TheInternetMajor, m) - // emit one internet node for incoming, one for outgoing - if len(m.Adjacency) > 0 { - node.ID = "in-" + TheInternetID - node.LabelMinor = "Incoming" - } else { - node.ID = "out-" + TheInternetID - node.LabelMinor = "Outgoing" - } - return RenderableNodes{node.ID: node} + return generateInternetNodeFor(m) } // We are a 'client' pseudo node if the port is in the ephemeral port range. @@ -239,8 +247,8 @@ 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)) { - return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} + if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { + return generateInternetNodeFor(m) } // Otherwise generate a pseudo node for every @@ -296,8 +304,8 @@ func MapEndpoint2IP(m RenderableNode, local report.Networks) RenderableNodes { if !ok { return RenderableNodes{} } - if !local.Contains(net.ParseIP(addr)) { - return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} + if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { + return generateInternetNodeFor(m) } result := RenderableNodes{addr: NewRenderableNodeWith(addr, "", "", "", m)} diff --git a/render/short_lived_connections_test.go b/render/short_lived_connections_test.go index b5d6b1a938..3ab2988afc 100644 --- a/render/short_lived_connections_test.go +++ b/render/short_lived_connections_test.go @@ -67,9 +67,10 @@ var ( } want = (render.RenderableNodes{ - render.TheInternetID: { - ID: render.TheInternetID, + render.IncomingInternetID: { + ID: render.IncomingInternetID, LabelMajor: render.TheInternetMajor, + LabelMinor: render.Incoming, Pseudo: true, Node: report.MakeNode().WithAdjacent(containerID), Origins: report.MakeIDList(randomEndpointNodeID),