Example #1
0
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))
	}
}
Example #2
0
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
}
Example #3
0
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...))

}
Example #4
0
// 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
}
Example #5
0
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))
	}
}
Example #6
0
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)
	}
}
Example #7
0
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)
}
Example #8
0
// 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
}
Example #9
0
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)
		}
	}
}
Example #10
0
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()))),
		))

	}
}
Example #11
0
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))
		}
	}
}
Example #12
0
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)
		}
	}
}
Example #13
0
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
}
Example #14
0
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))
		}
	}
}
Example #15
0
// 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
}
Example #16
0
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...)
}
Example #17
0
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)
		}
	}
}
Example #18
0
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))
		}
	}
}
Example #19
0
func (r *replicaSet) AddParent(topology, id string) {
	r.parents = r.parents.Add(topology, report.MakeStringSet(id))
}
Example #20
0
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)
		}
	}
}
Example #21
0
					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)).
Example #22
0
func (p *pod) AddParent(topology, id string) {
	p.parents = p.parents.Add(topology, report.MakeStringSet(id))
}
Example #23
0
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)
		}
	}
}
Example #24
0
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"})
	}
}
Example #25
0
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)
		}
	}
}
Example #26
0
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,