]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/terraform/terraform/eval_provider.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / eval_provider.go
CommitLineData
bae9f6d2
JC
1package terraform
2
3import (
4 "fmt"
107c1cdb 5 "log"
bae9f6d2 6
107c1cdb
ND
7 "github.com/hashicorp/hcl2/hcl"
8
9 "github.com/hashicorp/terraform/addrs"
10 "github.com/hashicorp/terraform/configs"
11 "github.com/hashicorp/terraform/providers"
12 "github.com/hashicorp/terraform/tfdiags"
bae9f6d2
JC
13)
14
107c1cdb
ND
15func buildProviderConfig(ctx EvalContext, addr addrs.ProviderConfig, config *configs.Provider) hcl.Body {
16 var configBody hcl.Body
17 if config != nil {
18 configBody = config.Config
19 }
bae9f6d2 20
107c1cdb
ND
21 var inputBody hcl.Body
22 inputConfig := ctx.ProviderInput(addr)
23 if len(inputConfig) > 0 {
24 inputBody = configs.SynthBody("<input-prompt>", inputConfig)
bae9f6d2
JC
25 }
26
107c1cdb
ND
27 switch {
28 case configBody != nil && inputBody != nil:
29 log.Printf("[TRACE] buildProviderConfig for %s: merging explicit config and input", addr)
30 // Note that the inputBody is the _base_ here, because configs.MergeBodies
31 // expects the base have all of the required fields, while these are
32 // forced to be optional for the override. The input process should
33 // guarantee that we have a value for each of the required arguments and
34 // that in practice the sets of attributes in each body will be
35 // disjoint.
36 return configs.MergeBodies(inputBody, configBody)
37 case configBody != nil:
38 log.Printf("[TRACE] buildProviderConfig for %s: using explicit config only", addr)
39 return configBody
40 case inputBody != nil:
41 log.Printf("[TRACE] buildProviderConfig for %s: using input only", addr)
42 return inputBody
43 default:
44 log.Printf("[TRACE] buildProviderConfig for %s: no configuration at all", addr)
45 return hcl.EmptyBody()
46 }
bae9f6d2
JC
47}
48
49// EvalConfigProvider is an EvalNode implementation that configures
50// a provider that is already initialized and retrieved.
51type EvalConfigProvider struct {
107c1cdb
ND
52 Addr addrs.ProviderConfig
53 Provider *providers.Interface
54 Config *configs.Provider
bae9f6d2
JC
55}
56
57func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
107c1cdb
ND
58 if n.Provider == nil {
59 return nil, fmt.Errorf("EvalConfigProvider Provider is nil")
60 }
61
62 var diags tfdiags.Diagnostics
63 provider := *n.Provider
64 config := n.Config
65
66 configBody := buildProviderConfig(ctx, n.Addr, config)
67
68 resp := provider.GetSchema()
69 diags = diags.Append(resp.Diagnostics)
70 if diags.HasErrors() {
71 return nil, diags.NonFatalErr()
72 }
73
74 configSchema := resp.Provider.Block
75 configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil, EvalDataForNoInstanceKey)
76 diags = diags.Append(evalDiags)
77 if evalDiags.HasErrors() {
78 return nil, diags.NonFatalErr()
79 }
80
81 configDiags := ctx.ConfigureProvider(n.Addr, configVal)
82 configDiags = configDiags.InConfigBody(configBody)
83
84 return nil, configDiags.ErrWithWarnings()
bae9f6d2
JC
85}
86
87// EvalInitProvider is an EvalNode implementation that initializes a provider
88// and returns nothing. The provider can be retrieved again with the
89// EvalGetProvider node.
90type EvalInitProvider struct {
15c0b25d 91 TypeName string
107c1cdb 92 Addr addrs.ProviderConfig
bae9f6d2
JC
93}
94
95func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) {
107c1cdb 96 return ctx.InitProvider(n.TypeName, n.Addr)
bae9f6d2
JC
97}
98
99// EvalCloseProvider is an EvalNode implementation that closes provider
100// connections that aren't needed anymore.
101type EvalCloseProvider struct {
107c1cdb 102 Addr addrs.ProviderConfig
bae9f6d2
JC
103}
104
105func (n *EvalCloseProvider) Eval(ctx EvalContext) (interface{}, error) {
107c1cdb 106 ctx.CloseProvider(n.Addr)
bae9f6d2
JC
107 return nil, nil
108}
109
110// EvalGetProvider is an EvalNode implementation that retrieves an already
111// initialized provider instance for the given name.
107c1cdb
ND
112//
113// Unlike most eval nodes, this takes an _absolute_ provider configuration,
114// because providers can be passed into and inherited between modules.
115// Resource nodes must therefore know the absolute path of the provider they
116// will use, which is usually accomplished by implementing
117// interface GraphNodeProviderConsumer.
bae9f6d2 118type EvalGetProvider struct {
107c1cdb
ND
119 Addr addrs.AbsProviderConfig
120 Output *providers.Interface
121
122 // If non-nil, Schema will be updated after eval to refer to the
123 // schema of the provider.
124 Schema **ProviderSchema
bae9f6d2
JC
125}
126
127func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) {
107c1cdb
ND
128 if n.Addr.ProviderConfig.Type == "" {
129 // Should never happen
130 panic("EvalGetProvider used with uninitialized provider configuration address")
131 }
132
133 result := ctx.Provider(n.Addr)
bae9f6d2 134 if result == nil {
107c1cdb 135 return nil, fmt.Errorf("provider %s not initialized", n.Addr)
bae9f6d2
JC
136 }
137
138 if n.Output != nil {
139 *n.Output = result
140 }
141
107c1cdb
ND
142 if n.Schema != nil {
143 *n.Schema = ctx.ProviderSchema(n.Addr)
bae9f6d2
JC
144 }
145
bae9f6d2
JC
146 return nil, nil
147}