From 79a3e33c4d98240ebdea3edabff3be78ee73bd6d Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Tue, 6 Oct 2020 13:05:09 -0400 Subject: [PATCH] command: Fix missing force new for sensitive vars If a value rendered for the diff is sensitive and results in replacement of the resource, we should render the standard "forces replacement" text after the "(sensitive)" value display. --- command/format/diff.go | 3 +++ command/format/diff_test.go | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/command/format/diff.go b/command/format/diff.go index f8d7c5656..84527f6be 100644 --- a/command/format/diff.go +++ b/command/format/diff.go @@ -827,6 +827,9 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual { if old.IsMarked() || new.IsMarked() { p.buf.WriteString("(sensitive)") + if p.pathForcesNewResource(path) { + p.buf.WriteString(p.color.Color(forcesNewResourceCaption)) + } return } diff --git a/command/format/diff_test.go b/command/format/diff_test.go index 8e31ce355..63047e465 100644 --- a/command/format/diff_test.go +++ b/command/format/diff_test.go @@ -4251,6 +4251,46 @@ func TestResourceChange_sensitiveVariable(t *testing.T) { # 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"), + }), + After: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("i-02ae66f368e8518a9"), + "ami": cty.StringVal("ami-AFTER"), + }), + BeforeValMarks: []cty.PathValueMarks{ + { + Path: cty.Path{cty.GetAttrStep{Name: "ami"}}, + Marks: cty.NewValueMarks("sensitive"), + }, + }, + AfterValMarks: []cty.PathValueMarks{ + { + Path: cty.Path{cty.GetAttrStep{Name: "ami"}}, + 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}, + }, + }, + RequiredReplace: cty.NewPathSet(cty.Path{ + cty.GetAttrStep{Name: "ami"}, + }), + Tainted: false, + ExpectedOutput: ` # test_instance.example must be replaced +-/+ resource "test_instance" "example" { + ~ ami = (sensitive) # forces replacement + id = "i-02ae66f368e8518a9" + } `, }, }