Merge pull request #26492 from hashicorp/alisdair/sensitive-value-force-replacement

command: Fix missing force new for sensitive vars and blocks
This commit is contained in:
Alisdair McDiarmid 2020-10-07 11:10:36 -04:00 committed by GitHub
commit d05e3b40bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 2 deletions

View File

@ -381,7 +381,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *config
// 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)
if old.IsMarked() || new.IsMarked() { if old.IsMarked() || new.IsMarked() {
p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore) p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore, path)
return 0 return 0
} }
@ -589,7 +589,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *config
return skippedBlocks return skippedBlocks
} }
func (p *blockBodyDiffPrinter) writeSensitiveNestedBlockDiff(name string, old, new cty.Value, indent int, blankBefore bool) { func (p *blockBodyDiffPrinter) writeSensitiveNestedBlockDiff(name string, old, new cty.Value, indent int, blankBefore bool, path cty.Path) {
unmarkedOld, _ := old.Unmark() unmarkedOld, _ := old.Unmark()
unmarkedNew, _ := new.Unmark() unmarkedNew, _ := new.Unmark()
eqV := unmarkedNew.Equals(unmarkedOld) eqV := unmarkedNew.Equals(unmarkedOld)
@ -618,6 +618,9 @@ func (p *blockBodyDiffPrinter) writeSensitiveNestedBlockDiff(name string, old, n
p.buf.WriteString(strings.Repeat(" ", indent)) p.buf.WriteString(strings.Repeat(" ", indent))
p.writeActionSymbol(action) p.writeActionSymbol(action)
fmt.Fprintf(p.buf, "%s {", name) fmt.Fprintf(p.buf, "%s {", name)
if action != plans.NoOp && p.pathForcesNewResource(path) {
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
}
p.buf.WriteRune('\n') p.buf.WriteRune('\n')
p.buf.WriteString(strings.Repeat(" ", indent+4)) p.buf.WriteString(strings.Repeat(" ", indent+4))
p.buf.WriteString("# At least one attribute in this block is (or was) sensitive,\n") p.buf.WriteString("# At least one attribute in this block is (or was) sensitive,\n")
@ -827,6 +830,9 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual { if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual {
if old.IsMarked() || new.IsMarked() { if old.IsMarked() || new.IsMarked() {
p.buf.WriteString("(sensitive)") p.buf.WriteString("(sensitive)")
if p.pathForcesNewResource(path) {
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
}
return return
} }

View File

@ -4251,6 +4251,80 @@ func TestResourceChange_sensitiveVariable(t *testing.T) {
# so its contents will not be displayed. # so its contents will not be displayed.
} }
} }
`,
},
"update with sensitive value forcing replacement": {
Action: plans.DeleteThenCreate,
Mode: addrs.ManagedResourceMode,
Before: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("i-02ae66f368e8518a9"),
"ami": cty.StringVal("ami-BEFORE"),
"nested_block_set": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"an_attr": cty.StringVal("secret"),
}),
}),
}),
After: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("i-02ae66f368e8518a9"),
"ami": cty.StringVal("ami-AFTER"),
"nested_block_set": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"an_attr": cty.StringVal("changed"),
}),
}),
}),
BeforeValMarks: []cty.PathValueMarks{
{
Path: cty.GetAttrPath("ami"),
Marks: cty.NewValueMarks("sensitive"),
},
{
Path: cty.GetAttrPath("nested_block_set"),
Marks: cty.NewValueMarks("sensitive"),
},
},
AfterValMarks: []cty.PathValueMarks{
{
Path: cty.GetAttrPath("ami"),
Marks: cty.NewValueMarks("sensitive"),
},
{
Path: cty.GetAttrPath("nested_block_set"),
Marks: cty.NewValueMarks("sensitive"),
},
},
Schema: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Optional: true, Computed: true},
"ami": {Type: cty.String, Optional: true},
},
BlockTypes: map[string]*configschema.NestedBlock{
"nested_block_set": {
Block: configschema.Block{
Attributes: map[string]*configschema.Attribute{
"an_attr": {Type: cty.String, Required: true},
},
},
Nesting: configschema.NestingSet,
},
},
},
RequiredReplace: cty.NewPathSet(
cty.GetAttrPath("ami"),
cty.GetAttrPath("nested_block_set"),
),
Tainted: false,
ExpectedOutput: ` # test_instance.example must be replaced
-/+ resource "test_instance" "example" {
~ ami = (sensitive) # forces replacement
id = "i-02ae66f368e8518a9"
~ nested_block_set { # forces replacement
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
`, `,
}, },
} }