@@ -9,12 +9,14 @@ import (
9
9
"strings"
10
10
"time"
11
11
12
+ "github.com/YakDriver/regexache"
12
13
"github.com/aws/aws-sdk-go-v2/aws"
13
14
"github.com/aws/aws-sdk-go-v2/service/odb"
14
15
odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types"
15
16
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
16
17
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
17
18
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
19
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
18
20
"github.com/hashicorp/terraform-plugin-framework/path"
19
21
"github.com/hashicorp/terraform-plugin-framework/resource"
20
22
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -55,6 +57,7 @@ func newResourceCloudVmCluster(_ context.Context) (resource.ResourceWithConfigur
55
57
56
58
const (
57
59
ResNameCloudVmCluster = "Cloud Vm Cluster"
60
+ MajorGiVersionPattern = `^\d+\.0\.0\.0$`
58
61
)
59
62
60
63
var ResourceCloudVmCluster = newResourceCloudVmCluster
@@ -70,6 +73,9 @@ func (r *resourceCloudVmCluster) Schema(ctx context.Context, req resource.Schema
70
73
licenseModelType := fwtypes .StringEnumType [odbtypes.LicenseModel ]()
71
74
diskRedundancyType := fwtypes .StringEnumType [odbtypes.DiskRedundancy ]()
72
75
computeModelType := fwtypes .StringEnumType [odbtypes.ComputeModel ]()
76
+ giVersionValidator := []validator.String {
77
+ stringvalidator .RegexMatches (regexache .MustCompile (MajorGiVersionPattern ), "Gi version must be of the format 19.0.0.0" ),
78
+ }
73
79
resp .Schema = schema.Schema {
74
80
Attributes : map [string ]schema.Attribute {
75
81
names .AttrARN : framework .ARNAttributeComputedOnly (),
@@ -98,11 +104,9 @@ func (r *resourceCloudVmCluster) Schema(ctx context.Context, req resource.Schema
98
104
Description : "The number of CPU cores to enable on the VM cluster. Changing this will create a new resource." ,
99
105
},
100
106
"data_storage_size_in_tbs" : schema.Float64Attribute {
101
- Optional : true ,
102
- Computed : true ,
107
+ Required : true ,
103
108
PlanModifiers : []planmodifier.Float64 {
104
109
float64planmodifier .RequiresReplace (),
105
- float64planmodifier .UseStateForUnknown (),
106
110
},
107
111
Description : "The size of the data disk group, in terabytes (TBs), to allocate for the VM cluster. Changing this will create a new resource." ,
108
112
},
@@ -151,8 +155,18 @@ func (r *resourceCloudVmCluster) Schema(ctx context.Context, req resource.Schema
151
155
PlanModifiers : []planmodifier.String {
152
156
stringplanmodifier .RequiresReplace (),
153
157
},
158
+ //Note: underlying API only accepts major gi_version.
159
+ Validators : giVersionValidator ,
154
160
Description : "A valid software version of Oracle Grid Infrastructure (GI). To get the list of valid values, use the ListGiVersions operation and specify the shape of the Exadata infrastructure. Example: 19.0.0.0 This member is required. Changing this will create a new resource." ,
155
161
},
162
+ //Underlying API returns complete gi version. For example if gi_version 23.0.0.0 then underlying api returns a version starting with 23
163
+ "gi_version_computed" : schema.StringAttribute {
164
+ Computed : true ,
165
+ PlanModifiers : []planmodifier.String {
166
+ stringplanmodifier .UseStateForUnknown (),
167
+ },
168
+ Description : "A complete software version of Oracle Grid Infrastructure (GI)." ,
169
+ },
156
170
//Underlying API treats Hostname as hostname prefix. Therefore, explicitly setting it. API also returns new hostname prefix by appending the input hostname
157
171
//prefix. Therefore, we have hostname_prefix and hostname_prefix_computed
158
172
"hostname_prefix_computed" : schema.StringAttribute {
@@ -475,7 +489,17 @@ func (r *resourceCloudVmCluster) Create(ctx context.Context, req resource.Create
475
489
plan .HostnamePrefix = types .StringValue (hostnamePrefix )
476
490
plan .HostnamePrefixComputed = types .StringValue (* createdVmCluster .Hostname )
477
491
//scan listener port not returned by API directly
478
- plan .ScanListenerPortTcp = types .Int32PointerValue (createdVmCluster .ListenerPort )
492
+ plan .ScanListenerPortTcp = flex .Int32ToFramework (ctx , createdVmCluster .ListenerPort )
493
+ plan .GiVersionComputed = flex .StringToFramework (ctx , createdVmCluster .GiVersion )
494
+ giVersionMajor , err := getMajorGiVersion (createdVmCluster .GiVersion )
495
+ if err != nil {
496
+ resp .Diagnostics .AddError (
497
+ create .ProblemStandardMessage (names .ODB , create .ErrActionWaitingForCreation , ResNameCloudVmCluster , plan .DisplayName .ValueString (), err ),
498
+ err .Error (),
499
+ )
500
+ return
501
+ }
502
+ plan .GiVersion = flex .StringToFramework (ctx , giVersionMajor )
479
503
resp .Diagnostics .Append (flex .Flatten (ctx , createdVmCluster , & plan )... )
480
504
if resp .Diagnostics .HasError () {
481
505
return
@@ -508,8 +532,17 @@ func (r *resourceCloudVmCluster) Read(ctx context.Context, req resource.ReadRequ
508
532
state .HostnamePrefix = types .StringValue (hostnamePrefix )
509
533
state .HostnamePrefixComputed = types .StringValue (* out .Hostname )
510
534
//scan listener port not returned by API directly
511
- state .ScanListenerPortTcp = types .Int32PointerValue (out .ListenerPort )
512
-
535
+ state .ScanListenerPortTcp = flex .Int32ToFramework (ctx , out .ListenerPort )
536
+ state .GiVersionComputed = flex .StringToFramework (ctx , out .GiVersion )
537
+ giVersionMajor , err := getMajorGiVersion (out .GiVersion )
538
+ if err != nil {
539
+ resp .Diagnostics .AddError (
540
+ create .ProblemStandardMessage (names .ODB , create .ErrActionWaitingForCreation , ResNameCloudVmCluster , state .CloudVmClusterId .ValueString (), err ),
541
+ err .Error (),
542
+ )
543
+ return
544
+ }
545
+ state .GiVersion = flex .StringToFramework (ctx , giVersionMajor )
513
546
resp .Diagnostics .Append (flex .Flatten (ctx , out , & state )... )
514
547
if resp .Diagnostics .HasError () {
515
548
return
@@ -620,6 +653,16 @@ func FindCloudVmClusterForResourceByID(ctx context.Context, conn *odb.Client, id
620
653
}
621
654
return out .CloudVmCluster , nil
622
655
}
656
+ func getMajorGiVersion (giVersionComputed * string ) (* string , error ) {
657
+ giVersionMajor := strings .Split (* giVersionComputed , "." )[0 ]
658
+ giVersionMajor = giVersionMajor + ".0.0.0"
659
+ regxGiVersionMajor := regexache .MustCompile (MajorGiVersionPattern )
660
+ if ! regxGiVersionMajor .MatchString (giVersionMajor ) {
661
+ err := errors .New ("gi_version major retrieved from gi_version_computed does not match the pattern 19.0.0.0" )
662
+ return nil , err
663
+ }
664
+ return & giVersionMajor , nil
665
+ }
623
666
624
667
type cloudVmClusterResourceModel struct {
625
668
framework.WithRegionModel
@@ -635,7 +678,8 @@ type cloudVmClusterResourceModel struct {
635
678
DiskRedundancy fwtypes.StringEnum [odbtypes.DiskRedundancy ] `tfsdk:"disk_redundancy"`
636
679
DisplayName types.String `tfsdk:"display_name"`
637
680
Domain types.String `tfsdk:"domain"`
638
- GiVersion types.String `tfsdk:"gi_version"`
681
+ GiVersion types.String `tfsdk:"gi_version" autoflex:",noflatten"`
682
+ GiVersionComputed types.String `tfsdk:"gi_version_computed" autoflex:",noflatten"`
639
683
HostnamePrefixComputed types.String `tfsdk:"hostname_prefix_computed" autoflex:",noflatten"`
640
684
HostnamePrefix types.String `tfsdk:"hostname_prefix" autoflex:"-"`
641
685
IormConfigCache fwtypes.ListNestedObjectValueOf [cloudVMCExadataIormConfigResourceModel ] `tfsdk:"iorm_config_cache"`
0 commit comments