Skip to content
Open
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
8 changes: 3 additions & 5 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,10 @@ usage: |-
| `TFMASK_VALUES_REGEX` | Regular expression used to match values | [see code] |
| `TFMASK_RESOURCES_REGEX` | Regular expression used to match resources | [see code] |

__IMPORTANT__: Pass `-no-color` to `terraform plan` and `terraform apply` for proper parsing

The basic usage looks like this. We're going to run `terraform plan` and filter it through `tfmask`:

```sh
terraform plan -no-color | tfmask
terraform plan | tfmask
```

### Direnv
Expand Down Expand Up @@ -152,7 +150,7 @@ examples: |-
Using `tfmask`, the output from `terraform plan` will be masked like this:

```sh
terraform plan -no-color | tfmask
terraform plan | tfmask
```

<details>
Expand Down Expand Up @@ -195,7 +193,7 @@ examples: |-
Using `tfmask`, the output from `terraform apply` will be masked like this:

```sh
terraform apply -no-color | tfmask
terraform apply | tfmask
```
<details>
<summary>Example of Masked Terraform Apply Output</summary>
Expand Down
33 changes: 33 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,29 @@ func getCurrentResource(expression expression, currentResource, line string) str
return currentResource
}

func stripAnsi(str string) string {
const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
re := regexp.MustCompile(ansi)
return re.ReplaceAllString(str, "")
}

func difference(a, b []string) (diff []string) {
for i, v := range a {
if v != b[i] {
diff = append(diff, v)
}
}
return diff
}

func processLine(expression expression, reTfResource,
reTfValues *regexp.Regexp, tfmaskChar, currentResource,
line string) string {

originalLine := line
// remove ansi codes
line = stripAnsi(line)
// process without ansi codes
if expression.planStatusRegex.MatchString(line) {
line = planStatus(expression.planStatusRegex, reTfResource, tfmaskChar,
line)
Expand All @@ -158,6 +178,19 @@ func processLine(expression expression, reTfResource,
line = assignmentLine(expression.reMapKeyPair, reTfValues,
tfmaskChar, line)
}
// compare original line with processed
if strings.Compare(stripAnsi(originalLine), line) == 0 {
// there were no secrets - return original line with ansi codes
line = originalLine
} else {
// find difference between original line(without ansi codes) and processed line(with masked secret)
diff := difference(strings.Split(stripAnsi(originalLine), ""), strings.Split(line, ""))
// this difference is a secret value
secret := strings.Join(diff, "")
// replace secret value in original line (with ansi codes) with asterisk
line = strings.Replace(originalLine, secret, strings.Repeat("*", len(secret)), 1)
}
// return line with ansi codes
return line
}

Expand Down
8 changes: 4 additions & 4 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ clean:

test: clean
terraform init
terraform plan -no-color | ../release/tfmask
terraform apply -auto-approve -no-color | ../release/tfmask
terraform plan | ../release/tfmask
terraform apply -auto-approve | ../release/tfmask
terraform taint random_string.some_password
terraform taint random_id.some_id
terraform plan -no-color | ../release/tfmask
terraform apply -auto-approve -no-color | ../release/tfmask
terraform plan | ../release/tfmask
terraform apply -auto-approve | ../release/tfmask