diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/eval_output.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/eval_output.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_output.go b/vendor/github.com/hashicorp/terraform/terraform/eval_output.go new file mode 100644 index 00000000..cf61781e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/terraform/eval_output.go @@ -0,0 +1,119 @@ +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 + Sensitive bool + 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] = &OutputState{ + Type: "string", + Sensitive: n.Sensitive, + Value: valueTyped, + } + case []interface{}: + mod.Outputs[n.Name] = &OutputState{ + Type: "list", + Sensitive: n.Sensitive, + Value: valueTyped, + } + case map[string]interface{}: + mod.Outputs[n.Name] = &OutputState{ + Type: "map", + Sensitive: n.Sensitive, + Value: valueTyped, + } + case []map[string]interface{}: + // an HCL map is multi-valued, so if this was read out of a config the + // map may still be in a slice. + if len(valueTyped) == 1 { + mod.Outputs[n.Name] = &OutputState{ + Type: "map", + Sensitive: n.Sensitive, + Value: valueTyped[0], + } + break + } + return nil, fmt.Errorf("output %s type (%T) with %d values not valid for type map", + n.Name, valueTyped, len(valueTyped)) + default: + return nil, fmt.Errorf("output %s is not a valid type (%T)\n", n.Name, valueTyped) + } + + return nil, nil +} |