remove IsMarked and ContainsMarked calls
Make sure sensitivity checks are looking for specific marks rather than any marks at all.
This commit is contained in:
parent
cdf7469efd
commit
55ebb2708c
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/hashicorp/terraform/internal/plans"
|
||||
"github.com/hashicorp/terraform/internal/plans/objchange"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
|
@ -733,7 +734,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *config
|
|||
// If either the old or the new value is marked,
|
||||
// Display a special diff because it is irrelevant
|
||||
// to list all obfuscated attributes as (sensitive)
|
||||
if old.IsMarked() || new.IsMarked() {
|
||||
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
||||
p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore, path)
|
||||
return 0
|
||||
}
|
||||
|
@ -1012,7 +1013,7 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiff(name string, label *string,
|
|||
|
||||
func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, indent int) {
|
||||
// Could check specifically for the sensitivity marker
|
||||
if val.IsMarked() {
|
||||
if val.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString("(sensitive)")
|
||||
return
|
||||
}
|
||||
|
@ -1177,7 +1178,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||
// However, these specialized implementations can apply only if both
|
||||
// values are known and non-null.
|
||||
if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual {
|
||||
if old.IsMarked() || new.IsMarked() {
|
||||
if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString("(sensitive)")
|
||||
if p.pathForcesNewResource(path) {
|
||||
p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
|
||||
|
@ -1548,7 +1549,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||
switch action {
|
||||
case plans.Create, plans.NoOp:
|
||||
v := new.Index(kV)
|
||||
if v.IsMarked() {
|
||||
if v.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString("(sensitive)")
|
||||
} else {
|
||||
p.writeValue(v, action, indent+4)
|
||||
|
@ -1558,7 +1559,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
|||
newV := cty.NullVal(oldV.Type())
|
||||
p.writeValueDiff(oldV, newV, indent+4, path)
|
||||
default:
|
||||
if oldV.IsMarked() || newV.IsMarked() {
|
||||
if oldV.HasMark(marks.Sensitive) || newV.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString("(sensitive)")
|
||||
} else {
|
||||
p.writeValueDiff(oldV, newV, indent+4, path)
|
||||
|
@ -1738,7 +1739,7 @@ func (p *blockBodyDiffPrinter) writeSensitivityWarning(old, new cty.Value, inden
|
|||
}
|
||||
}
|
||||
|
||||
if new.IsMarked() && !old.IsMarked() {
|
||||
if new.HasMark(marks.Sensitive) && !old.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString(strings.Repeat(" ", indent))
|
||||
p.buf.WriteString(p.color.Color(fmt.Sprintf("# [yellow]Warning:[reset] this %s will be marked as sensitive and will not\n", diffType)))
|
||||
p.buf.WriteString(strings.Repeat(" ", indent))
|
||||
|
@ -1746,7 +1747,7 @@ func (p *blockBodyDiffPrinter) writeSensitivityWarning(old, new cty.Value, inden
|
|||
}
|
||||
|
||||
// Note if changing this attribute will change its sensitivity
|
||||
if old.IsMarked() && !new.IsMarked() {
|
||||
if old.HasMark(marks.Sensitive) && !new.HasMark(marks.Sensitive) {
|
||||
p.buf.WriteString(strings.Repeat(" ", indent))
|
||||
p.buf.WriteString(p.color.Color(fmt.Sprintf("# [yellow]Warning:[reset] this %s will no longer be marked as sensitive\n", diffType)))
|
||||
p.buf.WriteString(strings.Repeat(" ", indent))
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -156,9 +157,10 @@ func (v *addHuman) writeConfigAttributesFromExisting(buf *strings.Builder, state
|
|||
} else {
|
||||
val = attrS.EmptyValue()
|
||||
}
|
||||
if attrS.Sensitive || val.IsMarked() {
|
||||
if attrS.Sensitive || val.HasMark(marks.Sensitive) {
|
||||
buf.WriteString("null # sensitive")
|
||||
} else {
|
||||
val, _ = val.Unmark()
|
||||
tok := hclwrite.TokensForValue(val)
|
||||
if _, err := tok.WriteTo(buf); err != nil {
|
||||
return err
|
||||
|
@ -322,7 +324,7 @@ func (v *addHuman) writeConfigBlocksFromExisting(buf *strings.Builder, stateVal
|
|||
func (v *addHuman) writeConfigNestedTypeAttributeFromExisting(buf *strings.Builder, name string, schema *configschema.Attribute, stateVal cty.Value, indent int) error {
|
||||
switch schema.NestedType.Nesting {
|
||||
case configschema.NestingSingle:
|
||||
if schema.Sensitive || stateVal.IsMarked() {
|
||||
if schema.Sensitive || stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString(strings.Repeat(" ", indent))
|
||||
buf.WriteString(fmt.Sprintf("%s = {} # sensitive\n", name))
|
||||
return nil
|
||||
|
@ -347,7 +349,7 @@ func (v *addHuman) writeConfigNestedTypeAttributeFromExisting(buf *strings.Build
|
|||
buf.WriteString(strings.Repeat(" ", indent))
|
||||
buf.WriteString(fmt.Sprintf("%s = [", name))
|
||||
|
||||
if schema.Sensitive || stateVal.IsMarked() {
|
||||
if schema.Sensitive || stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString("] # sensitive\n")
|
||||
return nil
|
||||
}
|
||||
|
@ -359,7 +361,7 @@ func (v *addHuman) writeConfigNestedTypeAttributeFromExisting(buf *strings.Build
|
|||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
|
||||
// The entire element is marked.
|
||||
if listVals[i].IsMarked() {
|
||||
if listVals[i].HasMark(marks.Sensitive) {
|
||||
buf.WriteString("{}, # sensitive\n")
|
||||
continue
|
||||
}
|
||||
|
@ -379,7 +381,7 @@ func (v *addHuman) writeConfigNestedTypeAttributeFromExisting(buf *strings.Build
|
|||
buf.WriteString(strings.Repeat(" ", indent))
|
||||
buf.WriteString(fmt.Sprintf("%s = {", name))
|
||||
|
||||
if schema.Sensitive || stateVal.IsMarked() {
|
||||
if schema.Sensitive || stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString(" } # sensitive\n")
|
||||
return nil
|
||||
}
|
||||
|
@ -397,7 +399,7 @@ func (v *addHuman) writeConfigNestedTypeAttributeFromExisting(buf *strings.Build
|
|||
buf.WriteString(fmt.Sprintf("%s = {", key))
|
||||
|
||||
// This entire value is marked
|
||||
if vals[key].IsMarked() {
|
||||
if vals[key].HasMark(marks.Sensitive) {
|
||||
buf.WriteString("} # sensitive\n")
|
||||
continue
|
||||
}
|
||||
|
@ -426,7 +428,7 @@ func (v *addHuman) writeConfigNestedBlockFromExisting(buf *strings.Builder, name
|
|||
buf.WriteString(fmt.Sprintf("%s {", name))
|
||||
|
||||
// If the entire value is marked, don't print any nested attributes
|
||||
if stateVal.IsMarked() {
|
||||
if stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString("} # sensitive\n")
|
||||
return nil
|
||||
}
|
||||
|
@ -440,7 +442,7 @@ func (v *addHuman) writeConfigNestedBlockFromExisting(buf *strings.Builder, name
|
|||
buf.WriteString("}\n")
|
||||
return nil
|
||||
case configschema.NestingList, configschema.NestingSet:
|
||||
if stateVal.IsMarked() {
|
||||
if stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString(strings.Repeat(" ", indent))
|
||||
buf.WriteString(fmt.Sprintf("%s {} # sensitive\n", name))
|
||||
return nil
|
||||
|
@ -460,7 +462,7 @@ func (v *addHuman) writeConfigNestedBlockFromExisting(buf *strings.Builder, name
|
|||
return nil
|
||||
case configschema.NestingMap:
|
||||
// If the entire value is marked, don't print any nested attributes
|
||||
if stateVal.IsMarked() {
|
||||
if stateVal.HasMark(marks.Sensitive) {
|
||||
buf.WriteString(fmt.Sprintf("%s {} # sensitive\n", name))
|
||||
return nil
|
||||
}
|
||||
|
@ -475,7 +477,7 @@ func (v *addHuman) writeConfigNestedBlockFromExisting(buf *strings.Builder, name
|
|||
buf.WriteString(strings.Repeat(" ", indent))
|
||||
buf.WriteString(fmt.Sprintf("%s %q {", name, key))
|
||||
// This entire map element is marked
|
||||
if vals[key].IsMarked() {
|
||||
if vals[key].HasMark(marks.Sensitive) {
|
||||
buf.WriteString("} # sensitive\n")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -343,7 +343,7 @@ func TestAdd_writeConfigBlocksFromExisting(t *testing.T) {
|
|||
v := addHuman{optional: true}
|
||||
val := cty.ObjectVal(map[string]cty.Value{
|
||||
"root_block_device": cty.ObjectVal(map[string]cty.Value{
|
||||
"volume_type": cty.StringVal("foo").Mark("bar"),
|
||||
"volume_type": cty.StringVal("foo").Mark(marks.Sensitive),
|
||||
}),
|
||||
})
|
||||
schema := addTestSchema(configschema.NestingSingle)
|
||||
|
@ -366,7 +366,7 @@ func TestAdd_writeConfigBlocksFromExisting(t *testing.T) {
|
|||
"root_block_device": cty.ObjectVal(map[string]cty.Value{
|
||||
"volume_type": cty.StringVal("foo"),
|
||||
}),
|
||||
}).Mark("bar")
|
||||
}).Mark(marks.Sensitive)
|
||||
schema := addTestSchema(configschema.NestingSingle)
|
||||
var buf strings.Builder
|
||||
v.writeConfigBlocksFromExisting(&buf, val, schema.BlockTypes, 0)
|
||||
|
@ -447,7 +447,7 @@ root_block_device {
|
|||
cty.ObjectVal(map[string]cty.Value{
|
||||
"volume_type": cty.StringVal("bar"),
|
||||
}),
|
||||
}).Mark("mark"),
|
||||
}).Mark(marks.Sensitive),
|
||||
})
|
||||
schema := addTestSchema(configschema.NestingList)
|
||||
var buf strings.Builder
|
||||
|
@ -784,13 +784,13 @@ func TestAdd_WriteConfigNestedTypeAttributeFromExisting(t *testing.T) {
|
|||
"disks": cty.ListVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"mount_point": cty.StringVal("/mnt/foo"),
|
||||
"size": cty.StringVal("50GB").Mark("hi"),
|
||||
"size": cty.StringVal("50GB").Mark(marks.Sensitive),
|
||||
}),
|
||||
// This is an odd example, where the entire element is marked.
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"mount_point": cty.StringVal("/mnt/bar"),
|
||||
"size": cty.StringVal("250GB"),
|
||||
}).Mark("bye"),
|
||||
}).Mark(marks.Sensitive),
|
||||
}),
|
||||
})
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hcled"
|
||||
"github.com/hashicorp/hcl/v2/hclparse"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -260,7 +261,7 @@ func NewDiagnostic(diag tfdiags.Diagnostic, sources map[string][]byte) *Diagnost
|
|||
Traversal: traversalStr,
|
||||
}
|
||||
switch {
|
||||
case val.IsMarked():
|
||||
case val.HasMark(marks.Sensitive):
|
||||
// We won't say anything at all about sensitive values,
|
||||
// because we might give away something that was
|
||||
// sensitive about them.
|
||||
|
@ -323,7 +324,7 @@ func compactValueStr(val cty.Value) string {
|
|||
// helpful but concise messages in diagnostics. It is not comprehensive
|
||||
// nor intended to be used for other purposes.
|
||||
|
||||
if val.IsMarked() {
|
||||
if val.HasMark(marks.Sensitive) {
|
||||
// We check this in here just to make sure, but note that the caller
|
||||
// of compactValueStr ought to have already checked this and skipped
|
||||
// calling into compactValueStr anyway, so this shouldn't actually
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
|
@ -62,28 +63,29 @@ func MakeToFunc(wantTy cty.Type) function.Function {
|
|||
// to be known here but may still be null.
|
||||
ret, err := convert.Convert(args[0], retType)
|
||||
if err != nil {
|
||||
val, _ := args[0].UnmarkDeep()
|
||||
// Because we used GetConversionUnsafe above, conversion can
|
||||
// still potentially fail in here. For example, if the user
|
||||
// asks to convert the string "a" to bool then we'll
|
||||
// optimistically permit it during type checking but fail here
|
||||
// once we note that the value isn't either "true" or "false".
|
||||
gotTy := args[0].Type()
|
||||
gotTy := val.Type()
|
||||
switch {
|
||||
case args[0].ContainsMarked():
|
||||
case marks.Contains(args[0], marks.Sensitive):
|
||||
// Generic message so we won't inadvertently disclose
|
||||
// information about sensitive values.
|
||||
return cty.NilVal, function.NewArgErrorf(0, "cannot convert this sensitive %s to %s", gotTy.FriendlyName(), wantTy.FriendlyNameForConstraint())
|
||||
|
||||
case gotTy == cty.String && wantTy == cty.Bool:
|
||||
what := "string"
|
||||
if !args[0].IsNull() {
|
||||
what = strconv.Quote(args[0].AsString())
|
||||
if !val.IsNull() {
|
||||
what = strconv.Quote(val.AsString())
|
||||
}
|
||||
return cty.NilVal, function.NewArgErrorf(0, `cannot convert %s to bool; only the strings "true" or "false" are allowed`, what)
|
||||
case gotTy == cty.String && wantTy == cty.Number:
|
||||
what := "string"
|
||||
if !args[0].IsNull() {
|
||||
what = strconv.Quote(args[0].AsString())
|
||||
if !val.IsNull() {
|
||||
what = strconv.Quote(val.AsString())
|
||||
}
|
||||
return cty.NilVal, function.NewArgErrorf(0, `cannot convert %s to number; given string must be a decimal representation of a number`, what)
|
||||
default:
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
|
@ -61,6 +62,12 @@ func TestTo(t *testing.T) {
|
|||
cty.StringVal("a").Mark("boop"),
|
||||
cty.Bool,
|
||||
cty.DynamicVal,
|
||||
`cannot convert "a" to bool; only the strings "true" or "false" are allowed`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("a").Mark(marks.Sensitive),
|
||||
cty.Bool,
|
||||
cty.DynamicVal,
|
||||
`cannot convert this sensitive string to bool`,
|
||||
},
|
||||
{
|
||||
|
@ -73,6 +80,12 @@ func TestTo(t *testing.T) {
|
|||
cty.StringVal("a").Mark("boop"),
|
||||
cty.Number,
|
||||
cty.DynamicVal,
|
||||
`cannot convert "a" to number; given string must be a decimal representation of a number`,
|
||||
},
|
||||
{
|
||||
cty.StringVal("a").Mark(marks.Sensitive),
|
||||
cty.Number,
|
||||
cty.DynamicVal,
|
||||
`cannot convert this sensitive string to number`,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/terraform/internal/lang"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -61,7 +62,7 @@ func evaluateForEachExpressionValue(expr hcl.Expression, ctx EvalContext, allowU
|
|||
|
||||
// If a whole map is marked, or a set contains marked values (which means the set is then marked)
|
||||
// give an error diagnostic as this value cannot be used in for_each
|
||||
if forEachVal.IsMarked() {
|
||||
if forEachVal.HasMark(marks.Sensitive) {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid for_each argument",
|
||||
|
|
|
@ -283,9 +283,7 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags
|
|||
// a sensitive result, to help avoid accidental exposure in the state
|
||||
// of a sensitive value that the user doesn't want to include there.
|
||||
if n.Addr.Module.IsRoot() {
|
||||
_, m := val.UnmarkDeep()
|
||||
_, hasSensitive := m[marks.Sensitive]
|
||||
if !n.Config.Sensitive && hasSensitive {
|
||||
if !n.Config.Sensitive && marks.Contains(val, marks.Sensitive) {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Output refers to sensitive values",
|
||||
|
|
Loading…
Reference in New Issue