func TestReportLocalNetworks(t *testing.T) { r := report.MakeReport().Merge(report.Report{ Host: report.Topology{ Nodes: report.Nodes{ "nonets": report.MakeNode("nonets"), "foo": report.MakeNode("foo").WithSets(report.EmptySets. Add(host.LocalNetworks, report.MakeStringSet( "10.0.0.1/8", "192.168.1.1/24", "10.0.0.1/8", "badnet/33")), ), }, }, Overlay: report.Topology{ Nodes: report.Nodes{ "router": report.MakeNode("router").WithSets(report.EmptySets. Add(host.LocalNetworks, report.MakeStringSet("10.32.0.1/12")), ), }, }, }) want := report.Networks([]*net.IPNet{ mustParseCIDR("10.0.0.1/8"), mustParseCIDR("192.168.1.1/24"), mustParseCIDR("10.32.0.1/12"), }) have := render.LocalNetworks(r) if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func (r *Reporter) containerTopology(localAddrs []net.IP) report.Topology { result := report.MakeTopology(). WithMetadataTemplates(ContainerMetadataTemplates). WithMetricTemplates(ContainerMetricTemplates). WithTableTemplates(ContainerTableTemplates) result.Controls.AddControls(ContainerControls) metadata := map[string]string{report.ControlProbeID: r.probeID} nodes := []report.Node{} r.registry.WalkContainers(func(c Container) { nodes = append(nodes, c.GetNode().WithLatests(metadata)) }) // Copy the IP addresses from other containers where they share network // namespaces & deal with containers in the host net namespace. This // is recursive to deal with people who decide to be clever. { hostNetworkInfo := report.EmptySets if hostIPs, err := getLocalIPs(); err == nil { hostIPsWithScopes := addScopeToIPs(r.hostID, hostIPs) hostNetworkInfo = hostNetworkInfo. Add(ContainerIPs, report.MakeStringSet(hostIPs...)). Add(ContainerIPsWithScopes, report.MakeStringSet(hostIPsWithScopes...)) } var networkInfo func(prefix string) report.Sets networkInfo = func(prefix string) report.Sets { container, ok := r.registry.GetContainerByPrefix(prefix) if !ok { return report.EmptySets } networkMode, ok := container.NetworkMode() if ok && strings.HasPrefix(networkMode, "container:") { return networkInfo(networkMode[10:]) } else if ok && networkMode == NetworkModeHost { return hostNetworkInfo } return container.NetworkInfo(localAddrs) } for _, node := range nodes { id, ok := report.ParseContainerNodeID(node.ID) if !ok { continue } networkInfo := networkInfo(id) result.AddNode(node.WithSets(networkInfo)) } } return result }
func (c *container) NetworkInfo(localAddrs []net.IP) report.Sets { c.RLock() defer c.RUnlock() ips := c.container.NetworkSettings.SecondaryIPAddresses if c.container.NetworkSettings.IPAddress != "" { ips = append(ips, c.container.NetworkSettings.IPAddress) } // Treat all Docker IPs as local scoped. ipsWithScopes := addScopeToIPs(c.hostID, ips) return report.EmptySets. Add(ContainerPorts, c.ports(localAddrs)). Add(ContainerIPs, report.MakeStringSet(ips...)). Add(ContainerIPsWithScopes, report.MakeStringSet(ipsWithScopes...)) }
// Tag implements Tagger. func (w *Weave) Tag(r report.Report) (report.Report, error) { w.mtx.RLock() defer w.mtx.RUnlock() // Put information from weaveDNS on the container nodes for _, entry := range w.statusCache.DNS.Entries { if entry.Tombstone > 0 { continue } nodeID := report.MakeContainerNodeID(entry.ContainerID) node, ok := r.Container.Nodes[nodeID] if !ok { continue } w, _ := node.Latest.Lookup(WeaveDNSHostname) hostnames := report.IDList(strings.Fields(w)) hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, ".")) r.Container.Nodes[nodeID] = node.WithLatests(map[string]string{WeaveDNSHostname: strings.Join(hostnames, " ")}) } // Put information from weave ps on the container nodes const maxPrefixSize = 12 for id, node := range r.Container.Nodes { prefix, ok := node.Latest.Lookup(docker.ContainerID) if !ok { continue } if len(prefix) > maxPrefixSize { prefix = prefix[:maxPrefixSize] } entry, ok := w.psCache[prefix] if !ok { continue } ipsWithScope := report.MakeStringSet() for _, ip := range entry.IPs { ipsWithScope = ipsWithScope.Add(report.MakeAddressNodeID("", ip)) } node = node.WithSet(docker.ContainerIPs, report.MakeStringSet(entry.IPs...)) node = node.WithSet(docker.ContainerIPsWithScopes, ipsWithScope) node = node.WithLatests(map[string]string{ WeaveMACAddress: entry.MACAddress, }) r.Container.Nodes[id] = node } return r, nil }
func TestContainerHostnameFilterRenderer(t *testing.T) { // add a system container into the topology and ensure // it is filtered out correctly. input := fixture.Report.Copy() clientContainer2ID := "f6g7h8i9j1" clientContainer2NodeID := report.MakeContainerNodeID(clientContainer2ID) input.Container.AddNode(report.MakeNodeWith(clientContainer2NodeID, map[string]string{ docker.LabelPrefix + "works.weave.role": "system", docker.ContainerHostname: fixture.ClientContainerHostname, report.HostNodeID: fixture.ClientHostNodeID, }). WithParents(report.EmptySets. Add("host", report.MakeStringSet(fixture.ClientHostNodeID)), ).WithTopology(report.Container)) have := Prune(render.ContainerHostnameRenderer.Render(input, render.FilterApplication)) want := Prune(expected.RenderedContainerHostnames) // Test works by virtue of the RenderedContainerHostname only having a container // counter == 1 if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func TestTagger(t *testing.T) { var ( hostID = "foo" endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored node = report.MakeNodeWith(endpointNodeID, map[string]string{"foo": "bar"}) ) r := report.MakeReport() r.Process.AddNode(node) rpt, _ := host.NewTagger(hostID).Tag(r) have := rpt.Process.Nodes[endpointNodeID].Copy() // It should now have the host ID wantHostID := report.MakeHostNodeID(hostID) if hostID, ok := have.Latest.Lookup(report.HostNodeID); !ok || hostID != wantHostID { t.Errorf("Expected %q got %q", wantHostID, report.MakeHostNodeID(hostID)) } // It should still have the other keys want := "bar" if have, ok := have.Latest.Lookup("foo"); !ok || have != want { t.Errorf("Expected %q got %q", want, have) } // It should have the host as a parent wantParent := report.MakeHostNodeID(hostID) if have, ok := have.Parents.Lookup(report.Host); !ok || len(have) != 1 || have[0] != wantParent { t.Errorf("Expected %q got %q", report.MakeStringSet(wantParent), have) } }
func (r *Reporter) addConnection(rpt *report.Report, t fourTuple, extraFromNode, extraToNode map[string]string) { // Update endpoint topology if !r.includeProcesses { return } var ( fromEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.fromAddr, strconv.Itoa(int(t.fromPort))) toEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.toAddr, strconv.Itoa(int(t.toPort))) fromNode = report.MakeNodeWith(fromEndpointNodeID, map[string]string{ Addr: t.fromAddr, Port: strconv.Itoa(int(t.fromPort)), }).WithEdge(toEndpointNodeID, report.EdgeMetadata{}) toNode = report.MakeNodeWith(toEndpointNodeID, map[string]string{ Addr: t.toAddr, Port: strconv.Itoa(int(t.toPort)), }) ) // In case we have a reverse resolution for the IP, we can use it for // the name... if toNames, err := r.reverseResolver.get(t.toAddr); err == nil { toNode = toNode.WithSet(ReverseDNSNames, report.MakeStringSet(toNames...)) } if extraFromNode != nil { fromNode = fromNode.WithLatests(extraFromNode) } if extraToNode != nil { toNode = toNode.WithLatests(extraToNode) } rpt.Endpoint = rpt.Endpoint.AddNode(fromNode) rpt.Endpoint = rpt.Endpoint.AddNode(toNode) }
// Report implements Reporter. func (w *Weave) Report() (report.Report, error) { w.mtx.RLock() defer w.mtx.RUnlock() r := report.MakeReport() r.Container = r.Container.WithMetadataTemplates(report.MetadataTemplates{ WeaveMACAddress: {ID: WeaveMACAddress, Label: "Weave MAC", From: report.FromLatest, Priority: 17}, WeaveDNSHostname: {ID: WeaveDNSHostname, Label: "Weave DNS Name", From: report.FromLatest, Priority: 18}, }) for _, peer := range w.statusCache.Router.Peers { r.Overlay.AddNode(report.MakeNodeWith(report.MakeOverlayNodeID(peer.Name), map[string]string{ WeavePeerName: peer.Name, WeavePeerNickName: peer.NickName, })) } if w.statusCache.IPAM.DefaultSubnet != "" { r.Overlay.AddNode( report.MakeNode(report.MakeOverlayNodeID(w.statusCache.Router.Name)).WithSets( report.MakeSets().Add(host.LocalNetworks, report.MakeStringSet(w.statusCache.IPAM.DefaultSubnet)), ), ) } return r, nil }
func TestMakeStringSet(t *testing.T) { for _, testcase := range []struct { input []string want report.StringSet }{ {input: nil, want: nil}, {input: []string{}, want: report.MakeStringSet()}, {input: []string{"a"}, want: report.MakeStringSet("a")}, {input: []string{"a", "a"}, want: report.MakeStringSet("a")}, {input: []string{"b", "c", "a"}, want: report.MakeStringSet("a", "b", "c")}, } { if want, have := testcase.want, report.MakeStringSet(testcase.input...); !reflect.DeepEqual(want, have) { t.Errorf("%v: want %v, have %v", testcase.input, want, have) } } }
func (t *Tagger) tag(tree process.Tree, topology *report.Topology) { for nodeID, node := range topology.Nodes { pidStr, ok := node.Latest.Lookup(process.PID) if !ok { continue } pid, err := strconv.ParseUint(pidStr, 10, 64) if err != nil { continue } var ( c Container candidate = int(pid) ) t.registry.LockedPIDLookup(func(lookup func(int) Container) { for { c = lookup(candidate) if c != nil { break } candidate, err = tree.GetParent(candidate) if err != nil { break } } }) if c == nil || ContainerIsStopped(c) || c.PID() == 1 { continue } topology.AddNode(report.MakeNodeWith(nodeID, map[string]string{ ContainerID: c.ID(), }).WithParents(report.EmptySets. Add(report.Container, report.MakeStringSet(report.MakeContainerNodeID(c.ID()))). Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID(c.Image()))), )) } }
func TestNodeTables(t *testing.T) { inputs := []struct { name string rpt report.Report node report.Node want []report.Table }{ { name: "container", rpt: report.Report{ Container: report.MakeTopology(). WithTableTemplates(docker.ContainerTableTemplates), }, node: report.MakeNodeWith(fixture.ClientContainerNodeID, map[string]string{ docker.ContainerID: fixture.ClientContainerID, docker.LabelPrefix + "label1": "label1value", docker.ContainerState: docker.StateRunning, }).WithTopology(report.Container).WithSets(report.EmptySets. Add(docker.ContainerIPs, report.MakeStringSet("10.10.10.0/24", "10.10.10.1/24")), ), want: []report.Table{ { ID: docker.EnvPrefix, Label: "Environment Variables", Rows: []report.MetadataRow{}, }, { ID: docker.LabelPrefix, Label: "Docker Labels", Rows: []report.MetadataRow{ { ID: "label_label1", Label: "label1", Value: "label1value", }, }, }, }, }, { name: "unknown topology", rpt: report.MakeReport(), node: report.MakeNodeWith(fixture.ClientContainerNodeID, map[string]string{ docker.ContainerID: fixture.ClientContainerID, }).WithTopology("foobar"), want: nil, }, } for _, input := range inputs { have := detailed.NodeTables(input.rpt, input.node) if !reflect.DeepEqual(input.want, have) { t.Errorf("%s: %s", input.name, test.Diff(input.want, have)) } } }
func TestSetsMerge(t *testing.T) { for _, testcase := range []struct { a, b report.Sets want map[string][]string }{ {report.EmptySets, report.EmptySets, map[string][]string{}}, { report.EmptySets, report.EmptySets.Add("a", report.MakeStringSet("b")), map[string][]string{"a": {"b"}}, }, { report.EmptySets, report.EmptySets.Add("a", report.MakeStringSet("b", "c")), map[string][]string{"a": {"b", "c"}}, }, { report.EmptySets.Add("a", report.MakeStringSet("1")).Add("b", report.MakeStringSet("2")), report.EmptySets.Add("c", report.MakeStringSet("3")).Add("b", report.MakeStringSet("3")), map[string][]string{"a": {"1"}, "b": {"2", "3"}, "c": {"3"}}, }, } { haveSets := testcase.a.Merge(testcase.b) have := map[string][]string{} keys := haveSets.Keys() for _, k := range keys { have[k], _ = haveSets.Lookup(k) } if !reflect.DeepEqual(testcase.want, have) { t.Errorf("%+v.Merge(%+v): want %+v, have %+v", testcase.a, testcase.b, testcase.want, have) } } }
func (c *container) getBaseNode() report.Node { result := report.MakeNodeWith(report.MakeContainerNodeID(c.ID()), map[string]string{ ContainerID: c.ID(), ContainerCreated: c.container.Created.Format(time.RFC822), ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "), ImageID: c.Image(), ContainerHostname: c.Hostname(), }).WithParents(report.EmptySets. Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID(c.Image()))), ) result = result.AddTable(LabelPrefix, c.container.Config.Labels) result = result.AddTable(EnvPrefix, c.env()) return result }
func TestParents(t *testing.T) { for _, c := range []struct { name string node report.Node want []detailed.Parent }{ { name: "Node accidentally tagged with itself", node: render.HostRenderer.Render(fixture.Report, render.FilterNoop)[fixture.ClientHostNodeID].WithParents( report.EmptySets.Add(report.Host, report.MakeStringSet(fixture.ClientHostNodeID)), ), want: nil, }, { node: render.HostRenderer.Render(fixture.Report, render.FilterNoop)[fixture.ClientHostNodeID], want: nil, }, { node: render.ContainerImageRenderer.Render(fixture.Report, render.FilterNoop)[fixture.ClientContainerImageNodeID], want: []detailed.Parent{ {ID: fixture.ClientHostNodeID, Label: fixture.ClientHostName, TopologyID: "hosts"}, }, }, { node: render.ContainerRenderer.Render(fixture.Report, render.FilterNoop)[fixture.ClientContainerNodeID], want: []detailed.Parent{ {ID: fixture.ClientContainerImageNodeID, Label: fixture.ClientContainerImageName, TopologyID: "containers-by-image"}, {ID: fixture.ClientHostNodeID, Label: fixture.ClientHostName, TopologyID: "hosts"}, {ID: fixture.ClientPodNodeID, Label: "pong-a", TopologyID: "pods"}, }, }, { node: render.ProcessRenderer.Render(fixture.Report, render.FilterNoop)[fixture.ClientProcess1NodeID], want: []detailed.Parent{ {ID: fixture.ClientContainerNodeID, Label: fixture.ClientContainerName, TopologyID: "containers"}, {ID: fixture.ClientContainerImageNodeID, Label: fixture.ClientContainerImageName, TopologyID: "containers-by-image"}, {ID: fixture.ClientHostNodeID, Label: fixture.ClientHostName, TopologyID: "hosts"}, }, }, } { name := c.name if name == "" { name = fmt.Sprintf("Node %q", c.node.ID) } if have := detailed.Parents(fixture.Report, c.node); !reflect.DeepEqual(c.want, have) { t.Errorf("%s: %s", name, test.Diff(c.want, have)) } } }
// Tag implements Tagger. func (t Tagger) Tag(r report.Report) (report.Report, error) { var ( metadata = map[string]string{report.HostNodeID: t.hostNodeID} parents = report.EmptySets.Add(report.Host, report.MakeStringSet(t.hostNodeID)) ) // Explicitly 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, r.Pod} { for _, node := range topology.Nodes { topology.AddNode(node.WithLatests(metadata).WithParents(parents)) } } return r, nil }
func (c *container) ports(localAddrs []net.IP) report.StringSet { if c.container.NetworkSettings == nil { return report.MakeStringSet() } ports := []string{} for port, bindings := range c.container.NetworkSettings.Ports { if len(bindings) == 0 { ports = append(ports, fmt.Sprintf("%s", port)) continue } for _, b := range bindings { if b.HostIP == "0.0.0.0" { for _, ip := range localAddrs { ports = append(ports, fmt.Sprintf("%s:%s->%s", ip, b.HostPort, port)) } } else { ports = append(ports, fmt.Sprintf("%s:%s->%s", b.HostIP, b.HostPort, port)) } } } return report.MakeStringSet(ports...) }
func TestStringSetContains(t *testing.T) { for _, testcase := range []struct { contents []string target string want bool }{ {nil, "foo", false}, {[]string{}, "foo", false}, {[]string{"a"}, "foo", false}, {[]string{"a", "foo"}, "foo", true}, {[]string{"foo", "b"}, "foo", true}, } { have := report.MakeStringSet(testcase.contents...).Contains(testcase.target) if testcase.want != have { t.Errorf("%+v.Contains(%q): want %v, have %v", testcase.contents, testcase.target, testcase.want, have) } } }
func TestNodeMetadata(t *testing.T) { inputs := []struct { name string node report.Node want []report.MetadataRow }{ { name: "container", node: report.MakeNodeWith(fixture.ClientContainerNodeID, map[string]string{ docker.ContainerID: fixture.ClientContainerID, docker.LabelPrefix + "label1": "label1value", docker.ContainerStateHuman: docker.StateRunning, }).WithTopology(report.Container).WithSets(report.EmptySets. Add(docker.ContainerIPs, report.MakeStringSet("10.10.10.0/24", "10.10.10.1/24")), ), want: []report.MetadataRow{ {ID: docker.ContainerID, Label: "ID", Value: fixture.ClientContainerID, Priority: 1}, {ID: docker.ContainerStateHuman, Label: "State", Value: "running", Priority: 2}, {ID: docker.ContainerIPs, Label: "IPs", Value: "10.10.10.0/24, 10.10.10.1/24", Priority: 14}, }, }, { name: "unknown topology", node: report.MakeNodeWith(fixture.ClientContainerNodeID, map[string]string{ docker.ContainerID: fixture.ClientContainerID, }).WithTopology("foobar"), want: nil, }, } for _, input := range inputs { have := detailed.NodeMetadata(fixture.Report, input.node) if !reflect.DeepEqual(input.want, have) { t.Errorf("%s: %s", input.name, test.Diff(input.want, have)) } } }
func (r *replicaSet) AddParent(topology, id string) { r.parents = r.parents.Add(topology, report.MakeStringSet(id)) }
func TestStringSetRemove(t *testing.T) { for _, testcase := range []struct { input report.StringSet strs []string want report.StringSet }{ {input: report.StringSet(nil), strs: []string{}, want: report.StringSet(nil)}, {input: report.MakeStringSet(), strs: []string{}, want: report.MakeStringSet()}, {input: report.MakeStringSet("a"), strs: []string{}, want: report.MakeStringSet("a")}, {input: report.MakeStringSet(), strs: []string{"a"}, want: report.MakeStringSet()}, {input: report.MakeStringSet("a"), strs: []string{"a"}, want: report.StringSet{}}, {input: report.MakeStringSet("b"), strs: []string{"a", "b"}, want: report.StringSet{}}, {input: report.MakeStringSet("a"), strs: []string{"c", "b"}, want: report.MakeStringSet("a")}, {input: report.MakeStringSet("a", "c"), strs: []string{"b", "b", "b"}, want: report.MakeStringSet("a", "c")}, } { if want, have := testcase.want, testcase.input.Remove(testcase.strs...); !reflect.DeepEqual(want, have) { t.Errorf("%v - %v: want %#v, have %#v", testcase.input, testcase.strs, want, have) } } }
endpoint.Addr: GoogleIP, endpoint.Port: GooglePort, endpoint.Procspied: True, }), }, }, Process: report.Topology{ Nodes: report.Nodes{ ClientProcess1NodeID: report.MakeNodeWith(ClientProcess1NodeID, map[string]string{ process.PID: Client1PID, process.Name: Client1Name, docker.ContainerID: ClientContainerID, report.HostNodeID: ClientHostNodeID, }). WithTopology(report.Process).WithParents(report.EmptySets. Add("host", report.MakeStringSet(ClientHostNodeID)). Add("container", report.MakeStringSet(ClientContainerNodeID)). Add("container_image", report.MakeStringSet(ClientContainerImageNodeID)), ).WithMetrics(report.Metrics{ process.CPUUsage: ClientProcess1CPUMetric, process.MemoryUsage: ClientProcess1MemoryMetric, }), ClientProcess2NodeID: report.MakeNodeWith(ClientProcess2NodeID, map[string]string{ process.PID: Client2PID, process.Name: Client2Name, docker.ContainerID: ClientContainerID, report.HostNodeID: ClientHostNodeID, }). WithTopology(report.Process).WithParents(report.EmptySets. Add("host", report.MakeStringSet(ClientHostNodeID)). Add("container", report.MakeStringSet(ClientContainerNodeID)).
func (p *pod) AddParent(topology, id string) { p.parents = p.parents.Add(topology, report.MakeStringSet(id)) }
func TestStringSetMerge(t *testing.T) { for _, testcase := range []struct { input report.StringSet other report.StringSet want report.StringSet }{ {input: report.StringSet(nil), other: report.StringSet(nil), want: report.StringSet(nil)}, {input: report.MakeStringSet(), other: report.MakeStringSet(), want: report.MakeStringSet()}, {input: report.MakeStringSet("a"), other: report.MakeStringSet(), want: report.MakeStringSet("a")}, {input: report.MakeStringSet(), other: report.MakeStringSet("a"), want: report.MakeStringSet("a")}, {input: report.MakeStringSet("a"), other: report.MakeStringSet("b"), want: report.MakeStringSet("a", "b")}, {input: report.MakeStringSet("b"), other: report.MakeStringSet("a"), want: report.MakeStringSet("a", "b")}, {input: report.MakeStringSet("a"), other: report.MakeStringSet("a"), want: report.MakeStringSet("a")}, {input: report.MakeStringSet("a", "c"), other: report.MakeStringSet("a", "b"), want: report.MakeStringSet("a", "b", "c")}, {input: report.MakeStringSet("b"), other: report.MakeStringSet("a"), want: report.MakeStringSet("a", "b")}, } { if want, have := testcase.want, testcase.input.Merge(testcase.other); !reflect.DeepEqual(want, have) { t.Errorf("%v + %v: want %v, have %v", testcase.input, testcase.other, want, have) } } }
func TestContainer(t *testing.T) { log.SetOutput(ioutil.Discard) oldDialStub, oldNewClientConnStub := docker.DialStub, docker.NewClientConnStub defer func() { docker.DialStub, docker.NewClientConnStub = oldDialStub, oldNewClientConnStub }() docker.DialStub = func(network, address string) (net.Conn, error) { return nil, nil } reader, writer := io.Pipe() connection := &mockConnection{reader} docker.NewClientConnStub = func(c net.Conn, r *bufio.Reader) docker.ClientConn { return connection } now := time.Unix(12345, 67890).UTC() mtime.NowForce(now) defer mtime.NowReset() const hostID = "scope" c := docker.NewContainer(container1, hostID) err := c.StartGatheringStats() if err != nil { t.Errorf("%v", err) } defer c.StopGatheringStats() // Send some stats to the docker container stats := &client.Stats{} stats.Read = now stats.MemoryStats.Usage = 12345 stats.MemoryStats.Limit = 45678 encoder := codec.NewEncoder(writer, &codec.JsonHandle{}) if err = encoder.Encode(&stats); err != nil { t.Error(err) } // Now see if we go them { uptime := (now.Sub(startTime) / time.Second) * time.Second want := report.MakeNodeWith("ping;<container>", map[string]string{ "docker_container_command": " ", "docker_container_created": "01 Jan 01 00:00 UTC", "docker_container_id": "ping", "docker_container_name": "pong", "docker_image_id": "baz", "docker_label_foo1": "bar1", "docker_label_foo2": "bar2", "docker_container_state": "running", "docker_container_state_human": "Up 6 years", "docker_container_uptime": uptime.String(), }). WithControls( docker.RestartContainer, docker.StopContainer, docker.PauseContainer, docker.AttachContainer, docker.ExecContainer, ).WithMetrics(report.Metrics{ "docker_cpu_total_usage": report.MakeMetric(), "docker_memory_usage": report.MakeMetric().Add(now, 12345).WithMax(45678), }).WithParents(report.EmptySets. Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID("baz"))), ) test.Poll(t, 100*time.Millisecond, want, func() interface{} { node := c.GetNode() node.Latest.ForEach(func(k, v string) { if v == "0" || v == "" { node.Latest = node.Latest.Delete(k) } }) return node }) } { want := report.EmptySets. Add("docker_container_ports", report.MakeStringSet("1.2.3.4:80->80/tcp", "81/tcp")). Add("docker_container_ips", report.MakeStringSet("1.2.3.4")). Add("docker_container_ips_with_scopes", report.MakeStringSet(";1.2.3.4")) test.Poll(t, 100*time.Millisecond, want, func() interface{} { return c.NetworkInfo([]net.IP{}) }) } if c.Image() != "baz" { t.Errorf("%s != baz", c.Image()) } if c.PID() != 2 { t.Errorf("%d != 2", c.PID()) } node := c.GetNode().WithSets(c.NetworkInfo([]net.IP{})) if have := docker.ExtractContainerIPs(node); !reflect.DeepEqual(have, []string{"1.2.3.4"}) { t.Errorf("%v != %v", have, []string{"1.2.3.4"}) } }
func TestWeaveTaggerOverlayTopology(t *testing.T) { w := overlay.NewWeave(mockHostID, weave.MockClient{}) defer w.Stop() // Wait until the reporter reports some nodes test.Poll(t, 300*time.Millisecond, 1, func() interface{} { have, _ := w.Report() return len(have.Overlay.Nodes) }) { // Overlay node should include peer name and nickname have, err := w.Report() if err != nil { t.Fatal(err) } nodeID := report.MakeOverlayNodeID(weave.MockWeavePeerName) node, ok := have.Overlay.Nodes[nodeID] if !ok { t.Errorf("Expected overlay node %q, but not found", nodeID) } if peerName, ok := node.Latest.Lookup(overlay.WeavePeerName); !ok || peerName != weave.MockWeavePeerName { t.Errorf("Expected weave peer name %q, got %q", weave.MockWeavePeerName, peerName) } if peerNick, ok := node.Latest.Lookup(overlay.WeavePeerNickName); !ok || peerNick != weave.MockWeavePeerNickName { t.Errorf("Expected weave peer nickname %q, got %q", weave.MockWeavePeerNickName, peerNick) } if localNetworks, ok := node.Sets.Lookup(host.LocalNetworks); !ok || !reflect.DeepEqual(localNetworks, report.MakeStringSet(weave.MockWeaveDefaultSubnet)) { t.Errorf("Expected weave node local_networks %q, got %q", report.MakeStringSet(weave.MockWeaveDefaultSubnet), localNetworks) } } { // Container nodes should be tagged with their overlay info nodeID := report.MakeContainerNodeID(weave.MockContainerID) have, err := w.Tag(report.Report{ Container: report.MakeTopology().AddNode(report.MakeNodeWith(nodeID, map[string]string{ docker.ContainerID: weave.MockContainerID, })), }) if err != nil { t.Fatal(err) } node, ok := have.Container.Nodes[nodeID] if !ok { t.Errorf("Expected container node %q, but not found", nodeID) } // Should have Weave DNS Hostname if have, ok := node.Latest.Lookup(overlay.WeaveDNSHostname); !ok || have != weave.MockHostname { t.Errorf("Expected weave dns hostname %q, got %q", weave.MockHostname, have) } // Should have Weave MAC Address if have, ok := node.Latest.Lookup(overlay.WeaveMACAddress); !ok || have != weave.MockContainerMAC { t.Errorf("Expected weave mac address %q, got %q", weave.MockContainerMAC, have) } // Should have Weave container ip if have, ok := node.Sets.Lookup(docker.ContainerIPs); !ok || !have.Contains(weave.MockContainerIP) { t.Errorf("Expected container ips to include the weave IP %q, got %q", weave.MockContainerIP, have) } // Should have Weave container ip (with scope) if have, ok := node.Sets.Lookup(docker.ContainerIPsWithScopes); !ok || !have.Contains(mockContainerIPWithScope) { t.Errorf("Expected container ips to include the weave IP (with scope) %q, got %q", mockContainerIPWithScope, have) } } }
func (r *replicationController) AddParent(topology, id string) { r.parents = r.parents.Add(topology, report.MakeStringSet(id)) }
endpoint.Addr: duplicatedIP, endpoint.Port: duplicatedPort, endpoint.Conntracked: "true", }). WithTopology(report.Endpoint), }, }, Container: report.Topology{ Nodes: report.Nodes{ container1NodeID: report.MakeNodeWith(container1NodeID, map[string]string{ docker.ContainerID: container1ID, docker.ContainerName: container1Name, report.HostNodeID: serverHostNodeID, }). WithSets(report.EmptySets. Add(docker.ContainerIPs, report.MakeStringSet(container1IP)). Add(docker.ContainerIPsWithScopes, report.MakeStringSet(report.MakeAddressNodeID("", container1IP))). Add(docker.ContainerPorts, report.MakeStringSet(fmt.Sprintf("%s:%s->%s/tcp", serverIP, serverPort, serverPort))), ).WithTopology(report.Container), container2NodeID: report.MakeNodeWith(container2NodeID, map[string]string{ docker.ContainerID: container2ID, docker.ContainerName: container2Name, report.HostNodeID: serverHostNodeID, }). WithSets(report.EmptySets. Add(docker.ContainerIPs, report.MakeStringSet(container2IP)). Add(docker.ContainerIPsWithScopes, report.MakeStringSet(report.MakeAddressNodeID("", container2IP))), ).WithTopology(report.Container), pauseContainerNodeID: report.MakeNodeWith(pauseContainerNodeID, map[string]string{ docker.ContainerID: pauseContainerID, docker.ContainerName: pauseContainerName,