]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan_instance.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_resource_plan_instance.go
index 7d9fcddb55ef8cd020380932762edd38cdaed655..75e0bcd343b9014067bb2f781fbf82a022bf98a8 100644 (file)
@@ -3,187 +3,205 @@ package terraform
 import (
        "fmt"
 
-       "github.com/hashicorp/terraform/config"
+       "github.com/hashicorp/terraform/plans"
+       "github.com/hashicorp/terraform/providers"
+       "github.com/hashicorp/terraform/states"
+
+       "github.com/hashicorp/terraform/addrs"
+       "github.com/zclconf/go-cty/cty"
 )
 
 // NodePlannableResourceInstance represents a _single_ resource
 // instance that is plannable. This means this represents a single
 // count index, for example.
 type NodePlannableResourceInstance struct {
-       *NodeAbstractResource
+       *NodeAbstractResourceInstance
+       ForceCreateBeforeDestroy bool
 }
 
+var (
+       _ GraphNodeSubPath              = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeReferenceable        = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeReferencer           = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeResource             = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeResourceInstance     = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeAttachResourceConfig = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeAttachResourceState  = (*NodePlannableResourceInstance)(nil)
+       _ GraphNodeEvalable             = (*NodePlannableResourceInstance)(nil)
+)
+
 // GraphNodeEvalable
 func (n *NodePlannableResourceInstance) EvalTree() EvalNode {
-       addr := n.NodeAbstractResource.Addr
-
-       // stateId is the ID to put into the state
-       stateId := addr.stateId()
+       addr := n.ResourceInstanceAddr()
 
-       // Build the instance info. More of this will be populated during eval
-       info := &InstanceInfo{
-               Id:         stateId,
-               Type:       addr.Type,
-               ModulePath: normalizeModulePath(addr.Path),
-       }
-
-       // Build the resource for eval
-       resource := &Resource{
-               Name:       addr.Name,
-               Type:       addr.Type,
-               CountIndex: addr.Index,
-       }
-       if resource.CountIndex < 0 {
-               resource.CountIndex = 0
-       }
+       // State still uses legacy-style internal ids, so we need to shim to get
+       // a suitable key to use.
+       stateId := NewLegacyResourceInstanceAddress(addr).stateId()
 
        // Determine the dependencies for the state.
        stateDeps := n.StateReferences()
 
        // Eval info is different depending on what kind of resource this is
-       switch n.Config.Mode {
-       case config.ManagedResourceMode:
-               return n.evalTreeManagedResource(
-                       stateId, info, resource, stateDeps,
-               )
-       case config.DataResourceMode:
-               return n.evalTreeDataResource(
-                       stateId, info, resource, stateDeps)
+       switch addr.Resource.Resource.Mode {
+       case addrs.ManagedResourceMode:
+               return n.evalTreeManagedResource(addr, stateId, stateDeps)
+       case addrs.DataResourceMode:
+               return n.evalTreeDataResource(addr, stateId, stateDeps)
        default:
                panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
        }
 }
 
-func (n *NodePlannableResourceInstance) evalTreeDataResource(
-       stateId string, info *InstanceInfo,
-       resource *Resource, stateDeps []string) EvalNode {
-       var provider ResourceProvider
-       var config *ResourceConfig
-       var diff *InstanceDiff
-       var state *InstanceState
+func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResourceInstance, stateId string, stateDeps []addrs.Referenceable) EvalNode {
+       config := n.Config
+       var provider providers.Interface
+       var providerSchema *ProviderSchema
+       var change *plans.ResourceInstanceChange
+       var state *states.ResourceInstanceObject
+       var configVal cty.Value
 
        return &EvalSequence{
                Nodes: []EvalNode{
-                       &EvalReadState{
-                               Name:   stateId,
-                               Output: &state,
+                       &EvalGetProvider{
+                               Addr:   n.ResolvedProvider,
+                               Output: &provider,
+                               Schema: &providerSchema,
                        },
 
-                       // We need to re-interpolate the config here because some
-                       // of the attributes may have become computed during
-                       // earlier planning, due to other resources having
-                       // "requires new resource" diffs.
-                       &EvalInterpolate{
-                               Config:   n.Config.RawConfig.Copy(),
-                               Resource: resource,
-                               Output:   &config,
+                       &EvalReadState{
+                               Addr:           addr.Resource,
+                               Provider:       &provider,
+                               ProviderSchema: &providerSchema,
+
+                               Output: &state,
                        },
 
+                       // If we already have a non-planned state then we already dealt
+                       // with this during the refresh walk and so we have nothing to do
+                       // here.
                        &EvalIf{
                                If: func(ctx EvalContext) (bool, error) {
-                                       computed := config.ComputedKeys != nil && len(config.ComputedKeys) > 0
-
-                                       // If the configuration is complete and we
-                                       // already have a state then we don't need to
-                                       // do any further work during apply, because we
-                                       // already populated the state during refresh.
-                                       if !computed && state != nil {
-                                               return true, EvalEarlyExitError{}
+                                       depChanges := false
+
+                                       // Check and see if any of our dependencies have changes.
+                                       changes := ctx.Changes()
+                                       for _, d := range n.StateReferences() {
+                                               ri, ok := d.(addrs.ResourceInstance)
+                                               if !ok {
+                                                       continue
+                                               }
+                                               change := changes.GetResourceInstanceChange(ri.Absolute(ctx.Path()), states.CurrentGen)
+                                               if change != nil && change.Action != plans.NoOp {
+                                                       depChanges = true
+                                                       break
+                                               }
                                        }
 
+                                       refreshed := state != nil && state.Status != states.ObjectPlanned
+
+                                       // If there are no dependency changes, and it's not a forced
+                                       // read because we there was no Refresh, then we don't need
+                                       // to re-read. If any dependencies have changes, it means
+                                       // our config may also have changes and we need to Read the
+                                       // data source again.
+                                       if !depChanges && refreshed {
+                                               return false, EvalEarlyExitError{}
+                                       }
                                        return true, nil
                                },
                                Then: EvalNoop{},
                        },
 
-                       &EvalGetProvider{
-                               Name:   n.ResolvedProvider,
-                               Output: &provider,
+                       &EvalValidateSelfRef{
+                               Addr:           addr.Resource,
+                               Config:         config.Config,
+                               ProviderSchema: &providerSchema,
                        },
 
-                       &EvalReadDataDiff{
-                               Info:        info,
-                               Config:      &config,
-                               Provider:    &provider,
-                               Output:      &diff,
-                               OutputState: &state,
+                       &EvalReadData{
+                               Addr:           addr.Resource,
+                               Config:         n.Config,
+                               Dependencies:   n.StateReferences(),
+                               Provider:       &provider,
+                               ProviderAddr:   n.ResolvedProvider,
+                               ProviderSchema: &providerSchema,
+                               ForcePlanRead:  true, // _always_ produce a Read change, even if the config seems ready
+                               OutputChange:   &change,
+                               OutputValue:    &configVal,
+                               OutputState:    &state,
                        },
 
                        &EvalWriteState{
-                               Name:         stateId,
-                               ResourceType: n.Config.Type,
-                               Provider:     n.ResolvedProvider,
-                               Dependencies: stateDeps,
-                               State:        &state,
+                               Addr:           addr.Resource,
+                               ProviderAddr:   n.ResolvedProvider,
+                               ProviderSchema: &providerSchema,
+                               State:          &state,
                        },
 
                        &EvalWriteDiff{
-                               Name: stateId,
-                               Diff: &diff,
+                               Addr:           addr.Resource,
+                               ProviderSchema: &providerSchema,
+                               Change:         &change,
                        },
                },
        }
 }
 
-func (n *NodePlannableResourceInstance) evalTreeManagedResource(
-       stateId string, info *InstanceInfo,
-       resource *Resource, stateDeps []string) EvalNode {
-       // Declare a bunch of variables that are used for state during
-       // evaluation. Most of this are written to by-address below.
-       var provider ResourceProvider
-       var diff *InstanceDiff
-       var state *InstanceState
-       var resourceConfig *ResourceConfig
+func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsResourceInstance, stateId string, stateDeps []addrs.Referenceable) EvalNode {
+       config := n.Config
+       var provider providers.Interface
+       var providerSchema *ProviderSchema
+       var change *plans.ResourceInstanceChange
+       var state *states.ResourceInstanceObject
 
        return &EvalSequence{
                Nodes: []EvalNode{
-                       &EvalInterpolate{
-                               Config:   n.Config.RawConfig.Copy(),
-                               Resource: resource,
-                               Output:   &resourceConfig,
-                       },
                        &EvalGetProvider{
-                               Name:   n.ResolvedProvider,
+                               Addr:   n.ResolvedProvider,
                                Output: &provider,
+                               Schema: &providerSchema,
                        },
-                       // Re-run validation to catch any errors we missed, e.g. type
-                       // mismatches on computed values.
-                       &EvalValidateResource{
-                               Provider:       &provider,
-                               Config:         &resourceConfig,
-                               ResourceName:   n.Config.Name,
-                               ResourceType:   n.Config.Type,
-                               ResourceMode:   n.Config.Mode,
-                               IgnoreWarnings: true,
-                       },
+
                        &EvalReadState{
-                               Name:   stateId,
+                               Addr:           addr.Resource,
+                               Provider:       &provider,
+                               ProviderSchema: &providerSchema,
+
                                Output: &state,
                        },
+
+                       &EvalValidateSelfRef{
+                               Addr:           addr.Resource,
+                               Config:         config.Config,
+                               ProviderSchema: &providerSchema,
+                       },
+
                        &EvalDiff{
-                               Name:        stateId,
-                               Info:        info,
-                               Config:      &resourceConfig,
-                               Resource:    n.Config,
-                               Provider:    &provider,
-                               State:       &state,
-                               OutputDiff:  &diff,
-                               OutputState: &state,
+                               Addr:                addr.Resource,
+                               Config:              n.Config,
+                               CreateBeforeDestroy: n.ForceCreateBeforeDestroy,
+                               Provider:            &provider,
+                               ProviderAddr:        n.ResolvedProvider,
+                               ProviderSchema:      &providerSchema,
+                               State:               &state,
+                               OutputChange:        &change,
+                               OutputState:         &state,
                        },
                        &EvalCheckPreventDestroy{
-                               Resource: n.Config,
-                               Diff:     &diff,
+                               Addr:   addr.Resource,
+                               Config: n.Config,
+                               Change: &change,
                        },
                        &EvalWriteState{
-                               Name:         stateId,
-                               ResourceType: n.Config.Type,
-                               Provider:     n.ResolvedProvider,
-                               Dependencies: stateDeps,
-                               State:        &state,
+                               Addr:           addr.Resource,
+                               ProviderAddr:   n.ResolvedProvider,
+                               State:          &state,
+                               ProviderSchema: &providerSchema,
                        },
                        &EvalWriteDiff{
-                               Name: stateId,
-                               Diff: &diff,
+                               Addr:           addr.Resource,
+                               ProviderSchema: &providerSchema,
+                               Change:         &change,
                        },
                },
        }