Skip to content

Add concept of sensitive args #14

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

Merged
merged 2 commits into from
Nov 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions shell/cmd.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package shell

import (
"os/exec"
"bufio"
"io"
"os"
"os/exec"
"strings"

"github.com/gruntwork-io/gruntwork-cli/errors"
"io"
"bufio"
)

// Run the specified shell command with the specified arguments. Connect the command's stdin, stdout, and stderr to
// the currently running app.
func RunShellCommand(options *ShellOptions, command string, args ... string) error {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
func RunShellCommand(options *ShellOptions, command string, args ...string) error {
if options.SensitiveArgs {
options.Logger.Infof("Running command: %s (args redacted)", command)
} else {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
}

cmd := exec.Command(command, args...)

Expand All @@ -27,8 +32,12 @@ func RunShellCommand(options *ShellOptions, command string, args ... string) err
}

// Run the specified shell command with the specified arguments. Return its stdout and stderr as a string
func RunShellCommandAndGetOutput(options *ShellOptions, command string, args ... string) (string, error) {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
func RunShellCommandAndGetOutput(options *ShellOptions, command string, args ...string) (string, error) {
if options.SensitiveArgs {
options.Logger.Infof("Running command: %s (args redacted)", command)
} else {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
}

cmd := exec.Command(command, args...)

Expand All @@ -41,8 +50,12 @@ func RunShellCommandAndGetOutput(options *ShellOptions, command string, args ...

// Run the specified shell command with the specified arguments. Return its stdout and stderr as a string and also
// stream stdout and stderr to the OS stdout/stderr
func RunShellCommandAndGetAndStreamOutput(options *ShellOptions, command string, args ... string) (string, error) {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
func RunShellCommandAndGetAndStreamOutput(options *ShellOptions, command string, args ...string) (string, error) {
if options.SensitiveArgs {
options.Logger.Infof("Running command: %s (args redacted)", command)
} else {
options.Logger.Infof("Running command: %s %s", command, strings.Join(args, " "))
}

cmd := exec.Command(command, args...)

Expand Down
69 changes: 68 additions & 1 deletion shell/cmd_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package shell

import (
"testing"
"bytes"
"github.com/stretchr/testify/assert"
"testing"

"github.com/gruntwork-io/gruntwork-cli/logging"
)

func TestRunShellCommand(t *testing.T) {
Expand Down Expand Up @@ -36,3 +39,67 @@ func TestCommandInstalledOnInvalidCommand(t *testing.T) {

assert.False(t, CommandInstalled("not-a-real-command"))
}

// Test that when SensitiveArgs is true, do not log the args
func TestSensitiveArgsTrueHidesOnRunShellCommand(t *testing.T) {
t.Parallel()

buffer := bytes.NewBufferString("")
logger := logging.GetLogger("")
logger.Out = buffer
options := NewShellOptions()
options.SensitiveArgs = true
options.Logger = logger

assert.Nil(t, RunShellCommand(options, "echo", "hi"))
assert.NotContains(t, buffer.String(), "hi")
assert.Contains(t, buffer.String(), "echo")
}

// Test that when SensitiveArgs is false, log the args
func TestSensitiveArgsFalseShowsOnRunShellCommand(t *testing.T) {
t.Parallel()

buffer := bytes.NewBufferString("")
logger := logging.GetLogger("")
logger.Out = buffer
options := NewShellOptions()
options.Logger = logger

assert.Nil(t, RunShellCommand(options, "echo", "hi"))
assert.Contains(t, buffer.String(), "hi")
assert.Contains(t, buffer.String(), "echo")
}

// Test that when SensitiveArgs is true, do not log the args
func TestSensitiveArgsTrueHidesOnRunShellCommandAndGetOutput(t *testing.T) {
t.Parallel()

buffer := bytes.NewBufferString("")
logger := logging.GetLogger("")
logger.Out = buffer
options := NewShellOptions()
options.SensitiveArgs = true
options.Logger = logger

_, err := RunShellCommandAndGetOutput(options, "echo", "hi")
assert.Nil(t, err)
assert.NotContains(t, buffer.String(), "hi")
assert.Contains(t, buffer.String(), "echo")
}

// Test that when SensitiveArgs is false, log the args
func TestSensitiveArgsFalseShowsOnRunShellCommandAndGetOutput(t *testing.T) {
t.Parallel()

buffer := bytes.NewBufferString("")
logger := logging.GetLogger("")
logger.Out = buffer
options := NewShellOptions()
options.Logger = logger

_, err := RunShellCommandAndGetOutput(options, "echo", "hi")
assert.Nil(t, err)
assert.Contains(t, buffer.String(), "hi")
assert.Contains(t, buffer.String(), "echo")
}
8 changes: 5 additions & 3 deletions shell/options.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package shell

import (
"github.com/sirupsen/logrus"
"github.com/gruntwork-io/gruntwork-cli/logging"
"github.com/sirupsen/logrus"
)

type ShellOptions struct {
NonInteractive bool
Logger *logrus.Logger
WorkingDir string
SensitiveArgs bool // If true, will not log the arguments to the command
}

func NewShellOptions() *ShellOptions {
return &ShellOptions{
NonInteractive: false,
Logger: logging.GetLogger(""),
WorkingDir: ".",
Logger: logging.GetLogger(""),
WorkingDir: ".",
SensitiveArgs: false,
}
}