Example #1
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.NewNodeMetadata(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.NewNodeMetadata(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))
	}
}
Example #2
0
func TestReporter(t *testing.T) {
	want := report.MakeReport()
	pod1ID := report.MakePodNodeID("ping", "pong-a")
	pod2ID := report.MakePodNodeID("ping", "pong-b")
	serviceID := report.MakeServiceNodeID("ping", "pongservice")
	want.Pod = report.MakeTopology().AddNode(pod1ID, report.MakeNodeWith(map[string]string{
		kubernetes.PodID:           "ping/pong-a",
		kubernetes.PodName:         "pong-a",
		kubernetes.Namespace:       "ping",
		kubernetes.PodCreated:      pod1.Created(),
		kubernetes.PodContainerIDs: "container1 container2",
		kubernetes.ServiceIDs:      "ping/pongservice",
	}).WithParents(report.Sets{
		report.Service: report.MakeStringSet(serviceID),
	})).AddNode(pod2ID, report.MakeNodeWith(map[string]string{
		kubernetes.PodID:           "ping/pong-b",
		kubernetes.PodName:         "pong-b",
		kubernetes.Namespace:       "ping",
		kubernetes.PodCreated:      pod1.Created(),
		kubernetes.PodContainerIDs: "container3 container4",
		kubernetes.ServiceIDs:      "ping/pongservice",
	}).WithParents(report.Sets{
		report.Service: report.MakeStringSet(serviceID),
	}))
	want.Service = report.MakeTopology().AddNode(serviceID, report.MakeNodeWith(map[string]string{
		kubernetes.ServiceID:      "ping/pongservice",
		kubernetes.ServiceName:    "pongservice",
		kubernetes.Namespace:      "ping",
		kubernetes.ServiceCreated: pod1.Created(),
	}))
	want.Container = report.MakeTopology().AddNode(report.MakeContainerNodeID("container1"), report.MakeNodeWith(map[string]string{
		kubernetes.PodID:     "ping/pong-a",
		kubernetes.Namespace: "ping",
	}).WithParents(report.Sets{
		report.Pod: report.MakeStringSet(pod1ID),
	})).AddNode(report.MakeContainerNodeID("container2"), report.MakeNodeWith(map[string]string{
		kubernetes.PodID:     "ping/pong-a",
		kubernetes.Namespace: "ping",
	}).WithParents(report.Sets{
		report.Pod: report.MakeStringSet(pod1ID),
	})).AddNode(report.MakeContainerNodeID("container3"), report.MakeNodeWith(map[string]string{
		kubernetes.PodID:     "ping/pong-b",
		kubernetes.Namespace: "ping",
	}).WithParents(report.Sets{
		report.Pod: report.MakeStringSet(pod2ID),
	})).AddNode(report.MakeContainerNodeID("container4"), report.MakeNodeWith(map[string]string{
		kubernetes.PodID:     "ping/pong-b",
		kubernetes.Namespace: "ping",
	}).WithParents(report.Sets{
		report.Pod: report.MakeStringSet(pod2ID),
	}))

	reporter := kubernetes.NewReporter(mockClientInstance)
	have, _ := reporter.Report()
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Example #3
0
func TestReporter(t *testing.T) {
	want := report.MakeReport()
	want.Container = report.Topology{
		Nodes: report.Nodes{
			report.MakeContainerNodeID("", "ping"): report.MakeNodeWith(map[string]string{
				docker.ContainerID:   "ping",
				docker.ContainerName: "pong",
				docker.ImageID:       "baz",
			}),
		},
		Controls: report.Controls{
			docker.RestartContainer: report.Control{
				ID:    docker.RestartContainer,
				Human: "Restart",
				Icon:  "fa-repeat",
			},
			docker.StartContainer: report.Control{
				ID:    docker.StartContainer,
				Human: "Start",
				Icon:  "fa-play",
			},
			docker.StopContainer: report.Control{
				ID:    docker.StopContainer,
				Human: "Stop",
				Icon:  "fa-stop",
			},
			docker.PauseContainer: report.Control{
				ID:    docker.PauseContainer,
				Human: "Pause",
				Icon:  "fa-pause",
			},
			docker.UnpauseContainer: report.Control{
				ID:    docker.UnpauseContainer,
				Human: "Unpause",
				Icon:  "fa-play",
			},
		},
	}
	want.ContainerImage = report.Topology{
		Nodes: report.Nodes{
			report.MakeContainerNodeID("", "baz"): report.MakeNodeWith(map[string]string{
				docker.ImageID:   "baz",
				docker.ImageName: "bang",
			}),
		},
		Controls: report.Controls{},
	}

	reporter := docker.NewReporter(mockRegistryInstance, "")
	have, _ := reporter.Report()
	if !reflect.DeepEqual(want, have) {
		t.Errorf("%s", test.Diff(want, have))
	}
}
Example #4
0
func TestControls(t *testing.T) {
	mdc := newMockClient()
	setupStubs(mdc, func() {
		registry, _ := docker.NewRegistry(10*time.Second, nil)
		defer registry.Stop()

		for _, tc := range []struct{ command, result string }{
			{docker.StopContainer, "stopped"},
			{docker.StartContainer, "started"},
			{docker.RestartContainer, "restarted"},
			{docker.PauseContainer, "paused"},
			{docker.UnpauseContainer, "unpaused"},
		} {
			result := controls.HandleControlRequest(xfer.Request{
				Control: tc.command,
				NodeID:  report.MakeContainerNodeID("a1b2c3d4e5"),
			})
			if !reflect.DeepEqual(result, xfer.Response{
				Error: tc.result,
			}) {
				t.Error(result)
			}
		}
	})
}
Example #5
0
// Tag implements Tagger.
func (w Weave) Tag(r report.Report) (report.Report, error) {
	status, err := w.update()
	if err != nil {
		return r, nil
	}

	for _, entry := range status.DNS.Entries {
		if entry.Tombstone > 0 {
			continue
		}
		nodeID := report.MakeContainerNodeID(w.hostID, entry.ContainerID)
		node, ok := r.Container.NodeMetadatas[nodeID]
		if !ok {
			continue
		}
		hostnames := report.IDList(strings.Fields(node.Metadata[WeaveDNSHostname]))
		hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, "."))
		node.Metadata[WeaveDNSHostname] = strings.Join(hostnames, " ")
		r.Container.NodeMetadatas[nodeID] = node
	}

	psEntries, err := w.ps()
	if err != nil {
		return r, nil
	}
	for _, e := range psEntries {
		w.tagContainer(r, e.containerIDPrefix, e.macAddress, e.ips)
	}
	return r, nil
}
Example #6
0
func TestPipes(t *testing.T) {
	oldNewPipe := controls.NewPipe
	defer func() { controls.NewPipe = oldNewPipe }()
	controls.NewPipe = func(_ controls.PipeClient, _ string) (string, xfer.Pipe, error) {
		return "pipeid", mockPipe{}, nil
	}

	mdc := newMockClient()
	setupStubs(mdc, func() {
		registry, _ := docker.NewRegistry(10*time.Second, nil)
		defer registry.Stop()

		test.Poll(t, 100*time.Millisecond, true, func() interface{} {
			_, ok := registry.GetContainer("ping")
			return ok
		})

		for _, tc := range []string{
			docker.AttachContainer,
			docker.ExecContainer,
		} {
			result := controls.HandleControlRequest(xfer.Request{
				Control: tc,
				NodeID:  report.MakeContainerNodeID("ping"),
			})
			want := xfer.Response{
				Pipe:   "pipeid",
				RawTTY: true,
			}
			if !reflect.DeepEqual(result, want) {
				t.Errorf("diff: %s", test.Diff(want, result))
			}
		}
	})
}
Example #7
0
func (r *Reporter) containerTopology(localAddrs []net.IP) report.Topology {
	result := report.MakeTopology()
	result.Controls.AddControl(report.Control{
		ID:    StopContainer,
		Human: "Stop",
		Icon:  "fa-stop",
	})
	result.Controls.AddControl(report.Control{
		ID:    StartContainer,
		Human: "Start",
		Icon:  "fa-play",
	})
	result.Controls.AddControl(report.Control{
		ID:    RestartContainer,
		Human: "Restart",
		Icon:  "fa-repeat",
	})
	result.Controls.AddControl(report.Control{
		ID:    PauseContainer,
		Human: "Pause",
		Icon:  "fa-pause",
	})
	result.Controls.AddControl(report.Control{
		ID:    UnpauseContainer,
		Human: "Unpause",
		Icon:  "fa-play",
	})

	r.registry.WalkContainers(func(c Container) {
		nodeID := report.MakeContainerNodeID(r.hostID, c.ID())
		result.AddNode(nodeID, c.GetNode(r.hostID, localAddrs))
	})

	return result
}
Example #8
0
func (r *Reporter) podTopology(services []Service) (report.Topology, report.Topology, error) {
	pods, containers := report.MakeTopology(), report.MakeTopology()
	selectors := map[string]labels.Selector{}
	for _, service := range services {
		selectors[service.ID()] = service.Selector()
	}
	err := r.client.WalkPods(func(p Pod) error {
		for serviceID, selector := range selectors {
			if selector.Matches(p.Labels()) {
				p.AddServiceID(serviceID)
			}
		}
		nodeID := report.MakePodNodeID(p.Namespace(), p.Name())
		pods = pods.AddNode(nodeID, p.GetNode())

		container := report.MakeNodeWith(map[string]string{
			PodID:     p.ID(),
			Namespace: p.Namespace(),
		}).WithParents(report.EmptySets.Add(report.Pod, report.MakeStringSet(nodeID)))
		for _, containerID := range p.ContainerIDs() {
			containers.AddNode(report.MakeContainerNodeID(containerID), container)
		}
		return nil
	})
	return pods, containers, err
}
Example #9
0
// MapProcess2Container maps process Nodes to container
// Nodes.
//
// If this function is given a node without a docker_container_id
// (including other pseudo nodes), it will produce an "Uncontained"
// pseudo node.
//
// Otherwise, this function will produce a node with the correct ID
// format for a container, but without any Major or Minor labels.
// It does not have enough info to do that, and the resulting graph
// must be merged with a container graph to get that info.
func MapProcess2Container(n report.Node, _ report.Networks) report.Nodes {
	// Propagate pseudo nodes
	if n.Topology == Pseudo {
		return report.Nodes{n.ID: n}
	}

	// Otherwise, if the process is not in a container, group it
	// 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.
	var (
		id   string
		node report.Node
	)
	if containerID, ok := n.Latest.Lookup(docker.ContainerID); ok {
		id = report.MakeContainerNodeID(containerID)
		node = NewDerivedNode(id, n).WithTopology(report.Container)
	} else {
		id = MakePseudoNodeID(UncontainedID, report.ExtractHostID(n))
		node = NewDerivedPseudoNode(id, n)
		node = propagateLatest(report.HostNodeID, n, node)
		node = propagateLatest(IsConnected, n, node)
	}
	return report.Nodes{id: node}
}
Example #10
0
func TestReporter(t *testing.T) {
	containerImageNodeID := report.MakeContainerImageNodeID("baz")
	rpt, err := docker.NewReporter(mockRegistryInstance, "host1", nil).Report()
	if err != nil {
		t.Fatal(err)
	}

	// Reporter should add a container
	{
		containerNodeID := report.MakeContainerNodeID("ping")
		node, ok := rpt.Container.Nodes[containerNodeID]
		if !ok {
			t.Fatalf("Expected report to have container image %q, but not found", containerNodeID)
		}

		for k, want := range map[string]string{
			docker.ContainerID:   "ping",
			docker.ContainerName: "pong",
			docker.ImageID:       "baz",
		} {
			if have, ok := node.Latest.Lookup(k); !ok || have != want {
				t.Errorf("Expected container %s latest %q: %q, got %q", containerNodeID, k, want, have)
			}
		}

		// container should have controls
		if len(rpt.Container.Controls) == 0 {
			t.Errorf("Container should have some controls")
		}

		// container should have the image as a parent
		if parents, ok := node.Parents.Lookup(report.ContainerImage); !ok || !parents.Contains(containerImageNodeID) {
			t.Errorf("Expected container %s to have parent container image %q, got %q", containerNodeID, containerImageNodeID, parents)
		}
	}

	// Reporter should add a container image
	{
		node, ok := rpt.ContainerImage.Nodes[containerImageNodeID]
		if !ok {
			t.Fatalf("Expected report to have container image %q, but not found", containerImageNodeID)
		}

		for k, want := range map[string]string{
			docker.ImageID:   "baz",
			docker.ImageName: "bang",
		} {
			if have, ok := node.Latest.Lookup(k); !ok || have != want {
				t.Errorf("Expected container image %s latest %q: %q, got %q", containerImageNodeID, k, want, have)
			}
		}

		// container image should have no controls
		if len(rpt.ContainerImage.Controls) != 0 {
			t.Errorf("Container images should not have any controls")
		}
	}
}
Example #11
0
func (r *Reporter) containerTopology() report.Topology {
	result := report.NewTopology()

	r.registry.WalkContainers(func(c Container) {
		nodeID := report.MakeContainerNodeID(r.scope, c.ID())
		result.NodeMetadatas[nodeID] = c.GetNodeMetadata()
	})

	return result
}
Example #12
0
func (r *Reporter) containerTopology() report.Topology {
	result := report.MakeTopology()

	r.registry.WalkContainers(func(c Container) {
		nodeID := report.MakeContainerNodeID(r.hostID, c.ID())
		result.AddNode(nodeID, c.GetNode())
	})

	return result
}
Example #13
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 := overlay.NewWeave(mockHostID, s.URL)
	defer w.Stop()
	w.Tick()

	{
		have, err := w.Report()
		if err != nil {
			t.Fatal(err)
		}
		if want, have := report.MakeTopology().AddNode(
			report.MakeOverlayNodeID(mockWeavePeerName),
			report.MakeNodeWith(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.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{
				docker.ContainerID:       mockContainerID,
				overlay.WeaveDNSHostname: mockHostname,
				overlay.WeaveMACAddress:  mockContainerMAC,
			}).WithSets(report.Sets{
				docker.ContainerIPs:           report.MakeStringSet(mockContainerIP),
				docker.ContainerIPsWithScopes: report.MakeStringSet(mockContainerIPWithScope),
			})),
		}
		have, err := w.Tag(report.Report{
			Container: report.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{
				docker.ContainerID: mockContainerID,
			})),
		})
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}
Example #14
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
		}

		node := report.MakeNodeWith(nodeID, map[string]string{
			ContainerID: c.ID(),
		}).WithParents(report.EmptySets.
			Add(report.Container, report.MakeStringSet(report.MakeContainerNodeID(c.ID()))),
		)

		// If we can work out the image name, add a parent tag for it
		image, ok := t.registry.GetContainerImage(c.Image())
		if ok && len(image.RepoTags) > 0 {
			imageName := ImageNameWithoutVersion(image.RepoTags[0])
			node = node.WithParents(report.EmptySets.
				Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID(imageName))),
			)
		}

		topology.AddNode(node)
	}
}
Example #15
0
// ContainerUpdated should be called whenever a container is updated.
func (r *Reporter) ContainerUpdated(c Container) {
	localAddrs, err := report.LocalAddresses()
	if err != nil {
		log.Errorf("Error getting local address: %v", err)
		return
	}

	// Publish a 'short cut' report container just this container
	rpt := report.MakeReport()
	rpt.Shortcut = true
	rpt.Container.AddNode(report.MakeContainerNodeID(c.ID()), c.GetNode(r.hostID, localAddrs))
	r.probe.Publish(rpt)
}
Example #16
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 #17
0
func TestTagger(t *testing.T) {
	mtime.NowForce(time.Now())
	defer mtime.NowReset()

	oldProcessTree := docker.NewProcessTreeStub
	defer func() { docker.NewProcessTreeStub = oldProcessTree }()

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

	var (
		pid1NodeID = report.MakeProcessNodeID("somehost.com", "2")
		pid2NodeID = report.MakeProcessNodeID("somehost.com", "3")
	)

	input := report.MakeReport()
	input.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"}))
	input.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"}))

	have, err := docker.NewTagger(mockRegistryInstance, nil).Tag(input)
	if err != nil {
		t.Errorf("%v", err)
	}

	// Processes should be tagged with their container ID, and parents
	for _, nodeID := range []string{pid1NodeID, pid2NodeID} {
		node, ok := have.Process.Nodes[nodeID]
		if !ok {
			t.Errorf("Expected process node %s, but not found", nodeID)
		}

		// node should have the container id added
		if have, ok := node.Latest.Lookup(docker.ContainerID); !ok || have != "ping" {
			t.Errorf("Expected process node %s to have container id %q, got %q", nodeID, "ping", have)
		}

		// node should have the container as a parent
		if have, ok := node.Parents.Lookup(report.Container); !ok || !have.Contains(report.MakeContainerNodeID("ping")) {
			t.Errorf("Expected process node %s to have container %q as a parent, got %q", nodeID, "ping", have)
		}

		// node should have the container image as a parent
		if have, ok := node.Parents.Lookup(report.ContainerImage); !ok || !have.Contains(report.MakeContainerImageNodeID("baz")) {
			t.Errorf("Expected process node %s to have container image %q as a parent, got %q", nodeID, "baz", have)
		}
	}
}
Example #18
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 #19
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.status.DNS.Entries {
		if entry.Tombstone > 0 {
			continue
		}
		nodeID := report.MakeContainerNodeID(w.hostID, entry.ContainerID)
		node, ok := r.Container.Nodes[nodeID]
		if !ok {
			continue
		}
		hostnames := report.IDList(strings.Fields(node.Metadata[WeaveDNSHostname]))
		hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, "."))
		node.Metadata[WeaveDNSHostname] = strings.Join(hostnames, " ")
	}

	// Put information from weave ps on the container nodes
	psEntries, err := w.ps()
	if err != nil {
		return r, nil
	}
	psEntriesByPrefix := map[string]psEntry{}
	for _, entry := range psEntries {
		psEntriesByPrefix[entry.containerIDPrefix] = entry
	}
	for id, node := range r.Container.Nodes {
		prefix := node.Metadata[docker.ContainerID][:12]
		entry, ok := psEntriesByPrefix[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.Metadata[WeaveMACAddress] = entry.macAddress
		r.Container.Nodes[id] = node
	}
	return r, nil
}
Example #20
0
func (r *Reporter) containerImageTopology() report.Topology {
	result := report.NewTopology()

	r.registry.WalkImages(func(image *docker_client.APIImages) {
		nmd := report.NodeMetadata{
			ImageID: image.ID,
		}

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

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

	return result
}
Example #21
0
// MapContainerIdentity maps a container topology node to a container
// renderable node. As it is only ever run on container topology nodes, we
// expect that certain keys are present.
func MapContainerIdentity(m RenderableNode, _ report.Networks) RenderableNodes {
	id, ok := m.Metadata[docker.ContainerID]
	if !ok {
		return RenderableNodes{}
	}

	var (
		major, _ = GetRenderableContainerName(m.Node)
		minor    = report.ExtractHostID(m.Node)
		rank     = m.Metadata[docker.ImageID]
	)

	node := NewRenderableNodeWith(id, major, minor, rank, m)
	if imageID, ok := m.Metadata[docker.ImageID]; ok {
		hostID, _, _ := report.ParseContainerNodeID(m.ID)
		node.Origins = node.Origins.Add(report.MakeContainerNodeID(hostID, imageID))
	}
	return RenderableNodes{id: node}
}
Example #22
0
func (r *Reporter) containerImageTopology() report.Topology {
	result := report.MakeTopology()

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

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

		nodeID := report.MakeContainerNodeID(r.hostID, image.ID)
		result.AddNode(nodeID, nmd)
	})

	return result
}
Example #23
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 || c.State() == StateStopped || c.PID() == 1 {
			continue
		}

		topology.AddNode(nodeID, report.MakeNodeWith(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 #24
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.status.DNS.Entries {
		if entry.Tombstone > 0 {
			continue
		}
		nodeID := report.MakeContainerNodeID(w.hostID, entry.ContainerID)
		node, ok := r.Container.Nodes[nodeID]
		if !ok {
			continue
		}
		hostnames := report.IDList(strings.Fields(node.Metadata[WeaveDNSHostname]))
		hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, "."))
		node.Metadata[WeaveDNSHostname] = strings.Join(hostnames, " ")
	}

	// Put information from weave ps on the container nodes
	psEntries, err := w.ps()
	if err != nil {
		return r, nil
	}
	containersByPrefix := map[string]report.Node{}
	for _, node := range r.Container.Nodes {
		prefix := node.Metadata[docker.ContainerID][:12]
		containersByPrefix[prefix] = node
	}
	for _, e := range psEntries {
		node, ok := containersByPrefix[e.containerIDPrefix]
		if !ok {
			continue
		}

		existingIPs := report.MakeIDList(docker.ExtractContainerIPs(node)...)
		existingIPs = existingIPs.Add(e.ips...)
		node.Metadata[docker.ContainerIPs] = strings.Join(existingIPs, " ")
		node.Metadata[WeaveMACAddress] = e.macAddress
	}
	return r, nil
}
Example #25
0
func (r processWithContainerNameRenderer) Render(rpt report.Report, dct Decorator) report.Nodes {
	processes := r.Renderer.Render(rpt, dct)
	containers := SelectContainer.Render(rpt, dct)

	outputs := report.Nodes{}
	for id, p := range processes {
		outputs[id] = p
		containerID, timestamp, ok := p.Latest.LookupEntry(docker.ContainerID)
		if !ok {
			continue
		}
		container, ok := containers[report.MakeContainerNodeID(containerID)]
		if !ok {
			continue
		}
		output := p.Copy()
		output.Latest = output.Latest.Set(docker.ContainerID, timestamp, containerID)
		if containerName, timestamp, ok := container.Latest.LookupEntry(docker.ContainerName); ok {
			output.Latest = output.Latest.Set(docker.ContainerName, timestamp, containerName)
		}
		outputs[id] = output
	}
	return outputs
}
Example #26
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{3: 2}}, nil
	}

	var (
		pid1NodeID = report.MakeProcessNodeID("somehost.com", "2")
		pid2NodeID = report.MakeProcessNodeID("somehost.com", "3")
		wantNode   = report.MakeNodeWith(map[string]string{
			docker.ContainerID: "ping",
		}).WithParents(report.Sets{
			report.Container:      report.MakeStringSet(report.MakeContainerNodeID("ping")),
			report.ContainerImage: report.MakeStringSet(report.MakeContainerImageNodeID("baz")),
		})
	)

	input := report.MakeReport()
	input.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"}))
	input.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"}))

	want := report.MakeReport()
	want.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"}).Merge(wantNode))
	want.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"}).Merge(wantNode))

	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))
	}
}
Example #27
0
	Server80NodeID       = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort)                 // apache
	UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, UnknownClient1Port) // we want to ensure two unknown clients, connnected
	UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, UnknownClient2Port) // to the same server, are deduped.
	UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, UnknownClient3Port) // Check this one isn't deduped
	RandomClientNodeID   = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, RandomClientPort)     // this should become an internet node
	NonContainerNodeID   = report.MakeEndpointNodeID(ServerHostID, ServerIP, NonContainerClientPort)
	GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, GooglePort)

	ClientProcess1NodeID      = report.MakeProcessNodeID(ClientHostID, Client1PID)
	ClientProcess2NodeID      = report.MakeProcessNodeID(ClientHostID, Client2PID)
	ServerProcessNodeID       = report.MakeProcessNodeID(ServerHostID, ServerPID)
	NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID)

	ClientContainerID     = "a1b2c3d4e5"
	ServerContainerID     = "5e4d3c2b1a"
	ClientContainerNodeID = report.MakeContainerNodeID(ClientHostID, ClientContainerID)
	ServerContainerNodeID = report.MakeContainerNodeID(ServerHostID, ServerContainerID)

	ClientContainerImageID     = "imageid123"
	ServerContainerImageID     = "imageid456"
	ClientContainerImageNodeID = report.MakeContainerNodeID(ClientHostID, ClientContainerImageID)
	ServerContainerImageNodeID = report.MakeContainerNodeID(ServerHostID, ServerContainerImageID)
	ClientContainerImageName   = "image/client"
	ServerContainerImageName   = "image/server"

	ClientAddressNodeID   = report.MakeAddressNodeID(ClientHostID, ClientIP)
	ServerAddressNodeID   = report.MakeAddressNodeID(ServerHostID, ServerIP)
	UnknownAddress1NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient1IP)
	UnknownAddress2NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient2IP)
	UnknownAddress3NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient3IP)
	RandomAddressNodeID   = report.MakeAddressNodeID(ServerHostID, RandomClientIP) // this should become an internet node
Example #28
0
func TestReporter(t *testing.T) {
	pod1ID := report.MakePodNodeID("ping", "pong-a")
	pod2ID := report.MakePodNodeID("ping", "pong-b")
	serviceID := report.MakeServiceNodeID("ping", "pongservice")
	rpt, _ := kubernetes.NewReporter(mockClientInstance).Report()

	// Reporter should have added the following pods
	for _, pod := range []struct {
		id            string
		parentService string
		latest        map[string]string
	}{
		{pod1ID, serviceID, map[string]string{
			kubernetes.PodID:           "ping/pong-a",
			kubernetes.PodName:         "pong-a",
			kubernetes.Namespace:       "ping",
			kubernetes.PodCreated:      pod1.Created(),
			kubernetes.PodContainerIDs: "container1 container2",
			kubernetes.ServiceIDs:      "ping/pongservice",
		}},
		{pod2ID, serviceID, map[string]string{
			kubernetes.PodID:           "ping/pong-b",
			kubernetes.PodName:         "pong-b",
			kubernetes.Namespace:       "ping",
			kubernetes.PodCreated:      pod1.Created(),
			kubernetes.PodContainerIDs: "container3 container4",
			kubernetes.ServiceIDs:      "ping/pongservice",
		}},
	} {
		node, ok := rpt.Pod.Nodes[pod.id]
		if !ok {
			t.Errorf("Expected report to have pod %q, but not found", pod.id)
		}

		if parents, ok := node.Parents.Lookup(report.Service); !ok || !parents.Contains(pod.parentService) {
			t.Errorf("Expected pod %s to have parent service %q, got %q", pod.id, pod.parentService, parents)
		}

		for k, want := range pod.latest {
			if have, ok := node.Latest.Lookup(k); !ok || have != want {
				t.Errorf("Expected pod %s latest %q: %q, got %q", pod.id, k, want, have)
			}
		}
	}

	// Reporter should have added a service
	{
		node, ok := rpt.Service.Nodes[serviceID]
		if !ok {
			t.Errorf("Expected report to have service %q, but not found", serviceID)
		}

		for k, want := range map[string]string{
			kubernetes.ServiceID:      "ping/pongservice",
			kubernetes.ServiceName:    "pongservice",
			kubernetes.Namespace:      "ping",
			kubernetes.ServiceCreated: pod1.Created(),
		} {
			if have, ok := node.Latest.Lookup(k); !ok || have != want {
				t.Errorf("Expected service %s latest %q: %q, got %q", serviceID, k, want, have)
			}
		}
	}

	// Reporter should have tagged the containers
	for _, pod := range []struct {
		id, nodeID string
		containers []string
	}{
		{"ping/pong-a", pod1ID, []string{"container1", "container2"}},
		{"ping/pong-b", pod2ID, []string{"container3", "container4"}},
	} {
		for _, containerID := range pod.containers {
			node, ok := rpt.Container.Nodes[report.MakeContainerNodeID(containerID)]
			if !ok {
				t.Errorf("Expected report to have container %q, but not found", containerID)
			}
			// container should have pod id
			if have, ok := node.Latest.Lookup(kubernetes.PodID); !ok || have != pod.id {
				t.Errorf("Expected container %s latest %q: %q, got %q", containerID, kubernetes.PodID, pod.id, have)
			}
			// container should have namespace
			if have, ok := node.Latest.Lookup(kubernetes.Namespace); !ok || have != "ping" {
				t.Errorf("Expected container %s latest %q: %q, got %q", containerID, kubernetes.Namespace, "ping", have)
			}
			// container should have pod parent
			if parents, ok := node.Parents.Lookup(report.Pod); !ok || !parents.Contains(pod.nodeID) {
				t.Errorf("Expected container %s to have parent service %q, got %q", containerID, pod.nodeID, parents)
			}
		}
	}
}
var (
	serverHostID     = "host1"
	serverHostNodeID = report.MakeHostNodeID(serverHostID)

	randomIP             = "3.4.5.6"
	randomPort           = "56789"
	randomEndpointNodeID = report.MakeEndpointNodeID(serverHostID, randomIP, randomPort)

	serverIP             = "192.168.1.1"
	serverPort           = "80"
	serverEndpointNodeID = report.MakeEndpointNodeID(serverHostID, serverIP, serverPort)

	containerID     = "a1b2c3d4e5"
	containerIP     = "192.168.0.1"
	containerName   = "foo"
	containerNodeID = report.MakeContainerNodeID(containerID)

	rpt = report.Report{
		Endpoint: report.Topology{
			Nodes: report.Nodes{
				randomEndpointNodeID: report.MakeNode().WithLatests(map[string]string{
					endpoint.Addr:        randomIP,
					endpoint.Port:        randomPort,
					endpoint.Conntracked: "true",
				}).WithAdjacent(serverEndpointNodeID).WithID(randomEndpointNodeID).WithTopology(report.Endpoint),

				serverEndpointNodeID: report.MakeNode().WithLatests(map[string]string{
					endpoint.Addr:        serverIP,
					endpoint.Port:        serverPort,
					endpoint.Conntracked: "true",
				}).WithID(serverEndpointNodeID).WithTopology(report.Endpoint),
Example #30
0
	Server80NodeID       = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort)                 // apache
	UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, UnknownClient1Port) // we want to ensure two unknown clients, connnected
	UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, UnknownClient2Port) // to the same server, are deduped.
	UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, UnknownClient3Port) // Check this one isn't deduped
	RandomClientNodeID   = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, RandomClientPort)     // this should become an internet node
	NonContainerNodeID   = report.MakeEndpointNodeID(ServerHostID, ServerIP, NonContainerClientPort)
	GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, GooglePort)

	ClientProcess1NodeID      = report.MakeProcessNodeID(ClientHostID, Client1PID)
	ClientProcess2NodeID      = report.MakeProcessNodeID(ClientHostID, Client2PID)
	ServerProcessNodeID       = report.MakeProcessNodeID(ServerHostID, ServerPID)
	NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID)

	ClientContainerID     = "a1b2c3d4e5"
	ServerContainerID     = "5e4d3c2b1a"
	ClientContainerNodeID = report.MakeContainerNodeID(ClientContainerID)
	ServerContainerNodeID = report.MakeContainerNodeID(ServerContainerID)

	ClientContainerImageID     = "imageid123"
	ServerContainerImageID     = "imageid456"
	ClientContainerImageNodeID = report.MakeContainerImageNodeID(ClientContainerImageID)
	ServerContainerImageNodeID = report.MakeContainerImageNodeID(ServerContainerImageID)
	ClientContainerImageName   = "image/client"
	ServerContainerImageName   = "image/server"

	ClientAddressNodeID   = report.MakeAddressNodeID(ClientHostID, ClientIP)
	ServerAddressNodeID   = report.MakeAddressNodeID(ServerHostID, ServerIP)
	UnknownAddress1NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient1IP)
	UnknownAddress2NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient2IP)
	UnknownAddress3NodeID = report.MakeAddressNodeID(ServerHostID, UnknownClient3IP)
	RandomAddressNodeID   = report.MakeAddressNodeID(ServerHostID, RandomClientIP) // this should become an internet node