-
Notifications
You must be signed in to change notification settings - Fork 712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add connection tables to details panel #1017
Changes from all commits
7b77210
a40b5a3
f154e7a
09de883
7d0b1ce
51fa8d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
package detailed | ||
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong. |
||
|
||
import ( | ||
"sort" | ||
"strconv" | ||
|
||
"github.com/weaveworks/scope/render" | ||
"github.com/weaveworks/scope/report" | ||
) | ||
|
||
const ( | ||
portKey = "port" | ||
portLabel = "Port" | ||
countKey = "count" | ||
countLabel = "Count" | ||
number = "number" | ||
) | ||
|
||
// Exported for testing | ||
var ( | ||
NormalColumns = []Column{ | ||
{ID: portKey, Label: portLabel}, | ||
{ID: countKey, Label: countLabel, DefaultSort: true}, | ||
} | ||
InternetColumns = []Column{ | ||
{ID: "foo", Label: "Remote"}, | ||
{ID: portKey, Label: portLabel}, | ||
{ID: countKey, Label: countLabel, DefaultSort: true}, | ||
} | ||
) | ||
|
||
type connectionsRow struct { | ||
remoteNode, localNode *render.RenderableNode | ||
remoteAddr, localAddr string | ||
port string // always the server-side port | ||
} | ||
|
||
func incomingConnectionsTable(topologyID string, n render.RenderableNode, ns render.RenderableNodes) NodeSummaryGroup { | ||
localEndpointIDs := endpointChildIDsOf(n) | ||
|
||
// For each node which has an edge TO me | ||
counts := map[connectionsRow]int{} | ||
for _, node := range ns { | ||
if !node.Adjacency.Contains(n.ID) { | ||
continue | ||
} | ||
remoteNode := node.Copy() | ||
|
||
// Work out what port they are talking to, and count the number of | ||
// connections to that port. | ||
// This is complicated as for internet nodes we break out individual | ||
// address, both when the internet node is remote (an incoming | ||
// connection from the internet) and 'local' (ie you are loading | ||
// details on the internet node) | ||
for _, child := range endpointChildrenOf(node) { | ||
for _, localEndpointID := range child.Adjacency.Intersection(localEndpointIDs) { | ||
_, localAddr, port, ok := render.ParseEndpointID(localEndpointID) | ||
if !ok { | ||
continue | ||
} | ||
key := connectionsRow{ | ||
localNode: &n, | ||
remoteNode: &remoteNode, | ||
port: port, | ||
} | ||
if isInternetNode(n) { | ||
key.localAddr = localAddr | ||
} | ||
counts[key] = counts[key] + 1 | ||
} | ||
} | ||
} | ||
|
||
columnHeaders := NormalColumns | ||
if isInternetNode(n) { | ||
columnHeaders = InternetColumns | ||
} | ||
return NodeSummaryGroup{ | ||
ID: "incoming-connections", | ||
TopologyID: topologyID, | ||
Label: "Inbound", | ||
Columns: columnHeaders, | ||
Nodes: connectionRows(counts, isInternetNode(n)), | ||
} | ||
} | ||
|
||
func outgoingConnectionsTable(topologyID string, n render.RenderableNode, ns render.RenderableNodes) NodeSummaryGroup { | ||
localEndpoints := endpointChildrenOf(n) | ||
|
||
// For each node which has an edge FROM me | ||
counts := map[connectionsRow]int{} | ||
for _, node := range ns { | ||
if !n.Adjacency.Contains(node.ID) { | ||
continue | ||
} | ||
remoteNode := node.Copy() | ||
remoteEndpointIDs := endpointChildIDsOf(remoteNode) | ||
|
||
for _, localEndpoint := range localEndpoints { | ||
_, localAddr, _, ok := render.ParseEndpointID(localEndpoint.ID) | ||
if !ok { | ||
continue | ||
} | ||
|
||
for _, remoteEndpointID := range localEndpoint.Adjacency.Intersection(remoteEndpointIDs) { | ||
_, _, port, ok := render.ParseEndpointID(remoteEndpointID) | ||
if !ok { | ||
continue | ||
} | ||
key := connectionsRow{ | ||
localNode: &n, | ||
remoteNode: &remoteNode, | ||
port: port, | ||
} | ||
if isInternetNode(n) { | ||
key.localAddr = localAddr | ||
} | ||
counts[key] = counts[key] + 1 | ||
} | ||
} | ||
} | ||
|
||
columnHeaders := NormalColumns | ||
if isInternetNode(n) { | ||
columnHeaders = InternetColumns | ||
} | ||
return NodeSummaryGroup{ | ||
ID: "outgoing-connections", | ||
TopologyID: topologyID, | ||
Label: "Outbound", | ||
Columns: columnHeaders, | ||
Nodes: connectionRows(counts, isInternetNode(n)), | ||
} | ||
} | ||
|
||
func endpointChildrenOf(n render.RenderableNode) []render.RenderableNode { | ||
result := []render.RenderableNode{} | ||
n.Children.ForEach(func(child render.RenderableNode) { | ||
if _, _, _, ok := render.ParseEndpointID(child.ID); ok { | ||
result = append(result, child) | ||
} | ||
}) | ||
return result | ||
} | ||
|
||
func endpointChildIDsOf(n render.RenderableNode) report.IDList { | ||
result := report.MakeIDList() | ||
n.Children.ForEach(func(child render.RenderableNode) { | ||
if _, _, _, ok := render.ParseEndpointID(child.ID); ok { | ||
result = append(result, child.ID) | ||
} | ||
}) | ||
return result | ||
} | ||
|
||
func isInternetNode(n render.RenderableNode) bool { | ||
return n.ID == render.IncomingInternetID || n.ID == render.OutgoingInternetID | ||
} | ||
|
||
func connectionRows(in map[connectionsRow]int, includeLocal bool) []NodeSummary { | ||
nodes := []NodeSummary{} | ||
for row, count := range in { | ||
id, label, linkable := row.remoteNode.ID, row.remoteNode.LabelMajor, true | ||
if row.remoteAddr != "" { | ||
id, label, linkable = row.remoteAddr+":"+row.port, row.remoteAddr, false | ||
} | ||
metadata := []MetadataRow{} | ||
if includeLocal { | ||
metadata = append(metadata, | ||
MetadataRow{ | ||
ID: "foo", | ||
Value: row.localAddr, | ||
Datatype: number, | ||
}) | ||
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
Sorry, something went wrong. |
||
} | ||
metadata = append(metadata, | ||
MetadataRow{ | ||
ID: portKey, | ||
Value: row.port, | ||
Datatype: number, | ||
}, | ||
MetadataRow{ | ||
ID: countKey, | ||
Value: strconv.Itoa(count), | ||
Datatype: number, | ||
}, | ||
) | ||
nodes = append(nodes, NodeSummary{ | ||
ID: id, | ||
Label: label, | ||
Linkable: linkable, | ||
Metadata: metadata, | ||
}) | ||
} | ||
sort.Sort(nodeSummariesByID(nodes)) | ||
return nodes | ||
} |
This comment was marked as abuse.
Sorry, something went wrong.