8383 NamespaceLifecycle internaltypes.ZeroObjectValue `tfsdk:"namespace_lifecycle"`
8484 ConnectivityRuleIds internaltypes.UnorderedStringListValue `tfsdk:"connectivity_rule_ids"`
8585 Timeouts timeouts.Value `tfsdk:"timeouts"`
86+ Capacity internaltypes.ZeroObjectValue `tfsdk:"capacity"`
8687 }
8788
8889 lifecycleModel struct {
@@ -107,6 +108,11 @@ type (
107108 GrpcAddress types.String `tfsdk:"grpc_address"`
108109 MtlsGrpcAddress types.String `tfsdk:"mtls_grpc_address"`
109110 }
111+
112+ capacityModel struct {
113+ Mode types.String `tfsdk:"mode"`
114+ Value types.Float64 `tfsdk:"value"`
115+ }
110116)
111117
112118var (
@@ -136,6 +142,11 @@ var (
136142 "grpc_address" : types .StringType ,
137143 "mtls_grpc_address" : types .StringType ,
138144 }
145+
146+ capacityAttrs = map [string ]attr.Type {
147+ "mode" : types .StringType ,
148+ "value" : types .Float64Type ,
149+ }
139150)
140151
141152func NewNamespaceResource () resource.Resource {
@@ -304,6 +315,25 @@ func (r *namespaceResource) Schema(ctx context.Context, _ resource.SchemaRequest
304315 listvalidator .SizeAtLeast (1 ),
305316 },
306317 },
318+ "capacity" : schema.SingleNestedAttribute {
319+ Optional : true ,
320+ Description : "The capacity configuration for the namespace." ,
321+ CustomType : internaltypes.ZeroObjectType {
322+ ObjectType : basetypes.ObjectType {
323+ AttrTypes : capacityAttrs ,
324+ },
325+ },
326+ Attributes : map [string ]schema.Attribute {
327+ "mode" : schema.StringAttribute {
328+ Description : "The mode of the capacity configuration. Must be one of 'provisioned' or 'on_demand'." ,
329+ Optional : true ,
330+ },
331+ "value" : schema.Float64Attribute {
332+ Description : "The value of the capacity configuration. Must be set when mode is 'provisioned'." ,
333+ Optional : true ,
334+ },
335+ },
336+ },
307337 },
308338 Blocks : map [string ]schema.Block {
309339 "timeouts" : timeouts .Block (ctx , timeouts.Opts {
@@ -376,6 +406,19 @@ func (r *namespaceResource) Create(ctx context.Context, req resource.CreateReque
376406 ConnectivityRuleIds : connectivityRuleIds ,
377407 }
378408
409+ if ! plan .Capacity .IsNull () {
410+ resp .Diagnostics .AddError ("Capacity on namespace creation is not supported" , "capacity should be null or not set when creating a namespace" )
411+ return
412+ // This will be enabled when capacity on namespace creation is supported
413+ // var d diag.Diagnostics
414+ // capacitySpec, d := getCapacityFromModel(ctx, &plan)
415+ // resp.Diagnostics.Append(d...)
416+ // if resp.Diagnostics.HasError() {
417+ // return
418+ // }
419+ // spec.CapacitySpec = capacitySpec
420+ }
421+
379422 if ! plan .ApiKeyAuth .ValueBool () && plan .AcceptedClientCA .IsNull () {
380423 resp .Diagnostics .AddError ("Namespace not configured with authentication" , "accepted_client_ca or api_key_auth must be set" )
381424 return
@@ -571,6 +614,16 @@ func (r *namespaceResource) Update(ctx context.Context, req resource.UpdateReque
571614 spec .MtlsAuth = mtls
572615 }
573616
617+ if ! plan .Capacity .IsNull () {
618+ var d diag.Diagnostics
619+ capacitySpec , d := getCapacityFromModel (ctx , & plan )
620+ resp .Diagnostics .Append (d ... )
621+ if resp .Diagnostics .HasError () {
622+ return
623+ }
624+ spec .CapacitySpec = capacitySpec
625+ }
626+
574627 if ! areRegionsEqual (currentNs .GetNamespace ().GetSpec ().GetRegions (), spec .Regions ) {
575628 resp .Diagnostics .AddError ("Namespace regions cannot be changed" , "Changing the regions of a namespace is not supported currently via terraform." )
576629 return
@@ -824,8 +877,41 @@ func updateModelFromSpec(
824877 connectivityRuleIdsState = internaltypes.UnorderedStringListValue {
825878 ListValue : planConnectivityRuleIds ,
826879 }
880+ }
827881
882+ capacitySpec := ns .GetSpec ().GetCapacitySpec ()
883+ if capacitySpec != nil {
884+ var capacityMode types.String
885+ var capacityValue types.Float64
886+ if capacitySpec .GetOnDemand () != nil {
887+ capacityMode = types .StringValue ("on_demand" )
888+ // For on_demand mode, set value to 0 if it's in the current state, otherwise leave it null
889+ if ! state .Capacity .IsNull () {
890+ var currentCapacity capacityModel
891+ diags .Append (state .Capacity .As (ctx , & currentCapacity , basetypes.ObjectAsOptions {})... )
892+ if ! diags .HasError () && ! currentCapacity .Value .IsNull () {
893+ // Preserve the value from state if it exists
894+ capacityValue = currentCapacity .Value
895+ }
896+ }
897+ } else if capacitySpec .GetProvisioned () != nil {
898+ capacityMode = types .StringValue ("provisioned" )
899+ capacityValue = types .Float64Value (capacitySpec .GetProvisioned ().GetValue ())
900+ }
901+ cp , objectDiags := types .ObjectValueFrom (ctx , capacityAttrs , & capacityModel {
902+ Mode : capacityMode ,
903+ Value : capacityValue ,
904+ })
905+ capacity := internaltypes.ZeroObjectValue {ObjectValue : cp }
906+ diags .Append (objectDiags ... )
907+ if diags .HasError () {
908+ return diags
909+ }
910+ state .Capacity = capacity
911+ } else {
912+ state .Capacity = internaltypes.ZeroObjectValue {ObjectValue : types .ObjectNull (capacityAttrs )}
828913 }
914+
829915 state .ConnectivityRuleIds = connectivityRuleIdsState
830916 state .Endpoints = endpointsState
831917 state .Regions = planRegionsUnordered
@@ -893,6 +979,38 @@ func getLifecycleFromModel(ctx context.Context, model *namespaceResourceModel) (
893979 }, diags
894980}
895981
982+ func getCapacityFromModel (ctx context.Context , model * namespaceResourceModel ) (* namespacev1.CapacitySpec , diag.Diagnostics ) {
983+ var diags diag.Diagnostics
984+ var capacity capacityModel
985+ diags .Append (model .Capacity .As (ctx , & capacity , basetypes.ObjectAsOptions {})... )
986+ if diags .HasError () {
987+ return nil , diags
988+ }
989+ switch capacity .Mode .ValueString () {
990+ case "provisioned" :
991+ if capacity .Value .IsNull () || capacity .Value .ValueFloat64 () <= 0 {
992+ diags .Append (diag .NewErrorDiagnostic ("Invalid capacity value" , "Capacity value must be set when mode is 'provisioned'" ))
993+ return nil , diags
994+ }
995+ return & namespacev1.CapacitySpec {
996+ Spec : & namespacev1.CapacitySpec_Provisioned_ {
997+ Provisioned : & namespacev1.CapacitySpec_Provisioned {
998+ Value : capacity .Value .ValueFloat64 (),
999+ },
1000+ },
1001+ }, diags
1002+ case "on_demand" :
1003+ return & namespacev1.CapacitySpec {
1004+ Spec : & namespacev1.CapacitySpec_OnDemand_ {
1005+ OnDemand : & namespacev1.CapacitySpec_OnDemand {},
1006+ },
1007+ }, diags
1008+ default :
1009+ diags .Append (diag .NewErrorDiagnostic ("Invalid capacity mode" , "Invalid capacity mode: " + capacity .Mode .ValueString ()))
1010+ return nil , diags
1011+ }
1012+ }
1013+
8961014func stringOrNull (s string ) types.String {
8971015 if s == "" {
8981016 return types .StringNull ()
0 commit comments