package terraform import ( "fmt" "github.com/hashicorp/terraform/config" ) // EvalLocal is an EvalNode implementation that evaluates the // expression for a local value and writes it into a transient part of // the state. type EvalLocal struct { Name string Value *config.RawConfig } func (n *EvalLocal) Eval(ctx EvalContext) (interface{}, error) { cfg, err := ctx.Interpolate(n.Value, nil) if err != nil { return nil, fmt.Errorf("local.%s: %s", n.Name, err) } state, lock := ctx.State() if state == nil { return nil, fmt.Errorf("cannot write local value to nil state") } // Get a write lock so we can access the state 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 } } if mod.Locals == nil { // initialize mod.Locals = map[string]interface{}{} } mod.Locals[n.Name] = valueRaw return nil, nil } // EvalDeleteLocal is an EvalNode implementation that deletes a Local value // from the state. Locals aren't persisted, but we don't need to evaluate them // during destroy. type EvalDeleteLocal struct { Name string } func (n *EvalDeleteLocal) 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.Locals, n.Name) return nil, nil }