core: Fix sensitive value/attribute conflict

When applying sensitivity marks to resources, we previously would first
mark any provider-denoted sensitive attributes, then apply the set of
planned-change sensitive value marks. This would cause a panic if a
provider marked an iterable value as sensitive, because it is invalid to
call `MarkWithPaths` against a marked iterable value.

Instead, we now merge the marks from the provider schema and the planned
change into a single set, and apply them with one call. The included
test panics without this change.
This commit is contained in:
Alisdair McDiarmid 2021-03-30 15:50:47 -04:00
parent 7ab4f1fb7d
commit c54c18680e
2 changed files with 15 additions and 3 deletions

View File

@ -758,11 +758,12 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc
} }
// If our provider schema contains sensitive values, mark those as sensitive // If our provider schema contains sensitive values, mark those as sensitive
afterMarks := change.AfterValMarks
if schema.ContainsSensitive() { if schema.ContainsSensitive() {
val = markProviderSensitiveAttributes(schema, val) afterMarks = append(afterMarks, getValMarks(schema, val, nil)...)
} }
instances[key] = val.MarkWithPaths(change.AfterValMarks) instances[key] = val.MarkWithPaths(afterMarks)
continue continue
} }

View File

@ -357,6 +357,9 @@ func TestEvaluatorGetResource_changes(t *testing.T) {
"id": cty.StringVal("foo"), "id": cty.StringVal("foo"),
"to_mark_val": cty.StringVal("pizza").Mark("sensitive"), "to_mark_val": cty.StringVal("pizza").Mark("sensitive"),
"sensitive_value": cty.StringVal("abc"), "sensitive_value": cty.StringVal("abc"),
"sensitive_collection": cty.MapVal(map[string]cty.Value{
"boop": cty.StringVal("beep"),
}),
}), }),
}, },
} }
@ -382,6 +385,11 @@ func TestEvaluatorGetResource_changes(t *testing.T) {
Computed: true, Computed: true,
Sensitive: true, Sensitive: true,
}, },
"sensitive_collection": {
Type: cty.Map(cty.String),
Computed: true,
Sensitive: true,
},
}, },
}, },
}, },
@ -408,7 +416,7 @@ func TestEvaluatorGetResource_changes(t *testing.T) {
Config: &configs.Config{ Config: &configs.Config{
Module: &configs.Module{ Module: &configs.Module{
ManagedResources: map[string]*configs.Resource{ ManagedResources: map[string]*configs.Resource{
"test_resource.foo": &configs.Resource{ "test_resource.foo": {
Mode: addrs.ManagedResourceMode, Mode: addrs.ManagedResourceMode,
Type: "test_resource", Type: "test_resource",
Name: "foo", Name: "foo",
@ -434,6 +442,9 @@ func TestEvaluatorGetResource_changes(t *testing.T) {
"id": cty.StringVal("foo"), "id": cty.StringVal("foo"),
"to_mark_val": cty.StringVal("pizza").Mark("sensitive"), "to_mark_val": cty.StringVal("pizza").Mark("sensitive"),
"sensitive_value": cty.StringVal("abc").Mark("sensitive"), "sensitive_value": cty.StringVal("abc").Mark("sensitive"),
"sensitive_collection": cty.MapVal(map[string]cty.Value{
"boop": cty.StringVal("beep"),
}).Mark("sensitive"),
}) })
got, diags := scope.Data.GetResource(addr, tfdiags.SourceRange{}) got, diags := scope.Data.GetResource(addr, tfdiags.SourceRange{})