summaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/terraform/terraform/eval_output.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/eval_output.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/eval_output.go119
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
+}