aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/config/import_tree.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/config/import_tree.go')
-rw-r--r--vendor/github.com/hashicorp/terraform/config/import_tree.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/config/import_tree.go b/vendor/github.com/hashicorp/terraform/config/import_tree.go
new file mode 100644
index 0000000..37ec11a
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/config/import_tree.go
@@ -0,0 +1,113 @@
1package config
2
3import (
4 "fmt"
5 "io"
6)
7
8// configurable is an interface that must be implemented by any configuration
9// formats of Terraform in order to return a *Config.
10type configurable interface {
11 Config() (*Config, error)
12}
13
14// importTree is the result of the first-pass load of the configuration
15// files. It is a tree of raw configurables and then any children (their
16// imports).
17//
18// An importTree can be turned into a configTree.
19type importTree struct {
20 Path string
21 Raw configurable
22 Children []*importTree
23}
24
25// This is the function type that must be implemented by the configuration
26// file loader to turn a single file into a configurable and any additional
27// imports.
28type fileLoaderFunc func(path string) (configurable, []string, error)
29
30// loadTree takes a single file and loads the entire importTree for that
31// file. This function detects what kind of configuration file it is an
32// executes the proper fileLoaderFunc.
33func loadTree(root string) (*importTree, error) {
34 var f fileLoaderFunc
35 switch ext(root) {
36 case ".tf", ".tf.json":
37 f = loadFileHcl
38 default:
39 }
40
41 if f == nil {
42 return nil, fmt.Errorf(
43 "%s: unknown configuration format. Use '.tf' or '.tf.json' extension",
44 root)
45 }
46
47 c, imps, err := f(root)
48 if err != nil {
49 return nil, err
50 }
51
52 children := make([]*importTree, len(imps))
53 for i, imp := range imps {
54 t, err := loadTree(imp)
55 if err != nil {
56 return nil, err
57 }
58
59 children[i] = t
60 }
61
62 return &importTree{
63 Path: root,
64 Raw: c,
65 Children: children,
66 }, nil
67}
68
69// Close releases any resources we might be holding open for the importTree.
70//
71// This can safely be called even while ConfigTree results are alive. The
72// importTree is not bound to these.
73func (t *importTree) Close() error {
74 if c, ok := t.Raw.(io.Closer); ok {
75 c.Close()
76 }
77 for _, ct := range t.Children {
78 ct.Close()
79 }
80
81 return nil
82}
83
84// ConfigTree traverses the importTree and turns each node into a *Config
85// object, ultimately returning a *configTree.
86func (t *importTree) ConfigTree() (*configTree, error) {
87 config, err := t.Raw.Config()
88 if err != nil {
89 return nil, fmt.Errorf(
90 "Error loading %s: %s",
91 t.Path,
92 err)
93 }
94
95 // Build our result
96 result := &configTree{
97 Path: t.Path,
98 Config: config,
99 }
100
101 // Build the config trees for the children
102 result.Children = make([]*configTree, len(t.Children))
103 for i, ct := range t.Children {
104 t, err := ct.ConfigTree()
105 if err != nil {
106 return nil, err
107 }
108
109 result.Children[i] = t
110 }
111
112 return result, nil
113}