From 0a135e6330fbdc268b114370f0ac827d96faca83 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 31 Jan 2017 15:37:43 +0000 Subject: [PATCH] Check for known services before external IPs Known services can be internal (e.g. same VPC in AWS) --- render/container.go | 7 +++--- render/id.go | 48 +++++++++++++++++++++++++++++++++++ render/process.go | 61 ++++++++------------------------------------- 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/render/container.go b/render/container.go index 82974107d5..a79dee7d83 100644 --- a/render/container.go +++ b/render/container.go @@ -1,7 +1,6 @@ package render import ( - "net" "regexp" "strings" @@ -111,9 +110,9 @@ func ShortLivedConnectionJoin(r Renderer, toIPs func(report.Node) []string) Rend if !ok { return report.Nodes{} } - if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { - node := externalNode(m) - return report.Nodes{node.ID: node} + + if externalNode, ok := NewDerivedExternalNode(m, addr, local); ok { + return report.Nodes{externalNode.ID: externalNode} } // We also allow for joining on ip:port pairs. This is useful diff --git a/render/id.go b/render/id.go index c2c2008296..83661899fd 100644 --- a/render/id.go +++ b/render/id.go @@ -1,11 +1,21 @@ package render import ( + "net" + "sort" "strings" + "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/report" ) +// Constants are used in the tests. +const ( + TheInternetID = "theinternet" + IncomingInternetID = "in-" + TheInternetID + OutgoingInternetID = "out-" + TheInternetID +) + // MakePseudoNodeID joins the parts of an id into the id of a pseudonode func MakePseudoNodeID(parts ...string) string { return strings.Join(append([]string{"pseudo"}, parts...), ":") @@ -26,3 +36,41 @@ func NewDerivedPseudoNode(id string, node report.Node) report.Node { output := NewDerivedNode(id, node).WithTopology(Pseudo) return output } + +// NewDerivedExternalNode figures out if a node should be considered external and creates the corresponding pseudo node +func NewDerivedExternalNode(n report.Node, addr string, local report.Networks) (report.Node, bool) { + // First, check if it's a known service and emit a a specific node if it + // is. This needs to be done before checking IPs since known services can + // live in the same network, see https://github.com/weaveworks/scope/issues/2163 + for _, hostname := range DNSNames(n) { + if isKnownService(hostname) { + return NewDerivedPseudoNode(ServiceNodeIDPrefix+hostname, n), true + } + } + + // If the dstNodeAddr is not in a network local to this report, we emit an + // internet pseudoNode + if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { + // emit one internet node for incoming, one for outgoing + if len(n.Adjacency) > 0 { + return NewDerivedPseudoNode(IncomingInternetID, n), true + } + return NewDerivedPseudoNode(OutgoingInternetID, n), true + } + + // The node is not external + return report.Node{}, false +} + +// DNSNames returns a prioritized list of snooped and reverse-resolved +// DNS names associated with node n. +func DNSNames(n report.Node) []string { + snoopedNames, _ := n.Sets.Lookup(endpoint.SnoopedDNSNames) + reverseNames, _ := n.Sets.Lookup(endpoint.ReverseDNSNames) + // sort the names, to make selection for display more + // deterministic + sort.StringSlice(snoopedNames).Sort() + sort.StringSlice(reverseNames).Sort() + // prioritize snooped names + return append(snoopedNames, reverseNames...) +} diff --git a/render/process.go b/render/process.go index e92397d904..982a52ebd7 100644 --- a/render/process.go +++ b/render/process.go @@ -1,9 +1,6 @@ package render import ( - "net" - "sort" - "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/process" @@ -12,13 +9,10 @@ import ( // Constants are used in the tests. const ( - TheInternetID = "theinternet" - IncomingInternetID = "in-" + TheInternetID - OutgoingInternetID = "out-" + TheInternetID - InboundMajor = "The Internet" - OutboundMajor = "The Internet" - InboundMinor = "Inbound connections" - OutboundMinor = "Outbound connections" + InboundMajor = "The Internet" + OutboundMajor = "The Internet" + InboundMinor = "Inbound connections" + OutboundMinor = "Outbound connections" // Topology for pseudo-nodes and IPs so we can differentiate them at the end Pseudo = "pseudo" @@ -88,24 +82,18 @@ var ProcessNameRenderer = ConditionalRenderer(renderProcesses, // MapEndpoint2Pseudo makes internet of host pesudo nodes from a endpoint node. func MapEndpoint2Pseudo(n report.Node, local report.Networks) report.Nodes { - var node report.Node - addr, ok := n.Latest.Lookup(endpoint.Addr) if !ok { return report.Nodes{} } - if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { - // If the dstNodeAddr is not in a network local to this report, we emit an - // external pseudoNode - node = externalNode(n) - } else { - // due to https://github.com/weaveworks/scope/issues/1323 we are dropping - // all non-internet pseudo nodes for now. - // node = NewDerivedPseudoNode(MakePseudoNodeID(addr), n) - return report.Nodes{} + if externalNode, ok := NewDerivedExternalNode(n, addr, local); ok { + return report.Nodes{externalNode.ID: externalNode} } - return report.Nodes{node.ID: node} + + // due to https://github.com/weaveworks/scope/issues/1323 we are dropping + // all non-external pseudo nodes for now. + return report.Nodes{} } // MapEndpoint2Process maps endpoint Nodes to process @@ -157,32 +145,3 @@ func MapProcess2Name(n report.Node, _ report.Networks) report.Nodes { node.Counters = node.Counters.Add(n.Topology, 1) return report.Nodes{name: node} } - -func externalNode(n report.Node) report.Node { - // First, check if it's a known service and emit a - // a specific node if it is - for _, hostname := range DNSNames(n) { - if isKnownService(hostname) { - return NewDerivedPseudoNode(ServiceNodeIDPrefix+hostname, n) - } - } - - // emit one internet node for incoming, one for outgoing - if len(n.Adjacency) > 0 { - return NewDerivedPseudoNode(IncomingInternetID, n) - } - return NewDerivedPseudoNode(OutgoingInternetID, n) -} - -// DNSNames returns a prioritized list of snooped and reverse-resolved -// DNS names associated with node n. -func DNSNames(n report.Node) []string { - snoopedNames, _ := n.Sets.Lookup(endpoint.SnoopedDNSNames) - reverseNames, _ := n.Sets.Lookup(endpoint.ReverseDNSNames) - // sort the names, to make selection for display more - // deterministic - sort.StringSlice(snoopedNames).Sort() - sort.StringSlice(reverseNames).Sort() - // prioritize snooped names - return append(snoopedNames, reverseNames...) -}