@@ -375,9 +375,310 @@ func RenderCopyFromPangoFunctions(pkgName string, terraformTypePrefix string, pr
375
375
return processTemplate (copyFromPangoTmpl , "copy-from-pango" , data , funcMap )
376
376
}
377
377
378
- func ResourceCreateFunction (structName string , serviceName string , paramSpec * properties.Normalization , terraformProvider * properties.TerraformProviderFile , resourceSDKName string ) (string , error ) {
378
+ const renderLocationTmpl = `
379
+ {{- range .Locations }}
380
+ type {{ .StructName }} struct {
381
+ {{- range .Fields }}
382
+ {{ .Name }} {{ .Type }} {{ range .Tags }}{{ . }} {{ end }}
383
+ {{- end }}
384
+ }
385
+ {{- end }}
386
+ `
387
+
388
+ func RenderLocationStructs (names * NameProvider , spec * properties.Normalization ) (string , error ) {
389
+ type fieldCtx struct {
390
+ Name string
391
+ Type string
392
+ Tags []string
393
+ }
394
+
395
+ type locationCtx struct {
396
+ StructName string
397
+ Fields []fieldCtx
398
+ }
399
+
400
+ type context struct {
401
+ Locations []locationCtx
402
+ }
403
+
404
+ var locations []locationCtx
405
+
406
+ // Create the top location structure that references other locations
407
+ topLocation := locationCtx {
408
+ StructName : fmt .Sprintf ("%sLocation" , names .StructName ),
409
+ }
410
+
411
+ for name , data := range spec .Locations {
412
+ structName := fmt .Sprintf ("%s%sLocation" , names .StructName , pascalCase (name ))
413
+ tfTag := fmt .Sprintf ("`tfsdk:\" %s\" `" , name )
414
+ var structType string
415
+ if len (data .Vars ) > 0 {
416
+ structType = fmt .Sprintf ("*%s" , structName )
417
+ } else {
418
+ structType = "types.Bool"
419
+ }
420
+
421
+ topLocation .Fields = append (topLocation .Fields , fieldCtx {
422
+ Name : pascalCase (name ),
423
+ Type : structType ,
424
+ Tags : []string {tfTag },
425
+ })
426
+
427
+ if len (data .Vars ) == 0 {
428
+ continue
429
+ }
430
+
431
+ var fields []fieldCtx
432
+ for paramName , param := range data .Vars {
433
+ paramTag := fmt .Sprintf ("`tfsdk:\" %s\" `" , paramName )
434
+ fields = append (fields , fieldCtx {
435
+ Name : param .Name .CamelCase ,
436
+ Type : "types.String" ,
437
+ Tags : []string {paramTag },
438
+ })
439
+ }
440
+
441
+ location := locationCtx {
442
+ StructName : structName ,
443
+ Fields : fields ,
444
+ }
445
+ locations = append (locations , location )
446
+ }
447
+
448
+ locations = append (locations , topLocation )
449
+
450
+ data := context {
451
+ Locations : locations ,
452
+ }
453
+ return processTemplate (renderLocationTmpl , "render-location-structs" , data , commonFuncMap )
454
+ }
455
+
456
+ const locationSchemaGetterTmpl = `
457
+ {{- define "renderLocationAttribute" }}
458
+ "{{ .Name }}": {{ .SchemaType }}{
459
+ Description: "{{ .Description }}",
460
+ {{- if .Required }}
461
+ Required: true
462
+ {{- else }}
463
+ Optional: true,
464
+ {{- end }}
465
+ {{- if .Computed }}
466
+ Computed: true,
467
+ {{- end }}
468
+ {{- if .Default }}
469
+ Default: {{ .Default.Type }}({{ .Default.Value }}),
470
+ {{- end }}
471
+ {{- if .Attributes }}
472
+ Attributes: map[string]rsschema.Attribute{
473
+ {{- range .Attributes }}
474
+ {{- template "renderLocationAttribute" . }}
475
+ {{- end }}
476
+ },
477
+ {{- end }}
478
+ PlanModifiers: []planmodifier.{{ .ModifierType }}{
479
+ {{ .ModifierType | LowerCase }}planmodifier.RequiresReplace(),
480
+ },
481
+ },
482
+ {{- end }}
483
+
484
+ func {{ .StructName }}LocationsSchema() rsschema.Attribute {
485
+ {{- with .Schema }}
486
+ return rsschema.SingleNestedAttribute{
487
+ Description: "{{ .Description }}",
488
+ Required: true,
489
+ Attributes: map[string]rsschema.Attribute{
490
+ {{- range .Attributes }}
491
+ {{- template "renderLocationAttribute" . }}
492
+ {{- end }}
493
+ },
494
+ }
495
+ }
496
+ {{- end }}
497
+ `
498
+
499
+ func RenderLocationSchemaGetter (names * NameProvider , spec * properties.Normalization ) (string , error ) {
500
+ type defaultCtx struct {
501
+ Type string
502
+ Value string
503
+ }
504
+
505
+ type attributeCtx struct {
506
+ Name string
507
+ SchemaType string
508
+ Description string
509
+ Required bool
510
+ Computed bool
511
+ Default * defaultCtx
512
+ ModifierType string
513
+ Attributes []attributeCtx
514
+ }
515
+
516
+ var attributes []attributeCtx
517
+ for name , data := range spec .Locations {
518
+ var schemaType string
519
+ if len (data .Vars ) == 0 {
520
+ schemaType = "rsschema.BoolAttribute"
521
+ } else {
522
+ schemaType = "rsschema.SingleNestedAttribute"
523
+ }
524
+
525
+ var variableAttrs []attributeCtx
526
+ for variableName , variable := range data .Vars {
527
+ attribute := attributeCtx {
528
+ Name : variableName ,
529
+ Description : variable .Description ,
530
+ SchemaType : "rsschema.StringAttribute" ,
531
+ Required : false ,
532
+ Computed : true ,
533
+ Default : & defaultCtx {
534
+ Type : "stringdefault.StaticString" ,
535
+ Value : fmt .Sprintf (`"%s"` , variable .Default ),
536
+ },
537
+ ModifierType : "String" ,
538
+ }
539
+ variableAttrs = append (variableAttrs , attribute )
540
+ }
541
+
542
+ var modifierType string
543
+ if len (variableAttrs ) > 0 {
544
+ modifierType = "Object"
545
+ } else {
546
+ modifierType = "Bool"
547
+ }
548
+
549
+ attribute := attributeCtx {
550
+ Name : name ,
551
+ SchemaType : schemaType ,
552
+ Description : data .Description ,
553
+ Required : false ,
554
+ Attributes : variableAttrs ,
555
+ ModifierType : modifierType ,
556
+ }
557
+ attributes = append (attributes , attribute )
558
+ }
559
+
560
+ topAttribute := attributeCtx {
561
+ Name : "location" ,
562
+ SchemaType : "rsschema.SingleNestedAttribute" ,
563
+ Description : "The location of this object." ,
564
+ Required : true ,
565
+ Attributes : attributes ,
566
+ ModifierType : "Object" ,
567
+ }
568
+
569
+ type context struct {
570
+ StructName string
571
+ Schema attributeCtx
572
+ }
573
+
574
+ data := context {
575
+ StructName : names .StructName ,
576
+ Schema : topAttribute ,
577
+ }
578
+
579
+ return processTemplate (locationSchemaGetterTmpl , "render-location-schema-getter" , data , commonFuncMap )
580
+ }
581
+
582
+ type locationFieldCtx struct {
583
+ Name string
584
+ Type string
585
+ }
586
+
587
+ type locationCtx struct {
588
+ Name string
589
+ TerraformStructName string
590
+ PangoStructName string
591
+ IsBool bool
592
+ Fields []locationFieldCtx
593
+ }
594
+
595
+ func renderLocationsGetContext (names * NameProvider , spec * properties.Normalization ) []locationCtx {
596
+ var locations []locationCtx
597
+
598
+ for _ , location := range spec .Locations {
599
+ var fields []locationFieldCtx
600
+ for _ , variable := range location .Vars {
601
+ fields = append (fields , locationFieldCtx {
602
+ Name : variable .Name .CamelCase ,
603
+ Type : "String" ,
604
+ })
605
+ }
606
+ locations = append (locations , locationCtx {
607
+ Name : location .Name .CamelCase ,
608
+ TerraformStructName : fmt .Sprintf ("%s%sLocation" , names .StructName , location .Name .CamelCase ),
609
+ PangoStructName : fmt .Sprintf ("%s.%sLocation" , names .PackageName , location .Name .CamelCase ),
610
+ IsBool : len (location .Vars ) == 0 ,
611
+ Fields : fields ,
612
+ })
613
+ }
614
+
615
+ type context struct {
616
+ Locations []locationCtx
617
+ }
618
+
619
+ return locations
620
+ }
621
+
622
+ const locationsPangoToState = `
623
+ {{- range .Locations }}
624
+ {{- if .IsBool }}
625
+ if loc.Location.{{ .Name }} {
626
+ state.Location.{{ .Name }} = types.BoolValue(true)
627
+ }
628
+ {{- else }}
629
+ if loc.Location.{{ .Name }} != nil {
630
+ location := &{{ .TerraformStructName }}{
631
+ {{ $locationName := .Name }}
632
+ {{- range .Fields }}
633
+ {{ .Name }}: types.{{ .Type }}Value(loc.Location.{{ $locationName }}.{{ .Name }}),
634
+ {{- end }}
635
+ }
636
+ state.Location.{{ .Name }} = location
637
+ }
638
+ {{- end }}
639
+ {{- end }}
640
+ `
641
+
642
+ func RenderLocationsPangoToState (names * NameProvider , spec * properties.Normalization ) (string , error ) {
643
+ type context struct {
644
+ Locations []locationCtx
645
+ }
646
+ data := context {Locations : renderLocationsGetContext (names , spec )}
647
+ return processTemplate (locationsPangoToState , "render-locations-pango-to-state" , data , commonFuncMap )
648
+ }
649
+
650
+ const locationsStateToPango = `
651
+ {{- range .Locations }}
652
+ {{- if .IsBool }}
653
+ if !state.Location.{{ .Name }}.IsNull() && state.Location.{{ .Name }}.ValueBool() {
654
+ loc.Location.{{ .Name }} = true
655
+ }
656
+ {{- else }}
657
+ if state.Location.{{ .Name }} != nil {
658
+ location := &{{ .PangoStructName }}{
659
+ {{ $locationName := .Name }}
660
+ {{- range .Fields }}
661
+ {{ .Name }}: state.Location.{{ $locationName }}.{{ .Name }}.ValueString(),
662
+ {{- end }}
663
+ }
664
+ loc.Location.{{ .Name }} = location
665
+ }
666
+ {{- end }}
667
+ {{- end }}
668
+ `
669
+
670
+ func RenderLocationsStateToPango (names * NameProvider , spec * properties.Normalization ) (string , error ) {
671
+ type context struct {
672
+ Locations []locationCtx
673
+ }
674
+ data := context {Locations : renderLocationsGetContext (names , spec )}
675
+ return processTemplate (locationsStateToPango , "render-locations-state-to-pango" , data , commonFuncMap )
676
+ }
677
+
678
+ func ResourceCreateFunction (names * NameProvider , serviceName string , paramSpec * properties.Normalization , terraformProvider * properties.TerraformProviderFile , resourceSDKName string ) (string , error ) {
379
679
funcMap := template.FuncMap {
380
- "ConfigToEntry" : ConfigEntry ,
680
+ "ConfigToEntry" : ConfigEntry ,
681
+ "RenderLocationsStateToPango" : func () (string , error ) { return RenderLocationsStateToPango (names , paramSpec ) },
381
682
"ResourceParamToSchema" : func (paramName string , paramParameters properties.SpecParam ) (string , error ) {
382
683
return ParamToSchemaResource (paramName , paramParameters , terraformProvider )
383
684
},
@@ -388,7 +689,7 @@ func ResourceCreateFunction(structName string, serviceName string, paramSpec *pr
388
689
}
389
690
390
691
data := map [string ]interface {}{
391
- "structName" : structName ,
692
+ "structName" : names . ResourceStructName ,
392
693
"serviceName" : naming .CamelCase ("" , serviceName , "" , false ),
393
694
"paramSpec" : paramSpec .Spec ,
394
695
"resourceSDKName" : resourceSDKName ,
@@ -398,33 +699,42 @@ func ResourceCreateFunction(structName string, serviceName string, paramSpec *pr
398
699
return processTemplate (resourceCreateFunction , "resource-create-function" , data , funcMap )
399
700
}
400
701
401
- func ResourceReadFunction (structName string , serviceName string , paramSpec * properties.Normalization , resourceSDKName string ) (string , error ) {
702
+ func ResourceReadFunction (names * NameProvider , serviceName string , paramSpec * properties.Normalization , resourceSDKName string ) (string , error ) {
402
703
if strings .Contains (serviceName , "group" ) {
403
704
serviceName = "group"
404
705
}
405
706
406
707
data := map [string ]interface {}{
407
- "structName" : structName ,
408
- "serviceName" : naming .CamelCase ("" , serviceName , "" , false ),
409
- "resourceSDKName" : resourceSDKName ,
410
- "locations" : paramSpec .Locations ,
708
+ "structName" : names .StructName ,
709
+ "resourceStructName" : names .ResourceStructName ,
710
+ "serviceName" : naming .CamelCase ("" , serviceName , "" , false ),
711
+ "resourceSDKName" : resourceSDKName ,
712
+ "locations" : paramSpec .Locations ,
411
713
}
412
714
413
- return processTemplate (resourceReadFunction , "resource-read-function" , data , nil )
715
+ funcMap := template.FuncMap {
716
+ "RenderLocationsPangoToState" : func () (string , error ) { return RenderLocationsPangoToState (names , paramSpec ) },
717
+ }
718
+
719
+ return processTemplate (resourceReadFunction , "resource-read-function" , data , funcMap )
414
720
}
415
721
416
- func ResourceUpdateFunction (structName string , serviceName string , paramSpec interface {} , resourceSDKName string ) (string , error ) {
722
+ func ResourceUpdateFunction (names * NameProvider , serviceName string , paramSpec * properties. Normalization , resourceSDKName string ) (string , error ) {
417
723
if strings .Contains (serviceName , "group" ) {
418
724
serviceName = "group"
419
725
}
420
726
421
727
data := map [string ]interface {}{
422
- "structName" : structName ,
728
+ "structName" : names . ResourceStructName ,
423
729
"serviceName" : naming .CamelCase ("" , serviceName , "" , false ),
424
730
"resourceSDKName" : resourceSDKName ,
425
731
}
426
732
427
- return processTemplate (resourceUpdateFunction , "resource-update-function" , data , nil )
733
+ funcMap := template.FuncMap {
734
+ "RenderLocationsStateToPango" : func () (string , error ) { return RenderLocationsStateToPango (names , paramSpec ) },
735
+ }
736
+
737
+ return processTemplate (resourceUpdateFunction , "resource-update-function" , data , funcMap )
428
738
}
429
739
430
740
func ResourceDeleteFunction (structName string , serviceName string , paramSpec interface {}, resourceSDKName string ) (string , error ) {
0 commit comments