@@ -351,6 +351,7 @@ func NewProvider(schema []byte, prefix string, modulePath string, metadata []byt
351
351
p .Resources [name ] = DefaultResource (name , terraformResource , terraformPluginFrameworkResource , providerMetadata .Resources [name ], p .DefaultResourceOptions ... )
352
352
p .Resources [name ].useTerraformPluginSDKClient = isTerraformPluginSDK
353
353
p .Resources [name ].useTerraformPluginFrameworkClient = isPluginFrameworkResource
354
+ p .injectServerSideApplyDefaults (p .Resources [name ], terraformResource , "" )
354
355
}
355
356
for i , refInjector := range p .refInjectors {
356
357
if err := refInjector .InjectReferences (p .Resources ); err != nil {
@@ -360,6 +361,58 @@ func NewProvider(schema []byte, prefix string, modulePath string, metadata []byt
360
361
return p
361
362
}
362
363
364
+ func (p * Provider ) injectServerSideApplyDefaults (cfg * Resource , res * schema.Resource , basePath string ) { //nolint:gocyclo // Easier to follow the logic in a single function
365
+
366
+ for k , es := range res .Schema {
367
+
368
+ var fieldPath string
369
+ if basePath == "" {
370
+ fieldPath = k
371
+ } else {
372
+ fieldPath = fmt .Sprintf ("%s.%s" , basePath , k )
373
+ }
374
+
375
+ if r , ok := es .Elem .(* schema.Resource ); ok {
376
+ if es .Type == schema .TypeList && es .MaxItems == 1 {
377
+ cfg .ServerSideApplyMergeStrategies [fieldPath ] = MergeStrategy {
378
+ ListMergeStrategy : ListMergeStrategy {
379
+ MergeStrategy : ListTypeMap ,
380
+ ListMapKeys : ListMapKeys {InjectedKey : InjectedKey {
381
+ Key : "ssamergekey" ,
382
+ DefaultValue : `"0"` ,
383
+ }},
384
+ },
385
+ }
386
+ }
387
+ p .injectServerSideApplyDefaults (cfg , r , fieldPath )
388
+ } else {
389
+ switch es .Type { //nolint:exhaustive
390
+ case schema .TypeSet :
391
+ if el , ok := es .Elem .(* schema.Schema ); ok {
392
+ switch el .Type { //nolint:exhaustive
393
+ case schema .TypeString , schema .TypeBool , schema .TypeInt , schema .TypeFloat :
394
+ cfg .ServerSideApplyMergeStrategies [fieldPath ] = MergeStrategy {
395
+ ListMergeStrategy : ListMergeStrategy {
396
+ MergeStrategy : ListTypeSet ,
397
+ },
398
+ }
399
+ }
400
+ }
401
+ case schema .TypeMap :
402
+ if el , ok := es .Elem .(* schema.Schema ); ok {
403
+ switch el .Type { //nolint:exhaustive
404
+ case schema .TypeString , schema .TypeBool , schema .TypeInt , schema .TypeFloat :
405
+ // TODO(jono): I think this may be unnecessary since maps appear to default to granular?
406
+ cfg .ServerSideApplyMergeStrategies [fieldPath ] = MergeStrategy {
407
+ MapMergeStrategy : MapTypeGranular ,
408
+ }
409
+ }
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }
415
+
363
416
// AddResourceConfigurator adds resource specific configurators.
364
417
func (p * Provider ) AddResourceConfigurator (resource string , c ResourceConfiguratorFn ) { //nolint:interfacer
365
418
// Note(turkenh): nolint reasoning - easier to provide a function without
0 commit comments