Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to hide args and env vars #2306

Merged
merged 4 commits into from Mar 7, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 26 additions & 12 deletions probe/docker/container.go
Expand Up @@ -98,20 +98,24 @@ type Container interface {

type container struct {
sync.RWMutex
container *docker.Container
stopStats chan<- bool
latestStats docker.Stats
pendingStats [60]docker.Stats
numPending int
hostID string
baseNode report.Node
container *docker.Container
stopStats chan<- bool
latestStats docker.Stats
pendingStats [60]docker.Stats
numPending int
hostID string
baseNode report.Node
noCommandLineArguments bool
noEnvironmentVariables bool
}

// NewContainer creates a new Container
func NewContainer(c *docker.Container, hostID string) Container {
func NewContainer(c *docker.Container, hostID string, noCommandLineArguments bool, noEnvironmentVariables bool) Container {
result := &container{
container: c,
hostID: hostID,
container: c,
hostID: hostID,
noCommandLineArguments: noCommandLineArguments,
noEnvironmentVariables: noEnvironmentVariables,
}
result.baseNode = result.getBaseNode()
return result
Expand Down Expand Up @@ -369,18 +373,28 @@ func (c *container) env() map[string]string {
return result
}

func (c *container) getSanitizedCommand() string {
result := c.container.Path
if !c.noCommandLineArguments {
result = result + " " + strings.Join(c.container.Args, " ")
}
return result
}

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.RFC3339Nano),
ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "),
ContainerCommand: c.getSanitizedCommand(),
ImageID: c.Image(),
ContainerHostname: c.Hostname(),
}).WithParents(report.EmptySets.
Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID(c.Image()))),
)
result = result.AddPrefixPropertyList(LabelPrefix, c.container.Config.Labels)
result = result.AddPrefixPropertyList(EnvPrefix, c.env())
if !c.noEnvironmentVariables {
result = result.AddPrefixPropertyList(EnvPrefix, c.env())
}
return result
}

Expand Down
42 changes: 40 additions & 2 deletions probe/docker/container_test.go
Expand Up @@ -2,6 +2,7 @@ package docker_test

import (
"net"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -40,7 +41,7 @@ func TestContainer(t *testing.T) {
defer mtime.NowReset()

const hostID = "scope"
c := docker.NewContainer(container1, hostID)
c := docker.NewContainer(container1, hostID, false, false)
s := newMockStatsGatherer()
err := c.StartGatheringStats(s)
if err != nil {
Expand Down Expand Up @@ -69,7 +70,7 @@ func TestContainer(t *testing.T) {
docker.RemoveContainer: {Dead: true},
}
want := report.MakeNodeWith("ping;<container>", map[string]string{
"docker_container_command": " ",
"docker_container_command": "ping foo.bar.local",
"docker_container_created": "0001-01-01T00:00:00Z",
"docker_container_id": "ping",
"docker_container_name": "pong",
Expand All @@ -79,6 +80,7 @@ func TestContainer(t *testing.T) {
"docker_container_state": "running",
"docker_container_state_human": c.Container().State.String(),
"docker_container_uptime": uptime.String(),
"docker_env_FOO": "secret-bar",
}).WithLatestControls(
controls,
).WithMetrics(report.Metrics{
Expand Down Expand Up @@ -125,3 +127,39 @@ func TestContainer(t *testing.T) {
t.Errorf("%v != %v", have, []string{"1.2.3.4", "5.6.7.8"})
}
}

func TestContainerHidingArgs(t *testing.T) {
const hostID = "scope"
c := docker.NewContainer(container1, hostID, true, false)
node := c.GetNode()
node.Latest.ForEach(func(k string, _ time.Time, v string) {
if strings.Contains(v, "foo.bar.local") {
t.Errorf("Found command line argument in node")
}
})
}

func TestContainerHidingEnv(t *testing.T) {
const hostID = "scope"
c := docker.NewContainer(container1, hostID, false, true)
node := c.GetNode()
node.Latest.ForEach(func(k string, _ time.Time, v string) {
if strings.Contains(v, "secret-bar") {
t.Errorf("Found environment variable in node")
}
})
}

func TestContainerHidingBoth(t *testing.T) {
const hostID = "scope"
c := docker.NewContainer(container1, hostID, true, true)
node := c.GetNode()
node.Latest.ForEach(func(k string, _ time.Time, v string) {
if strings.Contains(v, "foo.bar.local") {
t.Errorf("Found command line argument in node")
}
if strings.Contains(v, "secret-bar") {
t.Errorf("Found environment variable in node")
}
})
}
4 changes: 2 additions & 2 deletions probe/docker/controls_test.go
Expand Up @@ -18,7 +18,7 @@ func TestControls(t *testing.T) {
mdc := newMockClient()
setupStubs(mdc, func() {
hr := controls.NewDefaultHandlerRegistry()
registry, _ := docker.NewRegistry(10*time.Second, nil, false, "", hr, "")
registry, _ := docker.NewRegistry(10*time.Second, nil, false, "", hr, "", false, false)
defer registry.Stop()

for _, tc := range []struct{ command, result string }{
Expand Down Expand Up @@ -59,7 +59,7 @@ func TestPipes(t *testing.T) {
mdc := newMockClient()
setupStubs(mdc, func() {
hr := controls.NewDefaultHandlerRegistry()
registry, _ := docker.NewRegistry(10*time.Second, nil, false, "", hr, "")
registry, _ := docker.NewRegistry(10*time.Second, nil, false, "", hr, "", false, false)
defer registry.Stop()

test.Poll(t, 100*time.Millisecond, true, func() interface{} {
Expand Down
22 changes: 13 additions & 9 deletions probe/docker/registry.go
Expand Up @@ -51,13 +51,15 @@ type ContainerUpdateWatcher func(report.Node)

type registry struct {
sync.RWMutex
quit chan chan struct{}
interval time.Duration
collectStats bool
client Client
pipes controls.PipeClient
hostID string
handlerRegistry *controls.HandlerRegistry
quit chan chan struct{}
interval time.Duration
collectStats bool
client Client
pipes controls.PipeClient
hostID string
handlerRegistry *controls.HandlerRegistry
noCommandLineArguments bool
noEnvironmentVariables bool

watchers []ContainerUpdateWatcher
containers *radix.Tree
Expand Down Expand Up @@ -94,7 +96,7 @@ func newDockerClient(endpoint string) (Client, error) {
}

// NewRegistry returns a usable Registry. Don't forget to Stop it.
func NewRegistry(interval time.Duration, pipes controls.PipeClient, collectStats bool, hostID string, handlerRegistry *controls.HandlerRegistry, dockerEndpoint string) (Registry, error) {
func NewRegistry(interval time.Duration, pipes controls.PipeClient, collectStats bool, hostID string, handlerRegistry *controls.HandlerRegistry, dockerEndpoint string, noCommandLineArguments bool, noEnvironmentVariables bool) (Registry, error) {

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

client, err := NewDockerClientStub(dockerEndpoint)
if err != nil {
return nil, err
Expand All @@ -113,6 +115,8 @@ func NewRegistry(interval time.Duration, pipes controls.PipeClient, collectStats
hostID: hostID,
handlerRegistry: handlerRegistry,
quit: make(chan chan struct{}),
noCommandLineArguments: noCommandLineArguments,
noEnvironmentVariables: noEnvironmentVariables,
}

r.registerControls()
Expand Down Expand Up @@ -339,7 +343,7 @@ func (r *registry) updateContainerState(containerID string, intendedState *strin
o, ok := r.containers.Get(containerID)
var c Container
if !ok {
c = NewContainerStub(dockerContainer, r.hostID)
c = NewContainerStub(dockerContainer, r.hostID, r.noCommandLineArguments, r.noEnvironmentVariables)
r.containers.Insert(containerID, c)
} else {
c = o.(Container)
Expand Down
11 changes: 9 additions & 2 deletions probe/docker/registry_test.go
Expand Up @@ -22,7 +22,7 @@ import (

func testRegistry() docker.Registry {
hr := controls.NewDefaultHandlerRegistry()
registry, _ := docker.NewRegistry(10*time.Second, nil, true, "", hr, "")
registry, _ := docker.NewRegistry(10*time.Second, nil, true, "", hr, "", false, false)
return registry
}

Expand Down Expand Up @@ -203,6 +203,10 @@ var (
ID: "ping",
Name: "pong",
Image: "baz",
Path: "ping",
Args: []string{
"foo.bar.local",
},
State: client.State{
Pid: 2,
Running: true,
Expand All @@ -226,6 +230,9 @@ var (
},
},
Config: &client.Config{
Env: []string{
"FOO=secret-bar",
},
Labels: map[string]string{
"foo1": "bar1",
"foo2": "bar2",
Expand Down Expand Up @@ -294,7 +301,7 @@ func setupStubs(mdc *mockDockerClient, f func()) {
return mdc, nil
}

docker.NewContainerStub = func(c *client.Container, _ string) docker.Container {
docker.NewContainerStub = func(c *client.Container, _ string, _ bool, _ bool) docker.Container {
return &mockContainer{c}
}

Expand Down
26 changes: 18 additions & 8 deletions probe/process/reporter.go
Expand Up @@ -2,6 +2,7 @@ package process

import (
"strconv"
"strings"

"github.com/weaveworks/common/mtime"
"github.com/weaveworks/scope/report"
Expand Down Expand Up @@ -37,20 +38,22 @@ var (

// Reporter generates Reports containing the Process topology.
type Reporter struct {
scope string
walker Walker
jiffies Jiffies
scope string
walker Walker
jiffies Jiffies
noCommandLineArguments bool
}

// Jiffies is the type for the function used to fetch the elapsed jiffies.
type Jiffies func() (uint64, float64, error)

// NewReporter makes a new Reporter.
func NewReporter(walker Walker, scope string, jiffies Jiffies) *Reporter {
func NewReporter(walker Walker, scope string, jiffies Jiffies, noCommandLineArguments bool) *Reporter {
return &Reporter{
scope: scope,
walker: walker,
jiffies: jiffies,
scope: scope,
walker: walker,
jiffies: jiffies,
noCommandLineArguments: noCommandLineArguments,
}
}

Expand Down Expand Up @@ -85,14 +88,21 @@ func (r *Reporter) processTopology() (report.Topology, error) {
for _, tuple := range []struct{ key, value string }{
{PID, pidstr},
{Name, p.Name},
{Cmdline, p.Cmdline},
{Threads, strconv.Itoa(p.Threads)},
} {
if tuple.value != "" {
node = node.WithLatests(map[string]string{tuple.key: tuple.value})
}
}

if p.Cmdline != "" {
if r.noCommandLineArguments {
node = node.WithLatests(map[string]string{Cmdline: strings.Split(p.Cmdline, " ")[0]})
} else {
node = node.WithLatests(map[string]string{Cmdline: p.Cmdline})
}
}

if p.PPID > 0 {
node = node.WithLatests(map[string]string{PPID: strconv.Itoa(p.PPID)})
}
Expand Down
15 changes: 14 additions & 1 deletion probe/process/reporter_test.go
Expand Up @@ -35,7 +35,7 @@ func TestReporter(t *testing.T) {
mtime.NowForce(now)
defer mtime.NowReset()

rpt, err := process.NewReporter(walker, "", getDeltaTotalJiffies).Report()
rpt, err := process.NewReporter(walker, "", getDeltaTotalJiffies, false).Report()
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -97,4 +97,17 @@ func TestReporter(t *testing.T) {
if cmdline, ok := node.Latest.Lookup(process.Cmdline); !ok || cmdline != fmt.Sprint(processes[4].Cmdline) {
t.Errorf("Expected %q got %q", processes[4].Cmdline, cmdline)
}

// It doesn't report Cmdline args when asked not to
rpt, err = process.NewReporter(walker, "", getDeltaTotalJiffies, true).Report()
if err != nil {
t.Error(err)
}
node, ok = rpt.Process.Nodes[report.MakeProcessNodeID("", "4")]
if !ok {
t.Errorf("Expected report to include the pid 4 ping")
}
if cmdline, ok := node.Latest.Lookup(process.Cmdline); !ok || cmdline != fmt.Sprint("ping") {
t.Errorf("Expected %q got %q", "ping", cmdline)
}
}
26 changes: 15 additions & 11 deletions prog/main.go
Expand Up @@ -80,17 +80,19 @@ type flags struct {
}

type probeFlags struct {
token string
httpListen string
publishInterval time.Duration
spyInterval time.Duration
pluginsRoot string
insecure bool
logPrefix string
logLevel string
resolver string
noApp bool
noControls bool
token string
httpListen string
publishInterval time.Duration
spyInterval time.Duration
pluginsRoot string
insecure bool
logPrefix string
logLevel string
resolver string
noApp bool
noControls bool
noCommandLineArguments bool
noEnvironmentVariables bool

useConntrack bool // Use conntrack for endpoint topo
conntrackBufferSize int // Sie of kernel buffer for conntrack
Expand Down Expand Up @@ -266,6 +268,8 @@ func main() {
flag.DurationVar(&flags.probe.spyInterval, "probe.spy.interval", time.Second, "spy (scan) interval")
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", 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.")
Expand Down
4 changes: 2 additions & 2 deletions prog/probe.go
Expand Up @@ -163,7 +163,7 @@ func probeMain(flags probeFlags, targets []appclient.Target) {
processCache = process.NewCachingWalker(process.NewWalker(flags.procRoot))
scanner = procspy.NewConnectionScanner(processCache)
p.AddTicker(processCache)
p.AddReporter(process.NewReporter(processCache, hostID, process.GetDeltaTotalJiffies))
p.AddReporter(process.NewReporter(processCache, hostID, process.GetDeltaTotalJiffies, flags.noCommandLineArguments))
}

dnsSnooper, err := endpoint.NewDNSSnooper()
Expand Down Expand Up @@ -195,7 +195,7 @@ func probeMain(flags probeFlags, targets []appclient.Target) {
log.Errorf("Docker: problem with bridge %s: %v", flags.dockerBridge, err)
}
}
if registry, err := docker.NewRegistry(flags.dockerInterval, clients, true, hostID, handlerRegistry, dockerEndpoint); err == nil {
if registry, err := docker.NewRegistry(flags.dockerInterval, clients, true, hostID, handlerRegistry, dockerEndpoint, flags.noCommandLineArguments, flags.noEnvironmentVariables); err == nil {
defer registry.Stop()
if flags.procEnabled {
p.AddTagger(docker.NewTagger(registry, processCache))
Expand Down