mirror of
https://github.com/hashicorp/terraform.git
synced 2026-02-03 20:50:59 -05:00
we only want to send diagnostics for deeply nested deprecations in certain locations
Mainly terminal locations for the value where they are used, such as the config of a resource, for_each, outputs. We don't want to evaluate the deprecation deeply when it comes to values where the value is not yet used, e.g. locals This is because if e.g. a deeply nested value is deprecated it should still be ok for the entire object to be in a local whereas the same object should give a warning in e.g. an output
This commit is contained in:
parent
2f392d904e
commit
e6d969a2eb
6 changed files with 58 additions and 15 deletions
|
|
@ -37,19 +37,31 @@ func (d *Deprecations) SuppressModuleCallDeprecation(addr addrs.Module) {
|
|||
|
||||
// Validate checks the given value for deprecation marks and returns diagnostics
|
||||
// for each deprecation found, unless deprecation warnings are suppressed for the given module.
|
||||
// It does not check for deeply nested deprecation marks.
|
||||
func (d *Deprecations) Validate(value cty.Value, module addrs.Module, rng *hcl.Range) (cty.Value, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
deprecationMarks := marks.GetDeprecationMarks(value)
|
||||
if len(deprecationMarks) == 0 {
|
||||
return value, diags
|
||||
}
|
||||
|
||||
// This is appropriate for non-terminal values (values that can be referenced) only.
|
||||
// If the value can not be referenced, use ValidateDeep or ValidateAsConfig instead.
|
||||
func (d *Deprecations) Validate(value cty.Value, module addrs.Module, rng *hcl.Range) (cty.Value, tfdiags.Diagnostics) {
|
||||
deprecationMarks := marks.GetDeprecationMarks(value)
|
||||
notDeprecatedValue := marks.RemoveDeprecationMarks(value)
|
||||
return notDeprecatedValue, d.deprecationMarksToDiagnostics(deprecationMarks, module, rng)
|
||||
}
|
||||
|
||||
// ValidateDeep does the same as Validate but checks deeply nested deprecation marks as well.
|
||||
func (d *Deprecations) ValidateDeep(value cty.Value, module addrs.Module, rng *hcl.Range) (cty.Value, tfdiags.Diagnostics) {
|
||||
deprecationMarks := marks.GetDeprecationMarksDeep(value)
|
||||
notDeprecatedValue := marks.RemoveDeprecationMarksDeep(value)
|
||||
return notDeprecatedValue, d.deprecationMarksToDiagnostics(deprecationMarks, module, rng)
|
||||
}
|
||||
|
||||
func (d *Deprecations) deprecationMarksToDiagnostics(deprecationMarks []marks.DeprecationMark, module addrs.Module, rng *hcl.Range) tfdiags.Diagnostics {
|
||||
var diags tfdiags.Diagnostics
|
||||
if len(deprecationMarks) == 0 {
|
||||
return diags
|
||||
}
|
||||
|
||||
// Check if we need to suppress deprecation warnings for this module call.
|
||||
if d.IsModuleCallDeprecationSuppressed(module) {
|
||||
return notDeprecatedValue, diags
|
||||
return diags
|
||||
}
|
||||
|
||||
for _, depMark := range deprecationMarks {
|
||||
|
|
@ -66,8 +78,7 @@ func (d *Deprecations) Validate(value cty.Value, module addrs.Module, rng *hcl.R
|
|||
}
|
||||
diags = diags.Append(diag)
|
||||
}
|
||||
|
||||
return notDeprecatedValue, diags
|
||||
return diags
|
||||
}
|
||||
|
||||
// ValidateAsConfig checks the given value for deprecation marks and returns diagnostics
|
||||
|
|
|
|||
|
|
@ -68,9 +68,30 @@ func GetDeprecationMarks(val cty.Value) []DeprecationMark {
|
|||
return FilterDeprecationMarks(marks)
|
||||
}
|
||||
|
||||
// GetDeprecationMarksDeep returns all deprecation marks present on the given
|
||||
// cty.Value or any nested values.
|
||||
func GetDeprecationMarksDeep(val cty.Value) []DeprecationMark {
|
||||
_, marks := val.UnmarkDeep()
|
||||
return FilterDeprecationMarks(marks)
|
||||
}
|
||||
|
||||
// RemoveDeprecationMarks returns a copy of the given cty.Value with all
|
||||
// deprecation marks removed.
|
||||
func RemoveDeprecationMarks(val cty.Value) cty.Value {
|
||||
newVal, marks := val.Unmark()
|
||||
|
||||
for mark := range marks {
|
||||
if _, ok := mark.(DeprecationMark); !ok {
|
||||
newVal = newVal.Mark(mark)
|
||||
}
|
||||
}
|
||||
|
||||
return newVal
|
||||
}
|
||||
|
||||
// RemoveDeprecationMarksDeep returns a copy of the given cty.Value with all
|
||||
// deprecation marks deeply removed.
|
||||
func RemoveDeprecationMarksDeep(val cty.Value) cty.Value {
|
||||
newVal, pvms := val.UnmarkDeepWithPaths()
|
||||
otherPvms := RemoveAll(pvms, Deprecation)
|
||||
return newVal.MarkWithPaths(otherPvms)
|
||||
|
|
|
|||
|
|
@ -7477,6 +7477,17 @@ output "test_output2" {
|
|||
End: hcl.Pos{Line: 7, Column: 27, Byte: 97},
|
||||
},
|
||||
},
|
||||
).Append(
|
||||
&hcl.Diagnostic{
|
||||
Severity: hcl.DiagWarning,
|
||||
Summary: "Deprecated value used",
|
||||
Detail: "Please stop using this",
|
||||
Subject: &hcl.Range{
|
||||
Filename: filepath.Join(m.Module.SourceDir, "main.tf"),
|
||||
Start: hcl.Pos{Line: 7, Column: 10, Byte: 80},
|
||||
End: hcl.Pos{Line: 7, Column: 27, Byte: 97},
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func validateCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalCo
|
|||
errorMessage, moreDiags := lang.EvalCheckErrorMessage(rule.ErrorMessage, hclCtx, &addr)
|
||||
diags = diags.Append(moreDiags)
|
||||
|
||||
_, deprecationDiags := ctx.Deprecations().Validate(errorMessage, ctx.Path().Module(), rule.ErrorMessage.Range().Ptr())
|
||||
_, deprecationDiags := ctx.Deprecations().ValidateDeep(errorMessage, ctx.Path().Module(), rule.ErrorMessage.Range().Ptr())
|
||||
diags = diags.Append(deprecationDiags)
|
||||
|
||||
// NOTE: We've discarded any other marks the string might have been carrying,
|
||||
|
|
@ -170,7 +170,7 @@ func evalCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalContex
|
|||
}
|
||||
|
||||
// We don't care about the returned value here, only the diagnostics
|
||||
_, deprecationDiags := ctx.Deprecations().Validate(resultVal, addr.ModuleInstance().Module(), rule.Condition.Range().Ptr())
|
||||
_, deprecationDiags := ctx.Deprecations().ValidateDeep(resultVal, addr.ModuleInstance().Module(), rule.Condition.Range().Ptr())
|
||||
diags = diags.Append(deprecationDiags)
|
||||
|
||||
var err error
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ func evaluateCountExpressionValue(expr hcl.Expression, ctx EvalContext) (cty.Val
|
|||
})
|
||||
}
|
||||
|
||||
countVal, deprecationDiags := ctx.Deprecations().Validate(countVal, ctx.Path().Module(), expr.Range().Ptr())
|
||||
countVal, deprecationDiags := ctx.Deprecations().ValidateDeep(countVal, ctx.Path().Module(), expr.Range().Ptr())
|
||||
diags = diags.Append(deprecationDiags)
|
||||
|
||||
// Sensitive values are allowed in count but not for_each. This is a
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ If you do intend to export this data, annotate the output value as sensitive by
|
|||
}
|
||||
|
||||
if n.Config.DeprecatedSet {
|
||||
val = marks.RemoveDeprecationMarks(val)
|
||||
val = marks.RemoveDeprecationMarksDeep(val)
|
||||
if n.Addr.Module.IsRoot() {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
|
|
@ -530,7 +530,7 @@ If you do intend to export this data, annotate the output value as sensitive by
|
|||
}
|
||||
} else if n.Config.Expr != nil {
|
||||
var deprecationDiags tfdiags.Diagnostics
|
||||
val, deprecationDiags = ctx.Deprecations().Validate(val, n.ModulePath(), n.Config.Expr.Range().Ptr())
|
||||
val, deprecationDiags = ctx.Deprecations().ValidateDeep(val, n.ModulePath(), n.Config.Expr.Range().Ptr())
|
||||
diags = diags.Append(deprecationDiags)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue