Merge pull request #1863 from weaveworks/1082-nodes-for-known-services

Add pseudo-nodes for known services
This commit is contained in:
Alfonso Acosta
2016-09-20 23:00:52 +02:00
committed by GitHub
10 changed files with 323 additions and 15 deletions

View File

@@ -74,8 +74,8 @@ func ShortLivedConnectionJoin(r Renderer, toIPs func(report.Node) []string) Rend
return report.Nodes{}
}
// Propagate the internet pseudo node
if strings.HasSuffix(n.ID, TheInternetID) {
// Propagate the internet and service pseudo nodes
if strings.HasSuffix(n.ID, TheInternetID) || strings.HasPrefix(n.ID, ServiceNodeIDPrefix) {
return report.Nodes{n.ID: n}
}
@@ -112,7 +112,7 @@ func ShortLivedConnectionJoin(r Renderer, toIPs func(report.Node) []string) Rend
return report.Nodes{}
}
if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) {
node := theInternetNode(m)
node := externalNode(m)
return report.Nodes{node.ID: node}
}

View File

@@ -115,6 +115,7 @@ func pseudoNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) {
base.Pseudo = true
base.Rank = n.ID
// try rendering as an internet node
if template, ok := templates[n.ID]; ok {
base.Label = template.Label
base.LabelMinor = template.LabelMinor
@@ -122,6 +123,14 @@ func pseudoNodeSummary(base NodeSummary, n report.Node) (NodeSummary, bool) {
return base, true
}
// try rendering as a known service node
if strings.HasPrefix(n.ID, render.ServiceNodeIDPrefix) {
base.Label = n.ID[len(render.ServiceNodeIDPrefix):]
base.LabelMinor = ""
base.Shape = report.Cloud
return base, true
}
// try rendering it as an uncontained node
if strings.HasPrefix(n.ID, render.MakePseudoNodeID(render.UncontainedID)) {
base.Label = render.UncontainedMajor

View File

@@ -245,9 +245,9 @@ func IsApplication(n report.Node) bool {
var IsSystem = Complement(IsApplication)
// IsNotPseudo returns true if the node is not a pseudo node
// or the internet nodes.
// or internet/service nodes.
func IsNotPseudo(n report.Node) bool {
return n.Topology != Pseudo || strings.HasSuffix(n.ID, TheInternetID)
return n.Topology != Pseudo || strings.HasSuffix(n.ID, TheInternetID) || strings.HasPrefix(n.ID, ServiceNodeIDPrefix)
}
// IsNamespace checks if the node is a pod/service in the specified namespace

View File

@@ -2,6 +2,7 @@ package render
import (
"net"
"sort"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/endpoint"
@@ -96,8 +97,8 @@ func MapEndpoint2Pseudo(n report.Node, local report.Networks) 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
// internet node
node = theInternetNode(n)
// 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.
@@ -157,7 +158,21 @@ func MapProcess2Name(n report.Node, _ report.Networks) report.Nodes {
return report.Nodes{name: node}
}
func theInternetNode(m report.Node) report.Node {
func externalNode(m report.Node) report.Node {
// First, check if it's a known service and emit a
// a specific node if it is
snoopedHostnames, _ := m.Sets.Lookup(endpoint.SnoopedDNSNames)
reverseHostnames, _ := m.Sets.Lookup(endpoint.ReverseDNSNames)
// Sort the names to make the lookup more deterministic
sort.StringSlice(snoopedHostnames).Sort()
sort.StringSlice(reverseHostnames).Sort()
// Intentionally prioritize snooped hostnames
for _, hostname := range append(snoopedHostnames, reverseHostnames...) {
if isKnownService(hostname) {
return NewDerivedPseudoNode(ServiceNodeIDPrefix+hostname, m)
}
}
// emit one internet node for incoming, one for outgoing
if len(m.Adjacency) > 0 {
return NewDerivedPseudoNode(IncomingInternetID, m)

View File

@@ -2,11 +2,51 @@ package render
import (
"net"
"regexp"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/report"
)
var (
// ServiceNodeIDPrefix is how the ID of all service pseudo nodes begin
ServiceNodeIDPrefix = "service-"
knownServiceMatchers = []*regexp.Regexp{
// See http://docs.aws.amazon.com/general/latest/gr/rande.html for fainer grained
// details
regexp.MustCompile(`^.+\.amazonaws\.com$`),
regexp.MustCompile(`^.+\.googleapis\.com$`),
}
knownServiceExcluders = []*regexp.Regexp{
// We exclude ec2 machines because they are too generic
// and having separate nodes for them makes visualizations worse
regexp.MustCompile(`^ec2.*\.amazonaws\.com$`),
}
)
// TODO: Make it user-customizable https://github.com/weaveworks/scope/issues/1876
func isKnownService(hostname string) bool {
foundMatch := false
for _, matcher := range knownServiceMatchers {
if matcher.MatchString(hostname) {
foundMatch = true
break
}
}
if !foundMatch {
return false
}
for _, excluder := range knownServiceExcluders {
if excluder.MatchString(hostname) {
return false
}
}
return true
}
// LocalNetworks returns a superset of the networks (think: CIDRs) that are
// "local" from the perspective of each host represented in the report. It's
// used to determine which nodes in the report are "remote", i.e. outside of