forked from weaveworks/scope
-
Notifications
You must be signed in to change notification settings - Fork 0
/
theinternet.go
112 lines (98 loc) · 3.87 KB
/
theinternet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package render
import (
"net"
"regexp"
"strings"
"camlistore.org/pkg/lru"
"github.com/weaveworks/scope/report"
)
var (
// ServiceNodeIDPrefix is how the ID of all service pseudo nodes begin
ServiceNodeIDPrefix = "service-"
knownServiceMatcher = regexp.MustCompile(`^.+\.(` + strings.Join([]string{
// See http://docs.aws.amazon.com/general/latest/gr/rande.html
// for finer grained details
`amazonaws\.com`,
`googleapis\.com`,
`weave\.works`, // Weave Cloud
`core\.windows\.net`, // Azure Storage - Blob, Tables, Files & Queues
`servicebus\.windows\.net`, // Azure Service Bus
`azure-api\.net`, // Azure API Management
`onmicrosoft\.com`, // Azure Active Directory
`cloudapp\.azure\.com`, // Azure IaaS
`database\.windows\.net`, // Azure SQL DB
`documents\.azure\.com`, // Azure DocumentDB/CosmosDB
}, `|`) + `)$`)
knownServiceExcluder = regexp.MustCompile(`^(` + strings.Join([]string{
// We exclude ec2 machines because they are too generic
// and having separate nodes for them makes visualizations worse
`ec2.*\.amazonaws\.com`,
}, `|`) + `)$`)
// Memoization for isKnownService.
//
// The 10000 comes from the observation that large reports contain
// hundreds of names, and in a multi-tenant context we want to be
// able to render a few dozen reports concurrently. Also, unlike
// memoization in the reducers, which is keyed on reports, this
// cache is effective when rendering multiple reports from the
// same cluster of probes, e.g. from different points in time,
// since names tend to change infrequently.
//
// Since names are generally <50 bytes, this shouldn't weight in
// at more than a few MB of memory.
knownServiceCache = lru.New(10000)
)
func purgeKnownServiceCache() {
knownServiceCache = lru.New(10000)
}
// TODO: Make it user-customizable https://github.com/weaveworks/scope/issues/1876
// NB: this is a hotspot in rendering performance.
func isKnownService(hostname string) bool {
if v, ok := knownServiceCache.Get(hostname); ok {
return v.(bool)
}
known := knownServiceMatcher.MatchString(hostname) && !knownServiceExcluder.MatchString(hostname)
knownServiceCache.Add(hostname, known)
return known
}
// 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
// our infrastructure.
func LocalNetworks(r report.Report) report.Networks {
networks := report.MakeNetworks()
for _, topology := range []report.Topology{r.Host, r.Overlay} {
for _, md := range topology.Nodes {
nets, _ := md.Sets.Lookup(report.HostLocalNetworks)
for _, s := range nets {
networks.AddCIDR(s)
}
}
}
if extra := kubeServiceNetwork(r.Service); extra != nil {
networks.Add(extra)
}
return networks
}
// FIXME: Hideous hack to remove persistent-connection edges to
// virtual service IPs attributed to the internet. The global
// service-cluster-ip-range is not exposed by the API server (see
// https://github.com/kubernetes/kubernetes/issues/25533), so instead
// we synthesise it by computing the smallest network that contains
// all service IPs. That network may be smaller than the actual range
// but that is ok, since in the end all we care about is that it
// contains all the service IPs.
//
// The right way of fixing this is performing DNAT mapping on
// persistent connections for which we don't have a robust solution
// (see https://github.com/weaveworks/scope/issues/1491).
func kubeServiceNetwork(services report.Topology) *net.IPNet {
serviceIPs := make([]net.IP, 0, len(services.Nodes))
for _, md := range services.Nodes {
serviceIP, _ := md.Latest.Lookup(report.KubernetesIP)
if ip := net.ParseIP(serviceIP).To4(); ip != nil {
serviceIPs = append(serviceIPs, ip)
}
}
return report.ContainingIPv4Network(serviceIPs)
}