move docker labels into their own table of the details panel

This commit is contained in:
Paul Bellamy
2016-02-02 17:03:06 +00:00
parent 154c996d08
commit 0a292f530c
9 changed files with 113 additions and 65 deletions

View File

@@ -129,7 +129,7 @@ export default class NodeDetails extends React.Component {
renderDetails() {
const details = this.props.details;
const showSummary = details.metadata !== undefined || details.metrics !== undefined;
const showSummary = (details.metadata || details.metrics || details.docker_labels) !== undefined;
const showControls = details.controls && details.controls.length > 0;
const nodeColor = getNodeColorDark(details.rank, details.label, details.pseudo);
const {error, pending} = (this.props.nodeControlStatus || {});
@@ -168,7 +168,9 @@ export default class NodeDetails extends React.Component {
{showSummary && <div className="node-details-content-section">
<div className="node-details-content-section-header">Status</div>
{details.metrics && <NodeDetailsHealth metrics={details.metrics} />}
{details.metadata && <NodeDetailsInfo metadata={details.metadata} />}
{details.metadata && <NodeDetailsInfo rows={details.metadata} />}
{details.docker_labels && <div className="node-details-content-section-header">Docker Labels</div>}
{details.docker_labels && <NodeDetailsInfo rows={details.docker_labels} />}
</div>}
{details.children && details.children.map(children => {

View File

@@ -4,7 +4,7 @@ export default class NodeDetailsInfo extends React.Component {
render() {
return (
<div className="node-details-info">
{this.props.metadata && this.props.metadata.map(field => {
{this.props.rows && this.props.rows.map(field => {
return (
<div className="node-details-info-field" key={field.id}>
<div className="node-details-info-field-label truncate" title={field.label}>

View File

@@ -0,0 +1,30 @@
package detailed
import (
"sort"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/report"
)
// NodeDockerLabels produces a table (to be consumed directly by the UI) based
// on an origin ID, which is (optimistically) a node ID in one of our
// topologies.
func NodeDockerLabels(nmd report.Node) []MetadataRow {
if nmd.Topology != report.Container && nmd.Topology != report.ContainerImage {
return nil
}
var rows []MetadataRow
// Add labels in alphabetical order
labels := docker.ExtractLabels(nmd)
labelKeys := make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
sort.Strings(labelKeys)
for _, labelKey := range labelKeys {
rows = append(rows, MetadataRow{ID: "label_" + labelKey, Value: labels[labelKey]})
}
return rows
}

View File

@@ -0,0 +1,50 @@
package detailed_test
import (
"reflect"
"testing"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/render/detailed"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test"
"github.com/weaveworks/scope/test/fixture"
)
func TestNodeDockerLabels(t *testing.T) {
inputs := []struct {
name string
node report.Node
want []detailed.MetadataRow
}{
{
name: "container",
node: report.MakeNodeWith(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: []detailed.MetadataRow{
{
ID: "label_label1",
Value: "label1value",
},
},
},
{
name: "unknown topology",
node: report.MakeNodeWith(map[string]string{
docker.ContainerID: fixture.ClientContainerID,
}).WithTopology("foobar").WithID(fixture.ClientContainerNodeID),
want: nil,
},
}
for _, input := range inputs {
have := detailed.NodeDockerLabels(input.node)
if !reflect.DeepEqual(input.want, have) {
t.Errorf("%s: %s", input.name, test.Diff(input.want, have))
}
}
}

View File

@@ -1,7 +1,6 @@
package detailed
import (
"fmt"
"strings"
"github.com/weaveworks/scope/probe/docker"
@@ -54,7 +53,7 @@ func Label(key string) string {
return label
}
if strings.HasPrefix(key, "label_") {
return fmt.Sprintf("Label %q", strings.TrimPrefix(key, "label_"))
return strings.TrimPrefix(key, "label_")
}
return key
}

View File

@@ -2,7 +2,6 @@ package detailed
import (
"encoding/json"
"sort"
"strings"
"github.com/weaveworks/scope/probe/docker"
@@ -32,11 +31,9 @@ var (
ltst(docker.ContainerCommand),
ltst(overlay.WeaveMACAddress),
ltst(overlay.WeaveDNSHostname),
getDockerLabelRows,
)
containerImageNodeMetadata = renderMetadata(
ltst(docker.ImageID),
getDockerLabelRows,
)
podNodeMetadata = renderMetadata(
ltst(kubernetes.PodID),
@@ -123,18 +120,3 @@ func ltst(id string) func(report.Node) []MetadataRow {
return nil
}
}
func getDockerLabelRows(nmd report.Node) []MetadataRow {
rows := []MetadataRow{}
// Add labels in alphabetical order
labels := docker.ExtractLabels(nmd)
labelKeys := make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
sort.Strings(labelKeys)
for _, labelKey := range labelKeys {
rows = append(rows, MetadataRow{ID: "label_" + labelKey, Value: labels[labelKey]})
}
return rows
}

View File

@@ -30,10 +30,6 @@ func TestNodeMetadata(t *testing.T) {
{ID: docker.ContainerID, Value: fixture.ClientContainerID},
{ID: docker.ContainerState, Value: "running"},
{ID: docker.ContainerIPs, Value: "10.10.10.0/24, 10.10.10.1/24"},
{
ID: "label_label1",
Value: "label1value",
},
},
},
{

View File

@@ -121,6 +121,8 @@ func TestMakeDetailedContainerNode(t *testing.T) {
{ID: "docker_container_id", Value: fixture.ServerContainerID},
{ID: "docker_image_id", Value: fixture.ServerContainerImageID},
{ID: "docker_container_state", Value: "running"},
},
DockerLabels: []detailed.MetadataRow{
{ID: "label_" + render.AmazonECSContainerNameLabel, Value: `server`},
{ID: "label_foo1", Value: `bar1`},
{ID: "label_foo2", Value: `bar2`},

View File

@@ -34,11 +34,12 @@ func (g NodeSummaryGroup) Copy() NodeSummaryGroup {
// NodeSummary is summary information about a child for a Node.
type NodeSummary struct {
ID string `json:"id"`
Label string `json:"label"`
Linkable bool `json:"linkable"` // Whether this node can be linked-to
Metadata []MetadataRow `json:"metadata,omitempty"`
Metrics []MetricRow `json:"metrics,omitempty"`
ID string `json:"id"`
Label string `json:"label"`
Linkable bool `json:"linkable"` // Whether this node can be linked-to
Metadata []MetadataRow `json:"metadata,omitempty"`
DockerLabels []MetadataRow `json:"docker_labels,omitempty"`
Metrics []MetricRow `json:"metrics,omitempty"`
}
// MakeNodeSummary summarizes a node, if possible.
@@ -66,12 +67,26 @@ func (n NodeSummary) Copy() NodeSummary {
for _, row := range n.Metadata {
result.Metadata = append(result.Metadata, row.Copy())
}
for _, row := range n.DockerLabels {
result.DockerLabels = append(result.DockerLabels, row.Copy())
}
for _, row := range n.Metrics {
result.Metrics = append(result.Metrics, row.Copy())
}
return result
}
func baseNodeSummary(id, label string, linkable bool, nmd report.Node) NodeSummary {
return NodeSummary{
ID: id,
Label: label,
Linkable: linkable,
Metadata: NodeMetadata(nmd),
DockerLabels: NodeDockerLabels(nmd),
Metrics: NodeMetrics(nmd),
}
}
func processNodeSummary(nmd report.Node) NodeSummary {
var (
id string
@@ -84,57 +99,29 @@ func processNodeSummary(nmd report.Node) NodeSummary {
id = render.MakeProcessID(report.ExtractHostID(nmd), pid)
}
_, isConnected := nmd.Latest.Lookup(render.IsConnected)
return NodeSummary{
ID: id,
Label: label,
Linkable: isConnected,
Metadata: processNodeMetadata(nmd),
Metrics: processNodeMetrics(nmd),
}
return baseNodeSummary(id, label, isConnected, nmd)
}
func containerNodeSummary(nmd report.Node) NodeSummary {
label, _ := render.GetRenderableContainerName(nmd)
containerID, _ := nmd.Latest.Lookup(docker.ContainerID)
return NodeSummary{
ID: render.MakeContainerID(containerID),
Label: label,
Linkable: true,
Metadata: containerNodeMetadata(nmd),
Metrics: containerNodeMetrics(nmd),
}
return baseNodeSummary(render.MakeContainerID(containerID), label, true, nmd)
}
func containerImageNodeSummary(nmd report.Node) NodeSummary {
imageName, _ := nmd.Latest.Lookup(docker.ImageName)
return NodeSummary{
ID: render.MakeContainerImageID(render.ImageNameWithoutVersion(imageName)),
Label: imageName,
Linkable: true,
Metadata: containerImageNodeMetadata(nmd),
}
return baseNodeSummary(render.MakeContainerImageID(render.ImageNameWithoutVersion(imageName)), imageName, true, nmd)
}
func podNodeSummary(nmd report.Node) NodeSummary {
podID, _ := nmd.Latest.Lookup(kubernetes.PodID)
podName, _ := nmd.Latest.Lookup(kubernetes.PodName)
return NodeSummary{
ID: render.MakePodID(podID),
Label: podName,
Linkable: true,
Metadata: podNodeMetadata(nmd),
}
return baseNodeSummary(render.MakePodID(podID), podName, true, nmd)
}
func hostNodeSummary(nmd report.Node) NodeSummary {
hostName, _ := nmd.Latest.Lookup(host.HostName)
return NodeSummary{
ID: render.MakeHostID(hostName),
Label: hostName,
Linkable: true,
Metadata: hostNodeMetadata(nmd),
Metrics: hostNodeMetrics(nmd),
}
return baseNodeSummary(render.MakeHostID(hostName), hostName, true, nmd)
}
type nodeSummariesByID []NodeSummary