]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/terraform/terraform/resource_provider.go
vendor: github.com/hashicorp/terraform/...@v0.10.0
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / resource_provider.go
CommitLineData
bae9f6d2
JC
1package terraform
2
c680a8e1
RS
3import (
4 "fmt"
5
6 multierror "github.com/hashicorp/go-multierror"
7 "github.com/hashicorp/terraform/plugin/discovery"
8)
9
bae9f6d2
JC
10// ResourceProvider is an interface that must be implemented by any
11// resource provider: the thing that creates and manages the resources in
12// a Terraform configuration.
13//
14// Important implementation note: All returned pointers, such as
15// *ResourceConfig, *InstanceState, *InstanceDiff, etc. must not point to
16// shared data. Terraform is highly parallel and assumes that this data is safe
17// to read/write in parallel so it must be unique references. Note that it is
18// safe to return arguments as results, however.
19type ResourceProvider interface {
20 /*********************************************************************
21 * Functions related to the provider
22 *********************************************************************/
23
24 // Input is called to ask the provider to ask the user for input
25 // for completing the configuration if necesarry.
26 //
27 // This may or may not be called, so resource provider writers shouldn't
28 // rely on this being available to set some default values for validate
29 // later. Example of a situation where this wouldn't be called is if
30 // the user is not using a TTY.
31 Input(UIInput, *ResourceConfig) (*ResourceConfig, error)
32
33 // Validate is called once at the beginning with the raw configuration
34 // (no interpolation done) and can return a list of warnings and/or
35 // errors.
36 //
37 // This is called once with the provider configuration only. It may not
38 // be called at all if no provider configuration is given.
39 //
40 // This should not assume that any values of the configurations are valid.
41 // The primary use case of this call is to check that required keys are
42 // set.
43 Validate(*ResourceConfig) ([]string, []error)
44
45 // Configure configures the provider itself with the configuration
46 // given. This is useful for setting things like access keys.
47 //
48 // This won't be called at all if no provider configuration is given.
49 //
50 // Configure returns an error if it occurred.
51 Configure(*ResourceConfig) error
52
53 // Resources returns all the available resource types that this provider
54 // knows how to manage.
55 Resources() []ResourceType
56
57 // Stop is called when the provider should halt any in-flight actions.
58 //
59 // This can be used to make a nicer Ctrl-C experience for Terraform.
60 // Even if this isn't implemented to do anything (just returns nil),
61 // Terraform will still cleanly stop after the currently executing
62 // graph node is complete. However, this API can be used to make more
63 // efficient halts.
64 //
65 // Stop doesn't have to and shouldn't block waiting for in-flight actions
66 // to complete. It should take any action it wants and return immediately
67 // acknowledging it has received the stop request. Terraform core will
68 // automatically not make any further API calls to the provider soon
69 // after Stop is called (technically exactly once the currently executing
70 // graph nodes are complete).
71 //
72 // The error returned, if non-nil, is assumed to mean that signaling the
73 // stop somehow failed and that the user should expect potentially waiting
74 // a longer period of time.
75 Stop() error
76
77 /*********************************************************************
78 * Functions related to individual resources
79 *********************************************************************/
80
81 // ValidateResource is called once at the beginning with the raw
82 // configuration (no interpolation done) and can return a list of warnings
83 // and/or errors.
84 //
85 // This is called once per resource.
86 //
87 // This should not assume any of the values in the resource configuration
88 // are valid since it is possible they have to be interpolated still.
89 // The primary use case of this call is to check that the required keys
90 // are set and that the general structure is correct.
91 ValidateResource(string, *ResourceConfig) ([]string, []error)
92
93 // Apply applies a diff to a specific resource and returns the new
94 // resource state along with an error.
95 //
96 // If the resource state given has an empty ID, then a new resource
97 // is expected to be created.
98 Apply(
99 *InstanceInfo,
100 *InstanceState,
101 *InstanceDiff) (*InstanceState, error)
102
103 // Diff diffs a resource versus a desired state and returns
104 // a diff.
105 Diff(
106 *InstanceInfo,
107 *InstanceState,
108 *ResourceConfig) (*InstanceDiff, error)
109
110 // Refresh refreshes a resource and updates all of its attributes
111 // with the latest information.
112 Refresh(*InstanceInfo, *InstanceState) (*InstanceState, error)
113
114 /*********************************************************************
115 * Functions related to importing
116 *********************************************************************/
117
118 // ImportState requests that the given resource be imported.
119 //
120 // The returned InstanceState only requires ID be set. Importing
121 // will always call Refresh after the state to complete it.
122 //
123 // IMPORTANT: InstanceState doesn't have the resource type attached
124 // to it. A type must be specified on the state via the Ephemeral
125 // field on the state.
126 //
127 // This function can return multiple states. Normally, an import
128 // will map 1:1 to a physical resource. However, some resources map
129 // to multiple. For example, an AWS security group may contain many rules.
130 // Each rule is represented by a separate resource in Terraform,
131 // therefore multiple states are returned.
132 ImportState(*InstanceInfo, string) ([]*InstanceState, error)
133
134 /*********************************************************************
135 * Functions related to data resources
136 *********************************************************************/
137
138 // ValidateDataSource is called once at the beginning with the raw
139 // configuration (no interpolation done) and can return a list of warnings
140 // and/or errors.
141 //
142 // This is called once per data source instance.
143 //
144 // This should not assume any of the values in the resource configuration
145 // are valid since it is possible they have to be interpolated still.
146 // The primary use case of this call is to check that the required keys
147 // are set and that the general structure is correct.
148 ValidateDataSource(string, *ResourceConfig) ([]string, []error)
149
150 // DataSources returns all of the available data sources that this
151 // provider implements.
152 DataSources() []DataSource
153
154 // ReadDataDiff produces a diff that represents the state that will
155 // be produced when the given data source is read using a later call
156 // to ReadDataApply.
157 ReadDataDiff(*InstanceInfo, *ResourceConfig) (*InstanceDiff, error)
158
159 // ReadDataApply initializes a data instance using the configuration
160 // in a diff produced by ReadDataDiff.
161 ReadDataApply(*InstanceInfo, *InstanceDiff) (*InstanceState, error)
162}
163
c680a8e1
RS
164// ResourceProviderError may be returned when creating a Context if the
165// required providers cannot be satisfied. This error can then be used to
166// format a more useful message for the user.
167type ResourceProviderError struct {
168 Errors []error
169}
170
171func (e *ResourceProviderError) Error() string {
172 // use multierror to format the default output
173 return multierror.Append(nil, e.Errors...).Error()
174}
175
bae9f6d2
JC
176// ResourceProviderCloser is an interface that providers that can close
177// connections that aren't needed anymore must implement.
178type ResourceProviderCloser interface {
179 Close() error
180}
181
182// ResourceType is a type of resource that a resource provider can manage.
183type ResourceType struct {
184 Name string // Name of the resource, example "instance" (no provider prefix)
185 Importable bool // Whether this resource supports importing
186}
187
188// DataSource is a data source that a resource provider implements.
189type DataSource struct {
190 Name string
191}
192
c680a8e1
RS
193// ResourceProviderResolver is an interface implemented by objects that are
194// able to resolve a given set of resource provider version constraints
195// into ResourceProviderFactory callbacks.
196type ResourceProviderResolver interface {
197 // Given a constraint map, return a ResourceProviderFactory for each
198 // requested provider. If some or all of the constraints cannot be
199 // satisfied, return a non-nil slice of errors describing the problems.
200 ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
201}
202
203// ResourceProviderResolverFunc wraps a callback function and turns it into
204// a ResourceProviderResolver implementation, for convenience in situations
205// where a function and its associated closure are sufficient as a resolver
206// implementation.
207type ResourceProviderResolverFunc func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
208
209// ResolveProviders implements ResourceProviderResolver by calling the
210// wrapped function.
211func (f ResourceProviderResolverFunc) ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
212 return f(reqd)
213}
214
215// ResourceProviderResolverFixed returns a ResourceProviderResolver that
216// has a fixed set of provider factories provided by the caller. The returned
217// resolver ignores version constraints entirely and just returns the given
218// factory for each requested provider name.
219//
220// This function is primarily used in tests, to provide mock providers or
221// in-process providers under test.
222func ResourceProviderResolverFixed(factories map[string]ResourceProviderFactory) ResourceProviderResolver {
223 return ResourceProviderResolverFunc(func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
224 ret := make(map[string]ResourceProviderFactory, len(reqd))
225 var errs []error
226 for name := range reqd {
227 if factory, exists := factories[name]; exists {
228 ret[name] = factory
229 } else {
230 errs = append(errs, fmt.Errorf("provider %q is not available", name))
231 }
232 }
233 return ret, errs
234 })
235}
236
bae9f6d2
JC
237// ResourceProviderFactory is a function type that creates a new instance
238// of a resource provider.
239type ResourceProviderFactory func() (ResourceProvider, error)
240
241// ResourceProviderFactoryFixed is a helper that creates a
242// ResourceProviderFactory that just returns some fixed provider.
243func ResourceProviderFactoryFixed(p ResourceProvider) ResourceProviderFactory {
244 return func() (ResourceProvider, error) {
245 return p, nil
246 }
247}
248
249func ProviderHasResource(p ResourceProvider, n string) bool {
250 for _, rt := range p.Resources() {
251 if rt.Name == n {
252 return true
253 }
254 }
255
256 return false
257}
258
259func ProviderHasDataSource(p ResourceProvider, n string) bool {
260 for _, rt := range p.DataSources() {
261 if rt.Name == n {
262 return true
263 }
264 }
265
266 return false
267}
c680a8e1
RS
268
269// resourceProviderFactories matches available plugins to the given version
270// requirements to produce a map of compatible provider plugins if possible,
271// or an error if the currently-available plugins are insufficient.
272//
273// This should be called only with configurations that have passed calls
274// to config.Validate(), which ensures that all of the given version
275// constraints are valid. It will panic if any invalid constraints are present.
276func resourceProviderFactories(resolver ResourceProviderResolver, reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, error) {
277 ret, errs := resolver.ResolveProviders(reqd)
278 if errs != nil {
279 return nil, &ResourceProviderError{
280 Errors: errs,
281 }
282 }
283
284 return ret, nil
285}