terraform: convert StateDeps to use new structs

This commit is contained in:
Mitchell Hashimoto 2017-01-26 20:47:20 -08:00
parent c1e4bd7b72
commit d59725e9fd
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
7 changed files with 64 additions and 118 deletions

View File

@ -7229,7 +7229,7 @@ template_file.child:
type = template_file type = template_file
Dependencies: Dependencies:
template_file.parent template_file.parent.*
template_file.parent: template_file.parent:
ID = foo ID = foo
template = Hi template = Hi

View File

@ -18,10 +18,6 @@ type GraphNodeConfigResource struct {
Path []string Path []string
} }
func (n *GraphNodeConfigResource) DependableName() []string {
return []string{n.Resource.Id()}
}
// GraphNodeDependent impl. // GraphNodeDependent impl.
func (n *GraphNodeConfigResource) DependentOn() []string { func (n *GraphNodeConfigResource) DependentOn() []string {
result := make([]string, len(n.Resource.DependsOn), result := make([]string, len(n.Resource.DependsOn),

View File

@ -92,21 +92,10 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
// If the config isn't empty we update the state // If the config isn't empty we update the state
if n.Config != nil { 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{ rs = &ResourceState{
Type: n.Config.Type, Type: n.Config.Type,
Provider: n.Config.Provider, Provider: n.Config.Provider,
Dependencies: stateDeps, Dependencies: n.StateReferences(),
} }
} }

View File

@ -2,6 +2,7 @@ package terraform
import ( import (
"fmt" "fmt"
"strings"
"github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/dag"
@ -109,6 +110,63 @@ func (n *NodeAbstractResource) References() []string {
return nil 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 // GraphNodeProviderConsumer
func (n *NodeAbstractResource) ProvidedBy() []string { func (n *NodeAbstractResource) ProvidedBy() []string {
// If we have a config we prefer that above all else // If we have a config we prefer that above all else

View File

@ -70,16 +70,8 @@ func (n *NodeApplyableResource) EvalTree() EvalNode {
resource.CountIndex = 0 resource.CountIndex = 0
} }
// Determine the dependencies for the state. We use some older // Determine the dependencies for the state.
// code for this that we've used for a long time. stateDeps := n.StateReferences()
var stateDeps []string
{
oldN := &graphNodeExpandedResource{
Resource: n.Config,
Index: addr.Index,
}
stateDeps = oldN.StateDependencies()
}
// Eval info is different depending on what kind of resource this is // Eval info is different depending on what kind of resource this is
switch n.Config.Mode { switch n.Config.Mode {

View File

@ -37,13 +37,8 @@ func (n *NodePlannableResourceInstance) EvalTree() EvalNode {
resource.CountIndex = 0 resource.CountIndex = 0
} }
// Determine the dependencies for the state. We use some older // Determine the dependencies for the state.
// code for this that we've used for a long time. stateDeps := n.StateReferences()
var stateDeps []string
{
oldN := &graphNodeExpandedResource{Resource: n.Config}
stateDeps = oldN.StateDependencies()
}
// Eval info is different depending on what kind of resource this is // Eval info is different depending on what kind of resource this is
switch n.Config.Mode { switch n.Config.Mode {

View File

@ -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)
}