summaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/terraform/terraform/transform_attach_config_provider.go
blob: 10506ea060299ce829b6d45f4dbd616fcfe6ee47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package terraform

import (
	"log"

	"github.com/hashicorp/terraform/config"
	"github.com/hashicorp/terraform/config/module"
)

// GraphNodeAttachProvider is an interface that must be implemented by nodes
// that want provider configurations attached.
type GraphNodeAttachProvider interface {
	// Must be implemented to determine the path for the configuration
	GraphNodeSubPath

	// ProviderName with no module prefix. Example: "aws".
	ProviderName() string

	// Sets the configuration
	AttachProvider(*config.ProviderConfig)
}

// AttachProviderConfigTransformer goes through the graph and attaches
// provider configuration structures to nodes that implement the interfaces
// above.
//
// The attached configuration structures are directly from the configuration.
// If they're going to be modified, a copy should be made.
type AttachProviderConfigTransformer struct {
	Module *module.Tree // Module is the root module for the config
}

func (t *AttachProviderConfigTransformer) Transform(g *Graph) error {
	if err := t.attachProviders(g); err != nil {
		return err
	}

	return nil
}

func (t *AttachProviderConfigTransformer) attachProviders(g *Graph) error {
	// Go through and find GraphNodeAttachProvider
	for _, v := range g.Vertices() {
		// Only care about GraphNodeAttachProvider implementations
		apn, ok := v.(GraphNodeAttachProvider)
		if !ok {
			continue
		}

		// Determine what we're looking for
		path := normalizeModulePath(apn.Path())
		path = path[1:]
		name := apn.ProviderName()
		log.Printf("[TRACE] Attach provider request: %#v %s", path, name)

		// Get the configuration.
		tree := t.Module.Child(path)
		if tree == nil {
			continue
		}

		// Go through the provider configs to find the matching config
		for _, p := range tree.Config().ProviderConfigs {
			// Build the name, which is "name.alias" if an alias exists
			current := p.Name
			if p.Alias != "" {
				current += "." + p.Alias
			}

			// If the configs match then attach!
			if current == name {
				log.Printf("[TRACE] Attaching provider config: %#v", p)
				apn.AttachProvider(p)
				break
			}
		}
	}

	return nil
}