mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-29 10:21:01 -06:00
e57a399d71
This changes the representation of maps in the interpolator from the dotted flatmap form of a string variable named "var.variablename.key" per map element to use native HIL maps instead. This involves porting some of the interpolation functions in order to keep the tests green, and adding support for map outputs. There is one backwards incompatibility: as a result of an implementation detail of maps, one could access an indexed map variable using the syntax "${var.variablename.key}". This is no longer possible - instead HIL native syntax - "${var.variablename["key"]}" must be used. This was previously documented, (though not heavily used) so it must be noted as a backward compatibility issue for Terraform 0.7.
94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package terraform
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/config"
|
|
)
|
|
|
|
// EvalDeleteOutput is an EvalNode implementation that deletes an output
|
|
// from the state.
|
|
type EvalDeleteOutput struct {
|
|
Name string
|
|
}
|
|
|
|
// TODO: test
|
|
func (n *EvalDeleteOutput) Eval(ctx EvalContext) (interface{}, error) {
|
|
state, lock := ctx.State()
|
|
if state == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// Get a write lock so we can access this instance
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
|
|
// Look for the module state. If we don't have one, create it.
|
|
mod := state.ModuleByPath(ctx.Path())
|
|
if mod == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
delete(mod.Outputs, n.Name)
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
// EvalWriteOutput is an EvalNode implementation that writes the output
|
|
// for the given name to the current state.
|
|
type EvalWriteOutput struct {
|
|
Name string
|
|
Value *config.RawConfig
|
|
}
|
|
|
|
// TODO: test
|
|
func (n *EvalWriteOutput) Eval(ctx EvalContext) (interface{}, error) {
|
|
cfg, err := ctx.Interpolate(n.Value, nil)
|
|
if err != nil {
|
|
// Log error but continue anyway
|
|
log.Printf("[WARN] Output interpolation %q failed: %s", n.Name, err)
|
|
}
|
|
|
|
state, lock := ctx.State()
|
|
if state == nil {
|
|
return nil, fmt.Errorf("cannot write state to nil state")
|
|
}
|
|
|
|
// Get a write lock so we can access this instance
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
|
|
// Look for the module state. If we don't have one, create it.
|
|
mod := state.ModuleByPath(ctx.Path())
|
|
if mod == nil {
|
|
mod = state.AddModule(ctx.Path())
|
|
}
|
|
|
|
// Get the value from the config
|
|
var valueRaw interface{} = config.UnknownVariableValue
|
|
if cfg != nil {
|
|
var ok bool
|
|
valueRaw, ok = cfg.Get("value")
|
|
if !ok {
|
|
valueRaw = ""
|
|
}
|
|
if cfg.IsComputed("value") {
|
|
valueRaw = config.UnknownVariableValue
|
|
}
|
|
}
|
|
|
|
switch valueTyped := valueRaw.(type) {
|
|
case string:
|
|
mod.Outputs[n.Name] = valueTyped
|
|
case []interface{}:
|
|
mod.Outputs[n.Name] = valueTyped
|
|
case map[string]interface{}:
|
|
mod.Outputs[n.Name] = valueTyped
|
|
default:
|
|
return nil, fmt.Errorf("output %s is not a valid type (%T)\n", n.Name, valueTyped)
|
|
}
|
|
|
|
return nil, nil
|
|
}
|