From 152774a812d0ddd848db4714bc4b8a440ba79363 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Mon, 22 Jun 2015 15:29:07 +0000 Subject: [PATCH] Extract out rendered node id generation into a small set of functions. --- app/api_topology_test.go | 10 ++++---- render/id.go | 32 +++++++++++++++++++++++++ render/mapping.go | 16 ++++++------- render/topologies_test.go | 49 +++++++++++++++++++++------------------ report/id.go | 5 ---- 5 files changed, 72 insertions(+), 40 deletions(-) create mode 100644 render/id.go diff --git a/app/api_topology_test.go b/app/api_topology_test.go index 10a7cb882..b9622a534 100644 --- a/app/api_topology_test.go +++ b/app/api_topology_test.go @@ -23,12 +23,12 @@ func TestAPITopologyApplications(t *testing.T) { t.Fatal(err) } equals(t, 4, len(topo.Nodes)) - node, ok := topo.Nodes["pid:hostA:23128"] + node, ok := topo.Nodes["process:hostA:23128"] if !ok { t.Errorf("missing curl node") } equals(t, 1, len(node.Adjacency)) - equals(t, report.MakeIDList("pid:hostB:215"), node.Adjacency) + equals(t, report.MakeIDList("process:hostB:215"), node.Adjacency) equals(t, report.MakeIDList( report.MakeEndpointNodeID("hostA", "192.168.1.1", "12345"), report.MakeEndpointNodeID("hostA", "192.168.1.1", "12346"), @@ -41,19 +41,19 @@ func TestAPITopologyApplications(t *testing.T) { equals(t, false, node.Pseudo) } { - body := getRawJSON(t, ts, "/api/topology/applications/pid:hostA:23128") + body := getRawJSON(t, ts, "/api/topology/applications/process:hostA:23128") var node APINode if err := json.Unmarshal(body, &node); err != nil { t.Fatal(err) } - equals(t, "pid:hostA:23128", node.Node.ID) + equals(t, "process:hostA:23128", node.Node.ID) equals(t, "curl", node.Node.LabelMajor) equals(t, "hostA (23128)", node.Node.LabelMinor) equals(t, false, node.Node.Pseudo) // Let's not unit-test the specific content of the detail tables } { - body := getRawJSON(t, ts, "/api/topology/applications/pid:hostA:23128/pid:hostB:215") + body := getRawJSON(t, ts, "/api/topology/applications/process:hostA:23128/process:hostB:215") var edge APIEdge if err := json.Unmarshal(body, &edge); err != nil { t.Fatalf("JSON parse error: %s", err) diff --git a/render/id.go b/render/id.go new file mode 100644 index 000000000..5bbf4c06a --- /dev/null +++ b/render/id.go @@ -0,0 +1,32 @@ +package render + +import ( + "fmt" + "strings" +) + +// MakeEndpointID makes an endpoint node ID for rendered nodes. +func MakeEndpointID(hostID, addr, port string) string { + return fmt.Sprintf("endpoint:%s:%s:%s", hostID, addr, port) +} + +// MakeProcessID makes a process node ID for rendered nodes. +func MakeProcessID(hostID, pid string) string { + return fmt.Sprintf("process:%s:%s", hostID, pid) +} + +// MakeAddressID makes an address node ID for rendered nodes. +func MakeAddressID(hostID, addr string) string { + return fmt.Sprintf("address:%s:%s", hostID, addr) +} + +// MakeHostID makes a host node ID for rendered nodes. +func MakeHostID(hostID string) string { + return fmt.Sprintf("host:%s", hostID) +} + +// MakePseudoNodeID produces a pseudo node ID from its composite parts, +// for use in rendered nodes. +func MakePseudoNodeID(parts ...string) string { + return strings.Join(append([]string{"pseudo"}, parts...), ":") +} diff --git a/render/mapping.go b/render/mapping.go index 9c79153b2..4582758ff 100644 --- a/render/mapping.go +++ b/render/mapping.go @@ -48,7 +48,7 @@ type MapFunc func(RenderableNode) (RenderableNode, bool) // assume the presence of certain keys. func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( - id = fmt.Sprintf("endpoint:%s:%s:%s", report.ExtractHostID(m), m["addr"], m["port"]) + id = MakeEndpointID(report.ExtractHostID(m), m["addr"], m["port"]) major = fmt.Sprintf("%s:%s", m["addr"], m["port"]) pid, ok = m["pid"] minor = report.ExtractHostID(m) @@ -67,7 +67,7 @@ func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) { // presence of certain keys. func MapProcessIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( - id = fmt.Sprintf("pid:%s:%s", report.ExtractHostID(m), m["pid"]) + id = MakeProcessID(report.ExtractHostID(m), m["pid"]) major = m["comm"] minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), m["pid"]) rank = m["pid"] @@ -108,7 +108,7 @@ func MapContainerImageIdentity(m report.NodeMetadata) (RenderableNode, bool) { // assume the presence of certain keys. func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( - id = fmt.Sprintf("address:%s:%s", report.ExtractHostID(m), m["addr"]) + id = MakeAddressID(report.ExtractHostID(m), m["addr"]) major = m["addr"] minor = report.ExtractHostID(m) rank = major @@ -122,7 +122,7 @@ func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) { // assume the presence of certain keys. func MapHostIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( - id = fmt.Sprintf("host:%s", report.ExtractHostID(m)) + id = MakeHostID(report.ExtractHostID(m)) hostname = m["host_name"] parts = strings.SplitN(hostname, ".", 2) major, minor, rank = "", "", "" @@ -158,7 +158,7 @@ func MapEndpoint2Process(n RenderableNode) (RenderableNode, bool) { return RenderableNode{}, false } - id := fmt.Sprintf("pid:%s:%s", report.ExtractHostID(n.NodeMetadata), pid) + id := MakeProcessID(report.ExtractHostID(n.NodeMetadata), pid) return newDerivedNode(id, n), true } @@ -191,7 +191,7 @@ func MapProcess2Container(n RenderableNode) (RenderableNode, bool) { id, ok := n.NodeMetadata[docker.ContainerID] if !ok { hostID := report.ExtractHostID(n.NodeMetadata) - id = fmt.Sprintf("%s:%s", UncontainedID, hostID) + id = MakePseudoNodeID(UncontainedID, hostID) node := newDerivedPseudoNode(id, UncontainedMajor, n) node.LabelMinor = hostID return node, true @@ -257,7 +257,7 @@ func MapAddress2Host(n RenderableNode) (RenderableNode, bool) { return n, true } - id := fmt.Sprintf("host:%s", report.ExtractHostID(n.NodeMetadata)) + id := MakeHostID(report.ExtractHostID(n.NodeMetadata)) return newDerivedNode(id, n), true } @@ -280,7 +280,7 @@ func GenericPseudoNode(addresser func(id string) net.IP) PseudoFunc { // dstNodeAddr, srcNodeAddr, srcNodePort. srcNodeAddr, srcNodePort := trySplitAddr(src) - outputID := report.MakePseudoNodeID(dstNodeAddr.String(), srcNodeAddr, srcNodePort) + outputID := MakePseudoNodeID(dstNodeAddr.String(), srcNodeAddr, srcNodePort) major := dstNodeAddr.String() return newPseudoNode(outputID, major, ""), true } diff --git a/render/topologies_test.go b/render/topologies_test.go index 4aaf0a1b6..ca113ce8d 100644 --- a/render/topologies_test.go +++ b/render/topologies_test.go @@ -51,6 +51,7 @@ var ( serverContainerID = "5e4d3c2b1a" clientContainerNodeID = report.MakeContainerNodeID(clientHostID, clientContainerID) serverContainerNodeID = report.MakeContainerNodeID(serverHostID, serverContainerID) + uncontainedServerID = render.MakePseudoNodeID(render.UncontainedID, serverHostName) clientContainerImageID = "imageid123" serverContainerImageID = "imageid456" @@ -63,8 +64,8 @@ var ( unknownAddress2NodeID = report.MakeAddressNodeID(serverHostID, "10.10.10.11") randomAddressNodeID = report.MakeAddressNodeID(serverHostID, "51.52.53.54") // this should become an internet node - unknownPseudoNode1ID = "pseudo;10.10.10.10;192.168.1.1;80" - unknownPseudoNode2ID = "pseudo;10.10.10.11;192.168.1.1;80" + unknownPseudoNode1ID = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "80") + unknownPseudoNode2ID = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "80") unknownPseudoNode1 = render.RenderableNode{ ID: unknownPseudoNode1ID, LabelMajor: "10.10.10.10", @@ -277,9 +278,9 @@ func trimNodeMetadata(rns render.RenderableNodes) render.RenderableNodes { func TestProcessRenderer(t *testing.T) { var ( - clientProcessID = fmt.Sprintf("pid:%s:%s", clientHostID, clientPID) - serverProcessID = fmt.Sprintf("pid:%s:%s", serverHostID, serverPID) - nonContainerProcessID = fmt.Sprintf("pid:%s:%s", serverHostID, nonContainerPID) + clientProcessID = render.MakeProcessID(clientHostID, clientPID) + serverProcessID = render.MakeProcessID(serverHostID, serverPID) + nonContainerProcessID = render.MakeProcessID(serverHostID, nonContainerPID) ) want := render.RenderableNodes{ @@ -336,9 +337,6 @@ func TestProcessRenderer(t *testing.T) { } func TestProcessNameRenderer(t *testing.T) { - // For grouped, I've somewhat arbitrarily chosen to squash together all - // processes with the same name by removing the PID and domain (host) - // dimensions from the ID. That could be changed. want := render.RenderableNodes{ "curl": { ID: "curl", @@ -419,8 +417,8 @@ func TestContainerRenderer(t *testing.T) { render.KeyBytesEgress: 1500, }, }, - fmt.Sprintf("%s:%s", render.UncontainedID, serverHostName): { - ID: fmt.Sprintf("%s:%s", render.UncontainedID, serverHostName), + uncontainedServerID: { + ID: uncontainedServerID, LabelMajor: render.UncontainedMajor, LabelMinor: serverHostName, Rank: "", @@ -465,8 +463,8 @@ func TestContainerImageRenderer(t *testing.T) { render.KeyBytesEgress: 1500, }, }, - fmt.Sprintf("%s:%s", render.UncontainedID, serverHostName): { - ID: fmt.Sprintf("%s:%s", render.UncontainedID, serverHostName), + uncontainedServerID: { + ID: uncontainedServerID, LabelMajor: render.UncontainedMajor, LabelMinor: serverHostName, Rank: "", @@ -484,39 +482,46 @@ func TestContainerImageRenderer(t *testing.T) { } func TestHostRenderer(t *testing.T) { + var ( + serverHostRenderedID = render.MakeHostID(serverHostID) + clientHostRenderedID = render.MakeHostID(clientHostID) + pseudoHostID1 = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "") + pseudoHostID2 = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "") + ) + want := render.RenderableNodes{ - "host:server.hostname.com": { - ID: "host:server.hostname.com", + serverHostRenderedID: { + ID: serverHostRenderedID, LabelMajor: "server", // before first . LabelMinor: "hostname.com", // after first . Rank: "hostname.com", Pseudo: false, - Adjacency: report.MakeIDList("host:client.hostname.com", render.TheInternetID, "pseudo;10.10.10.10;192.168.1.1;", "pseudo;10.10.10.11;192.168.1.1;"), + Adjacency: report.MakeIDList(clientHostRenderedID, render.TheInternetID, pseudoHostID1, pseudoHostID2), Origins: report.MakeIDList(serverHostNodeID, serverAddressNodeID), AggregateMetadata: render.AggregateMetadata{ render.KeyMaxConnCountTCP: 3, }, }, - "host:client.hostname.com": { - ID: "host:client.hostname.com", + clientHostRenderedID: { + ID: clientHostRenderedID, LabelMajor: "client", // before first . LabelMinor: "hostname.com", // after first . Rank: "hostname.com", Pseudo: false, - Adjacency: report.MakeIDList("host:server.hostname.com"), + Adjacency: report.MakeIDList(serverHostRenderedID), Origins: report.MakeIDList(clientHostNodeID, clientAddressNodeID), AggregateMetadata: render.AggregateMetadata{ render.KeyMaxConnCountTCP: 3, }, }, - "pseudo;10.10.10.10;192.168.1.1;": { - ID: "pseudo;10.10.10.10;192.168.1.1;", + pseudoHostID1: { + ID: pseudoHostID1, LabelMajor: "10.10.10.10", Pseudo: true, AggregateMetadata: render.AggregateMetadata{}, }, - "pseudo;10.10.10.11;192.168.1.1;": { - ID: "pseudo;10.10.10.11;192.168.1.1;", + pseudoHostID2: { + ID: pseudoHostID2, LabelMajor: "10.10.10.11", Pseudo: true, AggregateMetadata: render.AggregateMetadata{}, diff --git a/report/id.go b/report/id.go index 4dcb4b9a2..f6205a21d 100644 --- a/report/id.go +++ b/report/id.go @@ -109,11 +109,6 @@ func ExtractHostID(m NodeMetadata) string { return hostid } -// MakePseudoNodeID produces a pseudo node ID from its composite parts. -func MakePseudoNodeID(parts ...string) string { - return strings.Join(append([]string{"pseudo"}, parts...), ScopeDelim) -} - // IDAddresser tries to convert a node ID to a net.IP, if possible. type IDAddresser func(string) net.IP