mirror of
https://github.com/weaveworks/scope.git
synced 2026-02-14 10:00:13 +00:00
Option to censor raw reports by command line args and env vars.
This commit is contained in:
@@ -13,12 +13,16 @@ import (
|
||||
// Raw report handler
|
||||
func makeRawReportHandler(rep Reporter) CtxHandlerFunc {
|
||||
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
report, err := rep.Report(ctx, time.Now())
|
||||
censorConfig := report.CensorConfig{
|
||||
HideCommandLineArguments: r.URL.Query().Get("hideCommandLineArguments") == "true",
|
||||
HideEnvironmentVariables: r.URL.Query().Get("hideEnvironmentVariables") == "true",
|
||||
}
|
||||
rawReport, err := rep.Report(ctx, time.Now())
|
||||
if err != nil {
|
||||
respondWith(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
respondWith(w, http.StatusOK, report)
|
||||
respondWith(w, http.StatusOK, report.CensorReport(rawReport, censorConfig))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@@ -41,17 +42,21 @@ type rendererHandler func(context.Context, render.Renderer, render.Transformer,
|
||||
|
||||
// Full topology.
|
||||
func handleTopology(ctx context.Context, renderer render.Renderer, transformer render.Transformer, rc detailed.RenderContext, w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
hideCommandLineArguments = true
|
||||
)
|
||||
respondWith(w, http.StatusOK, APITopology{
|
||||
Nodes: detailed.Summaries(ctx, rc, render.Render(ctx, rc.Report, renderer, transformer).Nodes),
|
||||
Nodes: detailed.Summaries(ctx, rc, hideCommandLineArguments, render.Render(ctx, rc.Report, renderer, transformer).Nodes),
|
||||
})
|
||||
}
|
||||
|
||||
// Individual nodes.
|
||||
func handleNode(ctx context.Context, renderer render.Renderer, transformer render.Transformer, rc detailed.RenderContext, w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
vars = mux.Vars(r)
|
||||
topologyID = vars["topology"]
|
||||
nodeID = vars["id"]
|
||||
vars = mux.Vars(r)
|
||||
topologyID = vars["topology"]
|
||||
nodeID = vars["id"]
|
||||
hideCommandLineArguments = true
|
||||
)
|
||||
// We must not lose the node during filtering. We achieve that by
|
||||
// (1) rendering the report with the base renderer, without
|
||||
@@ -71,7 +76,7 @@ func handleNode(ctx context.Context, renderer render.Renderer, transformer rende
|
||||
nodes.Nodes[nodeID] = node
|
||||
nodes.Filtered--
|
||||
}
|
||||
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, rc, nodes.Nodes, node)})
|
||||
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, rc, hideCommandLineArguments, nodes.Nodes, node)})
|
||||
}
|
||||
|
||||
// Websocket for the full topology.
|
||||
@@ -81,6 +86,9 @@ func handleWebsocket(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
var (
|
||||
hideCommandLineArguments = true
|
||||
)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
respondWith(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
@@ -145,7 +153,7 @@ func handleWebsocket(
|
||||
log.Errorf("Error generating report: %v", err)
|
||||
return
|
||||
}
|
||||
newTopo := detailed.Summaries(ctx, RenderContextForReporter(rep, re), render.Render(ctx, re, renderer, filter).Nodes)
|
||||
newTopo := detailed.Summaries(ctx, RenderContextForReporter(rep, re), hideCommandLineArguments, render.Render(ctx, re, renderer, filter).Nodes)
|
||||
diff := detailed.TopoDiff(previousTopo, newTopo)
|
||||
previousTopo = newTopo
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ const (
|
||||
CPUSystemCPUUsage = "docker_cpu_system_cpu_usage"
|
||||
|
||||
LabelPrefix = "docker_label_"
|
||||
EnvPrefix = "docker_env_"
|
||||
EnvPrefix = report.DockerEnvPrefix
|
||||
)
|
||||
|
||||
// These 'constants' are used for node states.
|
||||
|
||||
@@ -2,7 +2,6 @@ package process
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/weaveworks/common/mtime"
|
||||
"github.com/weaveworks/scope/report"
|
||||
@@ -93,7 +92,7 @@ func (r *Reporter) processTopology() (report.Topology, error) {
|
||||
|
||||
if p.Cmdline != "" {
|
||||
if r.noCommandLineArguments {
|
||||
node = node.WithLatest(Cmdline, now, strings.Split(p.Cmdline, " ")[0])
|
||||
node = node.WithLatest(Cmdline, now, report.StripCommandArgs(p.Cmdline))
|
||||
} else {
|
||||
node = node.WithLatest(Cmdline, now, p.Cmdline)
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ func setupFlags(flags *flags) {
|
||||
flag.StringVar(&flags.probe.pluginsRoot, "probe.plugins.root", "/var/run/scope/plugins", "Root directory to search for plugins")
|
||||
flag.BoolVar(&flags.probe.noControls, "probe.no-controls", false, "Disable controls (e.g. start/stop containers, terminals, logs ...)")
|
||||
flag.BoolVar(&flags.probe.noCommandLineArguments, "probe.omit.cmd-args", false, "Disable collection of command-line arguments")
|
||||
flag.BoolVar(&flags.probe.noEnvironmentVariables, "probe.omit.env-vars", true, "Disable collection of environment variables")
|
||||
flag.BoolVar(&flags.probe.noEnvironmentVariables, "probe.omit.env-vars", false, "Disable collection of environment variables")
|
||||
|
||||
flag.BoolVar(&flags.probe.insecure, "probe.insecure", false, "(SSL) explicitly allow \"insecure\" SSL connections and transfers")
|
||||
flag.StringVar(&flags.probe.resolver, "probe.resolver", "", "IP address & port of resolver to use. Default is to use system resolver.")
|
||||
|
||||
@@ -86,12 +86,12 @@ type RenderContext struct {
|
||||
|
||||
// MakeNode transforms a renderable node to a detailed node. It uses
|
||||
// aggregate metadata, plus the set of origin node IDs, to produce tables.
|
||||
func MakeNode(topologyID string, rc RenderContext, ns report.Nodes, n report.Node) Node {
|
||||
summary, _ := MakeNodeSummary(rc, n)
|
||||
func MakeNode(topologyID string, rc RenderContext, hideCommandLineArguments bool, ns report.Nodes, n report.Node) Node {
|
||||
summary, _ := MakeNodeSummary(rc, hideCommandLineArguments, n)
|
||||
return Node{
|
||||
NodeSummary: summary,
|
||||
Controls: controls(rc.Report, n),
|
||||
Children: children(rc, n),
|
||||
Children: children(rc, hideCommandLineArguments, n),
|
||||
Connections: []ConnectionsSummary{
|
||||
incomingConnectionsSummary(topologyID, rc.Report, n, ns),
|
||||
outgoingConnectionsSummary(topologyID, rc.Report, n, ns),
|
||||
@@ -222,13 +222,13 @@ var nodeSummaryGroupSpecs = []struct {
|
||||
},
|
||||
}
|
||||
|
||||
func children(rc RenderContext, n report.Node) []NodeSummaryGroup {
|
||||
func children(rc RenderContext, hideCommandLineArguments bool, n report.Node) []NodeSummaryGroup {
|
||||
summaries := map[string][]NodeSummary{}
|
||||
n.Children.ForEach(func(child report.Node) {
|
||||
if child.ID == n.ID {
|
||||
return
|
||||
}
|
||||
summary, ok := MakeNodeSummary(rc, child)
|
||||
summary, ok := MakeNodeSummary(rc, hideCommandLineArguments, child)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func child(t *testing.T, r render.Renderer, id string) detailed.NodeSummary {
|
||||
s, ok := detailed.MakeNodeSummary(detailed.RenderContext{Report: fixture.Report}, r.Render(context.Background(), fixture.Report).Nodes[id])
|
||||
s, ok := detailed.MakeNodeSummary(detailed.RenderContext{Report: fixture.Report}, false, r.Render(context.Background(), fixture.Report).Nodes[id])
|
||||
if !ok {
|
||||
t.Fatalf("Expected node %s to be summarizable, but wasn't", id)
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ func MakeBasicNodeSummary(r report.Report, n report.Node) (BasicNodeSummary, boo
|
||||
}
|
||||
|
||||
// MakeNodeSummary summarizes a node, if possible.
|
||||
func MakeNodeSummary(rc RenderContext, n report.Node) (NodeSummary, bool) {
|
||||
func MakeNodeSummary(rc RenderContext, hideCommandLineArguments bool, n report.Node) (NodeSummary, bool) {
|
||||
base, ok := MakeBasicNodeSummary(rc.Report, n)
|
||||
if !ok {
|
||||
return NodeSummary{}, false
|
||||
@@ -449,13 +449,13 @@ func (s nodeSummariesByID) Less(i, j int) bool { return s[i].ID < s[j].ID }
|
||||
type NodeSummaries map[string]NodeSummary
|
||||
|
||||
// Summaries converts RenderableNodes into a set of NodeSummaries
|
||||
func Summaries(ctx context.Context, rc RenderContext, rns report.Nodes) NodeSummaries {
|
||||
func Summaries(ctx context.Context, rc RenderContext, hideCommandLineArguments bool, rns report.Nodes) NodeSummaries {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "detailed.Summaries")
|
||||
defer span.Finish()
|
||||
|
||||
result := NodeSummaries{}
|
||||
for id, node := range rns {
|
||||
if summary, ok := MakeNodeSummary(rc, node); ok {
|
||||
if summary, ok := MakeNodeSummary(rc, hideCommandLineArguments, node); ok {
|
||||
for i, m := range summary.Metrics {
|
||||
summary.Metrics[i] = m.Summary()
|
||||
}
|
||||
|
||||
55
report/censor.go
Normal file
55
report/censor.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package report
|
||||
|
||||
import "strings"
|
||||
|
||||
// import log "github.com/sirupsen/logrus"
|
||||
|
||||
type keyMatcher func(string) bool
|
||||
|
||||
func keyEquals(fixedKey string) keyMatcher {
|
||||
return func(key string) bool {
|
||||
return key == fixedKey
|
||||
}
|
||||
}
|
||||
|
||||
func keyStartsWith(prefix string) keyMatcher {
|
||||
return func(key string) bool {
|
||||
return strings.HasPrefix(key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
type censorValueFunc func(string) string
|
||||
|
||||
func assignEmpty(key string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func censorTopology(t *Topology, match keyMatcher, censor censorValueFunc) {
|
||||
for nodeID := range t.Nodes {
|
||||
for entryID := range t.Nodes[nodeID].Latest {
|
||||
entry := &t.Nodes[nodeID].Latest[entryID]
|
||||
if match(entry.key) {
|
||||
// log.Infof("Blabla ... %s ... %s ... %s", entry.key, entry.Value, censor(entry.Value))
|
||||
entry.Value = censor(entry.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CensorConfig describe which parts of the report needs to be censored.
|
||||
type CensorConfig struct {
|
||||
HideCommandLineArguments bool
|
||||
HideEnvironmentVariables bool
|
||||
}
|
||||
|
||||
// CensorReport removes any sensitive data from the report.
|
||||
func CensorReport(r Report, cfg CensorConfig) Report {
|
||||
if cfg.HideCommandLineArguments {
|
||||
censorTopology(&r.Process, keyEquals(Cmdline), StripCommandArgs)
|
||||
censorTopology(&r.Container, keyEquals(DockerContainerCommand), StripCommandArgs)
|
||||
}
|
||||
if cfg.HideEnvironmentVariables {
|
||||
censorTopology(&r.Container, keyStartsWith(DockerEnvPrefix), assignEmpty)
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -43,6 +43,7 @@ const (
|
||||
DockerContainerUptime = "docker_container_uptime"
|
||||
DockerContainerRestartCount = "docker_container_restart_count"
|
||||
DockerContainerNetworkMode = "docker_container_network_mode"
|
||||
DockerEnvPrefix = "docker_env_"
|
||||
// probe/kubernetes
|
||||
KubernetesName = "kubernetes_name"
|
||||
KubernetesNamespace = "kubernetes_namespace"
|
||||
@@ -214,3 +215,7 @@ func lookupCommonKey(b []byte) string {
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func isCommandKey(key string) bool {
|
||||
return key == Cmdline || key == DockerContainerCommand
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -28,6 +30,11 @@ type MetadataTemplate struct {
|
||||
From string `json:"from,omitempty"` // Defines how to get the value from a report node
|
||||
}
|
||||
|
||||
// StripCommandArgs removes all the arguments from the command
|
||||
func StripCommandArgs(command string) string {
|
||||
return strings.Split(command, " ")[0]
|
||||
}
|
||||
|
||||
// MetadataRow returns the row for a node
|
||||
func (t MetadataTemplate) MetadataRow(n Node) (MetadataRow, bool) {
|
||||
from := fromDefault
|
||||
@@ -96,6 +103,10 @@ func (e MetadataTemplates) MetadataRows(n Node) []MetadataRow {
|
||||
rows := make([]MetadataRow, 0, len(e))
|
||||
for _, template := range e {
|
||||
if row, ok := template.MetadataRow(n); ok {
|
||||
if isCommandKey(row.ID) {
|
||||
row.Value = StripCommandArgs(row.Value)
|
||||
log.Infof("Blublu %s -- %v", n.ID, row)
|
||||
}
|
||||
rows = append(rows, row)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user