From 89831bfdd2245957cc08f8f1341f37ac1fb3128c Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Tue, 18 Aug 2015 11:12:35 +0000 Subject: [PATCH 1/3] Condense origin address entries into a single table. --- render/detailed_node.go | 52 ++++++++++++++++++----------------------- report/id.go | 9 +++++++ 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/render/detailed_node.go b/render/detailed_node.go index b739eb104..814989a1f 100644 --- a/render/detailed_node.go +++ b/render/detailed_node.go @@ -6,7 +6,6 @@ import ( "strconv" "github.com/weaveworks/scope/probe/docker" - "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/report" @@ -112,8 +111,10 @@ func MakeDetailedNode(r report.Report, n RenderableNode) DetailedNode { for _, id := range n.Origins { if table, ok := OriginTable(r, id); ok { tables = append(tables, table) - } else if nmd, ok := r.Endpoint.NodeMetadatas[id]; ok { - connections = append(connections, connectionDetailsRows(r.Endpoint, id, nmd)...) + } else if _, ok := r.Endpoint.NodeMetadatas[id]; ok { + connections = append(connections, connectionDetailsRows(r.Endpoint, id)...) + } else if _, ok := r.Address.NodeMetadatas[id]; ok { + connections = append(connections, connectionDetailsRows(r.Address, id)...) } } if len(connections) > 0 { @@ -135,9 +136,6 @@ func MakeDetailedNode(r report.Report, n RenderableNode) DetailedNode { // OriginTable produces a table (to be consumed directly by the UI) based on // an origin ID, which is (optimistically) a node ID in one of our topologies. func OriginTable(r report.Report, originID string) (Table, bool) { - if nmd, ok := r.Address.NodeMetadatas[originID]; ok { - return addressOriginTable(nmd) - } if nmd, ok := r.Process.NodeMetadatas[originID]; ok { return processOriginTable(nmd) } @@ -153,18 +151,27 @@ func OriginTable(r report.Report, originID string) (Table, bool) { return Table{}, false } -func connectionDetailsRows(endpointTopology report.Topology, originID string, nmd report.NodeMetadata) []Row { +func connectionDetailsRows(topology report.Topology, originID string) []Row { rows := []Row{} - local := fmt.Sprintf("%s:%s", nmd.Metadata[endpoint.Addr], nmd.Metadata[endpoint.Port]) - adjacencies := endpointTopology.Adjacency[report.MakeAdjacencyID(originID)] - sort.Strings(adjacencies) - for _, adj := range adjacencies { - if _, address, port, ok := report.ParseEndpointNodeID(adj); ok { - rows = append(rows, Row{ - Key: local, - ValueMajor: fmt.Sprintf("%s:%s", address, port), - }) + + labeler := func(nodeID string) string { + if _, addr, port, ok := report.ParseEndpointNodeID(nodeID); ok { + return fmt.Sprintf("%s:%s", addr, port) } + if _, addr, ok := report.ParseAddressNodeID(nodeID); ok { + return addr + } + return "" + } + + local := labeler(originID) + adjacencies := topology.Adjacency[report.MakeAdjacencyID(originID)] + sort.Strings(adjacencies) + for _, nodeID := range adjacencies { + rows = append(rows, Row{ + Key: local, + ValueMajor: labeler(nodeID), + }) } return rows } @@ -178,19 +185,6 @@ func connectionDetailsTable(connectionRows []Row) Table { } } -func addressOriginTable(nmd report.NodeMetadata) (Table, bool) { - rows := []Row{} - if val, ok := nmd.Metadata[endpoint.Addr]; ok { - rows = append(rows, Row{"Address", val, ""}) - } - return Table{ - Title: "Origin Address", - Numeric: false, - Rows: rows, - Rank: addressRank, - }, len(rows) > 0 -} - func processOriginTable(nmd report.NodeMetadata) (Table, bool) { rows := []Row{} for _, tuple := range []struct{ key, human string }{ diff --git a/report/id.go b/report/id.go index cb9bdb89c..a2a88de95 100644 --- a/report/id.go +++ b/report/id.go @@ -114,6 +114,15 @@ func ParseEndpointNodeID(endpointNodeID string) (hostID, address, port string, o return fields[0], fields[1], fields[2], true } +// ParseAddressNodeID produces the host ID, address from an address node ID. +func ParseAddressNodeID(addressNodeID string) (hostID, address string, ok bool) { + fields := strings.SplitN(addressNodeID, ScopeDelim, 2) + if len(fields) != 2 { + return "", "", false + } + return fields[0], fields[1], true +} + // ExtractHostID extracts the host id from NodeMetadata func ExtractHostID(m NodeMetadata) string { hostid, _, _ := ParseNodeID(m.Metadata[HostNodeID]) From 4efa811ef88755b425d396fe57d67928a612eeb0 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Tue, 18 Aug 2015 12:16:42 +0000 Subject: [PATCH 2/3] Add test. --- render/detailed_node_test.go | 76 ++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/render/detailed_node_test.go b/render/detailed_node_test.go index 7e561efb5..e0db93305 100644 --- a/render/detailed_node_test.go +++ b/render/detailed_node_test.go @@ -14,13 +14,6 @@ func TestOriginTable(t *testing.T) { t.Errorf("unknown origin ID gave unexpected success") } for originID, want := range map[string]render.Table{ - test.ClientAddressNodeID: { - Title: "Origin Address", - Numeric: false, - Rows: []render.Row{ - {"Address", test.ClientIP, ""}, - }, - }, test.ServerProcessNodeID: { Title: "Origin Process", Numeric: false, @@ -52,7 +45,74 @@ func TestOriginTable(t *testing.T) { } } -func TestMakeDetailedNode(t *testing.T) { +func TestMakeDetailedHostNode(t *testing.T) { + renderableNode := render.HostRenderer.Render(test.Report)[render.MakeHostID(test.ClientHostID)] + have := render.MakeDetailedNode(test.Report, renderableNode) + want := render.DetailedNode{ + ID: render.MakeHostID(test.ClientHostID), + LabelMajor: "client", + LabelMinor: "hostname.com", + Pseudo: false, + Tables: []render.Table{ + { + Title: "Connections", + Numeric: true, + Rank: 100, + Rows: []render.Row{ + { + Key: "TCP connections", + ValueMajor: "3", + ValueMinor: "", + }, + }, + }, + { + Title: "Origin Host", + Numeric: false, + Rank: 1, + Rows: []render.Row{ + { + Key: "Host name", + ValueMajor: "client.hostname.com", + ValueMinor: "", + }, + { + Key: "Load", + ValueMajor: "0.01 0.01 0.01", + ValueMinor: "", + }, + { + Key: "Operating system", + ValueMajor: "Linux", + ValueMinor: "", + }, + }, + }, + { + Title: "Connection Details", + Numeric: false, + Rank: 0, + Rows: []render.Row{ + { + Key: "Local", + ValueMajor: "Remote", + ValueMinor: "", + }, + { + Key: "10.10.10.20", + ValueMajor: "192.168.1.1", + ValueMinor: "", + }, + }, + }, + }, + } + if !reflect.DeepEqual(want, have) { + t.Errorf("%s", test.Diff(want, have)) + } +} + +func TestMakeDetailedContainerNode(t *testing.T) { renderableNode := render.ContainerRenderer.Render(test.Report)[test.ServerContainerID] have := render.MakeDetailedNode(test.Report, renderableNode) want := render.DetailedNode{ From 75369acb42d4ab4fc359c786f0991fd1ff9ab60a Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Wed, 19 Aug 2015 10:06:57 +0000 Subject: [PATCH 3/3] Review feedback --- render/detailed_node.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/render/detailed_node.go b/render/detailed_node.go index 814989a1f..77fc7bd13 100644 --- a/render/detailed_node.go +++ b/render/detailed_node.go @@ -153,25 +153,28 @@ func OriginTable(r report.Report, originID string) (Table, bool) { func connectionDetailsRows(topology report.Topology, originID string) []Row { rows := []Row{} - - labeler := func(nodeID string) string { + labeler := func(nodeID string) (string, bool) { if _, addr, port, ok := report.ParseEndpointNodeID(nodeID); ok { - return fmt.Sprintf("%s:%s", addr, port) + return fmt.Sprintf("%s:%s", addr, port), true } if _, addr, ok := report.ParseAddressNodeID(nodeID); ok { - return addr + return addr, true } - return "" + return "", false + } + local, ok := labeler(originID) + if !ok { + return rows } - - local := labeler(originID) adjacencies := topology.Adjacency[report.MakeAdjacencyID(originID)] sort.Strings(adjacencies) for _, nodeID := range adjacencies { - rows = append(rows, Row{ - Key: local, - ValueMajor: labeler(nodeID), - }) + if remote, ok := labeler(nodeID); ok { + rows = append(rows, Row{ + Key: local, + ValueMajor: remote, + }) + } } return rows }