@@ -123,12 +123,25 @@ func parameterDataSource() *schema.Resource {
123
123
if err != nil {
124
124
return diag .Errorf ("decode parameter: %s" , err )
125
125
}
126
- value := parameter .Default
126
+
127
+ var value * string
128
+ if ! rd .GetRawConfig ().AsValueMap ()["default" ].IsNull () {
129
+ value = & parameter .Default
130
+ }
131
+
127
132
envValue , ok := os .LookupEnv (ParameterEnvironmentVariable (parameter .Name ))
128
133
if ok {
129
- value = envValue
134
+ value = & envValue
135
+ }
136
+
137
+ if value != nil {
138
+ rd .Set ("value" , value )
139
+ } else {
140
+ // Maintaining backwards compatibility. The previous behavior was
141
+ // to write back an empty string.
142
+ // TODO: Should an empty string exist if no value is set?
143
+ rd .Set ("value" , "" )
130
144
}
131
- rd .Set ("value" , value )
132
145
133
146
if ! parameter .Mutable && parameter .Ephemeral {
134
147
return diag .Errorf ("parameter can't be immutable and ephemeral" )
@@ -138,21 +151,6 @@ func parameterDataSource() *schema.Resource {
138
151
return diag .Errorf ("ephemeral parameter requires the default property" )
139
152
}
140
153
141
- // Do ValidateFormType up front. If there is no error, update the
142
- // 'parameter.FormType' value to the new value. This is to handle default cases,
143
- // since the default logic is more advanced than the sdk provider schema
144
- // supports.
145
- //_, newFT, err := ValidateFormType(parameter.Type, len(parameter.Option), parameter.FormType)
146
- //if err == nil {
147
- // // If there is an error, parameter.Valid will catch it.
148
- // parameter.FormType = newFT
149
- //
150
- // // Set the form_type back in case the value was changed.
151
- // // Eg via a default. If a user does not specify, a default value
152
- // // is used and saved.
153
- // rd.Set("form_type", parameter.FormType)
154
- //}
155
-
156
154
diags := parameter .Valid (value )
157
155
if diags .HasError () {
158
156
return diags
@@ -399,12 +397,7 @@ func valueIsType(typ OptionType, value string) error {
399
397
return nil
400
398
}
401
399
402
- func (v * Parameter ) RelaxedValidation (value string ) diag.Diagnostics {
403
-
404
- return nil
405
- }
406
-
407
- func (v * Parameter ) Valid (value string ) diag.Diagnostics {
400
+ func (v * Parameter ) Valid (value * string ) diag.Diagnostics {
408
401
var err error
409
402
var optionType OptionType
410
403
@@ -422,88 +415,125 @@ func (v *Parameter) Valid(value string) diag.Diagnostics {
422
415
}
423
416
}
424
417
425
- optionNames := map [string ]any {}
426
- optionValues := map [string ]any {}
427
- if len (v .Option ) > 0 {
428
- for _ , option := range v .Option {
429
- _ , exists := optionNames [option .Name ]
430
- if exists {
431
- return diag.Diagnostics {{
432
- Severity : diag .Error ,
433
- Summary : "Option names must be unique." ,
434
- Detail : fmt .Sprintf ("multiple options found with the same name %q" , option .Name ),
435
- },
436
- }
437
- }
438
- _ , exists = optionValues [option .Value ]
439
- if exists {
440
- return diag.Diagnostics {
441
- {
442
- Severity : diag .Error ,
443
- Summary : "Option values must be unique." ,
444
- Detail : fmt .Sprintf ("multiple options found with the same value %q" , option .Value ),
445
- },
446
- }
447
- }
448
- err = valueIsType (optionType , option .Value )
449
- if err != nil {
450
- return diag.Diagnostics {
451
- {
452
- Severity : diag .Error ,
453
- Summary : fmt .Sprintf ("Option %q with value=%q is not of type %q" , option .Name , option .Value , optionType ),
454
- Detail : err .Error (),
455
- },
456
- }
457
- }
458
- optionValues [option .Value ] = nil
459
- optionNames [option .Name ] = nil
460
-
461
- // TODO: Option values should also be validated.
462
- // v.validValue(option.Value, optionType, nil, cty.Path{})
463
- }
418
+ optionValues , diags := v .ValidOptions (optionType )
419
+ if diags .HasError () {
420
+ return diags
464
421
}
465
422
466
- // Validate the default value
467
- if v .Default != "" {
468
- err := valueIsType (v .Type , v .Default )
423
+ // TODO: The default value should also be validated
424
+ //if v.Default != "" {
425
+ // err := valueIsType(v.Type, v.Default)
426
+ // if err != nil {
427
+ // return diag.Diagnostics{
428
+ // {
429
+ // Severity: diag.Error,
430
+ // Summary: fmt.Sprintf("Default value is not of type %q", v.Type),
431
+ // Detail: err.Error(),
432
+ // AttributePath: defaultValuePath,
433
+ // },
434
+ // }
435
+ // }
436
+ //
437
+ // d := v.validValue(v.Default, optionType, optionValues, defaultValuePath)
438
+ // if d.HasError() {
439
+ // return d
440
+ // }
441
+ //}
442
+
443
+ // TODO: Move this into 'Parameter.validValue'. It exists as another check outside because
444
+ // the current behavior is to always apply this validation, regardless if the param is set or not.
445
+ // Other validations are only applied if the parameter is set.
446
+ // This behavior should be standardized.
447
+ if len (v .Validation ) == 1 {
448
+ empty := ""
449
+ validVal := value
450
+ if value == nil {
451
+ validVal = & empty
452
+ }
453
+ validCheck := & v .Validation [0 ]
454
+ err := validCheck .Valid (v .Type , * validVal )
469
455
if err != nil {
470
456
return diag.Diagnostics {
471
457
{
472
458
Severity : diag .Error ,
473
- Summary : fmt .Sprintf ("Default value is not of type %q " , v . Type ),
459
+ Summary : fmt .Sprintf ("Invalid parameter %s according to 'validation' block " , strings . ToLower ( v . Name ) ),
474
460
Detail : err .Error (),
475
- AttributePath : defaultValuePath ,
461
+ AttributePath : cty. Path {} ,
476
462
},
477
463
}
478
464
}
465
+ }
479
466
480
- d := v .validValue (v .Default , optionType , optionValues , defaultValuePath )
467
+ // Value is only validated if it is set. If it is unset, validation
468
+ // is skipped.
469
+ if value != nil {
470
+ d := v .validValue (* value , optionType , optionValues , cty.Path {})
481
471
if d .HasError () {
482
472
return d
483
473
}
484
- }
485
474
486
- // Value must always be validated
487
- d := v .validValue (value , optionType , optionValues , cty.Path {})
488
- if d .HasError () {
489
- return d
475
+ err = valueIsType (v .Type , * value )
476
+ if err != nil {
477
+ return diag.Diagnostics {
478
+ {
479
+ Severity : diag .Error ,
480
+ Summary : fmt .Sprintf ("Parameter value is not of type %q" , v .Type ),
481
+ Detail : err .Error (),
482
+ },
483
+ }
484
+ }
490
485
}
491
486
492
- err = valueIsType (v .Type , value )
493
- if err != nil {
494
- return diag.Diagnostics {
495
- {
487
+ return nil
488
+ }
489
+
490
+ func (v * Parameter ) ValidOptions (optionType OptionType ) (map [string ]struct {}, diag.Diagnostics ) {
491
+ optionNames := map [string ]struct {}{}
492
+ optionValues := map [string ]struct {}{}
493
+
494
+ var diags diag.Diagnostics
495
+ for _ , option := range v .Option {
496
+ _ , exists := optionNames [option .Name ]
497
+ if exists {
498
+ return nil , diag.Diagnostics {{
496
499
Severity : diag .Error ,
497
- Summary : fmt .Sprintf ("Parameter value is not of type %q" , v .Type ),
500
+ Summary : "Option names must be unique." ,
501
+ Detail : fmt .Sprintf ("multiple options found with the same name %q" , option .Name ),
502
+ }}
503
+ }
504
+
505
+ _ , exists = optionValues [option .Value ]
506
+ if exists {
507
+ return nil , diag.Diagnostics {{
508
+ Severity : diag .Error ,
509
+ Summary : "Option values must be unique." ,
510
+ Detail : fmt .Sprintf ("multiple options found with the same value %q" , option .Value ),
511
+ }}
512
+ }
513
+
514
+ err := valueIsType (optionType , option .Value )
515
+ if err != nil {
516
+ diags = append (diags , diag.Diagnostic {
517
+ Severity : diag .Error ,
518
+ Summary : fmt .Sprintf ("Option %q with value=%q is not of type %q" , option .Name , option .Value , optionType ),
498
519
Detail : err .Error (),
499
- },
520
+ })
521
+ continue
500
522
}
523
+ optionValues [option .Value ] = struct {}{}
524
+ optionNames [option .Name ] = struct {}{}
525
+
526
+ // TODO: Option values should also be validated.
527
+ // v.validValue(option.Value, optionType, nil, cty.Path{})
501
528
}
502
529
503
- return nil
530
+ if diags .HasError () {
531
+ return nil , diags
532
+ }
533
+ return optionValues , nil
504
534
}
505
535
506
- func (v * Parameter ) validValue (value string , optionType OptionType , optionValues map [string ]any , path cty.Path ) diag.Diagnostics {
536
+ func (v * Parameter ) validValue (value string , optionType OptionType , optionValues map [string ]struct {} , path cty.Path ) diag.Diagnostics {
507
537
// name is used for constructing more precise error messages.
508
538
name := "Value"
509
539
if path .Equals (defaultValuePath ) {
@@ -568,21 +598,6 @@ func (v *Parameter) validValue(value string, optionType OptionType, optionValues
568
598
}
569
599
}
570
600
571
- if len (v .Validation ) == 1 {
572
- validCheck := & v .Validation [0 ]
573
- err := validCheck .Valid (v .Type , value )
574
- if err != nil {
575
- return diag.Diagnostics {
576
- {
577
- Severity : diag .Error ,
578
- Summary : fmt .Sprintf ("Invalid parameter %s according to 'validation' block" , strings .ToLower (name )),
579
- Detail : err .Error (),
580
- AttributePath : path ,
581
- },
582
- }
583
- }
584
- }
585
-
586
601
return nil
587
602
}
588
603
0 commit comments