Skip to content

Commit d73a9e9

Browse files
authored
support filtered regex (#1978)
* support masking of sensitive values
1 parent 3540796 commit d73a9e9

21 files changed

+254
-66
lines changed

cli/pkg/digger/digger_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (m *MockTerraformExecutor) Show(params []string, envs map[string]string, pl
6363
return nonEmptyTerraformPlanJson, "", nil
6464
}
6565

66-
func (m *MockTerraformExecutor) Plan(params []string, envs map[string]string, planJsonFilePath string) (bool, string, string, error) {
66+
func (m *MockTerraformExecutor) Plan(params []string, envs map[string]string, planJsonFilePath string, s *string) (bool, string, string, error) {
6767
m.Commands = append(m.Commands, RunInfo{"Plan", strings.Join(params, " "), time.Now()})
6868
return true, "", "", nil
6969
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: "Masking sensitive values"
3+
---
4+
5+
You can use a regular expression to ensure that senstivie outputs are masked from plan outputs and comments by digger.
6+
This can be done at the workflow level as follows:
7+
8+
```
9+
workflows:
10+
default:
11+
plan:
12+
filter_regex: "((?i)filterme:\\s\"?)[^\"]*"
13+
steps:
14+
- init
15+
- plan
16+
```
17+
18+
Currently this is only supported at the plan step. The filter_regex is a regular expression and it will mask any occurence of
19+
that expression in the logs and the comment, replacing it with `<REDACTED>`. For example the following terraform:
20+
21+
```
22+
output "filterme" {
23+
value = "example_secret: filterme: topsecret"
24+
}
25+
```
26+
27+
![](/images/configuration/masking-sensitive-values.png)
55.5 KB
Loading

docs/mint.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
"ce/howto/generate-projects",
9393
"ce/howto/group-plans-by-source",
9494
"ce/howto/include-exclude-patterns",
95+
"ce/howto/masking-sensitive-values",
9596
"ce/howto/multiacc-aws",
9697
"ce/howto/policy-overrides",
9798
"ce/howto/project-level-roles",

libs/digger_config/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ type Step struct {
9494
}
9595

9696
type Stage struct {
97-
Steps []Step
97+
Steps []Step
98+
FilterRegex *string
9899
}
99100

100101
func defaultWorkflow() *Workflow {

libs/digger_config/converters.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ func copyTerraformEnvConfig(terraformEnvConfig *TerraformEnvConfigYaml) *Terrafo
120120
}
121121

122122
func copyStage(stage *StageYaml) *Stage {
123-
result := Stage{}
123+
result := Stage{
124+
FilterRegex: stage.FilterRegex,
125+
}
124126
result.Steps = make([]Step, len(stage.Steps))
125127

126128
for i, s := range stage.Steps {

libs/digger_config/digger_config.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"path"
99
"path/filepath"
10+
"regexp"
1011
"strings"
1112

1213
"github.com/samber/lo"
@@ -546,6 +547,31 @@ func ValidateDiggerConfigYaml(configYaml *DiggerConfigYaml, fileName string) err
546547
}
547548
}
548549

550+
if configYaml.Workflows != nil {
551+
for _, workflow := range configYaml.Workflows {
552+
if workflow == nil {
553+
continue
554+
}
555+
if workflow.Plan != nil && workflow.Plan.FilterRegex != nil {
556+
_, err := regexp.Compile(*workflow.Plan.FilterRegex)
557+
if err != nil {
558+
slog.Error("invalid regex for plan filter",
559+
"regex", *workflow.Plan.FilterRegex,
560+
"error", err)
561+
return fmt.Errorf("regex for plan filter is invalid: %v", err)
562+
}
563+
}
564+
if workflow.Apply != nil && workflow.Apply.FilterRegex != nil {
565+
_, err := regexp.Compile(*workflow.Apply.FilterRegex)
566+
if err != nil {
567+
slog.Error("invalid regex for apply filter",
568+
"regex", *workflow.Apply.FilterRegex,
569+
"error", err)
570+
return fmt.Errorf("regex for apply filter is invalid: %v", err)
571+
}
572+
}
573+
}
574+
}
549575
if configYaml.GenerateProjectsConfig != nil {
550576
if configYaml.GenerateProjectsConfig.Include != "" &&
551577
configYaml.GenerateProjectsConfig.Exclude != "" &&

libs/digger_config/digger_config_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,10 +513,12 @@ projects:
513513
workflow: my_custom_workflow
514514
workflows:
515515
my_custom_workflow:
516-
steps:
517-
- run: echo "run"
518-
- init: terraform init
519-
- plan: terraform plan
516+
plan:
517+
filter_regex: "myregex"
518+
steps:
519+
- run: echo "run"
520+
- init:
521+
- plan:
520522
`
521523
deleteFile := createFile(path.Join(tempDir, "digger.yaml"), diggerCfg)
522524
defer deleteFile()
@@ -527,6 +529,8 @@ workflows:
527529
assert.Equal(t, "my_custom_workflow", dg.Projects[0].Workflow)
528530
_, ok := dg.Workflows["my_custom_workflow"]
529531
assert.True(t, ok)
532+
r := dg.Workflows["my_custom_workflow"].Plan.FilterRegex
533+
assert.Equal(t, "myregex", *r)
530534
}
531535

532536
func TestDiggerConfigCustomWorkflowMissingParams(t *testing.T) {

libs/digger_config/yaml.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ func (s *StageYaml) ToCoreStage() Stage {
7878
}
7979

8080
type StageYaml struct {
81-
Steps []StepYaml `yaml:"steps"`
81+
FilterRegex *string `yaml:"filter_regex,omitempty"`
82+
Steps []StepYaml `yaml:"steps"`
8283
}
8384

8485
type StepYaml struct {

libs/execution/execution.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func (d DiggerExecutor) Plan() (*iac_utils.IacSummary, bool, bool, string, strin
234234
// TODO remove those only for pulumi project
235235
planArgs = append(planArgs, step.ExtraArgs...)
236236

237-
_, stdout, stderr, err := d.TerraformExecutor.Plan(planArgs, d.CommandEnvVars, d.PlanPathProvider.LocalPlanFilePath())
237+
_, stdout, stderr, err := d.TerraformExecutor.Plan(planArgs, d.CommandEnvVars, d.PlanPathProvider.LocalPlanFilePath(), d.PlanStage.FilterRegex)
238238
if err != nil {
239239
return nil, false, false, "", "", fmt.Errorf("error executing plan: %v", err)
240240
}

0 commit comments

Comments
 (0)