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

feat: mask environment variables from outputs #463

Merged
merged 2 commits into from
Nov 9, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ const (
)

var (
dumpConfig dump.Config
assumeYes bool
dumpConfig dump.Config
assumeYes bool
noMaskValues bool
)

type mode int
Expand Down Expand Up @@ -280,6 +281,7 @@ func performDiff(ctx context.Context, currentState, targetState *state.KongState
TargetState: targetState,
KongClient: client,
StageDelaySec: delay,
NoMaskValues: noMaskValues,
})
if err != nil {
return 0, err
Expand Down
1 change: 1 addition & 0 deletions cmd/common_konnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func syncKonnect(ctx context.Context,
TargetState: targetState,
KongClient: kongClient,
KonnectClient: konnectClient,
NoMaskValues: noMaskValues,
})
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ that will be created, updated, or deleted.
"any plugins associated with consumers")
diffCmd.Flags().IntVar(&diffCmdParallelism, "parallelism",
10, "Maximum number of concurrent operations.")
diffCmd.Flags().BoolVar(&noMaskValues, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
diffCmd.Flags().StringSliceVar(&dumpConfig.SelectorTags,
"select-tag", []string{},
"only entities matching tags specified via this flag are diffed.\n"+
Expand Down
2 changes: 2 additions & 0 deletions cmd/konnect_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func newKonnectDiffCmd() *cobra.Command {
"with consumers.")
konnectDiffCmd.Flags().IntVar(&konnectDiffCmdParallelism, "parallelism",
100, "Maximum number of concurrent operations.")
konnectDiffCmd.Flags().BoolVar(&noMaskValues, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
konnectDiffCmd.Flags().BoolVar(&konnectDiffCmdNonZeroExitCode, "non-zero-exit-code",
false, "return exit code 2 if there is a diff present,\n"+
"exit code 0 if no diff is found,\n"+
Expand Down
2 changes: 2 additions & 0 deletions cmd/konnect_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ to get Konnect's state in sync with the input state.` + konnectAlphaState,
"with consumers.")
konnectSyncCmd.Flags().IntVar(&konnectDiffCmdParallelism, "parallelism",
100, "Maximum number of concurrent operations.")
konnectSyncCmd.Flags().BoolVar(&noMaskValues, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
addSilenceEventsFlag(konnectSyncCmd.Flags())
return konnectSyncCmd
}
2 changes: 2 additions & 0 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ By default, this command will ask for confirmation.`,
"(Kong Enterprise only).")
resetCmd.Flags().BoolVar(&resetAllWorkspaces, "all-workspaces",
false, "reset configuration of all workspaces (Kong Enterprise only).")
resetCmd.Flags().BoolVar(&noMaskValues, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
resetCmd.Flags().StringSliceVar(&dumpConfig.SelectorTags,
"select-tag", []string{},
"only entities matching tags specified via this flag are deleted.\n"+
Expand Down
2 changes: 2 additions & 0 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ to get Kong's state in sync with the input state.`,
"any plugins associated with consumers.")
syncCmd.Flags().IntVar(&syncCmdParallelism, "parallelism",
10, "Maximum number of concurrent operations.")
syncCmd.Flags().BoolVar(&noMaskValues, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
syncCmd.Flags().StringSliceVar(&dumpConfig.SelectorTags,
"select-tag", []string{},
"only entities matching tags specified via this flag are synced.\n"+
Expand Down
51 changes: 43 additions & 8 deletions diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ type Syncer struct {
konnectClient *konnect.Client

entityDiffers map[types.EntityType]types.Differ

noMaskValues bool
}

type SyncerOpts struct {
Expand All @@ -66,6 +68,8 @@ type SyncerOpts struct {

SilenceWarnings bool
StageDelaySec int

NoMaskValues bool
}

// NewSyncer constructs a Syncer.
Expand All @@ -79,6 +83,8 @@ func NewSyncer(opts SyncerOpts) (*Syncer, error) {

silenceWarnings: opts.SilenceWarnings,
stageDelaySec: opts.StageDelaySec,

noMaskValues: opts.NoMaskValues,
}

err := s.init()
Expand Down Expand Up @@ -322,6 +328,32 @@ type Stats struct {
DeleteOps *utils.AtomicInt32Counter
}

// Generete Diff output for 'sync' and 'diff' commands
func generateDiffString(e crud.Event, isDelete bool, noMaskValues bool) (string, error) {
var diffString string
var err error
if oldObj, ok := e.OldObj.(*state.Document); ok {
if !isDelete {
diffString, err = getDocumentDiff(oldObj, e.Obj.(*state.Document))
} else {
diffString, err = getDocumentDiff(e.Obj.(*state.Document), oldObj)
}
} else {
if !isDelete {
diffString, err = getDiff(e.OldObj, e.Obj)
} else {
diffString, err = getDiff(e.Obj, e.OldObj)
}
}
if err != nil {
return "", err
}
if !noMaskValues {
diffString = maskEnvVarValue(diffString)
}
return diffString, err
}

// Solve generates a diff and walks the graph.
func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool) (Stats, []error) {
stats := Stats{
Expand All @@ -347,20 +379,23 @@ func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool) (Stats,
c := e.Obj.(state.ConsoleString)
switch e.Op {
case crud.Create:
cprint.CreatePrintln("creating", e.Kind, c.Console())
case crud.Update:
var diffString string
if oldObj, ok := e.OldObj.(*state.Document); ok {
diffString, err = getDocumentDiff(oldObj, e.Obj.(*state.Document))
} else {
diffString, err = getDiff(e.OldObj, e.Obj)
diffString, err := generateDiffString(e, false, sc.noMaskValues)
if err != nil {
return nil, err
}
cprint.CreatePrintln("creating", e.Kind, c.Console(), diffString)
case crud.Update:
diffString, err := generateDiffString(e, false, sc.noMaskValues)
if err != nil {
return nil, err
}
cprint.UpdatePrintln("updating", e.Kind, c.Console(), diffString)
case crud.Delete:
cprint.DeletePrintln("deleting", e.Kind, c.Console())
diffString, err := generateDiffString(e, true, sc.noMaskValues)
if err != nil {
return nil, err
}
cprint.DeletePrintln("deleting", e.Kind, c.Console(), diffString)
default:
panic("unknown operation " + e.Op.String())
}
Expand Down
35 changes: 35 additions & 0 deletions diff/diff_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package diff
import (
"encoding/json"
"fmt"
"os"
"sort"
"strings"

"github.com/Kong/gojsondiff"
"github.com/Kong/gojsondiff/formatter"
Expand Down Expand Up @@ -83,3 +86,35 @@ func getDiff(a, b interface{}) (string, error) {
diffString, err := formatter.Format(d)
return diffString, err
}

type EnvVar struct {
Key string
Value string
}

func parseDeckEnvVars() []EnvVar {
const envVarPrefix = "DECK_"
var parsedEnvVars []EnvVar

for _, envVarStr := range os.Environ() {
envPair := strings.SplitN(envVarStr, "=", 2)
if strings.HasPrefix(envPair[0], envVarPrefix) {
envVar := EnvVar{}
envVar.Key = envPair[0]
envVar.Value = envPair[1]
parsedEnvVars = append(parsedEnvVars, envVar)
}
}

sort.Slice(parsedEnvVars, func(i, j int) bool {
return len(parsedEnvVars[i].Value) > len(parsedEnvVars[j].Value)
})
return parsedEnvVars
}

func maskEnvVarValue(diffString string) string {
for _, envVar := range parseDeckEnvVars() {
diffString = strings.Replace(diffString, envVar.Value, "[masked]", -1)
}
return diffString
}
33 changes: 33 additions & 0 deletions diff/diff_helpers_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package diff

import (
"os"
"testing"

"github.com/kong/deck/konnect"
Expand Down Expand Up @@ -145,3 +146,35 @@ bar
})
}
}

func Test_MaskEnvVarsValues(t *testing.T) {
tests := []struct {
name string
args string
want string
envVars map[string]string
}{
{
name: "JSON",
carnei-ro marked this conversation as resolved.
Show resolved Hide resolved
envVars: map[string]string{
"DECK_BAR": "barbar",
"DECK_BAZ": "bazbaz",
},
args: `{"foo":"foo","bar":"barbar","baz":"bazbaz"}`,
want: `{"foo":"foo","bar":"[masked]","baz":"[masked]"}`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for k, v := range tt.envVars {
os.Setenv(k, v)
defer func(k string) {
os.Unsetenv(k)
}(k)
}
if got := maskEnvVarValue(tt.args); got != tt.want {
t.Errorf("maskEnvVarValue() = %v\nwant %v", got, tt.want)
}
})
}
}