Make NodeMetadata a struct, move existing map[string]string to NodeMetadata.Metadata

This commit is contained in:
Tom Wilkie
2015-07-15 10:06:36 +00:00
parent c9e74f754d
commit c2065836e2
36 changed files with 246 additions and 227 deletions
+4 -4
View File
@@ -27,10 +27,10 @@ func getOriginHost(t report.Topology, nodeID string) (OriginHost, bool) {
}
return OriginHost{
Hostname: h[host.HostName],
OS: h[host.OS],
Networks: strings.Split(h[host.LocalNetworks], " "),
Load: h[host.Load],
Hostname: h.Metadata[host.HostName],
OS: h.Metadata[host.OS],
Networks: strings.Split(h.Metadata[host.LocalNetworks], " "),
Load: h.Metadata[host.Load],
}, true
}
+10 -10
View File
@@ -70,19 +70,19 @@ func DemoReport(nodeCount int) report.Report {
// Endpoint topology
if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok {
r.Endpoint.NodeMetadatas[srcPortID] = report.NodeMetadata{
r.Endpoint.NodeMetadatas[srcPortID] = report.NewNodeMetadata(report.Metadata{
docker.PID: "4000",
docker.Name: c.srcProc,
docker.Domain: "node-" + src,
}
})
}
r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID)
if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok {
r.Endpoint.NodeMetadatas[dstPortID] = report.NodeMetadata{
r.Endpoint.NodeMetadatas[dstPortID] = report.NewNodeMetadata(report.Metadata{
docker.PID: "4000",
docker.Name: c.dstProc,
docker.Domain: "node-" + dst,
}
})
}
r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID)
var (
@@ -100,25 +100,25 @@ func DemoReport(nodeCount int) report.Report {
// Address topology
if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
r.Address.NodeMetadatas[srcAddressID] = report.NodeMetadata{
r.Address.NodeMetadatas[srcAddressID] = report.NewNodeMetadata(report.Metadata{
docker.Name: src,
}
})
}
r.Address.Adjacency[nodeSrcAddressID] = r.Address.Adjacency[nodeSrcAddressID].Add(dstAddressID)
if _, ok := r.Address.NodeMetadatas[dstAddressID]; !ok {
r.Address.NodeMetadatas[dstAddressID] = report.NodeMetadata{
r.Address.NodeMetadatas[dstAddressID] = report.NewNodeMetadata(report.Metadata{
docker.Name: dst,
}
})
}
r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)
// Host data
r.Host.NodeMetadatas["hostX"] = report.NodeMetadata{
r.Host.NodeMetadatas["hostX"] = report.NewNodeMetadata(report.Metadata{
"ts": time.Now().UTC().Format(time.RFC3339Nano),
"host_name": "host-x",
"local_networks": localNet.String(),
"os": "linux",
}
})
}
return r
+10 -10
View File
@@ -69,19 +69,19 @@ func DemoReport(nodeCount int) report.Report {
// Endpoint topology
if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok {
r.Endpoint.NodeMetadatas[srcPortID] = report.NodeMetadata{
r.Endpoint.NodeMetadatas[srcPortID] = report.NewNodeMetadata(report.Metadata{
"pid": "4000",
"name": c.srcProc,
"domain": "node-" + src,
}
})
}
r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID)
if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok {
r.Endpoint.NodeMetadatas[dstPortID] = report.NodeMetadata{
r.Endpoint.NodeMetadatas[dstPortID] = report.NewNodeMetadata(report.Metadata{
"pid": "4000",
"name": c.dstProc,
"domain": "node-" + dst,
}
})
}
r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID)
var (
@@ -99,25 +99,25 @@ func DemoReport(nodeCount int) report.Report {
// Address topology
if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
r.Address.NodeMetadatas[srcAddressID] = report.NodeMetadata{
r.Address.NodeMetadatas[srcAddressID] = report.NewNodeMetadata(report.Metadata{
"name": src,
}
})
}
r.Address.Adjacency[nodeSrcAddressID] = r.Address.Adjacency[nodeSrcAddressID].Add(dstAddressID)
if _, ok := r.Address.NodeMetadatas[dstAddressID]; !ok {
r.Address.NodeMetadatas[dstAddressID] = report.NodeMetadata{
r.Address.NodeMetadatas[dstAddressID] = report.NewNodeMetadata(report.Metadata{
"name": dst,
}
})
}
r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)
// Host data
r.Host.NodeMetadatas["hostX"] = report.NodeMetadata{
r.Host.NodeMetadatas["hostX"] = report.NewNodeMetadata(report.Metadata{
"ts": time.Now().UTC().Format(time.RFC3339Nano),
"host_name": "host-x",
"local_networks": localNet.String(),
"os": "linux",
}
})
}
return r
+4 -4
View File
@@ -205,20 +205,20 @@ func (c *container) GetNodeMetadata() report.NodeMetadata {
c.RLock()
defer c.RUnlock()
result := report.NodeMetadata{
result := report.NewNodeMetadata(report.Metadata{
ContainerID: c.ID(),
ContainerName: strings.TrimPrefix(c.container.Name, "/"),
ContainerPorts: c.ports(),
ContainerCreated: c.container.Created.Format(time.RFC822),
ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "),
ImageID: c.container.Image,
}
})
if c.latestStats == nil {
return result
}
result.Merge(report.NodeMetadata{
result.Merge(report.NewNodeMetadata(report.Metadata{
NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10),
NetworkRxBytes: strconv.FormatUint(c.latestStats.Network.RxBytes, 10),
NetworkRxErrors: strconv.FormatUint(c.latestStats.Network.RxErrors, 10),
@@ -238,6 +238,6 @@ func (c *container) GetNodeMetadata() report.NodeMetadata {
CPUTotalUsage: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.TotalUsage, 10),
CPUUsageInKernelmode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInKernelmode, 10),
CPUSystemCPUUsage: strconv.FormatUint(c.latestStats.CPUStats.SystemCPUUsage, 10),
})
}))
return result
}
+1 -1
View File
@@ -62,6 +62,6 @@ func TestContainer(t *testing.T) {
// Now see if we go them
test.Poll(t, 10*time.Millisecond, "12345", func() interface{} {
return c.GetNodeMetadata()[docker.MemoryUsage]
return c.GetNodeMetadata().Metadata[docker.MemoryUsage]
})
}
+2 -2
View File
@@ -38,11 +38,11 @@ func (c *mockContainer) StartGatheringStats() error {
func (c *mockContainer) StopGatheringStats() {}
func (c *mockContainer) GetNodeMetadata() report.NodeMetadata {
return report.NodeMetadata{
return report.NewNodeMetadata(report.Metadata{
docker.ContainerID: c.c.ID,
docker.ContainerName: c.c.Name,
docker.ImageID: c.c.Image,
}
})
}
type mockDockerClient struct {
+3 -3
View File
@@ -49,12 +49,12 @@ func (r *Reporter) containerImageTopology() report.Topology {
result := report.NewTopology()
r.registry.WalkImages(func(image *docker_client.APIImages) {
nmd := report.NodeMetadata{
nmd := report.NewNodeMetadata(report.Metadata{
ImageID: image.ID,
}
})
if len(image.RepoTags) > 0 {
nmd[ImageName] = image.RepoTags[0]
nmd.Metadata[ImageName] = image.RepoTags[0]
}
nodeID := report.MakeContainerNodeID(r.scope, image.ID)
+4 -4
View File
@@ -53,21 +53,21 @@ func TestReporter(t *testing.T) {
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeContainerNodeID("", "ping"): report.NodeMetadata{
report.MakeContainerNodeID("", "ping"): report.NewNodeMetadata(report.Metadata{
docker.ContainerID: "ping",
docker.ContainerName: "pong",
docker.ImageID: "baz",
},
}),
},
}
want.ContainerImage = report.Topology{
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeContainerNodeID("", "baz"): report.NodeMetadata{
report.MakeContainerNodeID("", "baz"): report.NewNodeMetadata(report.Metadata{
docker.ImageID: "baz",
docker.ImageName: "bang",
},
}),
},
}
+3 -3
View File
@@ -50,7 +50,7 @@ func (t *Tagger) Tag(r report.Report) (report.Report, error) {
func (t *Tagger) tag(tree process.Tree, topology *report.Topology) {
for nodeID, nodeMetadata := range topology.NodeMetadatas {
pidStr, ok := nodeMetadata["pid"]
pidStr, ok := nodeMetadata.Metadata["pid"]
if !ok {
continue
}
@@ -83,9 +83,9 @@ func (t *Tagger) tag(tree process.Tree, topology *report.Topology) {
continue
}
md := report.NodeMetadata{
md := report.NewNodeMetadata(report.Metadata{
ContainerID: c.ID(),
}
})
topology.NodeMetadatas[nodeID].Merge(md)
}
+5 -5
View File
@@ -34,16 +34,16 @@ func TestTagger(t *testing.T) {
var (
pid1NodeID = report.MakeProcessNodeID("somehost.com", "1")
pid2NodeID = report.MakeProcessNodeID("somehost.com", "2")
wantNodeMetadata = report.NodeMetadata{docker.ContainerID: "ping"}
wantNodeMetadata = report.NewNodeMetadata(report.Metadata{docker.ContainerID: "ping"})
)
input := report.MakeReport()
input.Process.NodeMetadatas[pid1NodeID] = report.NodeMetadata{"pid": "1"}
input.Process.NodeMetadatas[pid2NodeID] = report.NodeMetadata{"pid": "2"}
input.Process.NodeMetadatas[pid1NodeID] = report.NewNodeMetadata(report.Metadata{"pid": "1"})
input.Process.NodeMetadatas[pid2NodeID] = report.NewNodeMetadata(report.Metadata{"pid": "2"})
want := report.MakeReport()
want.Process.NodeMetadatas[pid1NodeID] = report.NodeMetadata{"pid": "1"}.Merge(wantNodeMetadata)
want.Process.NodeMetadatas[pid2NodeID] = report.NodeMetadata{"pid": "2"}.Merge(wantNodeMetadata)
want.Process.NodeMetadatas[pid1NodeID] = report.NewNodeMetadata(report.Metadata{"pid": "1"}).Merge(wantNodeMetadata)
want.Process.NodeMetadatas[pid2NodeID] = report.NewNodeMetadata(report.Metadata{"pid": "2"}).Merge(wantNodeMetadata)
tagger := docker.NewTagger(mockRegistryInstance, nil)
have, err := tagger.Tag(input)
+4 -4
View File
@@ -80,10 +80,10 @@ func (r *Reporter) addConnection(rpt *report.Report, c *procspy.Connection) {
rpt.Address.Adjacency[key] = rpt.Address.Adjacency[key].Add(scopedRemote)
if _, ok := rpt.Address.NodeMetadatas[scopedLocal]; !ok {
rpt.Address.NodeMetadatas[scopedLocal] = report.NodeMetadata{
rpt.Address.NodeMetadatas[scopedLocal] = report.NewNodeMetadata(report.Metadata{
docker.Name: r.hostName,
docker.Addr: c.LocalAddress.String(),
}
})
}
countTCPConnection(rpt.Address.EdgeMetadatas, edgeKey)
@@ -100,11 +100,11 @@ func (r *Reporter) addConnection(rpt *report.Report, c *procspy.Connection) {
if _, ok := rpt.Endpoint.NodeMetadatas[scopedLocal]; !ok {
// First hit establishes NodeMetadata for scoped local address + port
md := report.NodeMetadata{
md := report.NewNodeMetadata(report.Metadata{
"addr": c.LocalAddress.String(),
"port": strconv.Itoa(int(c.LocalPort)),
"pid": fmt.Sprintf("%d", c.Proc.PID),
}
})
rpt.Endpoint.NodeMetadatas[scopedLocal] = md
}
+2 -2
View File
@@ -96,7 +96,7 @@ func TestSpyNoProcesses(t *testing.T) {
t.Fatalf("want %q, have %q", want, have)
}
if want, have := nodeName, r.Address.NodeMetadatas[scopedLocal][docker.Name]; want != have {
if want, have := nodeName, r.Address.NodeMetadatas[scopedLocal].Metadata[docker.Name]; want != have {
t.Fatalf("want %q, have %q", want, have)
}
}
@@ -130,7 +130,7 @@ func TestSpyWithProcesses(t *testing.T) {
for key, want := range map[string]string{
"pid": strconv.FormatUint(uint64(fixProcessPID), 10),
} {
if have := r.Endpoint.NodeMetadatas[scopedLocal][key]; want != have {
if have := r.Endpoint.NodeMetadatas[scopedLocal].Metadata[key]; want != have {
t.Errorf("Process.NodeMetadatas[%q][%q]: want %q, have %q", scopedLocal, key, want, have)
}
}
+2 -2
View File
@@ -75,7 +75,7 @@ func (r *Reporter) Report() (report.Report, error) {
return rep, err
}
rep.Host.NodeMetadatas[report.MakeHostNodeID(r.hostID)] = report.NodeMetadata{
rep.Host.NodeMetadatas[report.MakeHostNodeID(r.hostID)] = report.NewNodeMetadata(report.Metadata{
Timestamp: Now(),
HostName: r.hostName,
LocalNetworks: strings.Join(localCIDRs, " "),
@@ -83,7 +83,7 @@ func (r *Reporter) Report() (report.Report, error) {
Load: GetLoad(),
KernelVersion: kernel,
Uptime: uptime.String(),
}
})
return rep, nil
}
+2 -2
View File
@@ -46,7 +46,7 @@ func TestReporter(t *testing.T) {
host.InterfaceAddrs = func() ([]net.Addr, error) { _, ipnet, _ := net.ParseCIDR(network); return []net.Addr{ipnet}, nil }
want := report.MakeReport()
want.Host.NodeMetadatas[report.MakeHostNodeID(hostID)] = report.NodeMetadata{
want.Host.NodeMetadatas[report.MakeHostNodeID(hostID)] = report.NewNodeMetadata(report.Metadata{
host.Timestamp: now,
host.HostName: hostname,
host.LocalNetworks: network,
@@ -54,7 +54,7 @@ func TestReporter(t *testing.T) {
host.Load: load,
host.Uptime: uptime,
host.KernelVersion: kernel,
}
})
r := host.NewReporter(hostID, hostname)
have, _ := r.Report()
if !reflect.DeepEqual(want, have) {
+1 -1
View File
@@ -17,7 +17,7 @@ func NewTagger(hostID string) Tagger {
// Tag implements Tagger.
func (t Tagger) Tag(r report.Report) (report.Report, error) {
md := report.NodeMetadata{report.HostNodeID: t.hostNodeID}
md := report.NewNodeMetadata(report.Metadata{report.HostNodeID: t.hostNodeID})
for _, topology := range r.Topologies() {
for nodeID := range topology.NodeMetadatas {
topology.NodeMetadatas[nodeID].Merge(md)
+4 -2
View File
@@ -13,12 +13,14 @@ func TestTagger(t *testing.T) {
var (
hostID = "foo"
endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored
nodeMetadata = report.NodeMetadata{"foo": "bar"}
nodeMetadata = report.NewNodeMetadata(report.Metadata{"foo": "bar"})
)
r := report.MakeReport()
r.Endpoint.NodeMetadatas[endpointNodeID] = nodeMetadata
want := nodeMetadata.Merge(report.NodeMetadata{report.HostNodeID: report.MakeHostNodeID(hostID)})
want := nodeMetadata.Merge(report.NewNodeMetadata(report.Metadata{
report.HostNodeID: report.MakeHostNodeID(hostID),
}))
rpt, _ := host.NewTagger(hostID).Tag(r)
have := rpt.Endpoint.NodeMetadatas[endpointNodeID].Copy()
if !reflect.DeepEqual(want, have) {
+2 -2
View File
@@ -70,10 +70,10 @@ func (w Weave) Report() (report.Report, error) {
}
for _, peer := range status.Peers {
r.Overlay.NodeMetadatas[report.MakeOverlayNodeID(peer.Name)] = report.NodeMetadata{
r.Overlay.NodeMetadatas[report.MakeOverlayNodeID(peer.Name)] = report.NewNodeMetadata(report.Metadata{
WeavePeerName: peer.Name,
WeavePeerNickName: peer.NickName,
}
})
}
return r, nil
}
+2 -2
View File
@@ -29,10 +29,10 @@ func TestWeaveTaggerOverlayTopology(t *testing.T) {
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeOverlayNodeID(mockWeavePeerName): {
report.MakeOverlayNodeID(mockWeavePeerName): report.NewNodeMetadata(report.Metadata{
overlay.WeavePeerName: mockWeavePeerName,
overlay.WeavePeerNickName: mockWeavePeerNickName,
},
}),
},
}), have.Overlay; !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
+3 -3
View File
@@ -45,14 +45,14 @@ func (r *Reporter) processTopology() (report.Topology, error) {
err := r.walker.Walk(func(p *Process) {
pidstr := strconv.Itoa(p.PID)
nodeID := report.MakeProcessNodeID(r.scope, pidstr)
t.NodeMetadatas[nodeID] = report.NodeMetadata{
t.NodeMetadatas[nodeID] = report.NewNodeMetadata(report.Metadata{
PID: pidstr,
Comm: p.Comm,
Cmdline: p.Cmdline,
Threads: strconv.Itoa(p.Threads),
}
})
if p.PPID > 0 {
t.NodeMetadatas[nodeID][PPID] = strconv.Itoa(p.PPID)
t.NodeMetadatas[nodeID].Metadata[PPID] = strconv.Itoa(p.PPID)
}
})
+8 -8
View File
@@ -36,33 +36,33 @@ func TestReporter(t *testing.T) {
Adjacency: report.Adjacency{},
EdgeMetadatas: report.EdgeMetadatas{},
NodeMetadatas: report.NodeMetadatas{
report.MakeProcessNodeID("", "1"): report.NodeMetadata{
report.MakeProcessNodeID("", "1"): report.NewNodeMetadata(report.Metadata{
process.PID: "1",
process.Comm: "init",
process.Cmdline: "",
process.Threads: "0",
},
report.MakeProcessNodeID("", "2"): report.NodeMetadata{
}),
report.MakeProcessNodeID("", "2"): report.NewNodeMetadata(report.Metadata{
process.PID: "2",
process.Comm: "bash",
process.PPID: "1",
process.Cmdline: "",
process.Threads: "0",
},
report.MakeProcessNodeID("", "3"): report.NodeMetadata{
}),
report.MakeProcessNodeID("", "3"): report.NewNodeMetadata(report.Metadata{
process.PID: "3",
process.Comm: "apache",
process.PPID: "1",
process.Cmdline: "",
process.Threads: "2",
},
report.MakeProcessNodeID("", "4"): report.NodeMetadata{
}),
report.MakeProcessNodeID("", "4"): report.NewNodeMetadata(report.Metadata{
process.PID: "4",
process.Comm: "ping",
process.PPID: "2",
process.Cmdline: "ping foo.bar.local",
process.Threads: "0",
},
}),
},
}
+1 -1
View File
@@ -50,7 +50,7 @@ func (topologyTagger) Tag(r report.Report) (report.Report, error) {
"host": &(r.Host),
"overlay": &(r.Overlay),
} {
md := report.NodeMetadata{Topology: val}
md := report.NewNodeMetadata(report.Metadata{Topology: val})
for nodeID := range topology.NodeMetadatas {
(*topology).NodeMetadatas[nodeID].Merge(md)
}
+5 -5
View File
@@ -11,8 +11,8 @@ func TestApply(t *testing.T) {
var (
endpointNodeID = "c"
addressNodeID = "d"
endpointNodeMetadata = report.NodeMetadata{"5": "6"}
addressNodeMetadata = report.NodeMetadata{"7": "8"}
endpointNodeMetadata = report.NewNodeMetadata(report.Metadata{"5": "6"})
addressNodeMetadata = report.NewNodeMetadata(report.Metadata{"7": "8"})
)
r := report.MakeReport()
@@ -25,8 +25,8 @@ func TestApply(t *testing.T) {
from report.Topology
via string
}{
{endpointNodeMetadata.Copy().Merge(report.NodeMetadata{"topology": "endpoint"}), r.Endpoint, endpointNodeID},
{addressNodeMetadata.Copy().Merge(report.NodeMetadata{"topology": "address"}), r.Address, addressNodeID},
{endpointNodeMetadata.Copy().Merge(report.NewNodeMetadata(report.Metadata{"topology": "endpoint"})), r.Endpoint, endpointNodeID},
{addressNodeMetadata.Copy().Merge(report.NewNodeMetadata(report.Metadata{"topology": "address"})), r.Address, addressNodeID},
} {
if want, have := tuple.want, tuple.from.NodeMetadatas[tuple.via]; !reflect.DeepEqual(want, have) {
t.Errorf("want %+v, have %+v", want, have)
@@ -37,7 +37,7 @@ func TestApply(t *testing.T) {
func TestTagMissingID(t *testing.T) {
const nodeID = "not-found"
r := report.MakeReport()
want := report.NodeMetadata{}
want := report.NewNodeMetadata(report.Metadata{})
rpt, _ := newTopologyTagger().Tag(r)
have := rpt.Endpoint.NodeMetadatas[nodeID].Copy()
if !reflect.DeepEqual(want, have) {
+7 -7
View File
@@ -125,7 +125,7 @@ func OriginTable(r report.Report, originID string) (Table, bool) {
func connectionDetailsRows(endpointTopology report.Topology, originID string, nmd report.NodeMetadata) []Row {
rows := []Row{}
local := fmt.Sprintf("%s:%s", nmd[docker.Addr], nmd[docker.Port])
local := fmt.Sprintf("%s:%s", nmd.Metadata[docker.Addr], nmd.Metadata[docker.Port])
adjacencies := endpointTopology.Adjacency[report.MakeAdjacencyID(originID)]
sort.Strings(adjacencies)
for _, adj := range adjacencies {
@@ -150,7 +150,7 @@ func connectionDetailsTable(connectionRows []Row) Table {
func addressOriginTable(nmd report.NodeMetadata) (Table, bool) {
rows := []Row{}
if val, ok := nmd["addr"]; ok {
if val, ok := nmd.Metadata["addr"]; ok {
rows = append(rows, Row{"Address", val, ""})
}
return Table{
@@ -170,7 +170,7 @@ func processOriginTable(nmd report.NodeMetadata) (Table, bool) {
{process.Cmdline, "Command"},
{process.Threads, "# Threads"},
} {
if val, ok := nmd[tuple.key]; ok {
if val, ok := nmd.Metadata[tuple.key]; ok {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
@@ -193,12 +193,12 @@ func containerOriginTable(nmd report.NodeMetadata) (Table, bool) {
{docker.ContainerCreated, "Created"},
{docker.ContainerCommand, "Command"},
} {
if val, ok := nmd[tuple.key]; ok {
if val, ok := nmd.Metadata[tuple.key]; ok {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
if val, ok := nmd[docker.MemoryUsage]; ok {
if val, ok := nmd.Metadata[docker.MemoryUsage]; ok {
memory, err := strconv.ParseFloat(val, 64)
if err == nil {
memoryStr := fmt.Sprintf("%0.2f", memory/float64(mb))
@@ -220,7 +220,7 @@ func containerImageOriginTable(nmd report.NodeMetadata) (Table, bool) {
{docker.ImageID, "Image ID"},
{docker.ImageName, "Image name"},
} {
if val, ok := nmd[tuple.key]; ok {
if val, ok := nmd.Metadata[tuple.key]; ok {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
@@ -241,7 +241,7 @@ func hostOriginTable(nmd report.NodeMetadata) (Table, bool) {
{host.KernelVersion, "Kernel version"},
{host.Uptime, "Uptime"},
} {
if val, ok := nmd[tuple.key]; ok {
if val, ok := nmd.Metadata[tuple.key]; ok {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
+21 -21
View File
@@ -49,9 +49,9 @@ type MapFunc func(RenderableNode) (RenderableNode, bool)
// assume the presence of certain keys.
func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = MakeEndpointID(report.ExtractHostID(m), m["addr"], m["port"])
major = fmt.Sprintf("%s:%s", m["addr"], m["port"])
pid, ok = m["pid"]
id = MakeEndpointID(report.ExtractHostID(m), m.Metadata["addr"], m.Metadata["port"])
major = fmt.Sprintf("%s:%s", m.Metadata["addr"], m.Metadata["port"])
pid, ok = m.Metadata["pid"]
minor = report.ExtractHostID(m)
rank = major
)
@@ -68,10 +68,10 @@ func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) {
// presence of certain keys.
func MapProcessIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = MakeProcessID(report.ExtractHostID(m), m["pid"])
major = m["comm"]
minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), m["pid"])
rank = m["pid"]
id = MakeProcessID(report.ExtractHostID(m), m.Metadata["pid"])
major = m.Metadata["comm"]
minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), m.Metadata["pid"])
rank = m.Metadata["pid"]
)
return NewRenderableNode(id, major, minor, rank, m), true
@@ -82,10 +82,10 @@ func MapProcessIdentity(m report.NodeMetadata) (RenderableNode, bool) {
// nodes, we can safely assume the presences of certain keys.
func MapContainerIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = m[docker.ContainerID]
major = m[docker.ContainerName]
id = m.Metadata[docker.ContainerID]
major = m.Metadata[docker.ContainerName]
minor = report.ExtractHostID(m)
rank = m[docker.ImageID]
rank = m.Metadata[docker.ImageID]
)
return NewRenderableNode(id, major, minor, rank, m), true
@@ -96,9 +96,9 @@ func MapContainerIdentity(m report.NodeMetadata) (RenderableNode, bool) {
// topology nodes, we can safely assume the presences of certain keys.
func MapContainerImageIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = m[docker.ImageID]
major = m[docker.ImageName]
rank = m[docker.ImageID]
id = m.Metadata[docker.ImageID]
major = m.Metadata[docker.ImageName]
rank = m.Metadata[docker.ImageID]
)
return NewRenderableNode(id, major, "", rank, m), true
@@ -109,8 +109,8 @@ func MapContainerImageIdentity(m report.NodeMetadata) (RenderableNode, bool) {
// assume the presence of certain keys.
func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = MakeAddressID(report.ExtractHostID(m), m["addr"])
major = m["addr"]
id = MakeAddressID(report.ExtractHostID(m), m.Metadata["addr"])
major = m.Metadata["addr"]
minor = report.ExtractHostID(m)
rank = major
)
@@ -124,7 +124,7 @@ func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) {
func MapHostIdentity(m report.NodeMetadata) (RenderableNode, bool) {
var (
id = MakeHostID(report.ExtractHostID(m))
hostname = m[host.HostName]
hostname = m.Metadata[host.HostName]
parts = strings.SplitN(hostname, ".", 2)
major, minor, rank = "", "", ""
)
@@ -154,7 +154,7 @@ func MapEndpoint2Process(n RenderableNode) (RenderableNode, bool) {
return n, true
}
pid, ok := n.NodeMetadata["pid"]
pid, ok := n.NodeMetadata.Metadata["pid"]
if !ok {
return RenderableNode{}, false
}
@@ -189,7 +189,7 @@ func MapProcess2Container(n RenderableNode) (RenderableNode, bool) {
// into an per-host "Uncontained" node. If for whatever reason
// this node doesn't have a host id in their nodemetadata, it'll
// all get grouped into a single uncontained node.
id, ok := n.NodeMetadata[docker.ContainerID]
id, ok := n.NodeMetadata.Metadata[docker.ContainerID]
if !ok {
hostID := report.ExtractHostID(n.NodeMetadata)
id = MakePseudoNodeID(UncontainedID, hostID)
@@ -212,7 +212,7 @@ func MapProcess2Name(n RenderableNode) (RenderableNode, bool) {
return n, true
}
name, ok := n.NodeMetadata["comm"]
name, ok := n.NodeMetadata.Metadata["comm"]
if !ok {
return RenderableNode{}, false
}
@@ -242,7 +242,7 @@ func MapContainer2ContainerImage(n RenderableNode) (RenderableNode, bool) {
// Otherwise, if some some reason the container doesn't have a image_id
// (maybe slightly out of sync reports), just drop it
id, ok := n.NodeMetadata[docker.ImageID]
id, ok := n.NodeMetadata.Metadata[docker.ImageID]
if !ok {
return n, false
}
@@ -261,7 +261,7 @@ func MapContainerImage2Name(n RenderableNode) (RenderableNode, bool) {
return n, true
}
name, ok := n.NodeMetadata[docker.ImageName]
name, ok := n.NodeMetadata.Metadata[docker.ImageName]
if !ok {
return RenderableNode{}, false
}
+1 -1
View File
@@ -170,7 +170,7 @@ func (m LeafMap) Render(rpt report.Report) RenderableNodes {
origins := mapped.Origins
origins = origins.Add(nodeID)
origins = origins.Add(metadata[report.HostNodeID])
origins = origins.Add(metadata.Metadata[report.HostNodeID])
mapped.Origins = origins
nodes[mapped.ID] = mapped
+3 -3
View File
@@ -110,8 +110,8 @@ func TestMapEdge(t *testing.T) {
selector := func(_ report.Report) report.Topology {
return report.Topology{
NodeMetadatas: report.NodeMetadatas{
"foo": report.NodeMetadata{"id": "foo"},
"bar": report.NodeMetadata{"id": "bar"},
"foo": report.NewNodeMetadata(report.Metadata{"id": "foo"}),
"bar": report.NewNodeMetadata(report.Metadata{"id": "bar"}),
},
Adjacency: report.Adjacency{
">foo": report.MakeIDList("bar"),
@@ -125,7 +125,7 @@ func TestMapEdge(t *testing.T) {
}
identity := func(nmd report.NodeMetadata) (render.RenderableNode, bool) {
return render.NewRenderableNode(nmd["id"], "", "", "", nmd), true
return render.NewRenderableNode(nmd.Metadata["id"], "", "", "", nmd), true
}
mapper := render.Map{
+3 -3
View File
@@ -82,7 +82,7 @@ func newDerivedNode(id string, node RenderableNode) RenderableNode {
Pseudo: node.Pseudo,
AggregateMetadata: node.AggregateMetadata,
Origins: node.Origins,
NodeMetadata: report.NodeMetadata{},
NodeMetadata: report.NewNodeMetadata(report.Metadata{}),
}
}
@@ -94,7 +94,7 @@ func newPseudoNode(id, major, minor string) RenderableNode {
Rank: "",
Pseudo: true,
AggregateMetadata: AggregateMetadata{},
NodeMetadata: report.NodeMetadata{},
NodeMetadata: report.NewNodeMetadata(report.Metadata{}),
}
}
@@ -107,6 +107,6 @@ func newDerivedPseudoNode(id, major string, node RenderableNode) RenderableNode
Pseudo: true,
AggregateMetadata: node.AggregateMetadata,
Origins: node.Origins,
NodeMetadata: report.NodeMetadata{},
NodeMetadata: report.NewNodeMetadata(report.Metadata{}),
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ func LocalNetworks(r report.Report) report.Networks {
)
for _, md := range r.Host.NodeMetadatas {
val, ok := md[host.LocalNetworks]
val, ok := md.Metadata[host.LocalNetworks]
if !ok {
continue
}
+2 -2
View File
@@ -14,8 +14,8 @@ import (
func TestReportLocalNetworks(t *testing.T) {
r := report.MakeReport()
r.Merge(report.Report{Host: report.Topology{NodeMetadatas: report.NodeMetadatas{
"nonets": {},
"foo": {host.LocalNetworks: "10.0.0.1/8 192.168.1.1/24 10.0.0.1/8 badnet/33"},
"nonets": report.NewNodeMetadata(report.Metadata{}),
"foo": report.NewNodeMetadata(report.Metadata{host.LocalNetworks: "10.0.0.1/8 192.168.1.1/24 10.0.0.1/8 badnet/33"}),
}}})
want := report.Networks([]*net.IPNet{
mustParseCIDR("10.0.0.1/8"),
+2 -1
View File
@@ -6,13 +6,14 @@ import (
"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/render/expected"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test"
)
func trimNodeMetadata(rns render.RenderableNodes) render.RenderableNodes {
result := render.RenderableNodes{}
for id, rn := range rns {
rn.NodeMetadata = nil
rn.NodeMetadata = report.NodeMetadata{}
result[id] = rn
}
return result
+1 -1
View File
@@ -116,7 +116,7 @@ func ParseEndpointNodeID(endpointNodeID string) (hostID, address, port string, o
// ExtractHostID extracts the host id from NodeMetadata
func ExtractHostID(m NodeMetadata) string {
hostid, _, _ := ParseNodeID(m[HostNodeID])
hostid, _, _ := ParseNodeID(m.Metadata[HostNodeID])
return hostid
}
+11
View File
@@ -37,6 +37,17 @@ func (m *NodeMetadatas) Merge(other NodeMetadatas) {
}
}
// Merge merges two node metadata maps together. In case of conflict, the
// other (right-hand) side wins. Always reassign the result of merge to the
// destination. Merge is defined on the value-type, but node metadata map is
// itself a reference type, so if you want to maintain immutability, use copy.
func (nm NodeMetadata) Merge(other NodeMetadata) NodeMetadata {
for k, v := range other.Metadata {
nm.Metadata[k] = v // other takes precedence
}
return nm
}
// Merge merges another EdgeMetadatas into the receiver. If other is from
// another probe this is the union of both metadatas. Keys present in both are
// summed.
+61 -56
View File
@@ -4,10 +4,15 @@ import (
"reflect"
"testing"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/report"
)
const (
PID = "pid"
Name = "name"
Domain = "domain"
)
func TestMergeAdjacency(t *testing.T) {
for name, c := range map[string]struct {
a, b, want report.Adjacency
@@ -223,86 +228,86 @@ func TestMergeNodeMetadatas(t *testing.T) {
"Empty a": {
a: report.NodeMetadatas{},
b: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
want: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
},
"Empty b": {
a: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
b: report.NodeMetadatas{},
want: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
},
"Simple merge": {
a: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
b: report.NodeMetadatas{
":192.168.1.2:12345": report.NodeMetadata{
docker.PID: "42",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.2:12345": report.NewNodeMetadata(report.Metadata{
PID: "42",
Name: "curl",
Domain: "node-a.local",
}),
},
want: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.2:12345": report.NodeMetadata{
docker.PID: "42",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
":192.168.1.2:12345": report.NewNodeMetadata(report.Metadata{
PID: "42",
Name: "curl",
Domain: "node-a.local",
}),
},
},
"Merge conflict": {
a: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
b: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{ // <-- same ID
docker.PID: "0",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{ // <-- same ID
PID: "0",
Name: "curl",
Domain: "node-a.local",
}),
},
want: report.NodeMetadatas{
":192.168.1.1:12345": report.NodeMetadata{
docker.PID: "23128",
docker.Name: "curl",
docker.Domain: "node-a.local",
},
":192.168.1.1:12345": report.NewNodeMetadata(report.Metadata{
PID: "23128",
Name: "curl",
Domain: "node-a.local",
}),
},
},
} {
+17 -17
View File
@@ -41,30 +41,30 @@ type EdgeMetadata struct {
}
// NodeMetadata describes a superset of the metadata that probes can collect
// about a given node in a given topology. Right now it's a weakly-typed map,
// which should probably change (see comment on type MapFunc).
type NodeMetadata map[string]string
// about a given node in a given topology.
type NodeMetadata struct {
Metadata
}
// Metadata is shorthand for a string:string map.
type Metadata map[string]string
// NewNodeMetadata creates a new NodeMetadata with the supplied Metadata.
func NewNodeMetadata(m Metadata) NodeMetadata {
return NodeMetadata{
Metadata: m,
}
}
// Copy returns a value copy, useful for tests.
func (nm NodeMetadata) Copy() NodeMetadata {
cp := make(NodeMetadata, len(nm))
for k, v := range nm {
cp[k] = v
cp := NewNodeMetadata(Metadata{})
for k, v := range nm.Metadata {
cp.Metadata[k] = v
}
return cp
}
// Merge merges two node metadata maps together. In case of conflict, the
// other (right-hand) side wins. Always reassign the result of merge to the
// destination. Merge is defined on the value-type, but node metadata map is
// itself a reference type, so if you want to maintain immutability, use copy.
func (nm NodeMetadata) Merge(other NodeMetadata) NodeMetadata {
for k, v := range other {
nm[k] = v // other takes precedence
}
return nm
}
// NewTopology gives you a Topology.
func NewTopology() Topology {
return Topology{
+30 -30
View File
@@ -80,24 +80,24 @@ var (
// 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.NodeMetadata{
Client54001NodeID: report.NewNodeMetadata(report.Metadata{
"addr": ClientIP,
"port": ClientPort54001,
"pid": Client1PID,
report.HostNodeID: ClientHostNodeID,
},
Client54002NodeID: report.NodeMetadata{
}),
Client54002NodeID: report.NewNodeMetadata(report.Metadata{
"addr": ClientIP,
"port": ClientPort54002,
"pid": Client2PID,
report.HostNodeID: ClientHostNodeID,
},
Server80NodeID: report.NodeMetadata{
}),
Server80NodeID: report.NewNodeMetadata(report.Metadata{
"addr": ServerIP,
"port": ServerPort,
"pid": ServerPID,
report.HostNodeID: ServerHostNodeID,
},
}),
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(Client54001NodeID, Server80NodeID): report.EdgeMetadata{
@@ -141,60 +141,60 @@ var (
Process: report.Topology{
Adjacency: report.Adjacency{},
NodeMetadatas: report.NodeMetadatas{
ClientProcess1NodeID: report.NodeMetadata{
ClientProcess1NodeID: report.NewNodeMetadata(report.Metadata{
"pid": Client1PID,
"comm": "curl",
docker.ContainerID: ClientContainerID,
report.HostNodeID: ClientHostNodeID,
},
ClientProcess2NodeID: report.NodeMetadata{
}),
ClientProcess2NodeID: report.NewNodeMetadata(report.Metadata{
"pid": Client2PID,
"comm": "curl",
docker.ContainerID: ClientContainerID,
report.HostNodeID: ClientHostNodeID,
},
ServerProcessNodeID: report.NodeMetadata{
}),
ServerProcessNodeID: report.NewNodeMetadata(report.Metadata{
"pid": ServerPID,
"comm": "apache",
docker.ContainerID: ServerContainerID,
report.HostNodeID: ServerHostNodeID,
},
NonContainerProcessNodeID: report.NodeMetadata{
}),
NonContainerProcessNodeID: report.NewNodeMetadata(report.Metadata{
"pid": NonContainerPID,
"comm": "bash",
report.HostNodeID: ServerHostNodeID,
},
}),
},
EdgeMetadatas: report.EdgeMetadatas{},
},
Container: report.Topology{
NodeMetadatas: report.NodeMetadatas{
ClientContainerNodeID: report.NodeMetadata{
ClientContainerNodeID: report.NewNodeMetadata(report.Metadata{
docker.ContainerID: ClientContainerID,
docker.ContainerName: "client",
docker.ImageID: ClientContainerImageID,
report.HostNodeID: ClientHostNodeID,
},
ServerContainerNodeID: report.NodeMetadata{
}),
ServerContainerNodeID: report.NewNodeMetadata(report.Metadata{
docker.ContainerID: ServerContainerID,
docker.ContainerName: "server",
docker.ImageID: ServerContainerImageID,
report.HostNodeID: ServerHostNodeID,
},
}),
},
},
ContainerImage: report.Topology{
NodeMetadatas: report.NodeMetadatas{
ClientContainerImageNodeID: report.NodeMetadata{
ClientContainerImageNodeID: report.NewNodeMetadata(report.Metadata{
docker.ImageID: ClientContainerImageID,
docker.ImageName: ClientContainerImageName,
report.HostNodeID: ClientHostNodeID,
},
ServerContainerImageNodeID: report.NodeMetadata{
}),
ServerContainerImageNodeID: report.NewNodeMetadata(report.Metadata{
docker.ImageID: ServerContainerImageID,
docker.ImageName: ServerContainerImageName,
report.HostNodeID: ServerHostNodeID,
},
}),
},
},
Address: report.Topology{
@@ -204,14 +204,14 @@ var (
ClientAddressNodeID, UnknownAddress1NodeID, UnknownAddress2NodeID, RandomAddressNodeID), // no backlinks to unknown/random
},
NodeMetadatas: report.NodeMetadatas{
ClientAddressNodeID: report.NodeMetadata{
ClientAddressNodeID: report.NewNodeMetadata(report.Metadata{
"addr": ClientIP,
report.HostNodeID: ClientHostNodeID,
},
ServerAddressNodeID: report.NodeMetadata{
}),
ServerAddressNodeID: report.NewNodeMetadata(report.Metadata{
"addr": ServerIP,
report.HostNodeID: ServerHostNodeID,
},
}),
},
EdgeMetadatas: report.EdgeMetadatas{
report.MakeEdgeID(ClientAddressNodeID, ServerAddressNodeID): report.EdgeMetadata{
@@ -227,20 +227,20 @@ var (
Host: report.Topology{
Adjacency: report.Adjacency{},
NodeMetadatas: report.NodeMetadatas{
ClientHostNodeID: report.NodeMetadata{
ClientHostNodeID: report.NewNodeMetadata(report.Metadata{
"host_name": ClientHostName,
"local_networks": "10.10.10.0/24",
"os": "Linux",
"load": "0.01 0.01 0.01",
report.HostNodeID: ClientHostNodeID,
},
ServerHostNodeID: report.NodeMetadata{
}),
ServerHostNodeID: report.NewNodeMetadata(report.Metadata{
"host_name": ServerHostName,
"local_networks": "10.10.10.0/24",
"os": "Linux",
"load": "0.01 0.01 0.01",
report.HostNodeID: ServerHostNodeID,
},
}),
},
EdgeMetadatas: report.EdgeMetadatas{},
},
+4 -4
View File
@@ -41,12 +41,12 @@ func TestMerge(t *testing.T) {
{
r := report.MakeReport()
r.Host.NodeMetadatas[k1] = report.NodeMetadata{"host_name": "test1"}
r.Host.NodeMetadatas[k1] = report.NewNodeMetadata(report.Metadata{"host_name": "test1"})
p1.Publish(r)
}
{
r := report.MakeReport()
r.Host.NodeMetadatas[k2] = report.NodeMetadata{"host_name": "test2"}
r.Host.NodeMetadatas[k2] = report.NewNodeMetadata(report.Metadata{"host_name": "test2"})
p2.Publish(r)
}
@@ -54,10 +54,10 @@ func TestMerge(t *testing.T) {
go func() {
defer close(success)
for r := range c.Reports() {
if r.Host.NodeMetadatas[k1]["host_name"] != "test1" {
if r.Host.NodeMetadatas[k1].Metadata["host_name"] != "test1" {
continue
}
if r.Host.NodeMetadatas[k2]["host_name"] != "test2" {
if r.Host.NodeMetadatas[k2].Metadata["host_name"] != "test2" {
continue
}
return