Пример #1
0
func TestTagger(t *testing.T) {
	oldProcessTree := docker.NewProcessTreeStub
	defer func() { docker.NewProcessTreeStub = oldProcessTree }()

	docker.NewProcessTreeStub = func(_ process.Walker) (process.Tree, error) {
		return &mockProcessTree{map[int]int{2: 1}}, nil
	}

	var (
		pid1NodeID       = report.MakeProcessNodeID("somehost.com", "1")
		pid2NodeID       = report.MakeProcessNodeID("somehost.com", "2")
		wantNodeMetadata = report.MakeNodeMetadataWith(map[string]string{docker.ContainerID: "ping"})
	)

	input := report.MakeReport()
	input.Process.NodeMetadatas[pid1NodeID] = report.MakeNodeMetadataWith(map[string]string{"pid": "1"})
	input.Process.NodeMetadatas[pid2NodeID] = report.MakeNodeMetadataWith(map[string]string{"pid": "2"})

	want := report.MakeReport()
	want.Process.NodeMetadatas[pid1NodeID] = report.MakeNodeMetadataWith(map[string]string{"pid": "1"}).Merge(wantNodeMetadata)
	want.Process.NodeMetadatas[pid2NodeID] = report.MakeNodeMetadataWith(map[string]string{"pid": "2"}).Merge(wantNodeMetadata)

	tagger := docker.NewTagger(mockRegistryInstance, nil)
	have, err := tagger.Tag(input)
	if err != nil {
		t.Errorf("%v", err)
	}
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Пример #2
0
func TestReporter(t *testing.T) {
	want := report.MakeReport()
	want.Container = report.Topology{
		Adjacency:     report.Adjacency{},
		EdgeMetadatas: report.EdgeMetadatas{},
		NodeMetadatas: report.NodeMetadatas{
			report.MakeContainerNodeID("", "ping"): report.MakeNodeMetadataWith(map[string]string{
				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.MakeNodeMetadataWith(map[string]string{
				docker.ImageID:   "baz",
				docker.ImageName: "bang",
			}),
		},
	}

	reporter := docker.NewReporter(mockRegistryInstance, "")
	have, _ := reporter.Report()
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Пример #3
0
func TestApply(t *testing.T) {
	var (
		endpointNodeID       = "c"
		addressNodeID        = "d"
		endpointNodeMetadata = report.MakeNodeMetadataWith(map[string]string{"5": "6"})
		addressNodeMetadata  = report.MakeNodeMetadataWith(map[string]string{"7": "8"})
	)

	r := report.MakeReport()
	r.Endpoint.NodeMetadatas[endpointNodeID] = endpointNodeMetadata
	r.Address.NodeMetadatas[addressNodeID] = addressNodeMetadata
	r = Apply(r, []Tagger{newTopologyTagger()})

	for _, tuple := range []struct {
		want report.NodeMetadata
		from report.Topology
		via  string
	}{
		{endpointNodeMetadata.Merge(report.MakeNodeMetadataWith(map[string]string{"topology": "endpoint"})), r.Endpoint, endpointNodeID},
		{addressNodeMetadata.Merge(report.MakeNodeMetadataWith(map[string]string{"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)
		}
	}
}
Пример #4
0
func TestReporter(t *testing.T) {
	walker := &mockWalker{
		processes: []process.Process{
			{PID: 1, PPID: 0, Comm: "init"},
			{PID: 2, PPID: 1, Comm: "bash"},
			{PID: 3, PPID: 1, Comm: "apache", Threads: 2},
			{PID: 4, PPID: 2, Comm: "ping", Cmdline: "ping foo.bar.local"},
			{PID: 5, PPID: 1, Cmdline: "tail -f /var/log/syslog"},
		},
	}

	reporter := process.NewReporter(walker, "")
	want := report.MakeReport()
	want.Process = report.Topology{
		Adjacency:     report.Adjacency{},
		EdgeMetadatas: report.EdgeMetadatas{},
		NodeMetadatas: report.NodeMetadatas{
			report.MakeProcessNodeID("", "1"): report.MakeNodeMetadataWith(map[string]string{
				process.PID:     "1",
				process.Comm:    "init",
				process.Threads: "0",
			}),
			report.MakeProcessNodeID("", "2"): report.MakeNodeMetadataWith(map[string]string{
				process.PID:     "2",
				process.Comm:    "bash",
				process.PPID:    "1",
				process.Threads: "0",
			}),
			report.MakeProcessNodeID("", "3"): report.MakeNodeMetadataWith(map[string]string{
				process.PID:     "3",
				process.Comm:    "apache",
				process.PPID:    "1",
				process.Threads: "2",
			}),
			report.MakeProcessNodeID("", "4"): report.MakeNodeMetadataWith(map[string]string{
				process.PID:     "4",
				process.Comm:    "ping",
				process.PPID:    "2",
				process.Cmdline: "ping foo.bar.local",
				process.Threads: "0",
			}),
			report.MakeProcessNodeID("", "5"): report.MakeNodeMetadataWith(map[string]string{
				process.PID:     "5",
				process.PPID:    "1",
				process.Cmdline: "tail -f /var/log/syslog",
				process.Threads: "0",
			}),
		},
	}

	have, err := reporter.Report()
	if err != nil || !reflect.DeepEqual(want, have) {
		t.Errorf("%s (%v)", test.Diff(want, have), err)
	}
}
Пример #5
0
func TestMapEndpointIdentity(t *testing.T) {
	for _, input := range []testcase{
		{report.MakeNodeMetadata(), false},
		{report.MakeNodeMetadataWith(map[string]string{endpoint.Addr: "1.2.3.4"}), false},
		{report.MakeNodeMetadataWith(map[string]string{endpoint.Port: "1234"}), false},
		{report.MakeNodeMetadataWith(map[string]string{endpoint.Addr: "1.2.3.4", endpoint.Port: "1234"}), true},
		{report.MakeNodeMetadataWith(map[string]string{report.HostNodeID: report.MakeHostNodeID("foo"), endpoint.Addr: "10.0.0.1", endpoint.Port: "20001"}), true},
	} {
		testMap(t, render.MapEndpointIdentity, input)
	}
}
Пример #6
0
// Report implements Reporter.
func (w Weave) Report() (report.Report, error) {
	r := report.MakeReport()

	resp, err := http.Get(w.url)
	if err != nil {
		log.Printf("Weave Tagger: %v", err)
		return r, err
	}
	defer resp.Body.Close()

	var status struct {
		Peers []struct {
			Name     string `json:"Name"`
			NickName string `json:"NickName"`
		} `json:"Peers"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&status); err != nil {
		log.Printf("Weave Tagger: %v", err)
		return r, err
	}

	for _, peer := range status.Peers {
		r.Overlay.NodeMetadatas[report.MakeOverlayNodeID(peer.Name)] = report.MakeNodeMetadataWith(map[string]string{
			WeavePeerName:     peer.Name,
			WeavePeerNickName: peer.NickName,
		})
	}
	return r, nil
}
Пример #7
0
// Report implements Reporter.
func (r *Reporter) Report() (report.Report, error) {
	var (
		rep        = report.MakeReport()
		localCIDRs []string
	)

	for _, localNet := range r.localNets {
		localCIDRs = append(localCIDRs, localNet.String())
	}

	uptime, err := GetUptime()
	if err != nil {
		return rep, err
	}

	kernel, err := GetKernelVersion()
	if err != nil {
		return rep, err
	}

	rep.Host.NodeMetadatas[report.MakeHostNodeID(r.hostID)] = report.MakeNodeMetadataWith(map[string]string{
		Timestamp:     Now(),
		HostName:      r.hostName,
		LocalNetworks: strings.Join(localCIDRs, " "),
		OS:            runtime.GOOS,
		Load:          GetLoad(),
		KernelVersion: kernel,
		Uptime:        uptime.String(),
	})

	return rep, nil
}
Пример #8
0
func (c *mockContainer) GetNodeMetadata() report.NodeMetadata {
	return report.MakeNodeMetadataWith(map[string]string{
		docker.ContainerID:   c.c.ID,
		docker.ContainerName: c.c.Name,
		docker.ImageID:       c.c.Image,
	})
}
Пример #9
0
func TestWeaveTaggerOverlayTopology(t *testing.T) {
	s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter))
	defer s.Close()

	w, err := overlay.NewWeave(s.URL)
	if err != nil {
		t.Fatal(err)
	}

	have, err := w.Report()
	if err != nil {
		t.Fatal(err)
	}
	if want, have := (report.Topology{
		Adjacency:     report.Adjacency{},
		EdgeMetadatas: report.EdgeMetadatas{},
		NodeMetadatas: report.NodeMetadatas{
			report.MakeOverlayNodeID(mockWeavePeerName): report.MakeNodeMetadataWith(map[string]string{
				overlay.WeavePeerName:     mockWeavePeerName,
				overlay.WeavePeerNickName: mockWeavePeerNickName,
			}),
		},
	}), have.Overlay; !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Пример #10
0
func TestMapContainerImageIdentity(t *testing.T) {
	for _, input := range []testcase{
		{report.MakeNodeMetadata(), false},
		{report.MakeNodeMetadataWith(map[string]string{docker.ImageID: "a1b2c3"}), true},
	} {
		testMap(t, render.MapContainerImageIdentity, input)
	}
}
Пример #11
0
func TestMapAddressIdentity(t *testing.T) {
	for _, input := range []testcase{
		{report.MakeNodeMetadata(), false},
		{report.MakeNodeMetadataWith(map[string]string{endpoint.Addr: "192.168.1.1"}), true},
	} {
		testMap(t, render.MapAddressIdentity, input)
	}
}
Пример #12
0
func TestMapProcessIdentity(t *testing.T) {
	for _, input := range []testcase{
		{report.MakeNodeMetadata(), false},
		{report.MakeNodeMetadataWith(map[string]string{process.PID: "201"}), true},
	} {
		testMap(t, render.MapProcessIdentity, input)
	}
}
Пример #13
0
// Tag implements Tagger.
func (t Tagger) Tag(r report.Report) (report.Report, error) {
	other := report.MakeNodeMetadataWith(map[string]string{report.HostNodeID: t.hostNodeID})
	for _, topology := range r.Topologies() {
		for id, md := range topology.NodeMetadatas {
			topology.NodeMetadatas[id] = md.Merge(other)
		}
	}
	return r, nil
}
Пример #14
0
func TestTagger(t *testing.T) {
	var (
		hostID         = "foo"
		endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored
		nodeMetadata   = report.MakeNodeMetadataWith(map[string]string{"foo": "bar"})
	)

	r := report.MakeReport()
	r.Endpoint.NodeMetadatas[endpointNodeID] = nodeMetadata
	want := nodeMetadata.Merge(report.MakeNodeMetadataWith(map[string]string{
		report.HostNodeID: report.MakeHostNodeID(hostID),
	}))
	rpt, _ := host.NewTagger(hostID).Tag(r)
	have := rpt.Endpoint.NodeMetadatas[endpointNodeID].Copy()
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Пример #15
0
func (r *Reporter) addConnection(rpt *report.Report, c *procspy.Connection) {
	var (
		localAddressNodeID  = report.MakeAddressNodeID(r.hostID, c.LocalAddress.String())
		remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, c.RemoteAddress.String())
		adjecencyID         = report.MakeAdjacencyID(localAddressNodeID)
		edgeID              = report.MakeEdgeID(localAddressNodeID, remoteAddressNodeID)
	)

	rpt.Address.Adjacency[adjecencyID] = rpt.Address.Adjacency[adjecencyID].Add(remoteAddressNodeID)

	if _, ok := rpt.Address.NodeMetadatas[localAddressNodeID]; !ok {
		rpt.Address.NodeMetadatas[localAddressNodeID] = report.MakeNodeMetadataWith(map[string]string{
			"name": r.hostName,
			Addr:   c.LocalAddress.String(),
		})
	}

	countTCPConnection(rpt.Address.EdgeMetadatas, edgeID)

	if c.Proc.PID > 0 {
		var (
			localEndpointNodeID  = report.MakeEndpointNodeID(r.hostID, c.LocalAddress.String(), strconv.Itoa(int(c.LocalPort)))
			remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, c.RemoteAddress.String(), strconv.Itoa(int(c.RemotePort)))
			adjecencyID          = report.MakeAdjacencyID(localEndpointNodeID)
			edgeID               = report.MakeEdgeID(localEndpointNodeID, remoteEndpointNodeID)
		)

		rpt.Endpoint.Adjacency[adjecencyID] = rpt.Endpoint.Adjacency[adjecencyID].Add(remoteEndpointNodeID)

		if _, ok := rpt.Endpoint.NodeMetadatas[localEndpointNodeID]; !ok {
			// First hit establishes NodeMetadata for scoped local address + port
			md := report.MakeNodeMetadataWith(map[string]string{
				Addr:        c.LocalAddress.String(),
				Port:        strconv.Itoa(int(c.LocalPort)),
				process.PID: fmt.Sprint(c.Proc.PID),
			})

			rpt.Endpoint.NodeMetadatas[localEndpointNodeID] = md
		}

		countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID)
	}
}
Пример #16
0
func (c *container) GetNodeMetadata() report.NodeMetadata {
	c.RLock()
	defer c.RUnlock()

	result := report.MakeNodeMetadataWith(map[string]string{
		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,
		ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses,
			c.container.NetworkSettings.IPAddress), " "),
	})
	AddLabels(result, c.container.Config.Labels)

	if c.latestStats == nil {
		return result
	}

	result = result.Merge(report.MakeNodeMetadataWith(map[string]string{
		NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10),
		NetworkRxBytes:   strconv.FormatUint(c.latestStats.Network.RxBytes, 10),
		NetworkRxErrors:  strconv.FormatUint(c.latestStats.Network.RxErrors, 10),
		NetworkTxPackets: strconv.FormatUint(c.latestStats.Network.TxPackets, 10),
		NetworkTxDropped: strconv.FormatUint(c.latestStats.Network.TxDropped, 10),
		NetworkRxPackets: strconv.FormatUint(c.latestStats.Network.RxPackets, 10),
		NetworkTxErrors:  strconv.FormatUint(c.latestStats.Network.TxErrors, 10),
		NetworkTxBytes:   strconv.FormatUint(c.latestStats.Network.TxBytes, 10),

		MemoryMaxUsage: strconv.FormatUint(c.latestStats.MemoryStats.MaxUsage, 10),
		MemoryUsage:    strconv.FormatUint(c.latestStats.MemoryStats.Usage, 10),
		MemoryFailcnt:  strconv.FormatUint(c.latestStats.MemoryStats.Failcnt, 10),
		MemoryLimit:    strconv.FormatUint(c.latestStats.MemoryStats.Limit, 10),

		//		CPUPercpuUsage:       strconv.FormatUint(stats.CPUStats.CPUUsage.PercpuUsage, 10),
		CPUUsageInUsermode:   strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInUsermode, 10),
		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
}
Пример #17
0
func TestMapEdge(t *testing.T) {
	selector := func(_ report.Report) report.Topology {
		return report.Topology{
			NodeMetadatas: report.NodeMetadatas{
				"foo": report.MakeNodeMetadataWith(map[string]string{"id": "foo"}),
				"bar": report.MakeNodeMetadataWith(map[string]string{"id": "bar"}),
			},
			Adjacency: report.Adjacency{
				">foo": report.MakeIDList("bar"),
				">bar": report.MakeIDList("foo"),
			},
			EdgeMetadatas: report.EdgeMetadatas{
				"foo|bar": report.EdgeMetadata{EgressPacketCount: newu64(1), EgressByteCount: newu64(2)},
				"bar|foo": report.EdgeMetadata{EgressPacketCount: newu64(3), EgressByteCount: newu64(4)},
			},
		}
	}

	identity := func(nmd report.NodeMetadata) render.RenderableNodes {
		return render.RenderableNodes{nmd.Metadata["id"]: render.NewRenderableNode(nmd.Metadata["id"], "", "", "", nmd)}
	}

	mapper := render.Map{
		MapFunc: func(nodes render.RenderableNode) render.RenderableNodes {
			id := "_" + nodes.ID
			return render.RenderableNodes{id: render.RenderableNode{ID: id}}
		},
		Renderer: render.LeafMap{
			Selector: selector,
			Mapper:   identity,
			Pseudo:   nil,
		},
	}

	if want, have := (report.EdgeMetadata{
		EgressPacketCount: newu64(1),
		EgressByteCount:   newu64(2),
	}), mapper.EdgeMetadata(report.MakeReport(), "_foo", "_bar"); !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Пример #18
0
// Report implements Reporter.
func (w Weave) Report() (report.Report, error) {
	r := report.MakeReport()
	status, err := w.update()
	if err != nil {
		return r, err
	}

	for _, peer := range status.Router.Peers {
		r.Overlay.NodeMetadatas[report.MakeOverlayNodeID(peer.Name)] = report.MakeNodeMetadataWith(map[string]string{
			WeavePeerName:     peer.Name,
			WeavePeerNickName: peer.NickName,
		})
	}
	return r, nil
}
Пример #19
0
func TestReportLocalNetworks(t *testing.T) {
	r := report.MakeReport()
	r.Merge(report.Report{Host: report.Topology{NodeMetadatas: report.NodeMetadatas{
		"nonets": report.MakeNodeMetadata(),
		"foo":    report.MakeNodeMetadataWith(map[string]string{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"),
		mustParseCIDR("192.168.1.1/24"),
	})
	have := render.LocalNetworks(r)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Пример #20
0
func TestReporter(t *testing.T) {
	var (
		release     = "release"
		version     = "version"
		network     = "192.168.0.0/16"
		hostID      = "hostid"
		now         = "now"
		hostname    = "hostname"
		load        = "0.59 0.36 0.29"
		uptime      = "278h55m43s"
		kernel      = "release version"
		_, ipnet, _ = net.ParseCIDR(network)
		localNets   = report.Networks([]*net.IPNet{ipnet})
	)

	var (
		oldGetKernelVersion = host.GetKernelVersion
		oldGetLoad          = host.GetLoad
		oldGetUptime        = host.GetUptime
		oldNow              = host.Now
	)
	defer func() {
		host.GetKernelVersion = oldGetKernelVersion
		host.GetLoad = oldGetLoad
		host.GetUptime = oldGetUptime
		host.Now = oldNow
	}()
	host.GetKernelVersion = func() (string, error) { return release + " " + version, nil }
	host.GetLoad = func() string { return load }
	host.GetUptime = func() (time.Duration, error) { return time.ParseDuration(uptime) }
	host.Now = func() string { return now }

	want := report.MakeReport()
	want.Host.NodeMetadatas[report.MakeHostNodeID(hostID)] = report.MakeNodeMetadataWith(map[string]string{
		host.Timestamp:     now,
		host.HostName:      hostname,
		host.LocalNetworks: network,
		host.OS:            runtime.GOOS,
		host.Load:          load,
		host.Uptime:        uptime,
		host.KernelVersion: kernel,
	})
	have, _ := host.NewReporter(hostID, hostname, localNets).Report()
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Пример #21
0
// Tag implements Tagger
func (topologyTagger) Tag(r report.Report) (report.Report, error) {
	for val, topology := range map[string]*report.Topology{
		"endpoint":        &(r.Endpoint),
		"address":         &(r.Address),
		"process":         &(r.Process),
		"container":       &(r.Container),
		"container_image": &(r.ContainerImage),
		"host":            &(r.Host),
		"overlay":         &(r.Overlay),
	} {
		other := report.MakeNodeMetadataWith(map[string]string{Topology: val})
		for id, md := range topology.NodeMetadatas {
			topology.NodeMetadatas[id] = md.Merge(other)
		}
	}
	return r, nil
}
Пример #22
0
func (r *Reporter) processTopology() (report.Topology, error) {
	t := report.NewTopology()
	err := r.walker.Walk(func(p Process) {
		pidstr := strconv.Itoa(p.PID)
		nodeID := report.MakeProcessNodeID(r.scope, pidstr)
		t.NodeMetadatas[nodeID] = report.MakeNodeMetadataWith(map[string]string{
			PID:     pidstr,
			Comm:    p.Comm,
			Cmdline: p.Cmdline,
			Threads: strconv.Itoa(p.Threads),
		})
		if p.PPID > 0 {
			t.NodeMetadatas[nodeID].Metadata[PPID] = strconv.Itoa(p.PPID)
		}
	})

	return t, err
}
Пример #23
0
func (r *Reporter) containerImageTopology() report.Topology {
	result := report.NewTopology()

	r.registry.WalkImages(func(image *docker_client.APIImages) {
		nmd := report.MakeNodeMetadataWith(map[string]string{
			ImageID: image.ID,
		})

		if len(image.RepoTags) > 0 {
			nmd.Metadata[ImageName] = image.RepoTags[0]
		}

		nodeID := report.MakeContainerNodeID(r.scope, image.ID)
		result.NodeMetadatas[nodeID] = nmd
	})

	return result
}
Пример #24
0
func (t *Tagger) tag(tree process.Tree, topology *report.Topology) {
	for nodeID, nodeMetadata := range topology.NodeMetadatas {
		pidStr, ok := nodeMetadata.Metadata[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 {
			continue
		}

		md := report.MakeNodeMetadataWith(map[string]string{
			ContainerID: c.ID(),
		})

		topology.NodeMetadatas[nodeID] = nodeMetadata.Merge(md)
	}
}
Пример #25
0
func TestWeaveTaggerOverlayTopology(t *testing.T) {
	oldExecCmd := exec.Command
	defer func() { exec.Command = oldExecCmd }()
	exec.Command = func(name string, args ...string) exec.Cmd {
		return testExec.NewMockCmdString(fmt.Sprintf("%s %s %s/24\n", mockContainerID, mockContainerMAC, mockContainerIP))
	}

	s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter))
	defer s.Close()

	w, err := overlay.NewWeave(mockHostID, s.URL)
	if err != nil {
		t.Fatal(err)
	}

	{
		have, err := w.Report()
		if err != nil {
			t.Fatal(err)
		}
		if want, have := (report.Topology{
			Adjacency:     report.Adjacency{},
			EdgeMetadatas: report.EdgeMetadatas{},
			NodeMetadatas: report.NodeMetadatas{
				report.MakeOverlayNodeID(mockWeavePeerName): report.MakeNodeMetadataWith(map[string]string{
					overlay.WeavePeerName:     mockWeavePeerName,
					overlay.WeavePeerNickName: mockWeavePeerNickName,
				}),
			},
		}), have.Overlay; !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}

	{
		nodeID := report.MakeContainerNodeID(mockHostID, mockContainerID)
		want := report.Report{
			Container: report.Topology{
				NodeMetadatas: report.NodeMetadatas{
					nodeID: report.MakeNodeMetadataWith(map[string]string{
						docker.ContainerID:       mockContainerID,
						overlay.WeaveDNSHostname: mockHostname,
						overlay.WeaveMACAddress:  mockContainerMAC,
						docker.ContainerIPs:      mockContainerIP,
					}),
				},
			},
		}
		have, err := w.Tag(report.Report{
			Container: report.Topology{
				NodeMetadatas: report.NodeMetadatas{
					nodeID: report.MakeNodeMetadataWith(map[string]string{
						docker.ContainerID: mockContainerID,
					}),
				},
			},
		})
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}
Пример #26
0
			Adjacency: report.Adjacency{
				report.MakeAdjacencyID(Client54001NodeID):    report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(Client54002NodeID):    report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(UnknownClient1NodeID): report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(UnknownClient2NodeID): report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(UnknownClient3NodeID): report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(RandomClientNodeID):   report.MakeIDList(Server80NodeID),
				report.MakeAdjacencyID(NonContainerNodeID):   report.MakeIDList(GoogleEndpointNodeID),
			},
			NodeMetadatas: report.NodeMetadatas{
				// NodeMetadata is arbitrary. We're free to put only precisely what we
				// care to test into the fixture. Just be sure to include the bits
				// that the mapping funcs extract :)
				Client54001NodeID: report.MakeNodeMetadataWith(map[string]string{
					endpoint.Addr:     ClientIP,
					endpoint.Port:     ClientPort54001,
					process.PID:       Client1PID,
					report.HostNodeID: ClientHostNodeID,
				}),
				Client54002NodeID: report.MakeNodeMetadataWith(map[string]string{
					endpoint.Addr:     ClientIP,
					endpoint.Port:     ClientPort54002,
					process.PID:       Client2PID,
					report.HostNodeID: ClientHostNodeID,
				}),
				Server80NodeID: report.MakeNodeMetadataWith(map[string]string{
					endpoint.Addr:     ServerIP,
					endpoint.Port:     ServerPort,
					process.PID:       ServerPID,
					report.HostNodeID: ServerHostNodeID,
				}),
				NonContainerNodeID: report.MakeNodeMetadataWith(map[string]string{
Пример #27
0
func demoReport(nodeCount int) report.Report {
	r := report.MakeReport()

	// Make up some plausible IPv4 numbers.
	hosts := []string{}
	ip := [4]int{192, 168, 1, 1}
	for range make([]struct{}, nodeCount) {
		hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]))
		ip[3]++
		if ip[3] > 200 {
			ip[2]++
			ip[3] = 1
		}
	}
	hosts = append(hosts, []string{"1.2.3.4", "2.3.4.5"}...) // Some non-local ones, too.

	_, localNet, err := net.ParseCIDR("192.168.0.0/16")
	if err != nil {
		panic(err)
	}

	type conn struct {
		srcProc, dstProc string
		dstPort          int
	}
	procPool := []conn{
		{srcProc: "curl", dstPort: 80, dstProc: "apache"},
		{srcProc: "wget", dstPort: 80, dstProc: "apache"},
		{srcProc: "curl", dstPort: 80, dstProc: "nginx"},
		{srcProc: "curl", dstPort: 8080, dstProc: "app1"},
		{srcProc: "nginx", dstPort: 8080, dstProc: "app1"},
		{srcProc: "nginx", dstPort: 8080, dstProc: "app2"},
		{srcProc: "nginx", dstPort: 8080, dstProc: "app3"},
	}
	connectionCount := nodeCount * 2
	for i := 0; i < connectionCount; i++ {
		var (
			c                = procPool[rand.Intn(len(procPool))]
			src              = hosts[rand.Intn(len(hosts))]
			dst              = hosts[rand.Intn(len(hosts))]
			srcPort          = rand.Intn(50000) + 10000
			srcPortID        = report.MakeEndpointNodeID("", src, strconv.Itoa(srcPort))
			dstPortID        = report.MakeEndpointNodeID("", dst, strconv.Itoa(c.dstPort))
			srcID            = report.MakeAdjacencyID(srcPortID)
			dstID            = report.MakeAdjacencyID(dstPortID)
			srcAddressID     = report.MakeAddressNodeID("", src)
			dstAddressID     = report.MakeAddressNodeID("", dst)
			nodeSrcAddressID = report.MakeAdjacencyID(srcAddressID)
			nodeDstAddressID = report.MakeAdjacencyID(dstAddressID)
		)

		// Endpoint topology
		if _, ok := r.Endpoint.NodeMetadatas[srcPortID]; !ok {
			r.Endpoint.NodeMetadatas[srcPortID] = report.MakeNodeMetadataWith(map[string]string{
				process.PID: "4000",
				"name":      c.srcProc,
				"domain":    "node-" + src,
			})
		}
		r.Endpoint.Adjacency[srcID] = r.Endpoint.Adjacency[srcID].Add(dstPortID)
		if _, ok := r.Endpoint.NodeMetadatas[dstPortID]; !ok {
			r.Endpoint.NodeMetadatas[dstPortID] = report.MakeNodeMetadataWith(map[string]string{
				process.PID: "4000",
				"name":      c.dstProc,
				"domain":    "node-" + dst,
			})
		}
		r.Endpoint.Adjacency[dstID] = r.Endpoint.Adjacency[dstID].Add(srcPortID)
		var (
			edgeKeyEgress  = report.MakeEdgeID(srcPortID, dstPortID)
			edgeKeyIngress = report.MakeEdgeID(dstPortID, srcPortID)
		)
		r.Endpoint.EdgeMetadatas[edgeKeyEgress] = report.EdgeMetadata{
			MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)),
		}
		r.Endpoint.EdgeMetadatas[edgeKeyIngress] = report.EdgeMetadata{
			MaxConnCountTCP: newu64(uint64(rand.Intn(100) + 10)),
		}

		// Address topology
		if _, ok := r.Address.NodeMetadatas[srcAddressID]; !ok {
			r.Address.NodeMetadatas[srcAddressID] = report.MakeNodeMetadataWith(map[string]string{
				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.MakeNodeMetadataWith(map[string]string{
				docker.Name: dst,
			})
		}
		r.Address.Adjacency[nodeDstAddressID] = r.Address.Adjacency[nodeDstAddressID].Add(srcAddressID)

		// Host data
		r.Host.NodeMetadatas["hostX"] = report.MakeNodeMetadataWith(map[string]string{
			"ts":             time.Now().UTC().Format(time.RFC3339Nano),
			"host_name":      "host-x",
			"local_networks": localNet.String(),
			"os":             "linux",
		})
	}

	return r
}
Пример #28
0
func TestMergeNodeMetadatas(t *testing.T) {
	for name, c := range map[string]struct {
		a, b, want report.NodeMetadatas
	}{
		"Empty a": {
			a: report.NodeMetadatas{},
			b: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			want: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
		},
		"Empty b": {
			a: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			b: report.NodeMetadatas{},
			want: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
		},
		"Simple merge": {
			a: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			b: report.NodeMetadatas{
				":192.168.1.2:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "42",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			want: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
				":192.168.1.2:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "42",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
		},
		"Merge conflict": {
			a: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			b: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{ // <-- same ID
					PID:    "0",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
			want: report.NodeMetadatas{
				":192.168.1.1:12345": report.MakeNodeMetadataWith(map[string]string{
					PID:    "23128",
					Name:   "curl",
					Domain: "node-a.local",
				}),
			},
		},
	} {
		if have := c.a.Merge(c.b); !reflect.DeepEqual(c.want, have) {
			t.Errorf("%s: want\n\t%#v, have\n\t%#v", name, c.want, have)
		}
	}
}
Пример #29
0
func (r *Reporter) addConnection(rpt *report.Report, localAddr, remoteAddr string, localPort, remotePort uint16, proc *procspy.Proc) {
	localIsClient := int(localPort) > int(remotePort)

	// Update address topology
	{
		var (
			localAddressNodeID  = report.MakeAddressNodeID(r.hostID, localAddr)
			remoteAddressNodeID = report.MakeAddressNodeID(r.hostID, remoteAddr)
			adjacencyID         = ""
			edgeID              = ""
		)

		if localIsClient {
			adjacencyID = report.MakeAdjacencyID(localAddressNodeID)
			rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(remoteAddressNodeID)

			edgeID = report.MakeEdgeID(localAddressNodeID, remoteAddressNodeID)
		} else {
			adjacencyID = report.MakeAdjacencyID(remoteAddressNodeID)
			rpt.Address.Adjacency[adjacencyID] = rpt.Address.Adjacency[adjacencyID].Add(localAddressNodeID)

			edgeID = report.MakeEdgeID(remoteAddressNodeID, localAddressNodeID)
		}

		countTCPConnection(rpt.Address.EdgeMetadatas, edgeID)

		if _, ok := rpt.Address.NodeMetadatas[localAddressNodeID]; !ok {
			rpt.Address.NodeMetadatas[localAddressNodeID] = report.MakeNodeMetadataWith(map[string]string{
				"name": r.hostName,
				Addr:   localAddr,
			})
		}
	}

	// Update endpoint topology
	if r.includeProcesses {
		var (
			localEndpointNodeID  = report.MakeEndpointNodeID(r.hostID, localAddr, strconv.Itoa(int(localPort)))
			remoteEndpointNodeID = report.MakeEndpointNodeID(r.hostID, remoteAddr, strconv.Itoa(int(remotePort)))
			adjacencyID          = ""
			edgeID               = ""
		)

		if localIsClient {
			adjacencyID = report.MakeAdjacencyID(localEndpointNodeID)
			rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(remoteEndpointNodeID)

			edgeID = report.MakeEdgeID(localEndpointNodeID, remoteEndpointNodeID)
		} else {
			adjacencyID = report.MakeAdjacencyID(remoteEndpointNodeID)
			rpt.Endpoint.Adjacency[adjacencyID] = rpt.Endpoint.Adjacency[adjacencyID].Add(localEndpointNodeID)

			edgeID = report.MakeEdgeID(remoteEndpointNodeID, localEndpointNodeID)
		}

		countTCPConnection(rpt.Endpoint.EdgeMetadatas, edgeID)

		md, ok := rpt.Endpoint.NodeMetadatas[localEndpointNodeID]
		updated := !ok
		if !ok {
			md = report.MakeNodeMetadataWith(map[string]string{
				Addr: localAddr,
				Port: strconv.Itoa(int(localPort)),
			})
		}
		if proc != nil && proc.PID > 0 {
			pid := strconv.FormatUint(uint64(proc.PID), 10)
			updated = updated || md.Metadata[process.PID] != pid
			md.Metadata[process.PID] = pid
		}
		if updated {
			rpt.Endpoint.NodeMetadatas[localEndpointNodeID] = md
		}
	}
}