core: Fix crash for sensitive values in conditions
Precondition and postcondition blocks which evaluated expressions resulting in sensitive values would previously crash. This commit fixes the crashes, and adds an additional diagnostic if the error message expression produces a sensitive value (which we also elide).
This commit is contained in:
parent
6cd0876596
commit
6db174e210
|
@ -2859,3 +2859,65 @@ func TestContext2Plan_preconditionErrors(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Plan_preconditionSensitiveValues(t *testing.T) {
|
||||||
|
p := testProvider("test")
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
terraform {
|
||||||
|
experiments = [preconditions_postconditions]
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "boop" {
|
||||||
|
sensitive = true
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
output "a" {
|
||||||
|
sensitive = true
|
||||||
|
value = var.boop
|
||||||
|
|
||||||
|
precondition {
|
||||||
|
condition = length(var.boop) <= 4
|
||||||
|
error_message = "Boop is too long, ${length(var.boop)} > 4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan(m, states.NewState(), &PlanOpts{
|
||||||
|
Mode: plans.NormalMode,
|
||||||
|
SetVariables: InputValues{
|
||||||
|
"boop": &InputValue{
|
||||||
|
Value: cty.StringVal("bleep"),
|
||||||
|
SourceType: ValueFromCLIArg,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatal("succeeded; want errors")
|
||||||
|
}
|
||||||
|
if got, want := len(diags), 2; got != want {
|
||||||
|
t.Errorf("wrong number of diags, got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
for _, diag := range diags {
|
||||||
|
desc := diag.Description()
|
||||||
|
if desc.Summary == "Module output value precondition failed" {
|
||||||
|
if got, want := desc.Detail, "The error message included a sensitive value, so it will not be displayed."; !strings.Contains(got, want) {
|
||||||
|
t.Errorf("unexpected detail\ngot: %s\nwant to contain %q", got, want)
|
||||||
|
}
|
||||||
|
} else if desc.Summary == "Error message refers to sensitive values" {
|
||||||
|
if got, want := desc.Detail, "The error expression used to explain this condition refers to sensitive values."; !strings.Contains(got, want) {
|
||||||
|
t.Errorf("unexpected detail\ngot: %s\nwant to contain %q", got, want)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("unexpected summary\ngot: %s", desc.Summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/internal/configs"
|
"github.com/hashicorp/terraform/internal/configs"
|
||||||
"github.com/hashicorp/terraform/internal/instances"
|
"github.com/hashicorp/terraform/internal/instances"
|
||||||
"github.com/hashicorp/terraform/internal/lang"
|
"github.com/hashicorp/terraform/internal/lang"
|
||||||
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,6 +111,10 @@ func evalCheckRules(typ checkType, rules []*configs.CheckRule, ctx EvalContext,
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The condition result may be marked if the expression refers to a
|
||||||
|
// sensitive value.
|
||||||
|
result, _ = result.Unmark()
|
||||||
|
|
||||||
if result.True() {
|
if result.True() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -128,7 +133,23 @@ func evalCheckRules(typ checkType, rules []*configs.CheckRule, ctx EvalContext,
|
||||||
EvalContext: hclCtx,
|
EvalContext: hclCtx,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
errorMessage = strings.TrimSpace(errorValue.AsString())
|
if marks.Has(errorValue, marks.Sensitive) {
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: severity,
|
||||||
|
|
||||||
|
Summary: "Error message refers to sensitive values",
|
||||||
|
Detail: `The error expression used to explain this condition refers to sensitive values. Terraform will not display the resulting message.
|
||||||
|
|
||||||
|
You can correct this by removing references to sensitive values, or by carefully using the nonsensitive() function if the expression will not reveal the sensitive data.`,
|
||||||
|
|
||||||
|
Subject: rule.ErrorMessage.Range().Ptr(),
|
||||||
|
Expression: rule.ErrorMessage,
|
||||||
|
EvalContext: hclCtx,
|
||||||
|
})
|
||||||
|
errorMessage = "The error message included a sensitive value, so it will not be displayed."
|
||||||
|
} else {
|
||||||
|
errorMessage = strings.TrimSpace(errorValue.AsString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if errorMessage == "" {
|
if errorMessage == "" {
|
||||||
|
|
Loading…
Reference in New Issue