mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Merge pull request #32004 from hashicorp/brandonc/nested_attr_sensitive
fix: don't reveal nested attributes with sensitive schema
This commit is contained in:
commit
be5984d664
@ -172,8 +172,8 @@ func TestConsole_variables(t *testing.T) {
|
|||||||
commands := map[string]string{
|
commands := map[string]string{
|
||||||
"var.foo\n": "\"bar\"\n",
|
"var.foo\n": "\"bar\"\n",
|
||||||
"var.snack\n": "\"popcorn\"\n",
|
"var.snack\n": "\"popcorn\"\n",
|
||||||
"var.secret_snack\n": "(sensitive)\n",
|
"var.secret_snack\n": "(sensitive value)\n",
|
||||||
"local.snack_bar\n": "[\n \"popcorn\",\n (sensitive),\n]\n",
|
"local.snack_bar\n": "[\n \"popcorn\",\n (sensitive value),\n]\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{}
|
args := []string{}
|
||||||
|
@ -274,7 +274,10 @@ type blockBodyDiffResult struct {
|
|||||||
skippedBlocks int
|
skippedBlocks int
|
||||||
}
|
}
|
||||||
|
|
||||||
const forcesNewResourceCaption = " [red]# forces replacement[reset]"
|
const (
|
||||||
|
forcesNewResourceCaption = " [red]# forces replacement[reset]"
|
||||||
|
sensitiveCaption = "(sensitive value)"
|
||||||
|
)
|
||||||
|
|
||||||
// writeBlockBodyDiff writes attribute or block differences
|
// writeBlockBodyDiff writes attribute or block differences
|
||||||
// and returns true if any differences were found and written
|
// and returns true if any differences were found and written
|
||||||
@ -398,7 +401,7 @@ func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.At
|
|||||||
}
|
}
|
||||||
|
|
||||||
if attrS.NestedType != nil {
|
if attrS.NestedType != nil {
|
||||||
p.writeNestedAttrDiff(name, attrS.NestedType, old, new, nameLen, indent, path, action, showJustNew)
|
p.writeNestedAttrDiff(name, attrS, old, new, nameLen, indent, path, action, showJustNew)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +419,7 @@ func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.At
|
|||||||
p.buf.WriteString(" = ")
|
p.buf.WriteString(" = ")
|
||||||
|
|
||||||
if attrS.Sensitive {
|
if attrS.Sensitive {
|
||||||
p.buf.WriteString("(sensitive value)")
|
p.buf.WriteString(sensitiveCaption)
|
||||||
if p.pathForcesNewResource(path) {
|
if p.pathForcesNewResource(path) {
|
||||||
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
||||||
}
|
}
|
||||||
@ -441,9 +444,11 @@ func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.At
|
|||||||
// writeNestedAttrDiff is responsible for formatting Attributes with NestedTypes
|
// writeNestedAttrDiff is responsible for formatting Attributes with NestedTypes
|
||||||
// in the diff.
|
// in the diff.
|
||||||
func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
||||||
name string, objS *configschema.Object, old, new cty.Value,
|
name string, attrWithNestedS *configschema.Attribute, old, new cty.Value,
|
||||||
nameLen, indent int, path cty.Path, action plans.Action, showJustNew bool) {
|
nameLen, indent int, path cty.Path, action plans.Action, showJustNew bool) {
|
||||||
|
|
||||||
|
objS := attrWithNestedS.NestedType
|
||||||
|
|
||||||
p.buf.WriteString("\n")
|
p.buf.WriteString("\n")
|
||||||
p.writeSensitivityWarning(old, new, indent, action, false)
|
p.writeSensitivityWarning(old, new, indent, action, false)
|
||||||
p.buf.WriteString(strings.Repeat(" ", indent))
|
p.buf.WriteString(strings.Repeat(" ", indent))
|
||||||
@ -454,8 +459,12 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||||||
p.buf.WriteString(p.color.Color("[reset]"))
|
p.buf.WriteString(p.color.Color("[reset]"))
|
||||||
p.buf.WriteString(strings.Repeat(" ", nameLen-len(name)))
|
p.buf.WriteString(strings.Repeat(" ", nameLen-len(name)))
|
||||||
|
|
||||||
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
// Then schema of the attribute itself can be marked sensitive, or the values assigned
|
||||||
p.buf.WriteString(" = (sensitive value)")
|
sensitive := attrWithNestedS.Sensitive || old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive)
|
||||||
|
if sensitive {
|
||||||
|
p.buf.WriteString(" = ")
|
||||||
|
p.buf.WriteString(sensitiveCaption)
|
||||||
|
|
||||||
if p.pathForcesNewResource(path) {
|
if p.pathForcesNewResource(path) {
|
||||||
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
||||||
}
|
}
|
||||||
@ -475,6 +484,12 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||||||
p.buf.WriteString(strings.Repeat(" ", indent+2))
|
p.buf.WriteString(strings.Repeat(" ", indent+2))
|
||||||
p.buf.WriteString("}")
|
p.buf.WriteString("}")
|
||||||
|
|
||||||
|
if !new.IsKnown() {
|
||||||
|
p.buf.WriteString(" -> (known after apply)")
|
||||||
|
} else if new.IsNull() {
|
||||||
|
p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
|
||||||
|
}
|
||||||
|
|
||||||
case configschema.NestingList:
|
case configschema.NestingList:
|
||||||
p.buf.WriteString(" = [")
|
p.buf.WriteString(" = [")
|
||||||
if action != plans.NoOp && (p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1])) {
|
if action != plans.NoOp && (p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1])) {
|
||||||
@ -558,6 +573,8 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||||||
|
|
||||||
if !new.IsKnown() {
|
if !new.IsKnown() {
|
||||||
p.buf.WriteString(" -> (known after apply)")
|
p.buf.WriteString(" -> (known after apply)")
|
||||||
|
} else if new.IsNull() {
|
||||||
|
p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
|
||||||
}
|
}
|
||||||
|
|
||||||
case configschema.NestingSet:
|
case configschema.NestingSet:
|
||||||
@ -636,6 +653,8 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||||||
|
|
||||||
if !new.IsKnown() {
|
if !new.IsKnown() {
|
||||||
p.buf.WriteString(" -> (known after apply)")
|
p.buf.WriteString(" -> (known after apply)")
|
||||||
|
} else if new.IsNull() {
|
||||||
|
p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
|
||||||
}
|
}
|
||||||
|
|
||||||
case configschema.NestingMap:
|
case configschema.NestingMap:
|
||||||
@ -711,6 +730,8 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
|
|||||||
p.buf.WriteString("}")
|
p.buf.WriteString("}")
|
||||||
if !new.IsKnown() {
|
if !new.IsKnown() {
|
||||||
p.buf.WriteString(" -> (known after apply)")
|
p.buf.WriteString(" -> (known after apply)")
|
||||||
|
} else if new.IsNull() {
|
||||||
|
p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,7 +746,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *config
|
|||||||
|
|
||||||
// If either the old or the new value is marked,
|
// If either the old or the new value is marked,
|
||||||
// Display a special diff because it is irrelevant
|
// Display a special diff because it is irrelevant
|
||||||
// to list all obfuscated attributes as (sensitive)
|
// to list all obfuscated attributes as (sensitive value)
|
||||||
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
||||||
p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore, path)
|
p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore, path)
|
||||||
return 0
|
return 0
|
||||||
@ -1008,7 +1029,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiff(name string, label *string,
|
|||||||
func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, indent int) {
|
func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, indent int) {
|
||||||
// Could check specifically for the sensitivity marker
|
// Could check specifically for the sensitivity marker
|
||||||
if val.HasMark(marks.Sensitive) {
|
if val.HasMark(marks.Sensitive) {
|
||||||
p.buf.WriteString("(sensitive)")
|
p.buf.WriteString(sensitiveCaption)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,7 +1197,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||||||
// values are known and non-null.
|
// values are known and non-null.
|
||||||
if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual {
|
if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual {
|
||||||
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
||||||
p.buf.WriteString("(sensitive)")
|
p.buf.WriteString(sensitiveCaption)
|
||||||
if p.pathForcesNewResource(path) {
|
if p.pathForcesNewResource(path) {
|
||||||
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
||||||
}
|
}
|
||||||
@ -1547,7 +1568,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||||||
case plans.Create, plans.NoOp:
|
case plans.Create, plans.NoOp:
|
||||||
v := new.Index(kV)
|
v := new.Index(kV)
|
||||||
if v.HasMark(marks.Sensitive) {
|
if v.HasMark(marks.Sensitive) {
|
||||||
p.buf.WriteString("(sensitive)")
|
p.buf.WriteString(sensitiveCaption)
|
||||||
} else {
|
} else {
|
||||||
p.writeValue(v, action, indent+4)
|
p.writeValue(v, action, indent+4)
|
||||||
}
|
}
|
||||||
@ -1557,7 +1578,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||||||
p.writeValueDiff(oldV, newV, indent+4, path)
|
p.writeValueDiff(oldV, newV, indent+4, path)
|
||||||
default:
|
default:
|
||||||
if oldV.HasMark(marks.Sensitive) || newV.HasMark(marks.Sensitive) {
|
if oldV.HasMark(marks.Sensitive) || newV.HasMark(marks.Sensitive) {
|
||||||
p.buf.WriteString("(sensitive)")
|
p.buf.WriteString(sensitiveCaption)
|
||||||
} else {
|
} else {
|
||||||
p.writeValueDiff(oldV, newV, indent+4, path)
|
p.writeValueDiff(oldV, newV, indent+4, path)
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ func FormatValue(v cty.Value, indent int) string {
|
|||||||
return "(known after apply)"
|
return "(known after apply)"
|
||||||
}
|
}
|
||||||
if v.HasMark(marks.Sensitive) {
|
if v.HasMark(marks.Sensitive) {
|
||||||
return "(sensitive)"
|
return "(sensitive value)"
|
||||||
}
|
}
|
||||||
if v.IsNull() {
|
if v.IsNull() {
|
||||||
ty := v.Type()
|
ty := v.Type()
|
||||||
|
@ -171,8 +171,8 @@ EOT_`,
|
|||||||
`toset([])`,
|
`toset([])`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cty.StringVal("sensitive value").Mark(marks.Sensitive),
|
cty.StringVal("a sensitive value").Mark(marks.Sensitive),
|
||||||
"(sensitive)",
|
"(sensitive value)",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +63,11 @@ the `keys()` function will result in a list that is sensitive:
|
|||||||
```shell
|
```shell
|
||||||
> local.baz
|
> local.baz
|
||||||
{
|
{
|
||||||
"a" = (sensitive)
|
"a" = (sensitive value)
|
||||||
"b" = "dog"
|
"b" = "dog"
|
||||||
}
|
}
|
||||||
> keys(local.baz)
|
> keys(local.baz)
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
```
|
```
|
||||||
|
|
||||||
## When Terraform Calls Functions
|
## When Terraform Calls Functions
|
||||||
|
@ -292,7 +292,7 @@ Note that unlike `count`, splat expressions are _not_ directly applicable to res
|
|||||||
|
|
||||||
When defining the schema for a resource type, a provider developer can mark
|
When defining the schema for a resource type, a provider developer can mark
|
||||||
certain attributes as _sensitive_, in which case Terraform will show a
|
certain attributes as _sensitive_, in which case Terraform will show a
|
||||||
placeholder marker `(sensitive)` instead of the actual value when rendering
|
placeholder marker `(sensitive value)` instead of the actual value when rendering
|
||||||
a plan involving that attribute.
|
a plan involving that attribute.
|
||||||
|
|
||||||
A provider attribute marked as sensitive behaves similarly to an
|
A provider attribute marked as sensitive behaves similarly to an
|
||||||
|
@ -91,11 +91,11 @@ the local value `mixed_content`, with a valid JSON string assigned to
|
|||||||
|
|
||||||
```
|
```
|
||||||
> var.mixed_content_json
|
> var.mixed_content_json
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
> local.mixed_content
|
> local.mixed_content
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
> local.mixed_content["password"]
|
> local.mixed_content["password"]
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
> nonsensitive(local.mixed_content["username"])
|
> nonsensitive(local.mixed_content["username"])
|
||||||
"zqb"
|
"zqb"
|
||||||
> nonsensitive("clear")
|
> nonsensitive("clear")
|
||||||
|
@ -34,9 +34,9 @@ because they may be exposed in other ways outside of Terraform's control.
|
|||||||
|
|
||||||
```
|
```
|
||||||
> sensitive(1)
|
> sensitive(1)
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
> sensitive("hello")
|
> sensitive("hello")
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
> sensitive([])
|
> sensitive([])
|
||||||
(sensitive)
|
(sensitive value)
|
||||||
```
|
```
|
||||||
|
@ -159,7 +159,7 @@ Terraform will perform the following actions:
|
|||||||
|
|
||||||
# test_instance.x will be created
|
# test_instance.x will be created
|
||||||
+ resource "test_instance" "x" {
|
+ resource "test_instance" "x" {
|
||||||
+ some_attribute = (sensitive)
|
+ some_attribute = (sensitive value)
|
||||||
}
|
}
|
||||||
|
|
||||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||||
|
@ -218,8 +218,8 @@ Terraform will perform the following actions:
|
|||||||
|
|
||||||
# some_resource.a will be created
|
# some_resource.a will be created
|
||||||
+ resource "some_resource" "a" {
|
+ resource "some_resource" "a" {
|
||||||
+ name = (sensitive)
|
+ name = (sensitive value)
|
||||||
+ address = (sensitive)
|
+ address = (sensitive value)
|
||||||
}
|
}
|
||||||
|
|
||||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||||
@ -262,7 +262,7 @@ If a resource attribute is used as, or part of, the provider-defined resource id
|
|||||||
+ resource "random_pet" "animal" {
|
+ resource "random_pet" "animal" {
|
||||||
+ id = (known after apply)
|
+ id = (known after apply)
|
||||||
+ length = 2
|
+ length = 2
|
||||||
+ prefix = (sensitive)
|
+ prefix = (sensitive value)
|
||||||
+ separator = "-"
|
+ separator = "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user