]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/terraform/node_resource_plan.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_resource_plan.go
index 1afae7a048a0b79c27190e8e5e28ed03e73d461a..633c1c466242889f152cfdbd60f1a5387e756a85 100644 (file)
 package terraform
 
 import (
+       "log"
+
        "github.com/hashicorp/terraform/dag"
+       "github.com/hashicorp/terraform/tfdiags"
 )
 
 // NodePlannableResource represents a resource that is "plannable":
 // it is ready to be planned in order to create a diff.
 type NodePlannableResource struct {
-       *NodeAbstractCountResource
+       *NodeAbstractResource
+
+       // ForceCreateBeforeDestroy might be set via our GraphNodeDestroyerCBD
+       // during graph construction, if dependencies require us to force this
+       // on regardless of what the configuration says.
+       ForceCreateBeforeDestroy *bool
+}
+
+var (
+       _ GraphNodeSubPath              = (*NodePlannableResource)(nil)
+       _ GraphNodeDestroyerCBD         = (*NodePlannableResource)(nil)
+       _ GraphNodeDynamicExpandable    = (*NodePlannableResource)(nil)
+       _ GraphNodeReferenceable        = (*NodePlannableResource)(nil)
+       _ GraphNodeReferencer           = (*NodePlannableResource)(nil)
+       _ GraphNodeResource             = (*NodePlannableResource)(nil)
+       _ GraphNodeAttachResourceConfig = (*NodePlannableResource)(nil)
+)
+
+// GraphNodeEvalable
+func (n *NodePlannableResource) EvalTree() EvalNode {
+       addr := n.ResourceAddr()
+       config := n.Config
+
+       if config == nil {
+               // Nothing to do, then.
+               log.Printf("[TRACE] NodeApplyableResource: no configuration present for %s", addr)
+               return &EvalNoop{}
+       }
+
+       // this ensures we can reference the resource even if the count is 0
+       return &EvalWriteResourceState{
+               Addr:         addr.Resource,
+               Config:       config,
+               ProviderAddr: n.ResolvedProvider,
+       }
+}
+
+// GraphNodeDestroyerCBD
+func (n *NodePlannableResource) CreateBeforeDestroy() bool {
+       if n.ForceCreateBeforeDestroy != nil {
+               return *n.ForceCreateBeforeDestroy
+       }
+
+       // If we have no config, we just assume no
+       if n.Config == nil || n.Config.Managed == nil {
+               return false
+       }
+
+       return n.Config.Managed.CreateBeforeDestroy
+}
+
+// GraphNodeDestroyerCBD
+func (n *NodePlannableResource) ModifyCreateBeforeDestroy(v bool) error {
+       n.ForceCreateBeforeDestroy = &v
+       return nil
 }
 
 // GraphNodeDynamicExpandable
 func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
-       // Grab the state which we read
-       state, lock := ctx.State()
-       lock.RLock()
-       defer lock.RUnlock()
-
-       // Expand the resource count which must be available by now from EvalTree
-       count, err := n.Config.Count()
-       if err != nil {
-               return nil, err
+       var diags tfdiags.Diagnostics
+
+       count, countDiags := evaluateResourceCountExpression(n.Config.Count, ctx)
+       diags = diags.Append(countDiags)
+       if countDiags.HasErrors() {
+               return nil, diags.Err()
        }
 
+       // Next we need to potentially rename an instance address in the state
+       // if we're transitioning whether "count" is set at all.
+       fixResourceCountSetTransition(ctx, n.ResourceAddr(), count != -1)
+
+       // Our graph transformers require access to the full state, so we'll
+       // temporarily lock it while we work on this.
+       state := ctx.State().Lock()
+       defer ctx.State().Unlock()
+
        // The concrete resource factory we'll use
-       concreteResource := func(a *NodeAbstractResource) dag.Vertex {
+       concreteResource := func(a *NodeAbstractResourceInstance) dag.Vertex {
                // Add the config and state since we don't do that via transforms
                a.Config = n.Config
                a.ResolvedProvider = n.ResolvedProvider
+               a.Schema = n.Schema
+               a.ProvisionerSchemas = n.ProvisionerSchemas
 
                return &NodePlannableResourceInstance{
-                       NodeAbstractResource: a,
+                       NodeAbstractResourceInstance: a,
+
+                       // By the time we're walking, we've figured out whether we need
+                       // to force on CreateBeforeDestroy due to dependencies on other
+                       // nodes that have it.
+                       ForceCreateBeforeDestroy: n.CreateBeforeDestroy(),
                }
        }
 
-       // The concrete resource factory we'll use for oprhans
-       concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex {
+       // The concrete resource factory we'll use for orphans
+       concreteResourceOrphan := func(a *NodeAbstractResourceInstance) dag.Vertex {
                // Add the config and state since we don't do that via transforms
                a.Config = n.Config
                a.ResolvedProvider = n.ResolvedProvider
+               a.Schema = n.Schema
+               a.ProvisionerSchemas = n.ProvisionerSchemas
 
-               return &NodePlannableResourceOrphan{
-                       NodeAbstractResource: a,
+               return &NodePlannableResourceInstanceOrphan{
+                       NodeAbstractResourceInstance: a,
                }
        }
 
@@ -50,6 +122,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
                // Expand the count.
                &ResourceCountTransformer{
                        Concrete: concreteResource,
+                       Schema:   n.Schema,
                        Count:    count,
                        Addr:     n.ResourceAddr(),
                },
@@ -66,7 +139,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
                &AttachStateTransformer{State: state},
 
                // Targeting
-               &TargetsTransformer{ParsedTargets: n.Targets},
+               &TargetsTransformer{Targets: n.Targets},
 
                // Connect references so ordering is correct
                &ReferenceTransformer{},
@@ -81,5 +154,6 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
                Validate: true,
                Name:     "NodePlannableResource",
        }
-       return b.Build(ctx.Path())
+       graph, diags := b.Build(ctx.Path())
+       return graph, diags.ErrWithWarnings()
 }