@@ -63,7 +63,7 @@ type Cluster struct {
6363 NodePools types.List `tfsdk:"node_pools"`
6464 Maintenance types.Object `tfsdk:"maintenance"`
6565 Hibernations types.List `tfsdk:"hibernations"`
66- Extensions * Extensions `tfsdk:"extensions"`
66+ Extensions types. Object `tfsdk:"extensions"`
6767 KubeConfig types.String `tfsdk:"kube_config"`
6868}
6969
@@ -147,21 +147,39 @@ var hibernationTypes = map[string]attr.Type{
147147 "timezone" : basetypes.StringType {},
148148}
149149
150- type Extensions struct {
151- Argus * ArgusExtension `tfsdk:"argus"`
152- ACL * ACL `tfsdk:"acl"`
150+ type extensions struct {
151+ Argus types. Object `tfsdk:"argus"`
152+ ACL types. Object `tfsdk:"acl"`
153153}
154154
155- type ACL struct {
155+ // Types corresponding to extensions
156+ var extensionsTypes = map [string ]attr.Type {
157+ "argus" : basetypes.ObjectType {AttrTypes : argusExtensionTypes },
158+ "acl" : basetypes.ObjectType {AttrTypes : aclTypes },
159+ }
160+
161+ type acl struct {
156162 Enabled types.Bool `tfsdk:"enabled"`
157163 AllowedCIDRs types.List `tfsdk:"allowed_cidrs"`
158164}
159165
160- type ArgusExtension struct {
166+ // Types corresponding to acl
167+ var aclTypes = map [string ]attr.Type {
168+ "enabled" : basetypes.BoolType {},
169+ "allowed_cidrs" : basetypes.ListType {ElemType : types .StringType },
170+ }
171+
172+ type argusExtension struct {
161173 Enabled types.Bool `tfsdk:"enabled"`
162174 ArgusInstanceId types.String `tfsdk:"argus_instance_id"`
163175}
164176
177+ // Types corresponding to argusExtension
178+ var argusExtensionTypes = map [string ]attr.Type {
179+ "enabled" : basetypes.BoolType {},
180+ "argus_instance_id" : basetypes.StringType {},
181+ }
182+
165183// NewClusterResource is a helper function to simplify the provider implementation.
166184func NewClusterResource () resource.Resource {
167185 return & clusterResource {}
@@ -771,28 +789,54 @@ func toHibernationsPayload(ctx context.Context, m *Cluster) (*ske.Hibernation, e
771789}
772790
773791func toExtensionsPayload (ctx context.Context , m * Cluster ) (* ske.Extension , error ) {
774- if m .Extensions == nil {
792+ if m .Extensions . IsNull () || m . Extensions . IsUnknown () {
775793 return nil , nil
776794 }
777- ex := & ske.Extension {}
778- if m .Extensions .Argus != nil {
779- ex .Argus = & ske.Argus {
780- Enabled : conversion .BoolValueToPointer (m .Extensions .Argus .Enabled ),
781- ArgusInstanceId : conversion .StringValueToPointer (m .Extensions .Argus .ArgusInstanceId ),
782- }
795+ ex := extensions {}
796+ diags := m .Extensions .As (ctx , & ex , basetypes.ObjectAsOptions {})
797+ if diags .HasError () {
798+ return nil , fmt .Errorf ("converting extensions object: %v" , diags .Errors ())
783799 }
784- if m .Extensions .ACL != nil {
800+
801+ var skeAcl * ske.ACL
802+ if ! (ex .ACL .IsNull () || ex .ACL .IsUnknown ()) {
803+ acl := acl {}
804+ diags = ex .ACL .As (ctx , & acl , basetypes.ObjectAsOptions {})
805+ if diags .HasError () {
806+ return nil , fmt .Errorf ("converting extensions.acl object: %v" , diags .Errors ())
807+ }
808+ aclEnabled := conversion .BoolValueToPointer (acl .Enabled )
809+
785810 cidrs := []string {}
786- diags := m . Extensions . ACL .AllowedCIDRs .ElementsAs (ctx , & cidrs , true )
811+ diags = acl .AllowedCIDRs .ElementsAs (ctx , & cidrs , true )
787812 if diags .HasError () {
788- return nil , fmt .Errorf ("error in extension object converion %v" , diags .Errors ())
813+ return nil , fmt .Errorf ("converting extensions.acl.cidrs object: %v" , diags .Errors ())
789814 }
790- ex . Acl = & ske.ACL {
791- Enabled : conversion . BoolValueToPointer ( m . Extensions . ACL . Enabled ) ,
815+ skeAcl = & ske.ACL {
816+ Enabled : aclEnabled ,
792817 AllowedCidrs : & cidrs ,
793818 }
794819 }
795- return ex , nil
820+
821+ var skeArgusExtension * ske.Argus
822+ if ! (ex .Argus .IsNull () || ex .Argus .IsUnknown ()) {
823+ argus := argusExtension {}
824+ diags = ex .ACL .As (ctx , & argus , basetypes.ObjectAsOptions {})
825+ if diags .HasError () {
826+ return nil , fmt .Errorf ("converting extensions.acl object: %v" , diags .Errors ())
827+ }
828+ argusEnabled := conversion .BoolValueToPointer (argus .Enabled )
829+ argusInstanceId := conversion .StringValueToPointer (argus .ArgusInstanceId )
830+ skeArgusExtension = & ske.Argus {
831+ Enabled : argusEnabled ,
832+ ArgusInstanceId : argusInstanceId ,
833+ }
834+ }
835+
836+ return & ske.Extension {
837+ Acl : skeAcl ,
838+ Argus : skeArgusExtension ,
839+ }, nil
796840}
797841
798842func toMaintenancePayload (ctx context.Context , m * Cluster ) (* ske.Maintenance , error ) {
@@ -803,7 +847,7 @@ func toMaintenancePayload(ctx context.Context, m *Cluster) (*ske.Maintenance, er
803847 maintenance := Maintenance {}
804848 diags := m .Maintenance .As (ctx , & maintenance , basetypes.ObjectAsOptions {})
805849 if diags .HasError () {
806- return nil , fmt .Errorf ("error in maintenance object conversion %v" , diags .Errors ())
850+ return nil , fmt .Errorf ("converting maintenance object: %v" , diags .Errors ())
807851 }
808852
809853 var timeWindowStart * string
@@ -870,7 +914,7 @@ func mapFields(ctx context.Context, cl *ske.ClusterResponse, m *Cluster) error {
870914 m .AllowPrivilegedContainers = types .BoolPointerValue (cl .Kubernetes .AllowPrivilegedContainers )
871915 }
872916
873- err := mapNodePools (cl , m )
917+ err := mapNodePools (ctx , cl , m )
874918 if err != nil {
875919 return fmt .Errorf ("mapping node_pools: %w" , err )
876920 }
@@ -882,11 +926,14 @@ func mapFields(ctx context.Context, cl *ske.ClusterResponse, m *Cluster) error {
882926 if err != nil {
883927 return fmt .Errorf ("mapping hibernations: %w" , err )
884928 }
885- mapExtensions (cl , m )
929+ err = mapExtensions (ctx , cl , m )
930+ if err != nil {
931+ return fmt .Errorf ("mapping extensions: %w" , err )
932+ }
886933 return nil
887934}
888935
889- func mapNodePools (cl * ske.ClusterResponse , m * Cluster ) error {
936+ func mapNodePools (ctx context. Context , cl * ske.ClusterResponse , m * Cluster ) error {
890937 if cl .Nodepools == nil {
891938 m .NodePools = types .ListNull (types.ObjectType {AttrTypes : nodePoolTypes })
892939 return nil
@@ -941,11 +988,7 @@ func mapNodePools(cl *ske.ClusterResponse, m *Cluster) error {
941988 }
942989
943990 if nodePoolResp .AvailabilityZones != nil {
944- elems := []attr.Value {}
945- for _ , v := range * nodePoolResp .AvailabilityZones {
946- elems = append (elems , types .StringValue (v ))
947- }
948- elemsTF , diags := types .ListValue (types .StringType , elems )
991+ elemsTF , diags := types .ListValueFrom (ctx , types .StringType , * nodePoolResp .AvailabilityZones )
949992 if diags .HasError () {
950993 return fmt .Errorf ("mapping index %d, field availability_zones: %w" , i , core .DiagsToError (diags ))
951994 }
@@ -1026,7 +1069,7 @@ func mapHibernations(cl *ske.ClusterResponse, m *Cluster) error {
10261069}
10271070
10281071func mapMaintenance (ctx context.Context , cl * ske.ClusterResponse , m * Cluster ) error {
1029- // Aligned with SKE team that a flattened data structure is fine, because not extensions are planned.
1072+ // Aligned with SKE team that a flattened data structure is fine, because no extensions are planned.
10301073 if cl .Maintenance == nil {
10311074 m .Maintenance = types .ObjectNull (maintenanceTypes )
10321075 return nil
@@ -1041,7 +1084,7 @@ func mapMaintenance(ctx context.Context, cl *ske.ClusterResponse, m *Cluster) er
10411084 }
10421085 startTime , endTime , err := getMaintenanceTimes (ctx , cl , m )
10431086 if err != nil {
1044- return fmt .Errorf ("failed to get maintenance times: %w" , err )
1087+ return fmt .Errorf ("getting maintenance times: %w" , err )
10451088 }
10461089 maintenanceValues := map [string ]attr.Value {
10471090 "enable_kubernetes_version_updates" : ekvu ,
@@ -1051,7 +1094,7 @@ func mapMaintenance(ctx context.Context, cl *ske.ClusterResponse, m *Cluster) er
10511094 }
10521095 maintenanceObject , diags := types .ObjectValue (maintenanceTypes , maintenanceValues )
10531096 if diags .HasError () {
1054- return fmt .Errorf ("failed to create flavor: %w" , core .DiagsToError (diags ))
1097+ return fmt .Errorf ("creating flavor: %w" , core .DiagsToError (diags ))
10551098 }
10561099 m .Maintenance = maintenanceObject
10571100 return nil
@@ -1060,11 +1103,11 @@ func mapMaintenance(ctx context.Context, cl *ske.ClusterResponse, m *Cluster) er
10601103func getMaintenanceTimes (ctx context.Context , cl * ske.ClusterResponse , m * Cluster ) (startTime , endTime string , err error ) {
10611104 startTimeAPI , err := time .Parse (time .RFC3339 , * cl .Maintenance .TimeWindow .Start )
10621105 if err != nil {
1063- return "" , "" , fmt .Errorf ("failed to parse start time '%s' from API response as RFC3339 datetime: %w" , * cl .Maintenance .TimeWindow .Start , err )
1106+ return "" , "" , fmt .Errorf ("parsing start time '%s' from API response as RFC3339 datetime: %w" , * cl .Maintenance .TimeWindow .Start , err )
10641107 }
10651108 endTimeAPI , err := time .Parse (time .RFC3339 , * cl .Maintenance .TimeWindow .End )
10661109 if err != nil {
1067- return "" , "" , fmt .Errorf ("failed to parse end time '%s' from API response as RFC3339 datetime: %w" , * cl .Maintenance .TimeWindow .End , err )
1110+ return "" , "" , fmt .Errorf ("parsing end time '%s' from API response as RFC3339 datetime: %w" , * cl .Maintenance .TimeWindow .End , err )
10681111 }
10691112
10701113 if m .Maintenance .IsNull () || m .Maintenance .IsUnknown () {
@@ -1074,15 +1117,15 @@ func getMaintenanceTimes(ctx context.Context, cl *ske.ClusterResponse, m *Cluste
10741117 maintenance := & Maintenance {}
10751118 diags := m .Maintenance .As (ctx , maintenance , basetypes.ObjectAsOptions {})
10761119 if diags .HasError () {
1077- return "" , "" , fmt .Errorf ("error in maintenance object conversion %w" , core .DiagsToError (diags .Errors ()))
1120+ return "" , "" , fmt .Errorf ("converting maintenance object %w" , core .DiagsToError (diags .Errors ()))
10781121 }
10791122
10801123 if maintenance .Start .IsNull () || maintenance .Start .IsUnknown () {
10811124 startTime = startTimeAPI .Format ("15:04:05Z07:00" )
10821125 } else {
10831126 startTimeTF , err := time .Parse ("15:04:05Z07:00" , maintenance .Start .ValueString ())
10841127 if err != nil {
1085- return "" , "" , fmt .Errorf ("failed to parse start time '%s' from TF config as RFC time: %w" , maintenance .Start .ValueString (), err )
1128+ return "" , "" , fmt .Errorf ("parsing start time '%s' from TF config as RFC time: %w" , maintenance .Start .ValueString (), err )
10861129 }
10871130 if startTimeAPI .Format ("15:04:05Z07:00" ) != startTimeTF .Format ("15:04:05Z07:00" ) {
10881131 return "" , "" , fmt .Errorf ("start time '%v' from API response doesn't match start time '%v' from TF config" , * cl .Maintenance .TimeWindow .Start , maintenance .Start .ValueString ())
@@ -1095,7 +1138,7 @@ func getMaintenanceTimes(ctx context.Context, cl *ske.ClusterResponse, m *Cluste
10951138 } else {
10961139 endTimeTF , err := time .Parse ("15:04:05Z07:00" , maintenance .End .ValueString ())
10971140 if err != nil {
1098- return "" , "" , fmt .Errorf ("failed to parse end time '%s' from TF config as RFC time: %w" , maintenance .End .ValueString (), err )
1141+ return "" , "" , fmt .Errorf ("parsing end time '%s' from TF config as RFC time: %w" , maintenance .End .ValueString (), err )
10991142 }
11001143 if endTimeAPI .Format ("15:04:05Z07:00" ) != endTimeTF .Format ("15:04:05Z07:00" ) {
11011144 return "" , "" , fmt .Errorf ("end time '%v' from API response doesn't match end time '%v' from TF config" , * cl .Maintenance .TimeWindow .End , maintenance .End .ValueString ())
@@ -1106,32 +1149,70 @@ func getMaintenanceTimes(ctx context.Context, cl *ske.ClusterResponse, m *Cluste
11061149 return startTime , endTime , nil
11071150}
11081151
1109- func mapExtensions (cl * ske.ClusterResponse , m * Cluster ) {
1152+ func mapExtensions (ctx context. Context , cl * ske.ClusterResponse , m * Cluster ) error {
11101153 if cl .Extensions == nil || (cl .Extensions .Argus == nil && cl .Extensions .Acl == nil ) {
1111- return
1154+ m .Extensions = types .ObjectNull (extensionsTypes )
1155+ return nil
11121156 }
1113- if m .Extensions == nil {
1114- m .Extensions = & Extensions {}
1157+
1158+ var diags diag.Diagnostics
1159+ acl := types .ObjectNull (aclTypes )
1160+ if cl .Extensions .Acl != nil {
1161+ enabled := types .BoolNull ()
1162+ if cl .Extensions .Acl .Enabled != nil {
1163+ enabled = types .BoolValue (* cl .Extensions .Acl .Enabled )
1164+ }
1165+
1166+ cidrsList , diags := types .ListValueFrom (ctx , types .StringType , cl .Extensions .Acl .AllowedCidrs )
1167+ if diags .HasError () {
1168+ return fmt .Errorf ("creating allowed_cidrs list: %w" , core .DiagsToError (diags ))
1169+ }
1170+
1171+ aclValues := map [string ]attr.Value {
1172+ "enabled" : enabled ,
1173+ "allowed_cidrs" : cidrsList ,
1174+ }
1175+
1176+ acl , diags = types .ObjectValue (aclTypes , aclValues )
1177+ if diags .HasError () {
1178+ return fmt .Errorf ("creating acl: %w" , core .DiagsToError (diags ))
1179+ }
11151180 }
1181+
1182+ argusExtension := types .ObjectNull (argusExtensionTypes )
11161183 if cl .Extensions .Argus != nil {
1117- m . Extensions . Argus = & ArgusExtension {
1118- Enabled : types . BoolPointerValue ( cl .Extensions .Argus .Enabled ),
1119- ArgusInstanceId : types .StringPointerValue ( cl .Extensions .Argus .ArgusInstanceId ),
1184+ enabled := types . BoolNull ()
1185+ if cl .Extensions .Argus .Enabled != nil {
1186+ enabled = types .BoolValue ( * cl .Extensions .Argus .Enabled )
11201187 }
1121- }
11221188
1123- if cl .Extensions .Acl != nil {
1124- cidr := []attr.Value {}
1125- if cl .Extensions .Acl .AllowedCidrs != nil {
1126- for _ , v := range * cl .Extensions .Acl .AllowedCidrs {
1127- cidr = append (cidr , types .StringValue (v ))
1128- }
1189+ argusInstanceId := types .StringNull ()
1190+ if cl .Extensions .Argus .ArgusInstanceId != nil {
1191+ argusInstanceId = types .StringValue (* cl .Extensions .Argus .ArgusInstanceId )
1192+ }
1193+
1194+ argusExtensionValues := map [string ]attr.Value {
1195+ "enabled" : enabled ,
1196+ "argus_instance_id" : argusInstanceId ,
11291197 }
1130- m .Extensions .ACL = & ACL {
1131- Enabled : types .BoolPointerValue (cl .Extensions .Acl .Enabled ),
1132- AllowedCIDRs : types .ListValueMust (types .StringType , cidr ),
1198+
1199+ argusExtension , diags = types .ObjectValue (argusExtensionTypes , argusExtensionValues )
1200+ if diags .HasError () {
1201+ return fmt .Errorf ("creating argus extension: %w" , core .DiagsToError (diags ))
11331202 }
11341203 }
1204+
1205+ extensionsValues := map [string ]attr.Value {
1206+ "acl" : acl ,
1207+ "argus" : argusExtension ,
1208+ }
1209+
1210+ extensions , diags := types .ObjectValue (extensionsTypes , extensionsValues )
1211+ if diags .HasError () {
1212+ return fmt .Errorf ("creating extensions: %w" , core .DiagsToError (diags ))
1213+ }
1214+ m .Extensions = extensions
1215+ return nil
11351216}
11361217
11371218func toKubernetesPayload (m * Cluster , availableVersions []ske.KubernetesVersion ) (kubernetesPayload * ske.Kubernetes , hasDeprecatedVersion bool , err error ) {
0 commit comments