mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Merge d490309360
into 23a26b0e58
This commit is contained in:
commit
6506e085d7
@ -12,7 +12,6 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/backend"
|
||||
@ -265,31 +264,7 @@ func (b *Local) localRunForPlanFile(op *backend.Operation, pf *planfile.Reader,
|
||||
// we need to apply the plan.
|
||||
run.Plan = plan
|
||||
|
||||
subCall := op.RootCall.WithVariables(func(variable *configs.Variable) (cty.Value, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
name := variable.Name
|
||||
v, ok := plan.VariableValues[name]
|
||||
if !ok {
|
||||
if variable.Required() {
|
||||
// This should not happen...
|
||||
return cty.DynamicVal, diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Missing plan variable " + variable.Name,
|
||||
})
|
||||
}
|
||||
return variable.Default, nil
|
||||
}
|
||||
|
||||
parsed, parsedErr := v.Decode(cty.DynamicPseudoType)
|
||||
if parsedErr != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: parsedErr.Error(),
|
||||
})
|
||||
}
|
||||
return parsed, diags
|
||||
})
|
||||
subCall := op.RootCall.WithVariables(plan.VariableMapper())
|
||||
|
||||
loader := configload.NewLoaderFromSnapshot(snap)
|
||||
config, configDiags := loader.LoadConfig(snap.Modules[""].Dir, subCall)
|
||||
@ -299,6 +274,37 @@ func (b *Local) localRunForPlanFile(op *backend.Operation, pf *planfile.Reader,
|
||||
}
|
||||
run.Config = config
|
||||
|
||||
// Check that all provided variables are in the configuration
|
||||
_, undeclaredDiags := backend.ParseUndeclaredVariableValues(op.Variables, config.Module.Variables)
|
||||
diags = diags.Append(undeclaredDiags)
|
||||
// Check that all variables provided match
|
||||
for varName, varCfg := range config.Module.Variables {
|
||||
if _, ok := op.Variables[varName]; ok {
|
||||
// Variable provided via cli/files/env/etc...
|
||||
inputValue, inputDiags := op.RootCall.Variables()(varCfg)
|
||||
// Variable provided via the plan
|
||||
planValue, planDiags := subCall.Variables()(varCfg)
|
||||
|
||||
diags = diags.Append(inputDiags).Append(planDiags)
|
||||
if inputDiags.HasErrors() || planDiags.HasErrors() {
|
||||
return nil, snap, diags
|
||||
}
|
||||
|
||||
if inputValue.Equals(planValue).False() {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Mismatch between input and plan variable value",
|
||||
// TODO this is not a great error message
|
||||
fmt.Sprintf("Value %s for %s was provided, but does not match plan's value of %s", inputValue, varName, planValue),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if diags.HasErrors() {
|
||||
return nil, snap, diags
|
||||
}
|
||||
|
||||
// NOTE: We're intentionally comparing the current locks with the
|
||||
// configuration snapshot, rather than the lock snapshot in the plan file,
|
||||
// because it's the current locks which dictate our plugin selections
|
||||
|
@ -88,17 +88,6 @@ func (c *ApplyCommand) Run(rawArgs []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Check for invalid combination of plan file and variable overrides
|
||||
if planFile != nil && !args.Vars.Empty() {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Can't set variables when applying a saved plan",
|
||||
"The -var and -var-file options cannot be used when applying a saved plan file, because a saved plan includes the variable values that were set when it was created.",
|
||||
))
|
||||
view.Diagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// FIXME: the -input flag value is needed to initialize the backend and the
|
||||
// operation, but there is no clear path to pass this value down, so we
|
||||
// continue to mutate the Meta object state for now.
|
||||
|
@ -12,9 +12,6 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/backend"
|
||||
"github.com/opentofu/opentofu/internal/cloud"
|
||||
"github.com/opentofu/opentofu/internal/cloud/cloudplan"
|
||||
@ -371,31 +368,7 @@ func getDataFromPlanfileReader(planReader *planfile.Reader, rootCall configs.Sta
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
subCall := rootCall.WithVariables(func(variable *configs.Variable) (cty.Value, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
name := variable.Name
|
||||
v, ok := plan.VariableValues[name]
|
||||
if !ok {
|
||||
if variable.Required() {
|
||||
// This should not happen...
|
||||
return cty.DynamicVal, diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Missing plan variable " + variable.Name,
|
||||
})
|
||||
}
|
||||
return variable.Default, nil
|
||||
}
|
||||
|
||||
parsed, parsedErr := v.Decode(cty.DynamicPseudoType)
|
||||
if parsedErr != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: parsedErr.Error(),
|
||||
})
|
||||
}
|
||||
return parsed, diags
|
||||
})
|
||||
subCall := rootCall.WithVariables(plan.VariableMapper())
|
||||
|
||||
// Get config
|
||||
config, diags := planReader.ReadConfig(subCall)
|
||||
|
@ -51,6 +51,10 @@ func NewStaticModuleCall(addr addrs.Module, vars StaticModuleVariables, rootPath
|
||||
}
|
||||
}
|
||||
|
||||
func (s StaticModuleCall) Variables() StaticModuleVariables {
|
||||
return s.vars
|
||||
}
|
||||
|
||||
func (s StaticModuleCall) WithVariables(vars StaticModuleVariables) StaticModuleCall {
|
||||
return StaticModuleCall{
|
||||
addr: s.addr,
|
||||
|
@ -9,9 +9,11 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/lang/globalref"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
@ -198,6 +200,36 @@ func (p *Plan) ProviderAddrs() []addrs.AbsProviderConfig {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Variable mapper checks that all of the provided variables match what has been provided in the plan
|
||||
// They may be sourced from the environment, from cli args, and autoloaded tfvars files
|
||||
func (plan *Plan) VariableMapper() configs.StaticModuleVariables {
|
||||
return func(variable *configs.Variable) (cty.Value, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
name := variable.Name
|
||||
v, ok := plan.VariableValues[name]
|
||||
if !ok {
|
||||
if variable.Required() {
|
||||
// This should not happen...
|
||||
return cty.DynamicVal, diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Missing plan variable " + variable.Name,
|
||||
})
|
||||
}
|
||||
return variable.Default, nil
|
||||
}
|
||||
|
||||
parsed, parsedErr := v.Decode(cty.DynamicPseudoType)
|
||||
if parsedErr != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: parsedErr.Error(),
|
||||
})
|
||||
}
|
||||
return parsed, diags
|
||||
}
|
||||
}
|
||||
|
||||
// Backend represents the backend-related configuration and other data as it
|
||||
// existed when a plan was created.
|
||||
type Backend struct {
|
||||
|
Loading…
Reference in New Issue
Block a user