Beispiel #1
0
func renderTo(rpt report.Report, topology string) (render.RenderableNodes, error) {
	renderer, ok := map[string]render.Renderer{
		"applications":         render.FilterUnconnected(render.ProcessWithContainerNameRenderer),
		"applications-by-name": render.FilterUnconnected(render.ProcessNameRenderer),
		"containers":           render.ContainerWithImageNameRenderer,
		"containers-by-image":  render.ContainerImageRenderer,
		"hosts":                render.HostRenderer,
	}[topology]
	if !ok {
		return render.RenderableNodes{}, fmt.Errorf("unknown topology %v", topology)
	}
	return renderer.Render(rpt), nil
}
Beispiel #2
0
func TestFilterUnconnectedSelf(t *testing.T) {
	// Test nodes that are only connected to themselves are filtered.
	{
		nodes := render.RenderableNodes{
			"foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("foo")},
		}
		renderer := render.FilterUnconnected(mockRenderer{RenderableNodes: nodes})
		want := render.RenderableNodes{}
		have := renderer.Render(report.MakeReport()).Prune()
		if !reflect.DeepEqual(want, have) {
			t.Error(test.Diff(want, have))
		}
	}
}
Beispiel #3
0
func TestFilterRender(t *testing.T) {
	renderer := render.FilterUnconnected(
		mockRenderer{RenderableNodes: render.RenderableNodes{
			"foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")},
			"bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("foo")},
			"baz": {ID: "baz", Node: report.MakeNode()},
		}})
	want := render.RenderableNodes{
		"foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")},
		"bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("foo")},
	}
	have := renderer.Render(report.MakeReport()).Prune()
	if !reflect.DeepEqual(want, have) {
		t.Error(test.Diff(want, have))
	}
}
Beispiel #4
0
func TestFilterRender(t *testing.T) {
	renderer := render.FilterUnconnected(
		mockRenderer{RenderableNodes: render.RenderableNodes{
			"foo": {ID: "foo", Adjacency: report.MakeIDList("bar"), NodeMetadata: report.MakeNodeMetadata()},
			"bar": {ID: "bar", Adjacency: report.MakeIDList("foo"), NodeMetadata: report.MakeNodeMetadata()},
			"baz": {ID: "baz", Adjacency: report.MakeIDList(), NodeMetadata: report.MakeNodeMetadata()},
		}})
	want := render.RenderableNodes{
		"foo": {ID: "foo", Adjacency: report.MakeIDList("bar"), NodeMetadata: report.MakeNodeMetadata()},
		"bar": {ID: "bar", Adjacency: report.MakeIDList("foo"), NodeMetadata: report.MakeNodeMetadata()},
	}
	have := sterilize(renderer.Render(report.MakeReport()), true)
	if !reflect.DeepEqual(want, have) {
		t.Errorf("want %+v, have %+v", want, have)
	}
}
Beispiel #5
0
func TestFilterRender(t *testing.T) {
	renderer := render.FilterUnconnected(
		mockRenderer{RenderableNodes: render.RenderableNodes{
			"foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")},
			"bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("foo")},
			"baz": {ID: "baz", Node: report.MakeNode()},
		}})
	want := render.RenderableNodes{
		"foo": {ID: "foo", Node: report.MakeNode().WithAdjacent("bar")},
		"bar": {ID: "bar", Node: report.MakeNode().WithAdjacent("foo")},
	}
	have := expected.Sterilize(renderer.Render(report.MakeReport()))
	if !reflect.DeepEqual(want, have) {
		t.Errorf("want %+v, have %+v", want, have)
	}
}
Beispiel #6
0
type APIDetails struct {
	ID      string `json:"id"`
	Version string `json:"version"`
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
	respondWith(w, http.StatusOK, APIDetails{ID: uniqueID, Version: version})
}

// Topology option labels should tell the current state. The first item must
// be the verb to get to that state
var topologyRegistry = map[string]topologyView{
	"applications": {
		human:    "Applications",
		parent:   "",
		renderer: render.FilterUnconnected(render.ProcessWithContainerNameRenderer),
		options: optionParams{"unconnected": {
			// Show the user why there are filtered nodes in this view.
			// Don't give them the option to show those nodes.
			{"hide", "Unconnected nodes hidden", true, nop},
		}},
	},
	"applications-by-name": {
		human:    "by name",
		parent:   "applications",
		renderer: render.FilterUnconnected(render.ProcessNameRenderer),
		options: optionParams{"unconnected": {
			// Ditto above.
			{"hide", "Unconnected nodes hidden", true, nop},
		}},
	},
Beispiel #7
0
func init() {
	containerFilters := map[string][]APITopologyOption{
		"system": {
			{"show", "System containers shown", false, render.FilterNoop},
			{"hide", "System containers hidden", true, render.FilterSystem},
		},
		"stopped": {
			{"show", "Stopped containers shown", false, render.FilterNoop},
			{"hide", "Stopped containers hidden", true, render.FilterStopped},
		},
	}

	// Topology option labels should tell the current state. The first item must
	// be the verb to get to that state
	topologyRegistry.add(
		APITopologyDesc{
			id:       "processes",
			renderer: render.FilterUnconnected(render.ProcessWithContainerNameRenderer),
			Name:     "Processes",
			Rank:     1,
			Options: map[string][]APITopologyOption{"unconnected": {
				// Show the user why there are filtered nodes in this view.
				// Don't give them the option to show those nodes.
				{"hide", "Unconnected nodes hidden", true, render.FilterNoop},
			}},
		},
		APITopologyDesc{
			id:       "processes-by-name",
			parent:   "processes",
			renderer: render.FilterUnconnected(render.ProcessNameRenderer),
			Name:     "by name",
			Options: map[string][]APITopologyOption{"unconnected": {
				// Ditto above.
				{"hide", "Unconnected nodes hidden", true, render.FilterNoop},
			}},
		},
		APITopologyDesc{
			id:       "containers",
			renderer: render.ContainerWithImageNameRenderer,
			Name:     "Containers",
			Rank:     2,
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:       "containers-by-image",
			parent:   "containers",
			renderer: render.ContainerImageRenderer,
			Name:     "by image",
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:       "containers-by-hostname",
			parent:   "containers",
			renderer: render.ContainerHostnameRenderer,
			Name:     "by DNS name",
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:       "hosts",
			renderer: render.HostRenderer,
			Name:     "Hosts",
			Rank:     4,
			Options:  map[string][]APITopologyOption{},
		},
	)
}
Beispiel #8
0
func init() {
	containerFilters := []APITopologyOptionGroup{
		{
			ID:      "system",
			Default: "application",
			Options: []APITopologyOption{
				{"system", "System containers", render.IsSystem, false},
				{"application", "Application containers", render.IsApplication, false},
				{"both", "Both", nil, false},
			},
		},
		{
			ID:      "stopped",
			Default: "running",
			Options: []APITopologyOption{
				{"stopped", "Stopped containers", render.IsStopped, false},
				{"running", "Running containers", render.IsRunning, false},
				{"both", "Both", nil, false},
			},
		},
		{
			ID:      "pseudo",
			Default: "show",
			Options: []APITopologyOption{
				{"show", "Show Uncontained", nil, false},
				{"hide", "Hide Uncontained", render.IsNotPseudo, true},
			},
		},
	}

	unconnectedFilter := []APITopologyOptionGroup{
		{
			ID:      "unconnected",
			Default: "hide",
			Options: []APITopologyOption{
				// Show the user why there are filtered nodes in this view.
				// Don't give them the option to show those nodes.
				{"hide", "Unconnected nodes hidden", nil, false},
			},
		},
	}

	// Topology option labels should tell the current state. The first item must
	// be the verb to get to that state
	topologyRegistry.add(
		APITopologyDesc{
			id:          "processes",
			renderer:    render.FilterUnconnected(render.ProcessWithContainerNameRenderer),
			Name:        "Processes",
			Rank:        1,
			Options:     unconnectedFilter,
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:          "processes-by-name",
			parent:      "processes",
			renderer:    render.FilterUnconnected(render.ProcessNameRenderer),
			Name:        "by name",
			Options:     unconnectedFilter,
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:       "containers",
			renderer: render.ContainerWithImageNameRenderer,
			Name:     "Containers",
			Rank:     2,
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:       "containers-by-hostname",
			parent:   "containers",
			renderer: render.ContainerHostnameRenderer,
			Name:     "by DNS name",
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:       "containers-by-image",
			parent:   "containers",
			renderer: render.ContainerImageRenderer,
			Name:     "by image",
			Options:  containerFilters,
		},
		APITopologyDesc{
			id:          "pods",
			renderer:    render.PodRenderer,
			Name:        "Pods",
			Rank:        3,
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:          "replica-sets",
			parent:      "pods",
			renderer:    render.ReplicaSetRenderer,
			Name:        "replica sets",
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:          "deployments",
			parent:      "pods",
			renderer:    render.DeploymentRenderer,
			Name:        "deployments",
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:          "services",
			parent:      "pods",
			renderer:    render.PodServiceRenderer,
			Name:        "services",
			HideIfEmpty: true,
		},
		APITopologyDesc{
			id:       "hosts",
			renderer: render.HostRenderer,
			Name:     "Hosts",
			Rank:     4,
		},
	)
}