]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/terraform/module_dependencies.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / module_dependencies.go
index 4594cb6033223c3c9cd4abd22e6823ec888f1165..66a68c7de84ae469419660eefa5bd5e1d145959d 100644 (file)
 package terraform
 
 import (
-       "github.com/hashicorp/terraform/config"
-       "github.com/hashicorp/terraform/config/module"
+       version "github.com/hashicorp/go-version"
+
+       "github.com/hashicorp/terraform/addrs"
+       "github.com/hashicorp/terraform/configs"
        "github.com/hashicorp/terraform/moduledeps"
        "github.com/hashicorp/terraform/plugin/discovery"
+       "github.com/hashicorp/terraform/states"
 )
 
-// ModuleTreeDependencies returns the dependencies of the tree of modules
-// described by the given configuration tree and state.
+// ConfigTreeDependencies returns the dependencies of the tree of modules
+// described by the given configuration and state.
 //
 // Both configuration and state are required because there can be resources
 // implied by instances in the state that no longer exist in config.
-//
-// This function will panic if any invalid version constraint strings are
-// present in the configuration. This is guaranteed not to happen for any
-// configuration that has passed a call to Config.Validate().
-func ModuleTreeDependencies(root *module.Tree, state *State) *moduledeps.Module {
+func ConfigTreeDependencies(root *configs.Config, state *states.State) *moduledeps.Module {
        // First we walk the configuration tree to build the overall structure
        // and capture the explicit/implicit/inherited provider dependencies.
-       deps := moduleTreeConfigDependencies(root, nil)
+       deps := configTreeConfigDependencies(root, nil)
 
        // Next we walk over the resources in the state to catch any additional
        // dependencies created by existing resources that are no longer in config.
        // Most things we find in state will already be present in 'deps', but
        // we're interested in the rare thing that isn't.
-       moduleTreeMergeStateDependencies(deps, state)
+       configTreeMergeStateDependencies(deps, state)
 
        return deps
 }
 
-func moduleTreeConfigDependencies(root *module.Tree, inheritProviders map[string]*config.ProviderConfig) *moduledeps.Module {
+func configTreeConfigDependencies(root *configs.Config, inheritProviders map[string]*configs.Provider) *moduledeps.Module {
        if root == nil {
                // If no config is provided, we'll make a synthetic root.
                // This isn't necessarily correct if we're called with a nil that
                // *isn't* at the root, but in practice that can never happen.
                return &moduledeps.Module{
-                       Name: "root",
+                       Name:      "root",
+                       Providers: make(moduledeps.Providers),
                }
        }
 
+       name := "root"
+       if len(root.Path) != 0 {
+               name = root.Path[len(root.Path)-1]
+       }
+
        ret := &moduledeps.Module{
-               Name: root.Name(),
+               Name: name,
        }
 
-       cfg := root.Config()
-       providerConfigs := cfg.ProviderConfigsByFullName()
+       module := root.Module
 
        // Provider dependencies
        {
-               providers := make(moduledeps.Providers, len(providerConfigs))
+               providers := make(moduledeps.Providers)
 
-               // Any providerConfigs elements are *explicit* provider dependencies,
-               // which is the only situation where the user might provide an actual
-               // version constraint. We'll take care of these first.
-               for fullName, pCfg := range providerConfigs {
+               // The main way to declare a provider dependency is explicitly inside
+               // the "terraform" block, which allows declaring a requirement without
+               // also creating a configuration.
+               for fullName, constraints := range module.ProviderRequirements {
                        inst := moduledeps.ProviderInstance(fullName)
-                       versionSet := discovery.AllVersions
-                       if pCfg.Version != "" {
-                               versionSet = discovery.ConstraintStr(pCfg.Version).MustParse()
+
+                       // The handling here is a bit fiddly because the moduledeps package
+                       // was designed around the legacy (pre-0.12) configuration model
+                       // and hasn't yet been revised to handle the new model. As a result,
+                       // we need to do some translation here.
+                       // FIXME: Eventually we should adjust the underlying model so we
+                       // can also retain the source location of each constraint, for
+                       // more informative output from the "terraform providers" command.
+                       var rawConstraints version.Constraints
+                       for _, constraint := range constraints {
+                               rawConstraints = append(rawConstraints, constraint.Required...)
                        }
+                       discoConstraints := discovery.NewConstraints(rawConstraints)
+
                        providers[inst] = moduledeps.ProviderDependency{
-                               Constraints: versionSet,
+                               Constraints: discoConstraints,
                                Reason:      moduledeps.ProviderDependencyExplicit,
                        }
                }
 
+               // Provider configurations can also include version constraints,
+               // allowing for more terse declaration in situations where both a
+               // configuration and a constraint are defined in the same module.
+               for fullName, pCfg := range module.ProviderConfigs {
+                       inst := moduledeps.ProviderInstance(fullName)
+                       discoConstraints := discovery.AllVersions
+                       if pCfg.Version.Required != nil {
+                               discoConstraints = discovery.NewConstraints(pCfg.Version.Required)
+                       }
+                       if existing, exists := providers[inst]; exists {
+                               existing.Constraints = existing.Constraints.Append(discoConstraints)
+                       } else {
+                               providers[inst] = moduledeps.ProviderDependency{
+                                       Constraints: discoConstraints,
+                                       Reason:      moduledeps.ProviderDependencyExplicit,
+                               }
+                       }
+               }
+
                // Each resource in the configuration creates an *implicit* provider
                // dependency, though we'll only record it if there isn't already
                // an explicit dependency on the same provider.
-               for _, rc := range cfg.Resources {
-                       fullName := rc.ProviderFullName()
-                       inst := moduledeps.ProviderInstance(fullName)
+               for _, rc := range module.ManagedResources {
+                       addr := rc.ProviderConfigAddr()
+                       inst := moduledeps.ProviderInstance(addr.StringCompact())
+                       if _, exists := providers[inst]; exists {
+                               // Explicit dependency already present
+                               continue
+                       }
+
+                       reason := moduledeps.ProviderDependencyImplicit
+                       if _, inherited := inheritProviders[addr.StringCompact()]; inherited {
+                               reason = moduledeps.ProviderDependencyInherited
+                       }
+
+                       providers[inst] = moduledeps.ProviderDependency{
+                               Constraints: discovery.AllVersions,
+                               Reason:      reason,
+                       }
+               }
+               for _, rc := range module.DataResources {
+                       addr := rc.ProviderConfigAddr()
+                       inst := moduledeps.ProviderInstance(addr.StringCompact())
                        if _, exists := providers[inst]; exists {
                                // Explicit dependency already present
                                continue
                        }
 
                        reason := moduledeps.ProviderDependencyImplicit
-                       if _, inherited := inheritProviders[fullName]; inherited {
+                       if _, inherited := inheritProviders[addr.String()]; inherited {
                                reason = moduledeps.ProviderDependencyInherited
                        }
 
@@ -91,31 +142,31 @@ func moduleTreeConfigDependencies(root *module.Tree, inheritProviders map[string
                ret.Providers = providers
        }
 
-       childInherit := make(map[string]*config.ProviderConfig)
+       childInherit := make(map[string]*configs.Provider)
        for k, v := range inheritProviders {
                childInherit[k] = v
        }
-       for k, v := range providerConfigs {
+       for k, v := range module.ProviderConfigs {
                childInherit[k] = v
        }
-       for _, c := range root.Children() {
-               ret.Children = append(ret.Children, moduleTreeConfigDependencies(c, childInherit))
+       for _, c := range root.Children {
+               ret.Children = append(ret.Children, configTreeConfigDependencies(c, childInherit))
        }
 
        return ret
 }
 
-func moduleTreeMergeStateDependencies(root *moduledeps.Module, state *State) {
+func configTreeMergeStateDependencies(root *moduledeps.Module, state *states.State) {
        if state == nil {
                return
        }
 
-       findModule := func(path []string) *moduledeps.Module {
+       findModule := func(path addrs.ModuleInstance) *moduledeps.Module {
                module := root
-               for _, name := range path[1:] { // skip initial "root"
+               for _, step := range path {
                        var next *moduledeps.Module
                        for _, cm := range module.Children {
-                               if cm.Name == name {
+                               if cm.Name == step.Name {
                                        next = cm
                                        break
                                }
@@ -124,7 +175,8 @@ func moduleTreeMergeStateDependencies(root *moduledeps.Module, state *State) {
                        if next == nil {
                                // If we didn't find a next node, we'll need to make one
                                next = &moduledeps.Module{
-                                       Name: name,
+                                       Name:      step.Name,
+                                       Providers: make(moduledeps.Providers),
                                }
                                module.Children = append(module.Children, next)
                        }
@@ -135,15 +187,11 @@ func moduleTreeMergeStateDependencies(root *moduledeps.Module, state *State) {
        }
 
        for _, ms := range state.Modules {
-               module := findModule(ms.Path)
+               module := findModule(ms.Addr)
 
-               for _, is := range ms.Resources {
-                       fullName := config.ResourceProviderFullName(is.Type, is.Provider)
-                       inst := moduledeps.ProviderInstance(fullName)
+               for _, rs := range ms.Resources {
+                       inst := moduledeps.ProviderInstance(rs.ProviderConfig.ProviderConfig.StringCompact())
                        if _, exists := module.Providers[inst]; !exists {
-                               if module.Providers == nil {
-                                       module.Providers = make(moduledeps.Providers)
-                               }
                                module.Providers[inst] = moduledeps.ProviderDependency{
                                        Constraints: discovery.AllVersions,
                                        Reason:      moduledeps.ProviderDependencyFromState,
@@ -151,5 +199,4 @@ func moduleTreeMergeStateDependencies(root *moduledeps.Module, state *State) {
                        }
                }
        }
-
 }