From d59725e9fded11a9608cbe34cffe5b549ecc8ab5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 26 Jan 2017 20:47:20 -0800 Subject: [PATCH] terraform: convert StateDeps to use new structs --- terraform/context_apply_test.go | 2 +- terraform/graph_config_node_resource.go | 4 -- terraform/node_data_refresh.go | 13 +--- terraform/node_resource_abstract.go | 58 ++++++++++++++++ terraform/node_resource_apply.go | 12 +--- terraform/node_resource_plan_instance.go | 9 +-- terraform/transform_resource.go | 84 ------------------------ 7 files changed, 64 insertions(+), 118 deletions(-) delete mode 100644 terraform/transform_resource.go diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index a96ac1a98..0e543975a 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -7229,7 +7229,7 @@ template_file.child: type = template_file Dependencies: - template_file.parent + template_file.parent.* template_file.parent: ID = foo template = Hi diff --git a/terraform/graph_config_node_resource.go b/terraform/graph_config_node_resource.go index 220f92673..6bb0410f0 100644 --- a/terraform/graph_config_node_resource.go +++ b/terraform/graph_config_node_resource.go @@ -18,10 +18,6 @@ type GraphNodeConfigResource struct { Path []string } -func (n *GraphNodeConfigResource) DependableName() []string { - return []string{n.Resource.Id()} -} - // GraphNodeDependent impl. func (n *GraphNodeConfigResource) DependentOn() []string { result := make([]string, len(n.Resource.DependsOn), diff --git a/terraform/node_data_refresh.go b/terraform/node_data_refresh.go index ae64d844a..d504c892c 100644 --- a/terraform/node_data_refresh.go +++ b/terraform/node_data_refresh.go @@ -92,21 +92,10 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode { // If the config isn't empty we update the state if n.Config != nil { - // Determine the dependencies for the state. We use some older - // code for this that we've used for a long time. - var stateDeps []string - { - oldN := &graphNodeExpandedResource{ - Resource: n.Config, - Index: addr.Index, - } - stateDeps = oldN.StateDependencies() - } - rs = &ResourceState{ Type: n.Config.Type, Provider: n.Config.Provider, - Dependencies: stateDeps, + Dependencies: n.StateReferences(), } } diff --git a/terraform/node_resource_abstract.go b/terraform/node_resource_abstract.go index 22218e224..9946e358e 100644 --- a/terraform/node_resource_abstract.go +++ b/terraform/node_resource_abstract.go @@ -2,6 +2,7 @@ package terraform import ( "fmt" + "strings" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/dag" @@ -109,6 +110,63 @@ func (n *NodeAbstractResource) References() []string { return nil } +// StateReferences returns the dependencies to put into the state for +// this resource. +func (n *NodeAbstractResource) StateReferences() []string { + self := n.ReferenceableName() + + // Determine what our "prefix" is for checking for references to + // ourself. + addrCopy := n.Addr.Copy() + addrCopy.Index = -1 + selfPrefix := addrCopy.String() + "." + + depsRaw := n.References() + deps := make([]string, 0, len(depsRaw)) + for _, d := range depsRaw { + // Ignore any variable dependencies + if strings.HasPrefix(d, "var.") { + continue + } + + // If this has a backup ref, ignore those for now. The old state + // file never contained those and I'd rather store the rich types we + // add in the future. + if idx := strings.IndexRune(d, '/'); idx != -1 { + d = d[:idx] + } + + // If we're referencing ourself, then ignore it + found := false + for _, s := range self { + if d == s { + found = true + } + } + if found { + continue + } + + // If this is a reference to ourself and a specific index, we keep + // it. For example, if this resource is "foo.bar" and the reference + // is "foo.bar.0" then we keep it exact. Otherwise, we strip it. + if strings.HasSuffix(d, ".0") && !strings.HasPrefix(d, selfPrefix) { + d = d[:len(d)-2] + } + + // This is sad. The dependencies are currently in the format of + // "module.foo.bar" (the full field). This strips the field off. + if strings.HasPrefix(d, "module.") { + parts := strings.SplitN(d, ".", 3) + d = strings.Join(parts[0:2], ".") + } + + deps = append(deps, d) + } + + return deps +} + // GraphNodeProviderConsumer func (n *NodeAbstractResource) ProvidedBy() []string { // If we have a config we prefer that above all else diff --git a/terraform/node_resource_apply.go b/terraform/node_resource_apply.go index b5ce47f6c..3599782b9 100644 --- a/terraform/node_resource_apply.go +++ b/terraform/node_resource_apply.go @@ -70,16 +70,8 @@ func (n *NodeApplyableResource) EvalTree() EvalNode { resource.CountIndex = 0 } - // Determine the dependencies for the state. We use some older - // code for this that we've used for a long time. - var stateDeps []string - { - oldN := &graphNodeExpandedResource{ - Resource: n.Config, - Index: addr.Index, - } - stateDeps = oldN.StateDependencies() - } + // 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 { diff --git a/terraform/node_resource_plan_instance.go b/terraform/node_resource_plan_instance.go index 418d0f657..b52956908 100644 --- a/terraform/node_resource_plan_instance.go +++ b/terraform/node_resource_plan_instance.go @@ -37,13 +37,8 @@ func (n *NodePlannableResourceInstance) EvalTree() EvalNode { resource.CountIndex = 0 } - // Determine the dependencies for the state. We use some older - // code for this that we've used for a long time. - var stateDeps []string - { - oldN := &graphNodeExpandedResource{Resource: n.Config} - stateDeps = oldN.StateDependencies() - } + // 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 { diff --git a/terraform/transform_resource.go b/terraform/transform_resource.go deleted file mode 100644 index 9fe328337..000000000 --- a/terraform/transform_resource.go +++ /dev/null @@ -1,84 +0,0 @@ -package terraform - -import ( - "fmt" - "strings" - - "github.com/hashicorp/terraform/config" -) - -type graphNodeExpandedResource struct { - Index int - Resource *config.Resource - Path []string -} - -func (n *graphNodeExpandedResource) Name() string { - if n.Index == -1 { - return n.Resource.Id() - } - - return fmt.Sprintf("%s #%d", n.Resource.Id(), n.Index) -} - -// GraphNodeDependent impl. -func (n *graphNodeExpandedResource) DependentOn() []string { - configNode := &GraphNodeConfigResource{Resource: n.Resource} - result := configNode.DependentOn() - - // Walk the variables to find any count-specific variables we depend on. - configNode.VarWalk(func(v config.InterpolatedVariable) { - rv, ok := v.(*config.ResourceVariable) - if !ok { - return - } - - // We only want ourselves - if rv.ResourceId() != n.Resource.Id() { - return - } - - // If this isn't a multi-access (which shouldn't be allowed but - // is verified elsewhere), then we depend on the specific count - // of this resource, ignoring ourself (which again should be - // validated elsewhere). - if rv.Index > -1 { - id := fmt.Sprintf("%s.%d", rv.ResourceId(), rv.Index) - if id != n.stateId() && id != n.stateId()+".0" { - result = append(result, id) - } - } - }) - - return result -} - -func (n *graphNodeExpandedResource) StateDependencies() []string { - depsRaw := n.DependentOn() - deps := make([]string, 0, len(depsRaw)) - for _, d := range depsRaw { - // Ignore any variable dependencies - if strings.HasPrefix(d, "var.") { - continue - } - - // This is sad. The dependencies are currently in the format of - // "module.foo.bar" (the full field). This strips the field off. - if strings.HasPrefix(d, "module.") { - parts := strings.SplitN(d, ".", 3) - d = strings.Join(parts[0:2], ".") - } - deps = append(deps, d) - } - - return deps -} - -// stateId is the name used for the state key -func (n *graphNodeExpandedResource) stateId() string { - if n.Index == -1 { - return n.Resource.Id() - } - - return fmt.Sprintf("%s.%d", n.Resource.Id(), n.Index) -}