Move Adjacency info inside the NodeMetadata struct; move pseudo node generation to the probes.

This commit is contained in:
Tom Wilkie
2015-08-28 15:20:27 +00:00
parent 9edd507bd4
commit 1f6b3d4a45
26 changed files with 442 additions and 649 deletions
+36 -32
View File
@@ -73,37 +73,37 @@ func demoReport(nodeCount int) report.Report {
connectionCount := nodeCount * 2
for i := 0; i < connectionCount; i++ {
var (
c = procPool[rand.Intn(len(procPool))]
src = hosts[rand.Intn(len(hosts))]
dst = hosts[rand.Intn(len(hosts))]
srcPort = rand.Intn(50000) + 10000
srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort))
dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort))
srcID = report.MakeAdjacencyID(srcPortID)
dstID = report.MakeAdjacencyID(dstPortID)
srcAddressID = report.MakeAddressNodeID("", src)
dstAddressID = report.MakeAddressNodeID("", dst)
nodeSrcAddressID = report.MakeAdjacencyID(srcAddressID)
nodeDstAddressID = report.MakeAdjacencyID(dstAddressID)
c = procPool[rand.Intn(len(procPool))]
src = hosts[rand.Intn(len(hosts))]
dst = hosts[rand.Intn(len(hosts))]
srcPort = rand.Intn(50000) + 10000
srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort))
dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort))
srcAddressID = report.MakeAddressNodeID("", src)
dstAddressID = report.MakeAddressNodeID("", dst)
)
// Endpoint topology
if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok {
r.Endpoint.NodeMetadatas[srcPortID] = report.MakeNodeMetadataWith(map[string]string{
process.PID: "4000",
"name": c.srcProc,
"domain": "node-" + src,
})
r.Endpoint.NodeMetadatas[srcPortID] = report.NodeMetadata{
Metadata: map[string]string{
process.PID: "4000",
"name": c.srcProc,
"domain": "node-" + src,
},
Adjacency: report.MakeIDList(dstPortID),
}
}
r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID)
if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok {
r.Endpoint.NodeMetadatas[dstPortID] = report.MakeNodeMetadataWith(map[string]string{
process.PID: "4000",
"name": c.dstProc,
"domain": "node-" + dst,
})
r.Endpoint.NodeMetadatas[dstPortID] = report.NodeMetadata{
Metadata: map[string]string{
process.PID: "4000",
"name": c.dstProc,
"domain": "node-" + dst,
},
Adjacency: report.MakeIDList(srcPortID),
}
}
r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID)
var (
edgeKeyEgress = report.MakeEdgeID(srcPortID, dstPortID)
edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID)
@@ -117,17 +117,21 @@ func demoReport(nodeCount int) report.Report {
// Address topology
if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
r.Address.NodeMetadatas[srcAddressID] = report.MakeNodeMetadataWith(map[string]string{
docker.Name: src,
})
r.Address.NodeMetadatas[srcAddressID] = report.NodeMetadata{
Metadata: map[string]string{
docker.Name: src,
},
Adjacency: report.MakeIDList(dstAddressID),
}
}
r.Address.Adjacency[nodeSrcAddressID] = r.Address.Adjacency[nodeSrcAddressID].Add(dstAddressID)
if _, ok := r.Address.NodeMetadatas[dstAddressID]; !ok {
r.Address.NodeMetadatas[dstAddressID] = report.MakeNodeMetadataWith(map[string]string{
docker.Name: dst,
})
r.Address.NodeMetadatas[dstAddressID] = report.NodeMetadata{
Metadata: map[string]string{
docker.Name: dst,
},
Adjacency: report.MakeIDList(srcAddressID),
}
}
r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)
// Host data
r.Host.NodeMetadatas["hostX"] = report.MakeNodeMetadataWith(map[string]string{
+36 -32
View File
@@ -53,37 +53,37 @@ func DemoReport(nodeCount int) report.Report {
connectionCount := nodeCount * 8
for i := 0; i < connectionCount; i++ {
var (
c = procPool[rand.Intn(len(procPool))]
src = hosts[rand.Intn(len(hosts))]
dst = hosts[rand.Intn(len(hosts))]
srcPort = rand.Intn(50000) + 10000
srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort))
dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort))
srcID = report.MakeAdjacencyID(srcPortID)
dstID = report.MakeAdjacencyID(dstPortID)
srcAddressID = report.MakeAddressNodeID("", src)
dstAddressID = report.MakeAddressNodeID("", dst)
nodeSrcAddressID = report.MakeAdjacencyID(srcAddressID)
nodeDstAddressID = report.MakeAdjacencyID(dstAddressID)
c = procPool[rand.Intn(len(procPool))]
src = hosts[rand.Intn(len(hosts))]
dst = hosts[rand.Intn(len(hosts))]
srcPort = rand.Intn(50000) + 10000
srcPortID = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort))
dstPortID = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort))
srcAddressID = report.MakeAddressNodeID("", src)
dstAddressID = report.MakeAddressNodeID("", dst)
)
// Endpoint topology
if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok {
r.Endpoint.NodeMetadatas[srcPortID] = report.MakeNodeMetadataWith(map[string]string{
"pid": "4000",
"name": c.srcProc,
"domain": "node-" + src,
})
r.Endpoint.NodeMetadatas[srcPortID] = report.NodeMetadata{
Metadata: map[string]string{
"pid": "4000",
"name": c.srcProc,
"domain": "node-" + src,
},
Adjacency: report.MakeIDList(dstPortID),
}
}
r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID)
if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok {
r.Endpoint.NodeMetadatas[dstPortID] = report.MakeNodeMetadataWith(map[string]string{
"pid": "4000",
"name": c.dstProc,
"domain": "node-" + dst,
})
r.Endpoint.NodeMetadatas[dstPortID] = report.NodeMetadata{
Metadata: map[string]string{
"pid": "4000",
"name": c.dstProc,
"domain": "node-" + dst,
},
Adjacency: report.MakeIDList(srcPortID),
}
}
r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID)
var (
edgeKeyEgress = report.MakeEdgeID(srcPortID, dstPortID)
edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID)
@@ -97,17 +97,21 @@ func DemoReport(nodeCount int) report.Report {
// Address topology
if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
r.Address.NodeMetadatas[srcAddressID] = report.MakeNodeMetadataWith(map[string]string{
"name": src,
})
r.Address.NodeMetadatas[srcAddressID] = report.NodeMetadata{
Metadata: map[string]string{
"name": src,
},
Adjacency: report.MakeIDList(dstAddressID),
}
}
r.Address.Adjacency[nodeSrcAddressID] = r.Address.Adjacency[nodeSrcAddressID].Add(dstAddressID)
if _, ok := r.Address.NodeMetadatas[dstAddressID]; !ok {
r.Address.NodeMetadatas[dstAddressID] = report.MakeNodeMetadataWith(map[string]string{
"name": dst,
})
r.Address.NodeMetadatas[dstAddressID] = report.NodeMetadata{
Metadata: map[string]string{
"name": dst,
},
Adjacency: report.MakeIDList(srcAddressID),
}
}
r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)
// Host data
r.Host.NodeMetadatas["hostX"] = report.MakeNodeMetadataWith(map[string]string{
-2
View File
@@ -50,7 +50,6 @@ var (
func TestReporter(t *testing.T) {
want := report.MakeReport()
want.Container = report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeContainerNodeID("", "ping"): report.MakeNodeMetadataWith(map[string]string{
@@ -61,7 +60,6 @@ func TestReporter(t *testing.T) {
},
}
want.ContainerImage = report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeContainerNodeID("", "baz"): report.MakeNodeMetadataWith(map[string]string{
+40 -38
View File
@@ -125,37 +125,45 @@ func (r *Reporter) Report() (report.Report, error) {
}
func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr string, localPort, remotePort uint16, proc *procspy.Proc) {
localIsClient := int(localPort) > int(remotePort)
var (
localIsClient = int(localPort) > int(remotePort)
hostNodeID = report.MakeHostNodeID(r.hostID)
addNode = func(t report.Topology, nodeID string, nmd report.NodeMetadata) {
if existing, ok := t.NodeMetadatas[nodeID]; ok {
nmd = nmd.Merge(existing)
}
t.NodeMetadatas[nodeID] = nmd
}
)
// Update address topology
{
var (
localAddressNodeID = report.MakeAddressNodeID(r.hostID, localAddr)
remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, remoteAddr)
adjacencyID = ""
edgeID = ""
localNode = report.MakeNodeMetadataWith(map[string]string{
"name": r.hostName,
Addr: localAddr,
report.HostNodeID: hostNodeID,
})
remoteNode = report.MakeNodeMetadataWith(map[string]string{
Addr: remoteAddr,
})
)
if localIsClient {
adjacencyID = report.MakeAdjacencyID(localAddressNodeID)
rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(remoteAddressNodeID)
localNode.Adjacency = localNode.Adjacency.Add(remoteAddressNodeID)
edgeID = report.MakeEdgeID(localAddressNodeID, remoteAddressNodeID)
} else {
adjacencyID = report.MakeAdjacencyID(remoteAddressNodeID)
rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(localAddressNodeID)
remoteNode.Adjacency = localNode.Adjacency.Add(localAddressNodeID)
edgeID = report.MakeEdgeID(remoteAddressNodeID, localAddressNodeID)
}
addNode(rpt.Address, localAddressNodeID, localNode)
addNode(rpt.Address, remoteAddressNodeID, remoteNode)
countTCPConnection(rpt.Address.EdgeMetadatas, edgeID)
if _, ok := rpt.Address.NodeMetadatas[localAddressNodeID]; !ok {
rpt.Address.NodeMetadatas[localAddressNodeID] = report.MakeNodeMetadataWith(map[string]string{
"name": r.hostName,
Addr: localAddr,
})
}
}
// Update endpoint topology
@@ -163,40 +171,34 @@ func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr strin
var (
localEndpointNodeID = report.MakeEndpointNodeID(r.hostID, localAddr, strconv.Itoa(int(localPort)))
remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, remoteAddr, strconv.Itoa(int(remotePort)))
adjacencyID = ""
edgeID = ""
localNode = report.MakeNodeMetadataWith(map[string]string{
Addr: localAddr,
Port: strconv.Itoa(int(localPort)),
report.HostNodeID: hostNodeID,
})
remoteNode = report.MakeNodeMetadataWith(map[string]string{
Addr: remoteAddr,
Port: strconv.Itoa(int(remotePort)),
})
)
if localIsClient {
adjacencyID = report.MakeAdjacencyID(localEndpointNodeID)
rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(remoteEndpointNodeID)
localNode.Adjacency = localNode.Adjacency.Add(remoteEndpointNodeID)
edgeID = report.MakeEdgeID(localEndpointNodeID, remoteEndpointNodeID)
} else {
adjacencyID = report.MakeAdjacencyID(remoteEndpointNodeID)
rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(localEndpointNodeID)
remoteNode.Adjacency = remoteNode.Adjacency.Add(localEndpointNodeID)
edgeID = report.MakeEdgeID(remoteEndpointNodeID, localEndpointNodeID)
}
countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID)
md, ok := rpt.Endpoint.NodeMetadatas[localEndpointNodeID]
updated := !ok
if !ok {
md = report.MakeNodeMetadataWith(map[string]string{
Addr: localAddr,
Port: strconv.Itoa(int(localPort)),
})
}
if proc != nil && proc.PID > 0 {
pid := strconv.FormatUint(uint64(proc.PID), 10)
updated = updated || md.Metadata[process.PID] != pid
md.Metadata[process.PID] = pid
}
if updated {
rpt.Endpoint.NodeMetadatas[localEndpointNodeID] = md
localNode.Metadata[process.PID] = strconv.FormatUint(uint64(proc.PID), 10)
}
addNode(rpt.Endpoint, localEndpointNodeID, localNode)
addNode(rpt.Endpoint, remoteEndpointNodeID, remoteNode)
countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID)
}
}
+9 -11
View File
@@ -77,25 +77,24 @@ func TestSpyNoProcesses(t *testing.T) {
//t.Logf("\n%s\n", buf)
// No process nodes, please
if want, have := 0, len(r.Endpoint.Adjacency); want != have {
if want, have := 0, len(r.Endpoint.NodeMetadatas); want != have {
t.Fatalf("want %d, have %d", want, have)
}
var (
scopedLocal = report.MakeAddressNodeID(nodeID, fixLocalAddress.String())
scopedRemote = report.MakeAddressNodeID(nodeID, fixRemoteAddress.String())
remoteKey = report.MakeAdjacencyID(scopedRemote)
)
if want, have := 1, len(r.Address.Adjacency[remoteKey]); want != have {
t.Fatalf("want %d, have %d", want, have)
}
if want, have := scopedLocal, r.Address.Adjacency[remoteKey][0]; want != have {
if want, have := nodeName, r.Address.NodeMetadatas[scopedLocal].Metadata[docker.Name]; want != have {
t.Fatalf("want %q, have %q", want, have)
}
if want, have := nodeName, r.Address.NodeMetadatas[scopedLocal].Metadata[docker.Name]; want != have {
if want, have := 1, len(r.Address.NodeMetadatas[scopedRemote].Adjacency); want != have {
t.Fatalf("want %d, have %d", want, have)
}
if want, have := scopedLocal, r.Address.NodeMetadatas[scopedRemote].Adjacency[0]; want != have {
t.Fatalf("want %q, have %q", want, have)
}
}
@@ -115,14 +114,13 @@ func TestSpyWithProcesses(t *testing.T) {
var (
scopedLocal = report.MakeEndpointNodeID(nodeID, fixLocalAddress.String(), strconv.Itoa(int(fixLocalPort)))
scopedRemote = report.MakeEndpointNodeID(nodeID, fixRemoteAddress.String(), strconv.Itoa(int(fixRemotePort)))
remoteKey = report.MakeAdjacencyID(scopedRemote)
)
if want, have := 1, len(r.Endpoint.Adjacency[remoteKey]); want != have {
if want, have := 1, len(r.Endpoint.NodeMetadatas[scopedRemote].Adjacency); want != have {
t.Fatalf("want %d, have %d", want, have)
}
if want, have := scopedLocal, r.Endpoint.Adjacency[remoteKey][0]; want != have {
if want, have := scopedLocal, r.Endpoint.NodeMetadatas[scopedRemote].Adjacency[0]; want != have {
t.Fatalf("want %q, have %q", want, have)
}
+4 -1
View File
@@ -18,7 +18,10 @@ func NewTagger(hostID string) Tagger {
// Tag implements Tagger.
func (t Tagger) Tag(r report.Report) (report.Report, error) {
other := report.MakeNodeMetadataWith(map[string]string{report.HostNodeID: t.hostNodeID})
for _, topology := range r.Topologies() {
// Explicity don't tag Endpoints and Addresses - These topologies include pseudo nodes,
// and as such do their own host tagging
for _, topology := range []report.Topology{r.Process, r.Container, r.ContainerImage, r.Host, r.Overlay} {
for id, md := range topology.NodeMetadatas {
topology.NodeMetadatas[id] = md.Merge(other)
}
+2 -2
View File
@@ -17,12 +17,12 @@ func TestTagger(t *testing.T) {
)
r := report.MakeReport()
r.Endpoint.NodeMetadatas[endpointNodeID] = nodeMetadata
r.Process.NodeMetadatas[endpointNodeID] = nodeMetadata
want := nodeMetadata.Merge(report.MakeNodeMetadataWith(map[string]string{
report.HostNodeID: report.MakeHostNodeID(hostID),
}))
rpt, _ := host.NewTagger(hostID).Tag(r)
have := rpt.Endpoint.NodeMetadatas[endpointNodeID].Copy()
have := rpt.Process.NodeMetadatas[endpointNodeID].Copy()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
-1
View File
@@ -36,7 +36,6 @@ func TestWeaveTaggerOverlayTopology(t *testing.T) {
t.Fatal(err)
}
if want, have := (report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeOverlayNodeID(mockWeavePeerName): report.MakeNodeMetadataWith(map[string]string{
-1
View File
@@ -34,7 +34,6 @@ func TestReporter(t *testing.T) {
reporter := process.NewReporter(walker, "")
want := report.MakeReport()
want.Process = report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeProcessNodeID("", "1"): report.MakeNodeMetadataWith(map[string]string{
+21 -20
View File
@@ -250,21 +250,30 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) {
return
}
addAdjacency := func(t report.Topology, srcNodeID, dstNodeID string) {
srcNode, ok := t.NodeMetadatas[srcNodeID]
if !ok {
srcNode = report.MakeNodeMetadata()
}
srcNode.Adjacency = srcNode.Adjacency.Add(dstNodeID)
t.NodeMetadatas[srcNodeID] = srcNode
if _, ok := t.NodeMetadatas[dstNodeID]; !ok {
t.NodeMetadatas[dstNodeID] = report.MakeNodeMetadata()
}
}
// For sure, we can add to the address topology.
{
var (
srcNodeID = report.MakeAddressNodeID(s.hostID, localIP)
dstNodeID = report.MakeAddressNodeID(s.hostID, remoteIP)
edgeID = report.MakeEdgeID(srcNodeID, dstNodeID)
srcAdjacencyID = report.MakeAdjacencyID(srcNodeID)
srcNodeID = report.MakeAddressNodeID(s.hostID, localIP)
dstNodeID = report.MakeAddressNodeID(s.hostID, remoteIP)
edgeID = report.MakeEdgeID(srcNodeID, dstNodeID)
)
if _, ok := rpt.Address.NodeMetadatas[srcNodeID]; !ok {
rpt.Address.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata()
}
addAdjacency(rpt.Address, srcNodeID, dstNodeID)
emd := rpt.Address.EdgeMetadatas[edgeID]
if egress {
if emd.EgressPacketCount == nil {
emd.EgressPacketCount = new(uint64)
@@ -284,26 +293,20 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) {
}
*emd.IngressByteCount += uint64(p.Network)
}
rpt.Address.EdgeMetadatas[edgeID] = emd
rpt.Address.Adjacency[srcAdjacencyID] = rpt.Address.Adjacency[srcAdjacencyID].Add(dstNodeID)
}
// If we have ports, we can add to the endpoint topology, too.
if p.SrcPort != "" && p.DstPort != "" {
var (
srcNodeID = report.MakeEndpointNodeID(s.hostID, localIP, localPort)
dstNodeID = report.MakeEndpointNodeID(s.hostID, remoteIP, remotePort)
edgeID = report.MakeEdgeID(srcNodeID, dstNodeID)
srcAdjacencyID = report.MakeAdjacencyID(srcNodeID)
srcNodeID = report.MakeEndpointNodeID(s.hostID, localIP, localPort)
dstNodeID = report.MakeEndpointNodeID(s.hostID, remoteIP, remotePort)
edgeID = report.MakeEdgeID(srcNodeID, dstNodeID)
)
if _, ok := rpt.Endpoint.NodeMetadatas[srcNodeID]; !ok {
rpt.Endpoint.NodeMetadatas[srcNodeID] = report.MakeNodeMetadata()
}
addAdjacency(rpt.Endpoint, srcNodeID, dstNodeID)
emd := rpt.Endpoint.EdgeMetadatas[edgeID]
if egress {
if emd.EgressPacketCount == nil {
emd.EgressPacketCount = new(uint64)
@@ -323,8 +326,6 @@ func (s *Sniffer) Merge(p Packet, rpt report.Report) {
}
*emd.IngressByteCount += uint64(p.Transport)
}
rpt.Endpoint.EdgeMetadatas[edgeID] = emd
rpt.Endpoint.Adjacency[srcAdjacencyID] = rpt.Endpoint.Adjacency[srcAdjacencyID].Add(dstNodeID)
}
}
+20 -12
View File
@@ -65,11 +65,6 @@ func TestMerge(t *testing.T) {
dstEndpointNodeID = report.MakeEndpointNodeID(hostID, p.DstIP, p.DstPort)
)
if want, have := (report.Topology{
Adjacency: report.Adjacency{
report.MakeAdjacencyID(srcEndpointNodeID): report.MakeIDList(
dstEndpointNodeID,
),
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(srcEndpointNodeID, dstEndpointNodeID): report.EdgeMetadata{
EgressPacketCount: newu64(1),
@@ -77,7 +72,16 @@ func TestMerge(t *testing.T) {
},
},
NodeMetadatas: report.NodeMetadatas{
srcEndpointNodeID: report.MakeNodeMetadata(),
srcEndpointNodeID: {
Metadata: map[string]string{},
Counters: map[string]int{},
Adjacency: report.MakeIDList(dstEndpointNodeID),
},
dstEndpointNodeID: report.NodeMetadata{
Metadata: map[string]string{},
Counters: map[string]int{},
Adjacency: report.MakeIDList(),
},
},
}), rpt.Endpoint; !reflect.DeepEqual(want, have) {
t.Errorf("%s", test.Diff(want, have))
@@ -88,11 +92,6 @@ func TestMerge(t *testing.T) {
dstAddressNodeID = report.MakeAddressNodeID(hostID, p.DstIP)
)
if want, have := (report.Topology{
Adjacency: report.Adjacency{
report.MakeAdjacencyID(srcAddressNodeID): report.MakeIDList(
dstAddressNodeID,
),
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(srcAddressNodeID, dstAddressNodeID): report.EdgeMetadata{
EgressPacketCount: newu64(1),
@@ -100,7 +99,16 @@ func TestMerge(t *testing.T) {
},
},
NodeMetadatas: report.NodeMetadatas{
srcAddressNodeID: report.MakeNodeMetadata(),
srcAddressNodeID: report.NodeMetadata{
Metadata: map[string]string{},
Counters: map[string]int{},
Adjacency: report.MakeIDList(dstAddressNodeID),
},
dstAddressNodeID: report.NodeMetadata{
Metadata: map[string]string{},
Counters: map[string]int{},
Adjacency: report.MakeIDList(),
},
},
}), rpt.Address; !reflect.DeepEqual(want, have) {
t.Errorf("%s", test.Diff(want, have))
+4 -8
View File
@@ -219,8 +219,7 @@ func connectionDetailsRows(topology report.Topology, originID string) []Row {
return rows
}
// Firstly, collection outgoing connections from this node.
originAdjID := report.MakeAdjacencyID(originID)
for _, serverNodeID := range topology.Adjacency[originAdjID] {
for _, serverNodeID := range topology.NodeMetadatas[originID].Adjacency {
remote, ok := labeler(serverNodeID)
if !ok {
continue
@@ -232,17 +231,14 @@ func connectionDetailsRows(topology report.Topology, originID string) []Row {
})
}
// Next, scan the topology for incoming connections to this node.
for clientAdjID, serverNodeIDs := range topology.Adjacency {
if clientAdjID == originAdjID {
for clientNodeID, clientNodeMetadata := range topology.NodeMetadatas {
if clientNodeID == originID {
continue
}
serverNodeIDs := clientNodeMetadata.Adjacency
if !serverNodeIDs.Contains(originID) {
continue
}
clientNodeID, ok := report.ParseAdjacencyID(clientAdjID)
if !ok {
continue
}
remote, ok := labeler(clientNodeID)
if !ok {
continue
+4 -4
View File
@@ -176,19 +176,19 @@ func TestMakeDetailedContainerNode(t *testing.T) {
{"Egress byte rate", "1.0", "KBps", false},
{"Client", "Server", "", true},
{
fmt.Sprintf("%s:%s", test.UnknownClient1IP, test.ClientPort54010),
fmt.Sprintf("%s:%s", test.UnknownClient1IP, test.UnknownClient1Port),
fmt.Sprintf("%s:%s", test.ServerIP, test.ServerPort),
"",
true,
},
{
fmt.Sprintf("%s:%s", test.UnknownClient1IP, test.ClientPort54020),
fmt.Sprintf("%s:%s", test.UnknownClient2IP, test.UnknownClient2Port),
fmt.Sprintf("%s:%s", test.ServerIP, test.ServerPort),
"",
true,
},
{
fmt.Sprintf("%s:%s", test.UnknownClient3IP, test.ClientPort54020),
fmt.Sprintf("%s:%s", test.UnknownClient3IP, test.UnknownClient3Port),
fmt.Sprintf("%s:%s", test.ServerIP, test.ServerPort),
"",
true,
@@ -206,7 +206,7 @@ func TestMakeDetailedContainerNode(t *testing.T) {
true,
},
{
fmt.Sprintf("%s:%s", test.RandomClientIP, test.ClientPort12345),
fmt.Sprintf("%s:%s", test.RandomClientIP, test.RandomClientPort),
fmt.Sprintf("%s:%s", test.ServerIP, test.ServerPort),
"",
true,
+6 -6
View File
@@ -323,8 +323,8 @@ var (
ServerHostRenderedID = render.MakeHostID(test.ServerHostID)
ClientHostRenderedID = render.MakeHostID(test.ClientHostID)
pseudoHostID1 = render.MakePseudoNodeID("10.10.10.10", "192.168.1.1", "")
pseudoHostID2 = render.MakePseudoNodeID("10.10.10.11", "192.168.1.1", "")
pseudoHostID1 = render.MakePseudoNodeID(test.UnknownClient1IP, test.ServerIP)
pseudoHostID2 = render.MakePseudoNodeID(test.UnknownClient3IP, test.ServerIP)
RenderedHosts = render.RenderableNodes{
ServerHostRenderedID: {
@@ -361,21 +361,21 @@ var (
},
pseudoHostID1: {
ID: pseudoHostID1,
LabelMajor: "10.10.10.10",
LabelMajor: test.UnknownClient1IP,
Pseudo: true,
Adjacency: report.MakeIDList(ServerHostRenderedID),
NodeMetadata: report.MakeNodeMetadata(),
EdgeMetadata: report.EdgeMetadata{},
Origins: report.MakeIDList(test.UnknownAddress1NodeID),
Origins: report.MakeIDList(test.UnknownAddress1NodeID, test.UnknownAddress2NodeID),
},
pseudoHostID2: {
ID: pseudoHostID2,
LabelMajor: "10.10.10.11",
LabelMajor: test.UnknownClient3IP,
Pseudo: true,
Adjacency: report.MakeIDList(ServerHostRenderedID),
NodeMetadata: report.MakeNodeMetadata(),
EdgeMetadata: report.EdgeMetadata{},
Origins: report.MakeIDList(test.UnknownAddress2NodeID),
Origins: report.MakeIDList(test.UnknownAddress3NodeID),
},
render.TheInternetID: {
ID: render.TheInternetID,
+56 -66
View File
@@ -3,6 +3,7 @@ package render
import (
"fmt"
"net"
"strconv"
"strings"
"github.com/weaveworks/scope/probe/docker"
@@ -31,14 +32,7 @@ const (
//
// A single NodeMetadata can yield arbitrary many representations, including
// representations that reduce (or even increase) the cardinality of the set of nodes.
type LeafMapFunc func(report.NodeMetadata) RenderableNodes
// PseudoFunc creates RenderableNode representing pseudo nodes given the
// srcNodeID. dstNodeID is the node id of one of the nodes this node has an
// edge to. srcNodeID and dstNodeID are node IDs prior to mapping. srcIsClient
// indicates the direction of the edge to dstNodeID - true indicates srcNodeID
// is the client, false indicates dstNodeID is the server.
type PseudoFunc func(srcNodeID, dstNodeID string, srcIsClient bool, local report.Networks) (RenderableNode, bool)
type LeafMapFunc func(report.NodeMetadata, report.Networks) RenderableNodes
// MapFunc is anything which can take an arbitrary RenderableNode and
// return a set of other RenderableNodes.
@@ -50,7 +44,7 @@ type MapFunc func(RenderableNode) RenderableNodes
// MapEndpointIdentity maps an endpoint topology node to a single endpoint
// renderable node. As it is only ever run on endpoint topology nodes, we
// expect that certain keys are present.
func MapEndpointIdentity(m report.NodeMetadata) RenderableNodes {
func MapEndpointIdentity(m report.NodeMetadata, local report.Networks) RenderableNodes {
addr, ok := m.Metadata[endpoint.Addr]
if !ok {
return RenderableNodes{}
@@ -61,6 +55,34 @@ func MapEndpointIdentity(m report.NodeMetadata) RenderableNodes {
return RenderableNodes{}
}
// Nodes without a hostid are treated as psuedo nodes
_, ok = m.Metadata[report.HostNodeID]
if !ok {
// If the dstNodeAddr is not in a network local to this report, we emit an
// internet node
if !local.Contains(net.ParseIP(addr)) {
return RenderableNodes{TheInternetID: newPseudoNode(TheInternetID, TheInternetMajor, "")}
}
// We are a 'client' pseudo node if the port is in the ephemeral port range.
// Linux uses 32768 to 61000.
if p, err := strconv.Atoi(port); err == nil && p >= 32768 && p < 61000 {
// We only exist if there is something in our adjacency
// Generate a single pseudo node for every (client ip, server ip, server port)
dstNodeID := m.Adjacency[0]
serverIP, serverPort := trySplitAddr(dstNodeID)
outputID := MakePseudoNodeID(addr, serverIP, serverPort)
return RenderableNodes{outputID: newPseudoNode(outputID, addr, "")}
}
// Otherwise (the server node is missing), generate a pseudo node for every (server ip, server port)
outputID := MakePseudoNodeID(addr, port)
if port != "" {
return RenderableNodes{outputID: newPseudoNode(outputID, addr+":"+port, "")}
}
return RenderableNodes{outputID: newPseudoNode(outputID, addr, "")}
}
var (
id = MakeEndpointID(report.ExtractHostID(m), addr, port)
major = fmt.Sprintf("%s:%s", addr, port)
@@ -78,7 +100,7 @@ func MapEndpointIdentity(m report.NodeMetadata) RenderableNodes {
// MapProcessIdentity maps a process topology node to a process renderable
// node. As it is only ever run on process topology nodes, we expect that
// certain keys are present.
func MapProcessIdentity(m report.NodeMetadata) RenderableNodes {
func MapProcessIdentity(m report.NodeMetadata, _ report.Networks) RenderableNodes {
pid, ok := m.Metadata[process.PID]
if !ok {
return RenderableNodes{}
@@ -97,7 +119,7 @@ func MapProcessIdentity(m report.NodeMetadata) RenderableNodes {
// MapContainerIdentity maps a container topology node to a container
// renderable node. As it is only ever run on container topology nodes, we
// expect that certain keys are present.
func MapContainerIdentity(m report.NodeMetadata) RenderableNodes {
func MapContainerIdentity(m report.NodeMetadata, _ report.Networks) RenderableNodes {
id, ok := m.Metadata[docker.ContainerID]
if !ok {
return RenderableNodes{}
@@ -115,7 +137,7 @@ func MapContainerIdentity(m report.NodeMetadata) RenderableNodes {
// MapContainerImageIdentity maps a container image topology node to container
// image renderable node. As it is only ever run on container image topology
// nodes, we expect that certain keys are present.
func MapContainerImageIdentity(m report.NodeMetadata) RenderableNodes {
func MapContainerImageIdentity(m report.NodeMetadata, _ report.Networks) RenderableNodes {
id, ok := m.Metadata[docker.ImageID]
if !ok {
return RenderableNodes{}
@@ -132,12 +154,27 @@ func MapContainerImageIdentity(m report.NodeMetadata) RenderableNodes {
// MapAddressIdentity maps an address topology node to an address renderable
// node. As it is only ever run on address topology nodes, we expect that
// certain keys are present.
func MapAddressIdentity(m report.NodeMetadata) RenderableNodes {
func MapAddressIdentity(m report.NodeMetadata, local report.Networks) RenderableNodes {
addr, ok := m.Metadata[endpoint.Addr]
if !ok {
return RenderableNodes{}
}
// Nodes without a hostid are treated as psuedo nodes
_, ok = m.Metadata[report.HostNodeID]
if !ok {
// If the addr is not in a network local to this report, we emit an
// internet node
if !local.Contains(net.ParseIP(addr)) {
return RenderableNodes{TheInternetID: newPseudoNode(TheInternetID, TheInternetMajor, "")}
}
// Otherwise generate a pseudo node for every
_, dstID, _ := report.ParseAddressNodeID(m.Adjacency[0])
outputID := MakePseudoNodeID(addr, dstID)
return RenderableNodes{outputID: newPseudoNode(outputID, addr, "")}
}
var (
id = MakeAddressID(report.ExtractHostID(m), addr)
major = addr
@@ -151,7 +188,7 @@ func MapAddressIdentity(m report.NodeMetadata) RenderableNodes {
// MapHostIdentity maps a host topology node to a host renderable node. As it
// is only ever run on host topology nodes, we expect that certain keys are
// present.
func MapHostIdentity(m report.NodeMetadata) RenderableNodes {
func MapHostIdentity(m report.NodeMetadata, _ report.Networks) RenderableNodes {
var (
id = MakeHostID(report.ExtractHostID(m))
hostname = m.Metadata[host.HostName]
@@ -172,7 +209,7 @@ func MapHostIdentity(m report.NodeMetadata) RenderableNodes {
// with container nodes. We drop endpoint nodes with pids, as they
// will be joined to containers through the process topology, and we
// don't want to double count edges.
func MapEndpoint2IP(m report.NodeMetadata) RenderableNodes {
func MapEndpoint2IP(m report.NodeMetadata, local report.Networks) RenderableNodes {
_, ok := m.Metadata[process.PID]
if ok {
return RenderableNodes{}
@@ -181,26 +218,16 @@ func MapEndpoint2IP(m report.NodeMetadata) RenderableNodes {
if !ok {
return RenderableNodes{}
}
return RenderableNodes{addr: NewRenderableNode(addr, "", "", "", m)}
}
// IPPseudoNode maps endpoint pseudo nodes to regular IP address nodes, or
// the internet node.
func IPPseudoNode(srcNodeID, _ string, _ bool, local report.Networks) (RenderableNode, bool) {
// Use the addresser to extract the IP of the missing node
srcNodeAddr := report.EndpointIDAddresser(srcNodeID)
// If the dstNodeAddr is not in a network local to this report, we emit an
// internet node
if !local.Contains(srcNodeAddr) {
return newPseudoNode(TheInternetID, TheInternetMajor, ""), true
if !local.Contains(net.ParseIP(addr)) {
return RenderableNodes{TheInternetID: newPseudoNode(TheInternetID, TheInternetMajor, "")}
}
return NewRenderableNode(srcNodeAddr.String(), "", "", "", report.MakeNodeMetadata()), true
return RenderableNodes{addr: NewRenderableNode(addr, "", "", "", m)}
}
// MapContainer2IP maps container nodes to their IP addresses (outputs
// multiple nodes). This allows container to be joined directly with
// the endpoint topology.
func MapContainer2IP(m report.NodeMetadata) RenderableNodes {
func MapContainer2IP(m report.NodeMetadata, _ report.Networks) RenderableNodes {
result := RenderableNodes{}
addrs, ok := m.Metadata[docker.ContainerIPs]
if !ok {
@@ -430,43 +457,6 @@ func MapAddress2Host(n RenderableNode) RenderableNodes {
return RenderableNodes{id: newDerivedNode(id, n)}
}
// GenericPseudoNode makes a PseudoFunc given an addresser. The returned
// PseudoFunc will produce Internet pseudo nodes for addresses not in
// the report's local networks. Otherwise, the returned function will
// produce a single pseudo node per (dst address, src address, src port).
func GenericPseudoNode(addresser func(id string) net.IP) PseudoFunc {
return func(srcNodeID, dstNodeID string, srcIsClient bool, local report.Networks) (RenderableNode, bool) {
// Use the addresser to extract the IP of the missing node
srcNodeAddr := addresser(srcNodeID)
// If the dstNodeAddr is not in a network local to this report, we emit an
// internet node
if !local.Contains(srcNodeAddr) {
return newPseudoNode(TheInternetID, TheInternetMajor, ""), true
}
if srcIsClient {
// If the client node is missing, generate a single pseudo node for every (client ip, server ip, server port)
serverIP, serverPort := trySplitAddr(dstNodeID)
outputID := MakePseudoNodeID(srcNodeAddr.String(), serverIP, serverPort)
major := srcNodeAddr.String()
return newPseudoNode(outputID, major, ""), true
}
// Otherwise (the server node is missing), generate a pseudo node for every (server ip, server port)
serverIP, serverPort := trySplitAddr(srcNodeID)
outputID := MakePseudoNodeID(serverIP, serverPort)
if serverPort != "" {
return newPseudoNode(outputID, serverIP+":"+serverPort, ""), true
}
return newPseudoNode(outputID, serverIP, ""), true
}
}
// PanicPseudoNode just panics; it is for Topologies without edges
func PanicPseudoNode(src, dst string, isClient bool, local report.Networks) (RenderableNode, bool) {
panic(src)
}
// trySplitAddr is basically ParseArbitraryNodeID, since its callsites
// (pseudo funcs) just have opaque node IDs and don't know what topology they
// come from. Without changing how pseudo funcs work, we can't make it much
+1 -1
View File
@@ -72,7 +72,7 @@ type testcase struct {
}
func testMap(t *testing.T, f render.LeafMapFunc, input testcase) {
if have := f(input.md); input.ok != (len(have) > 0) {
if have := f(input.md, report.Networks{}); input.ok != (len(have) > 0) {
t.Errorf("%v: want %v, have %v", input.md, input.ok, have)
}
}
+19 -57
View File
@@ -130,7 +130,6 @@ func (m Map) EdgeMetadata(rpt report.Report, srcRenderableID, dstRenderableID st
type LeafMap struct {
Selector report.TopologySelector
Mapper LeafMapFunc
Pseudo PseudoFunc
}
// Render transforms a given Report into a set of RenderableNodes, which
@@ -142,15 +141,16 @@ func (m LeafMap) Render(rpt report.Report) RenderableNodes {
var (
t = m.Selector(rpt)
nodes = RenderableNodes{}
source2mapped = map[string]report.IDList{} // input node ID -> output node IDs
adjacencies = map[string]report.IDList{} // input node ID -> input node Adjacencies
localNetworks = LocalNetworks(rpt)
)
// Build a set of RenderableNodes for all non-pseudo probes, and an
// addressID to nodeID lookup map. Multiple addressIDs can map to the same
// RenderableNodes.
source2mapped := map[string]report.IDList{} // source node ID -> mapped node IDs
for nodeID, metadata := range t.NodeMetadatas {
for _, mapped := range m.Mapper(metadata) {
for _, mapped := range m.Mapper(metadata, localNetworks) {
// mapped.ID needs not be unique over all addressIDs. If not, we merge with
// the existing data, on the assumption that the MapFunc returns the same
// data.
@@ -161,66 +161,25 @@ func (m LeafMap) Render(rpt report.Report) RenderableNodes {
origins := mapped.Origins
origins = origins.Add(nodeID)
origins = origins.Add(metadata.Metadata[report.HostNodeID])
if hostNodeID, ok := metadata.Metadata[report.HostNodeID]; ok {
origins = origins.Add(hostNodeID)
}
mapped.Origins = origins
nodes[mapped.ID] = mapped
source2mapped[nodeID] = source2mapped[nodeID].Add(mapped.ID)
adjacencies[nodeID] = metadata.Adjacency
}
}
mkPseudoNode := func(srcNodeID, dstNodeID string, srcIsClient bool) report.IDList {
pseudoNode, ok := m.Pseudo(srcNodeID, dstNodeID, srcIsClient, localNetworks)
if !ok {
return report.MakeIDList()
}
pseudoNode.Origins = pseudoNode.Origins.Add(srcNodeID)
existing, ok := nodes[pseudoNode.ID]
if ok {
pseudoNode.Merge(existing)
}
nodes[pseudoNode.ID] = pseudoNode
source2mapped[pseudoNode.ID] = source2mapped[pseudoNode.ID].Add(srcNodeID)
return report.MakeIDList(pseudoNode.ID)
}
// Walk the graph and make connections.
for src, dsts := range t.Adjacency {
srcNodeID, ok := report.ParseAdjacencyID(src)
if !ok {
log.Printf("bad adjacency ID %q", src)
continue
}
srcRenderableIDs, ok := source2mapped[srcNodeID]
if !ok {
// One of the entries in dsts must be a non-pseudo node, unless
// it was dropped by the mapping function.
for _, dstNodeID := range dsts {
if _, ok := source2mapped[dstNodeID]; ok {
srcRenderableIDs = mkPseudoNode(srcNodeID, dstNodeID, true)
break
}
}
}
if len(srcRenderableIDs) == 0 {
continue
}
for _, srcRenderableID := range srcRenderableIDs {
for srcNodeID, dstNodeIDs := range adjacencies {
for _, srcRenderableID := range source2mapped[srcNodeID] {
srcRenderableNode := nodes[srcRenderableID]
for _, dstNodeID := range dsts {
dstRenderableIDs, ok := source2mapped[dstNodeID]
if !ok {
dstRenderableIDs = mkPseudoNode(dstNodeID, srcNodeID, false)
}
if len(dstRenderableIDs) == 0 {
continue
}
for _, dstRenderableID := range dstRenderableIDs {
for _, dstNodeID := range dstNodeIDs {
for _, dstRenderableID := range source2mapped[dstNodeID] {
dstRenderableNode := nodes[dstRenderableID]
srcRenderableNode.Adjacency = srcRenderableNode.Adjacency.Add(dstRenderableID)
// We propagate edge metadata to nodes on both ends of the edges.
@@ -253,8 +212,11 @@ func ids(nodes RenderableNodes) report.IDList {
// level, it uses the supplied mapping function to translate address IDs to
// renderable node (mapped) IDs.
func (m LeafMap) EdgeMetadata(rpt report.Report, srcRenderableID, dstRenderableID string) report.EdgeMetadata {
t := m.Selector(rpt)
metadata := report.EdgeMetadata{}
var (
t = m.Selector(rpt)
localNetworks = LocalNetworks(rpt)
metadata = report.EdgeMetadata{}
)
for edgeID, edgeMeta := range t.EdgeMetadatas {
src, dst, ok := report.ParseEdgeID(edgeID)
if !ok {
@@ -263,11 +225,11 @@ func (m LeafMap) EdgeMetadata(rpt report.Report, srcRenderableID, dstRenderableI
}
srcs, dsts := report.MakeIDList(src), report.MakeIDList(dst)
if src != report.TheInternet {
mapped := m.Mapper(t.NodeMetadatas[src])
mapped := m.Mapper(t.NodeMetadatas[src], localNetworks)
srcs = ids(mapped)
}
if dst != report.TheInternet {
mapped := m.Mapper(t.NodeMetadatas[dst])
mapped := m.Mapper(t.NodeMetadatas[dst], localNetworks)
dsts = ids(mapped)
}
if srcs.Contains(srcRenderableID) && dsts.Contains(dstRenderableID) {
+18 -8
View File
@@ -112,12 +112,14 @@ func TestMapEdge(t *testing.T) {
selector := func(_ report.Report) report.Topology {
return report.Topology{
NodeMetadatas: report.NodeMetadatas{
"foo": report.MakeNodeMetadataWith(map[string]string{"id": "foo"}),
"bar": report.MakeNodeMetadataWith(map[string]string{"id": "bar"}),
},
Adjacency: report.Adjacency{
">foo": report.MakeIDList("bar"),
">bar": report.MakeIDList("foo"),
"foo": {
Metadata: map[string]string{"id": "foo"},
Adjacency: report.MakeIDList("bar"),
},
"bar": {
Metadata: map[string]string{"id": "bar"},
Adjacency: report.MakeIDList("foo"),
},
},
EdgeMetadatas: report.EdgeMetadatas{
"foo|bar": report.EdgeMetadata{EgressPacketCount: newu64(1), EgressByteCount: newu64(2)},
@@ -126,7 +128,7 @@ func TestMapEdge(t *testing.T) {
}
}
identity := func(nmd report.NodeMetadata) render.RenderableNodes {
identity := func(nmd report.NodeMetadata, _ report.Networks) render.RenderableNodes {
return render.RenderableNodes{nmd.Metadata["id"]: render.NewRenderableNode(nmd.Metadata["id"], "", "", "", nmd)}
}
@@ -138,10 +140,18 @@ func TestMapEdge(t *testing.T) {
Renderer: render.LeafMap{
Selector: selector,
Mapper: identity,
Pseudo: nil,
},
}
have := mapper.Render(report.MakeReport())
want := render.RenderableNodes{
"_foo": {ID: "_foo", Adjacency: report.MakeIDList("_bar")},
"_bar": {ID: "_bar", Adjacency: report.MakeIDList("_foo")},
}
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
if want, have := (report.EdgeMetadata{
EgressPacketCount: newu64(1),
EgressByteCount: newu64(2),
+4 -1
View File
@@ -44,7 +44,10 @@ func sterilize(r render.RenderableNodes, destructive bool) render.RenderableNode
// case where we explicitly don't compare node metadata.
for id, n := range r {
if n.Adjacency == nil {
n.Adjacency = report.IDList{}
n.Adjacency = report.MakeIDList()
}
if destructive || n.NodeMetadata.Adjacency == nil {
n.NodeMetadata.Adjacency = report.MakeIDList()
}
if destructive || n.NodeMetadata.Metadata == nil {
n.NodeMetadata.Metadata = map[string]string{}
-9
View File
@@ -12,7 +12,6 @@ import (
var EndpointRenderer = LeafMap{
Selector: report.SelectEndpoint,
Mapper: MapEndpointIdentity,
Pseudo: GenericPseudoNode(report.EndpointIDAddresser),
}
// ProcessRenderer is a Renderer which produces a renderable process
@@ -25,7 +24,6 @@ var ProcessRenderer = MakeReduce(
LeafMap{
Selector: report.SelectProcess,
Mapper: MapProcessIdentity,
Pseudo: PanicPseudoNode,
},
)
@@ -40,7 +38,6 @@ func (r ProcessWithContainerNameRenderer) Render(rpt report.Report) RenderableNo
containers := LeafMap{
Selector: report.SelectContainer,
Mapper: MapContainerIdentity,
Pseudo: PanicPseudoNode,
}.Render(rpt)
for id, p := range processes {
@@ -103,7 +100,6 @@ var ContainerRenderer = MakeReduce(
LeafMap{
Selector: report.SelectContainer,
Mapper: MapContainerIdentity,
Pseudo: PanicPseudoNode,
},
// This mapper brings in short lived connections by joining with container IPs.
@@ -117,12 +113,10 @@ var ContainerRenderer = MakeReduce(
LeafMap{
Selector: report.SelectContainer,
Mapper: MapContainer2IP,
Pseudo: PanicPseudoNode,
},
LeafMap{
Selector: report.SelectEndpoint,
Mapper: MapEndpoint2IP,
Pseudo: IPPseudoNode,
},
),
),
@@ -143,7 +137,6 @@ var ContainerImageRenderer = Map{
LeafMap{
Selector: report.SelectContainerImage,
Mapper: MapContainerImageIdentity,
Pseudo: PanicPseudoNode,
},
),
},
@@ -154,7 +147,6 @@ var ContainerImageRenderer = Map{
var AddressRenderer = LeafMap{
Selector: report.SelectAddress,
Mapper: MapAddressIdentity,
Pseudo: GenericPseudoNode(report.AddressIDAddresser),
}
// HostRenderer is a Renderer which produces a renderable host
@@ -167,6 +159,5 @@ var HostRenderer = MakeReduce(
LeafMap{
Selector: report.SelectHost,
Mapper: MapHostIdentity,
Pseudo: PanicPseudoNode,
},
)
-36
View File
@@ -21,19 +21,6 @@ const (
EdgeDelim = "|"
)
// MakeAdjacencyID produces an adjacency ID from a node id.
func MakeAdjacencyID(srcNodeID string) string {
return ">" + srcNodeID
}
// ParseAdjacencyID produces a node ID from an adjancency ID.
func ParseAdjacencyID(adjacencyID string) (string, bool) {
if !strings.HasPrefix(adjacencyID, ">") {
return "", false
}
return adjacencyID[1:], true
}
// MakeEdgeID produces an edge ID from composite parts.
func MakeEdgeID(srcNodeID, dstNodeID string) string {
return srcNodeID + EdgeDelim + dstNodeID
@@ -129,29 +116,6 @@ func ExtractHostID(m NodeMetadata) string {
return hostid
}
// IDAddresser tries to convert a node ID to a net.IP, if possible.
type IDAddresser func(string) net.IP
// EndpointIDAddresser converts an endpoint node ID to an IP.
func EndpointIDAddresser(id string) net.IP {
fields := strings.SplitN(id, ScopeDelim, 3)
if len(fields) != 3 {
//log.Printf("EndpointIDAddresser: bad input %q", id)
return nil
}
return net.ParseIP(fields[1])
}
// AddressIDAddresser converts an address node ID to an IP.
func AddressIDAddresser(id string) net.IP {
fields := strings.SplitN(id, ScopeDelim, 2)
if len(fields) != 2 {
//log.Printf("AddressIDAddresser: bad input %q", id)
return nil
}
return net.ParseIP(fields[1])
}
func isLoopback(address string) bool {
ip := net.ParseIP(address)
return ip != nil && ip.IsLoopback()
+7 -9
View File
@@ -21,15 +21,6 @@ func MakeIDList(ids ...string) IDList {
return IDList(ids)
}
// Copy returns a copy of the IDList.
func (a IDList) Copy() IDList {
cp := make(IDList, len(a))
for i, s := range a {
cp[i] = s
}
return cp
}
// Add is the only correct way to add ids to an IDList.
func (a IDList) Add(ids ...string) IDList {
for _, s := range ids {
@@ -46,6 +37,13 @@ func (a IDList) Add(ids ...string) IDList {
return a
}
// Copy returns a copy of the IDList.
func (a IDList) Copy() IDList {
result := make(IDList, len(a))
copy(result, a)
return result
}
// Merge all elements from a and b into a new list
func (a IDList) Merge(b IDList) IDList {
if len(b) == 0 { // Optimise special case, to avoid allocating
-73
View File
@@ -1,8 +1,6 @@
package report_test
import (
"net"
"reflect"
"testing"
"github.com/weaveworks/scope/report"
@@ -32,49 +30,6 @@ var (
unknownAddressNodeID = report.MakeAddressNodeID(unknownHostID, unknownAddress)
)
func TestAdjacencyID(t *testing.T) {
for _, bad := range []string{
client54001EndpointNodeID,
client54002EndpointNodeID,
unknown1EndpointNodeID,
unknown2EndpointNodeID,
unknown3EndpointNodeID,
clientAddressNodeID,
serverAddressNodeID,
unknownAddressNodeID,
clientHostNodeID,
serverHostNodeID,
";",
"",
} {
if srcNodeID, ok := report.ParseAdjacencyID(bad); ok {
t.Errorf("%q: expected failure, but got (%q)", bad, srcNodeID)
}
}
for input, want := range map[string]struct{ srcNodeID string }{
report.MakeAdjacencyID(report.MakeEndpointNodeID("a", "b", "c")): {report.MakeEndpointNodeID("a", "b", "c")},
report.MakeAdjacencyID(report.MakeAddressNodeID("a", "b")): {report.MakeAddressNodeID("a", "b")},
report.MakeAdjacencyID(report.MakeProcessNodeID("a", "b")): {report.MakeProcessNodeID("a", "b")},
report.MakeAdjacencyID(report.MakeHostNodeID("a")): {report.MakeHostNodeID("a")},
">host.com;1.2.3.4": {"host.com;1.2.3.4"},
">a;b;c": {"a;b;c"},
">a;b": {"a;b"},
">a;": {"a;"},
">;b": {";b"},
">;": {";"},
} {
srcNodeID, ok := report.ParseAdjacencyID(input)
if !ok {
t.Errorf("%q: not OK", input)
continue
}
if want, have := want.srcNodeID, srcNodeID; want != have {
t.Errorf("%q: want %q, have %q", input, want, have)
}
}
}
func TestEndpointNodeID(t *testing.T) {
for _, bad := range []string{
clientAddressNodeID,
@@ -158,31 +113,3 @@ func TestEdgeID(t *testing.T) {
}
}
}
func TestEndpointIDAddresser(t *testing.T) {
if nodeID := "1.2.4.5"; report.EndpointIDAddresser(nodeID) != nil {
t.Errorf("%q: bad node ID parsed as good", nodeID)
}
var (
nodeID = report.MakeEndpointNodeID(clientHostID, clientAddress, "12345")
want = net.ParseIP(clientAddress)
have = report.EndpointIDAddresser(nodeID)
)
if !reflect.DeepEqual(want, have) {
t.Errorf("want %s, have %s", want, have)
}
}
func TestAddressIDAddresser(t *testing.T) {
if nodeID := "1.2.4.5"; report.AddressIDAddresser(nodeID) != nil {
t.Errorf("%q: bad node ID parsed as good", nodeID)
}
var (
nodeID = report.MakeAddressNodeID(clientHostID, clientAddress)
want = net.ParseIP(clientAddress)
have = report.AddressIDAddresser(nodeID)
)
if !reflect.DeepEqual(want, have) {
t.Errorf("want %s, have %s", want, have)
}
}
-89
View File
@@ -14,95 +14,6 @@ const (
Domain = "domain"
)
func TestMergeAdjacency(t *testing.T) {
for name, c := range map[string]struct {
a, b, want report.Adjacency
}{
"Empty b": {
a: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:80"),
"hostA|:192.168.1.1:8888": report.MakeIDList(":1.2.3.4:22"),
"hostB|:192.168.1.2:80": report.MakeIDList(":192.168.1.1:12345"),
},
b: report.Adjacency{},
want: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:80"),
"hostA|:192.168.1.1:8888": report.MakeIDList(":1.2.3.4:22"),
"hostB|:192.168.1.2:80": report.MakeIDList(":192.168.1.1:12345"),
},
},
"Empty a": {
a: report.Adjacency{},
b: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:80"),
"hostA|:192.168.1.1:8888": report.MakeIDList(":1.2.3.4:22"),
"hostB|:192.168.1.2:80": report.MakeIDList(":192.168.1.1:12345"),
},
want: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:80"),
"hostA|:192.168.1.1:8888": report.MakeIDList(":1.2.3.4:22"),
"hostB|:192.168.1.2:80": report.MakeIDList(":192.168.1.1:12345"),
},
},
"Same address": {
a: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:80"),
},
b: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(":192.168.1.2:8080"),
},
want: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(
":192.168.1.2:80", ":192.168.1.2:8080",
),
},
},
"No duplicates": {
a: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(
":192.168.1.2:80",
":192.168.1.2:8080",
":192.168.1.2:555",
),
},
b: report.Adjacency{
"hostA|:192.168.1.1:12345": report.MakeIDList(
":192.168.1.2:8080",
":192.168.1.2:80",
":192.168.1.2:444",
),
},
want: report.Adjacency{
"hostA|:192.168.1.1:12345": []string{
":192.168.1.2:444",
":192.168.1.2:555",
":192.168.1.2:80",
":192.168.1.2:8080",
},
},
},
"Double keys": {
a: report.Adjacency{
"key1": report.MakeIDList("a", "c", "d", "b"),
"key2": report.MakeIDList("c", "a"),
},
b: report.Adjacency{
"key1": report.MakeIDList("a", "b", "e"),
"key3": report.MakeIDList("e", "a", "a", "a", "e"),
},
want: report.Adjacency{
"key1": report.MakeIDList("a", "b", "c", "d", "e"),
"key2": report.MakeIDList("a", "c"),
"key3": report.MakeIDList("a", "e"),
},
},
} {
if have := c.a.Merge(c.b); !reflect.DeepEqual(c.want, have) {
t.Errorf("%s: want\n\t%#v\nhave\n\t%#v", name, c.want, have)
}
}
}
func TestMergeEdgeMetadatas(t *testing.T) {
for name, c := range map[string]struct {
a, b, want report.EdgeMetadatas
+25 -65
View File
@@ -6,10 +6,10 @@ import (
)
// Topology describes a specific view of a network. It consists of nodes and
// edges, represented by Adjacency, and metadata about those nodes and edges,
// represented by EdgeMetadatas and NodeMetadatas respectively.
// edges, and metadata about those nodes and edges, represented by EdgeMetadatas
// and NodeMetadatas respectively. Edges are directional, and embedded in the
// NodeMetadata.
type Topology struct {
Adjacency
EdgeMetadatas
NodeMetadatas
}
@@ -17,7 +17,6 @@ type Topology struct {
// MakeTopology gives you a Topology.
func MakeTopology() Topology {
return Topology{
Adjacency: map[string]IDList{},
EdgeMetadatas: map[string]EdgeMetadata{},
NodeMetadatas: map[string]NodeMetadata{},
}
@@ -26,7 +25,6 @@ func MakeTopology() Topology {
// Copy returns a value copy of the Topology.
func (t Topology) Copy() Topology {
return Topology{
Adjacency: t.Adjacency.Copy(),
EdgeMetadatas: t.EdgeMetadatas.Copy(),
NodeMetadatas: t.NodeMetadatas.Copy(),
}
@@ -36,35 +34,11 @@ func (t Topology) Copy() Topology {
// The original is not modified.
func (t Topology) Merge(other Topology) Topology {
return Topology{
Adjacency: t.Adjacency.Merge(other.Adjacency),
EdgeMetadatas: t.EdgeMetadatas.Merge(other.EdgeMetadatas),
NodeMetadatas: t.NodeMetadatas.Merge(other.NodeMetadatas),
}
}
// Adjacency is an adjacency-list encoding of the topology. Keys are adjacency
// IDs, values are lists of node IDs.
type Adjacency map[string]IDList
// Copy returns a value copy of the adjacency.
func (a Adjacency) Copy() Adjacency {
cp := make(Adjacency, len(a))
for k, v := range a {
cp[k] = v.Copy()
}
return cp
}
// Merge merges the other object into this one, and returns the result object.
// The original is not modified.
func (a Adjacency) Merge(other Adjacency) Adjacency {
cp := a.Copy()
for k, v := range other {
cp[k] = cp[k].Merge(v)
}
return cp
}
// EdgeMetadatas collect metadata about each edge in a topology. Keys are a
// concatenation of node IDs.
type EdgeMetadatas map[string]EdgeMetadata
@@ -173,8 +147,9 @@ func (e EdgeMetadata) Flatten(other EdgeMetadata) EdgeMetadata {
// NodeMetadata describes a superset of the metadata that probes can collect
// about a given node in a given topology.
type NodeMetadata struct {
Metadata map[string]string
Counters map[string]int
Metadata map[string]string
Counters map[string]int
Adjacency IDList
}
// MakeNodeMetadata creates a new NodeMetadata with no initial metadata.
@@ -185,8 +160,9 @@ func MakeNodeMetadata() NodeMetadata {
// MakeNodeMetadataWith creates a new NodeMetadata with the supplied map.
func MakeNodeMetadataWith(m map[string]string) NodeMetadata {
return NodeMetadata{
Metadata: m,
Counters: map[string]int{},
Metadata: m,
Counters: map[string]int{},
Adjacency: MakeIDList(),
}
}
@@ -199,6 +175,7 @@ func (n NodeMetadata) Copy() NodeMetadata {
for k, v := range n.Counters {
cp.Counters[k] = v
}
cp.Adjacency = n.Adjacency.Copy()
return cp
}
@@ -213,6 +190,7 @@ func (n NodeMetadata) Merge(other NodeMetadata) NodeMetadata {
for k, v := range other.Counters {
cp.Counters[k] = n.Counters[k] + v
}
cp.Adjacency = cp.Adjacency.Merge(other.Adjacency)
return cp
}
@@ -227,48 +205,30 @@ func (t Topology) Validate() error {
errs = append(errs, fmt.Sprintf("invalid edge ID %q", edgeID))
continue
}
// For each edge, at least one of the ends must exist in nodemetadata
if _, ok := t.NodeMetadatas[srcNodeID]; !ok {
if _, ok := t.NodeMetadatas[dstNodeID]; !ok {
errs = append(errs, fmt.Sprintf("node metadatas missing for edge %q", edgeID))
}
}
dstNodeIDs, ok := t.Adjacency[MakeAdjacencyID(srcNodeID)]
if !ok {
errs = append(errs, fmt.Sprintf("adjacency entries missing for source node ID %q (from edge %q)", srcNodeID, edgeID))
continue
}
if !dstNodeIDs.Contains(dstNodeID) {
errs = append(errs, fmt.Sprintf("adjacency destination missing for destination node ID %q (from edge %q)", dstNodeID, edgeID))
}
}
// Check all adjancency keys has entries in NodeMetadata.
for adjacencyID, dsts := range t.Adjacency {
srcNodeID, ok := ParseAdjacencyID(adjacencyID)
if !ok {
errs = append(errs, fmt.Sprintf("invalid adjacency ID %q", adjacencyID))
continue
}
for _, dstNodeID := range dsts {
// For each edge, at least one of the ends must exist in nodemetadata
if _, ok := t.NodeMetadatas[srcNodeID]; !ok {
if _, ok := t.NodeMetadatas[dstNodeID]; !ok {
errs = append(errs, fmt.Sprintf("node metadata missing from adjacency %q -> %q", srcNodeID, dstNodeID))
}
}
// For each edge, ensure they are connected in the right direction
if src, ok := t.NodeMetadatas[srcNodeID]; !ok {
errs = append(errs, fmt.Sprintf("node %s metadatas missing for edge %q", srcNodeID, edgeID))
} else if !src.Adjacency.Contains(dstNodeID) {
errs = append(errs, fmt.Sprintf("adjacency destination missing for destination node ID %q (from edge %q)", srcNodeID, edgeID))
}
}
// Check all node metadatas are valid, and the keys are parseable, i.e.
// contain a scope.
for nodeID := range t.NodeMetadatas {
if t.NodeMetadatas[nodeID].Metadata == nil {
for nodeID, nmd := range t.NodeMetadatas {
if nmd.Metadata == nil {
errs = append(errs, fmt.Sprintf("node ID %q has nil metadata", nodeID))
}
if _, _, ok := ParseNodeID(nodeID); !ok {
errs = append(errs, fmt.Sprintf("invalid node ID %q", nodeID))
}
// Check all adjancency keys has entries in NodeMetadata.
for _, dstNodeID := range nmd.Adjacency {
if _, ok := t.NodeMetadatas[dstNodeID]; !ok {
errs = append(errs, fmt.Sprintf("node metadata missing from adjacency %q -> %q", nodeID, dstNodeID))
}
}
}
if len(errs) > 0 {
+130 -65
View File
@@ -18,18 +18,22 @@ var (
ClientIP = "10.10.10.20"
ServerIP = "192.168.1.1"
ClientPort54001 = "54001"
ClientPort54010 = "54010"
ClientPort54002 = "54002"
ClientPort54020 = "54020"
ClientPort12345 = "12345"
ServerPort = "80"
UnknownClient1IP = "10.10.10.10"
UnknownClient2IP = "10.10.10.10"
UnknownClient3IP = "10.10.10.11"
RandomClientIP = "51.52.53.54"
GoogleIP = "8.8.8.8"
ClientPort54001 = "54001"
ClientPort54002 = "54002"
ServerPort = "80"
UnknownClient1Port = "54010"
UnknownClient2Port = "54020"
UnknownClient3Port = "54020"
RandomClientPort = "12345"
GooglePort = "80"
NonContainerClientPort = "46789"
ClientHostName = ClientHostID
ServerHostName = ServerHostID
@@ -46,15 +50,15 @@ var (
ClientHostNodeID = report.MakeHostNodeID(ClientHostID)
ServerHostNodeID = report.MakeHostNodeID(ServerHostID)
Client54001NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001) // curl (1)
Client54002NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002) // curl (2)
Server80NodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort) // apache
UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, "54010") // we want to ensure two unknown clients, connnected
UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, "54020") // to the same server, are deduped.
UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, "54020") // Check this one isn't deduped
RandomClientNodeID = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, "12345") // this should become an internet node
NonContainerNodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, "46789")
GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, "80")
Client54001NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001) // curl (1)
Client54002NodeID = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002) // curl (2)
Server80NodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort) // apache
UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, UnknownClient1Port) // we want to ensure two unknown clients, connnected
UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, UnknownClient2Port) // to the same server, are deduped.
UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, UnknownClient3Port) // Check this one isn't deduped
RandomClientNodeID = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, RandomClientPort) // this should become an internet node
NonContainerNodeID = report.MakeEndpointNodeID(ServerHostID, ServerIP, NonContainerClientPort)
GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, GooglePort)
ClientProcess1NodeID = report.MakeProcessNodeID(ClientHostID, Client1PID)
ClientProcess2NodeID = report.MakeProcessNodeID(ClientHostID, Client2PID)
@@ -73,51 +77,92 @@ var (
ClientContainerImageName = "image/client"
ServerContainerImageName = "image/server"
ClientAddressNodeID = report.MakeAddressNodeID(ClientHostID, "10.10.10.20")
ServerAddressNodeID = report.MakeAddressNodeID(ServerHostID, "192.168.1.1")
UnknownAddress1NodeID = report.MakeAddressNodeID(ServerHostID, "10.10.10.10")
UnknownAddress2NodeID = report.MakeAddressNodeID(ServerHostID, "10.10.10.11")
RandomAddressNodeID = report.MakeAddressNodeID(ServerHostID, "51.52.53.54") // this should become an internet node
ClientAddressNodeID = report.MakeAddressNodeID(ClientHostID, ClientIP)
ServerAddressNodeID = report.MakeAddressNodeID(ServerHostID, ServerIP)
UnknownAddress1NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient1IP)
UnknownAddress2NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient2IP)
UnknownAddress3NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient3IP)
RandomAddressNodeID = report.MakeAddressNodeID(ServerHostID, RandomClientIP) // this should become an internet node
Report = report.Report{
Endpoint: report.Topology{
Adjacency: report.Adjacency{
report.MakeAdjacencyID(Client54001NodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(Client54002NodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(UnknownClient1NodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(UnknownClient2NodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(UnknownClient3NodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(RandomClientNodeID): report.MakeIDList(Server80NodeID),
report.MakeAdjacencyID(NonContainerNodeID): report.MakeIDList(GoogleEndpointNodeID),
},
NodeMetadatas: report.NodeMetadatas{
// NodeMetadata is arbitrary. We're free to put only precisely what we
// care to test into the fixture. Just be sure to include the bits
// that the mapping funcs extract :)
Client54001NodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ClientIP,
endpoint.Port: ClientPort54001,
process.PID: Client1PID,
report.HostNodeID: ClientHostNodeID,
}),
Client54002NodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ClientIP,
endpoint.Port: ClientPort54002,
process.PID: Client2PID,
report.HostNodeID: ClientHostNodeID,
}),
Server80NodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ServerIP,
endpoint.Port: ServerPort,
process.PID: ServerPID,
report.HostNodeID: ServerHostNodeID,
}),
NonContainerNodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ServerIP,
endpoint.Port: "46789",
process.PID: NonContainerPID,
report.HostNodeID: ServerHostNodeID,
}),
Client54001NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: ClientIP,
endpoint.Port: ClientPort54001,
process.PID: Client1PID,
report.HostNodeID: ClientHostNodeID,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
Client54002NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: ClientIP,
endpoint.Port: ClientPort54002,
process.PID: Client2PID,
report.HostNodeID: ClientHostNodeID,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
Server80NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: ServerIP,
endpoint.Port: ServerPort,
process.PID: ServerPID,
report.HostNodeID: ServerHostNodeID,
},
Adjacency: report.MakeIDList(),
},
NonContainerNodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: ServerIP,
endpoint.Port: NonContainerClientPort,
process.PID: NonContainerPID,
report.HostNodeID: ServerHostNodeID,
},
Adjacency: report.MakeIDList(GoogleEndpointNodeID),
},
// Probe pseudo nodes
UnknownClient1NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient1IP,
endpoint.Port: UnknownClient1Port,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
UnknownClient2NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient2IP,
endpoint.Port: UnknownClient2Port,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
UnknownClient3NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient3IP,
endpoint.Port: UnknownClient3Port,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
RandomClientNodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: RandomClientIP,
endpoint.Port: RandomClientPort,
},
Adjacency: report.MakeIDList(Server80NodeID),
},
GoogleEndpointNodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: GoogleIP,
endpoint.Port: GooglePort,
},
Adjacency: report.MakeIDList(),
},
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(Client54001NodeID, Server80NodeID): report.EdgeMetadata{
@@ -147,7 +192,6 @@ var (
},
},
Process: report.Topology{
Adjacency: report.Adjacency{},
NodeMetadatas: report.NodeMetadatas{
ClientProcess1NodeID: report.MakeNodeMetadataWith(map[string]string{
process.PID: Client1PID,
@@ -210,21 +254,43 @@ var (
},
},
Address: report.Topology{
Adjacency: report.Adjacency{
report.MakeAdjacencyID(ClientAddressNodeID): report.MakeIDList(ServerAddressNodeID),
report.MakeAdjacencyID(UnknownAddress1NodeID): report.MakeIDList(ServerAddressNodeID),
report.MakeAdjacencyID(UnknownAddress2NodeID): report.MakeIDList(ServerAddressNodeID),
report.MakeAdjacencyID(RandomAddressNodeID): report.MakeIDList(ServerAddressNodeID),
},
NodeMetadatas: report.NodeMetadatas{
ClientAddressNodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ClientIP,
report.HostNodeID: ClientHostNodeID,
}),
ClientAddressNodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: ClientIP,
report.HostNodeID: ClientHostNodeID,
},
Adjacency: report.MakeIDList(ServerAddressNodeID),
},
ServerAddressNodeID: report.MakeNodeMetadataWith(map[string]string{
endpoint.Addr: ServerIP,
report.HostNodeID: ServerHostNodeID,
}),
UnknownAddress1NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient1IP,
},
Adjacency: report.MakeIDList(ServerAddressNodeID),
},
UnknownAddress2NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient2IP,
},
Adjacency: report.MakeIDList(ServerAddressNodeID),
},
UnknownAddress3NodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: UnknownClient3IP,
},
Adjacency: report.MakeIDList(ServerAddressNodeID),
},
RandomAddressNodeID: report.NodeMetadata{
Metadata: map[string]string{
endpoint.Addr: RandomClientIP,
},
Adjacency: report.MakeIDList(ServerAddressNodeID),
},
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(ClientAddressNodeID, ServerAddressNodeID): report.EdgeMetadata{
@@ -233,7 +299,6 @@ var (
},
},
Host: report.Topology{
Adjacency: report.Adjacency{},
NodeMetadatas: report.NodeMetadatas{
ClientHostNodeID: report.MakeNodeMetadataWith(map[string]string{
"host_name": ClientHostName,