Skip to content

Commit

Permalink
feat: mask environment variables from outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
carnei-ro committed Aug 3, 2022
1 parent fa27b0e commit 63cb183
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 37 deletions.
8 changes: 4 additions & 4 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func getWorkspaceName(workspaceFlag string, targetContent *file.Content) string
}

func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
delay int, workspace string,
delay int, workspace string, noMaskValues bool,
) error {
// read target file
targetContent, err := file.GetContentFromFiles(filenames)
Expand Down Expand Up @@ -203,7 +203,7 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
return err
}

totalOps, err := performDiff(ctx, currentState, targetState, dry, parallelism, delay, kongClient)
totalOps, err := performDiff(ctx, currentState, targetState, dry, parallelism, delay, kongClient, noMaskValues)
if err != nil {
return err
}
Expand Down Expand Up @@ -251,7 +251,7 @@ func fetchCurrentState(ctx context.Context, client *kong.Client, dumpConfig dump
}

func performDiff(ctx context.Context, currentState, targetState *state.KongState,
dry bool, parallelism int, delay int, client *kong.Client,
dry bool, parallelism int, delay int, client *kong.Client, noMaskValues bool,
) (int, error) {
s, err := diff.NewSyncer(diff.SyncerOpts{
CurrentState: currentState,
Expand All @@ -263,7 +263,7 @@ func performDiff(ctx context.Context, currentState, targetState *state.KongState
return 0, err
}

stats, errs := s.Solve(ctx, parallelism, dry)
stats, errs := s.Solve(ctx, parallelism, dry, noMaskValues)
// print stats before error to report completed operations
printStats(stats)
if errs != nil {
Expand Down
8 changes: 4 additions & 4 deletions cmd/common_konnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func getKongClientForKonnectMode(ctx context.Context) (*kong.Client, error) {
})
}

func resetKonnectV2(ctx context.Context) error {
func resetKonnectV2(ctx context.Context, resetNoMaskDeckEnvVarsValue bool) error {
client, err := getKongClientForKonnectMode(ctx)
if err != nil {
return err
Expand All @@ -119,7 +119,7 @@ func resetKonnectV2(ctx context.Context) error {
if err != nil {
return err
}
_, err = performDiff(ctx, currentState, targetState, false, 10, 0, client)
_, err = performDiff(ctx, currentState, targetState, false, 10, 0, client, resetNoMaskDeckEnvVarsValue)
if err != nil {
return err
}
Expand Down Expand Up @@ -152,7 +152,7 @@ func dumpKonnectV2(ctx context.Context) error {
}

func syncKonnect(ctx context.Context,
filenames []string, dry bool, parallelism int,
filenames []string, dry bool, parallelism int, noMaskValues bool,
) error {
httpClient := utils.HTTPClient()

Expand Down Expand Up @@ -231,7 +231,7 @@ func syncKonnect(ctx context.Context,
return err
}

stats, errs := s.Solve(ctx, parallelism, dry)
stats, errs := s.Solve(ctx, parallelism, dry, noMaskValues)
// print stats before error to report completed operations
printStats(stats)
if errs != nil {
Expand Down
13 changes: 8 additions & 5 deletions cmd/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
)

var (
diffCmdKongStateFile []string
diffCmdParallelism int
diffCmdNonZeroExitCode bool
diffWorkspace string
diffCmdKongStateFile []string
diffCmdParallelism int
diffCmdNoMaskDeckEnvVarsValue bool
diffCmdNonZeroExitCode bool
diffWorkspace string
)

// newDiffCmd represents the diff command
Expand All @@ -27,7 +28,7 @@ that will be created, updated, or deleted.
Args: validateNoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return syncMain(cmd.Context(), diffCmdKongStateFile, true,
diffCmdParallelism, 0, diffWorkspace)
diffCmdParallelism, 0, diffWorkspace, diffCmdNoMaskDeckEnvVarsValue)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(diffCmdKongStateFile) == 0 {
Expand All @@ -51,6 +52,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(&diffCmdNoMaskDeckEnvVarsValue, "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
11 changes: 7 additions & 4 deletions cmd/konnect_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
)

var (
konnectDiffCmdKongStateFile []string
konnectDiffCmdParallelism int
konnectDiffCmdNonZeroExitCode bool
konnectDiffCmdKongStateFile []string
konnectDiffCmdParallelism int
konnectDiffCmdNoMaskDeckEnvVarsValue bool
konnectDiffCmdNonZeroExitCode bool
)

// newKonnectDiffCmd represents the 'deck konnect diff' command.
Expand All @@ -32,7 +33,7 @@ func newKonnectDiffCmd() *cobra.Command {
konnectConfig.Address = defaultLegacyKonnectURL
}
return syncKonnect(cmd.Context(), konnectDiffCmdKongStateFile, true,
konnectDiffCmdParallelism)
konnectDiffCmdParallelism, konnectDiffCmdNoMaskDeckEnvVarsValue)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
return preRunSilenceEventsFlag()
Expand All @@ -47,6 +48,8 @@ func newKonnectDiffCmd() *cobra.Command {
"with consumers.")
konnectDiffCmd.Flags().IntVar(&konnectDiffCmdParallelism, "parallelism",
100, "Maximum number of concurrent operations.")
konnectDiffCmd.Flags().BoolVar(&konnectDiffCmdNoMaskDeckEnvVarsValue, "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
4 changes: 3 additions & 1 deletion cmd/konnect_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ to get Konnect's state in sync with the input state.` + konnectAlphaState,
konnectConfig.Address = defaultLegacyKonnectURL
}
return syncKonnect(cmd.Context(), konnectDiffCmdKongStateFile, false,
konnectDiffCmdParallelism)
konnectDiffCmdParallelism, konnectDiffCmdNoMaskDeckEnvVarsValue)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
return preRunSilenceEventsFlag()
Expand All @@ -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(&konnectDiffCmdNoMaskDeckEnvVarsValue, "no-mask-deck-env-vars-value",
false, "do not mask DECK_ environment variable values at diff output.")
addSilenceEventsFlag(konnectSyncCmd.Flags())
return konnectSyncCmd
}
13 changes: 8 additions & 5 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (
)

var (
resetCmdForce bool
resetWorkspace string
resetAllWorkspaces bool
resetCmdForce bool
resetWorkspace string
resetAllWorkspaces bool
resetNoMaskDeckEnvVarsValue bool
)

// newResetCmd represents the reset command
Expand Down Expand Up @@ -47,7 +48,7 @@ By default, this command will ask for confirmation.`,
mode := getMode(nil)
if mode == modeKonnect {
_ = sendAnalytics("reset", "", mode)
return resetKonnectV2(ctx)
return resetKonnectV2(ctx, resetNoMaskDeckEnvVarsValue)
}

rootClient, err := utils.GetKongClient(rootConfig)
Expand Down Expand Up @@ -99,7 +100,7 @@ By default, this command will ask for confirmation.`,
if err != nil {
return err
}
_, err = performDiff(ctx, currentState, targetState, false, 10, 0, wsClient)
_, err = performDiff(ctx, currentState, targetState, false, 10, 0, wsClient, resetNoMaskDeckEnvVarsValue)
if err != nil {
return err
}
Expand All @@ -118,6 +119,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(&resetNoMaskDeckEnvVarsValue, "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
11 changes: 7 additions & 4 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
)

var (
syncCmdParallelism int
syncCmdDBUpdateDelay int
syncWorkspace string
syncCmdParallelism int
syncCmdDBUpdateDelay int
syncCmdNoMaskDeckEnvVarsValue bool
syncWorkspace string
)

// newSyncCmd represents the sync command
Expand All @@ -24,7 +25,7 @@ to get Kong's state in sync with the input state.`,
Args: validateNoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return syncMain(cmd.Context(), syncCmdKongStateFile, false,
syncCmdParallelism, syncCmdDBUpdateDelay, syncWorkspace)
syncCmdParallelism, syncCmdDBUpdateDelay, syncWorkspace, syncCmdNoMaskDeckEnvVarsValue)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(syncCmdKongStateFile) == 0 {
Expand All @@ -48,6 +49,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(&syncCmdNoMaskDeckEnvVarsValue, "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
47 changes: 38 additions & 9 deletions diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,34 @@ 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) {
func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool, noMaskValues bool) (Stats, []error) {
stats := Stats{
CreateOps: &utils.AtomicInt32Counter{},
UpdateOps: &utils.AtomicInt32Counter{},
Expand All @@ -345,20 +371,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, noMaskValues)
if err != nil {
return nil, err
}
cprint.CreatePrintln("creating", e.Kind, c.Console(), diffString)
case crud.Update:
diffString, err := generateDiffString(e, false, 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, 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",
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)
}
})
}
}
Loading

0 comments on commit 63cb183

Please sign in to comment.