99
1010 "github.com/hashicorp/go-multierror"
1111
12+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1213 "github.com/hashicorp/terraform-plugin-sdk/v2/internal/configs/configschema"
1314 "github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
1415)
@@ -58,7 +59,9 @@ type Provider struct {
5859 ConfigureFunc ConfigureFunc
5960
6061 // ConfigureContextFunc is a function for configuring the provider. If the
61- // provider doesn't need to be configured, this can be omitted.
62+ // provider doesn't need to be configured, this can be omitted. This function
63+ // receives a context.Context that will cancel when Terraform sends a
64+ // cancellation signal. This function can yield Diagnostics
6265 ConfigureContextFunc ConfigureContextFunc
6366
6467 meta interface {}
@@ -77,7 +80,7 @@ type ConfigureFunc func(*ResourceData) (interface{}, error)
7780// the subsequent resources as the meta parameter. This return value is
7881// usually used to pass along a configured API client, a configuration
7982// structure, etc.
80- type ConfigureContextFunc func (context.Context , * ResourceData ) (interface {}, error )
83+ type ConfigureContextFunc func (context.Context , * ResourceData ) (interface {}, diag. Diagnostics )
8184
8285// InternalValidate should be called to validate the structure
8386// of the provider.
@@ -179,29 +182,32 @@ func (p *Provider) GetSchema(req *terraform.ProviderSchemaRequest) (*terraform.P
179182}
180183
181184// Validate is called once at the beginning with the raw configuration
182- // (no interpolation done) and can return a list of warnings and/or
183- // errors.
185+ // (no interpolation done) and can return diagnostics
184186//
185187// This is called once with the provider configuration only. It may not
186188// be called at all if no provider configuration is given.
187189//
188190// This should not assume that any values of the configurations are valid.
189191// The primary use case of this call is to check that required keys are
190192// set.
191- func (p * Provider ) Validate (c * terraform.ResourceConfig ) ([] string , [] error ) {
193+ func (p * Provider ) Validate (c * terraform.ResourceConfig ) diag. Diagnostics {
192194 if err := p .InternalValidate (); err != nil {
193- return nil , []error {fmt .Errorf (
194- "Internal validation of the provider failed! This is always a bug\n " +
195- "with the provider itself, and not a user issue. Please report\n " +
196- "this bug:\n \n %s" , err )}
195+ return []diag.Diagnostic {
196+ {
197+ Severity : diag .Error ,
198+ Summary : "InternalValidate" ,
199+ Detail : fmt .Sprintf ("Internal validation of the provider failed! This is always a bug\n " +
200+ "with the provider itself, and not a user issue. Please report\n " +
201+ "this bug:\n \n %s" , err ),
202+ },
203+ }
197204 }
198205
199206 return schemaMap (p .Schema ).Validate (c )
200207}
201208
202209// ValidateResource is called once at the beginning with the raw
203- // configuration (no interpolation done) and can return a list of warnings
204- // and/or errors.
210+ // configuration (no interpolation done) and can return diagnostics.
205211//
206212// This is called once per resource.
207213//
@@ -210,11 +216,15 @@ func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
210216// The primary use case of this call is to check that the required keys
211217// are set and that the general structure is correct.
212218func (p * Provider ) ValidateResource (
213- t string , c * terraform.ResourceConfig ) ([] string , [] error ) {
219+ t string , c * terraform.ResourceConfig ) diag. Diagnostics {
214220 r , ok := p .ResourcesMap [t ]
215221 if ! ok {
216- return nil , []error {fmt .Errorf (
217- "Provider doesn't support resource: %s" , t )}
222+ return []diag.Diagnostic {
223+ {
224+ Severity : diag .Error ,
225+ Summary : fmt .Sprintf ("Provider doesn't support resource: %s" , t ),
226+ },
227+ }
218228 }
219229
220230 return r .Validate (c )
@@ -224,12 +234,13 @@ func (p *Provider) ValidateResource(
224234// given. This is useful for setting things like access keys.
225235//
226236// This won't be called at all if no provider configuration is given.
227- //
228- // Configure returns an error if it occurred.
229- func (p * Provider ) Configure (ctx context.Context , c * terraform.ResourceConfig ) error {
237+ func (p * Provider ) Configure (ctx context.Context , c * terraform.ResourceConfig ) diag.Diagnostics {
238+
239+ var diags diag.Diagnostics
240+
230241 // No configuration
231242 if p .ConfigureFunc == nil && p .ConfigureContextFunc == nil {
232- return nil
243+ return diags
233244 }
234245
235246 sm := schemaMap (p .Schema )
@@ -238,26 +249,31 @@ func (p *Provider) Configure(ctx context.Context, c *terraform.ResourceConfig) e
238249 // generate an intermediary "diff" although that is never exposed.
239250 diff , err := sm .Diff (ctx , nil , c , nil , p .meta , true )
240251 if err != nil {
241- return err
252+ return append ( diags , diag . FromErr ( err ))
242253 }
243254
244255 data , err := sm .Data (nil , diff )
245256 if err != nil {
246- return err
257+ return append ( diags , diag . FromErr ( err ))
247258 }
248259
249- var meta interface {}
250- if p .ConfigureContextFunc != nil {
251- meta , err = p .ConfigureContextFunc (ctx , data )
252- } else {
253- meta , err = p .ConfigureFunc (data )
260+ if p .ConfigureFunc != nil {
261+ meta , err := p .ConfigureFunc (data )
262+ if err != nil {
263+ return append (diags , diag .FromErr (err ))
264+ }
265+ p .meta = meta
254266 }
255- if err != nil {
256- return err
267+ if p .ConfigureContextFunc != nil {
268+ meta , ds := p .ConfigureContextFunc (ctx , data )
269+ diags = append (diags , ds ... )
270+ if diags .HasError () {
271+ return diags
272+ }
273+ p .meta = meta
257274 }
258275
259- p .meta = meta
260- return nil
276+ return diags
261277}
262278
263279// Resources returns all the available resource types that this provider
@@ -361,8 +377,7 @@ func (p *Provider) ImportState(
361377}
362378
363379// ValidateDataSource is called once at the beginning with the raw
364- // configuration (no interpolation done) and can return a list of warnings
365- // and/or errors.
380+ // configuration (no interpolation done) and can return diagnostics.
366381//
367382// This is called once per data source instance.
368383//
@@ -371,11 +386,15 @@ func (p *Provider) ImportState(
371386// The primary use case of this call is to check that the required keys
372387// are set and that the general structure is correct.
373388func (p * Provider ) ValidateDataSource (
374- t string , c * terraform.ResourceConfig ) ([] string , [] error ) {
389+ t string , c * terraform.ResourceConfig ) diag. Diagnostics {
375390 r , ok := p .DataSourcesMap [t ]
376391 if ! ok {
377- return nil , []error {fmt .Errorf (
378- "Provider doesn't support data source: %s" , t )}
392+ return []diag.Diagnostic {
393+ {
394+ Severity : diag .Error ,
395+ Summary : fmt .Sprintf ("Provider doesn't support data source: %s" , t ),
396+ },
397+ }
379398 }
380399
381400 return r .Validate (c )
0 commit comments