@@ -145,6 +145,9 @@ func (r *SettingsResource) Create(ctx context.Context, req resource.CreateReques
145145 if ! data .Auth .IsNull () {
146146 resp .Diagnostics .Append (updateAuthConfig (ctx , & data , r .client )... )
147147 }
148+ if ! data .Storage .IsNull () {
149+ resp .Diagnostics .Append (updateStorageConfig (ctx , & data , r .client )... )
150+ }
148151 // TODO: update all settings above concurrently
149152 if resp .Diagnostics .HasError () {
150153 return
@@ -183,6 +186,9 @@ func (r *SettingsResource) Read(ctx context.Context, req resource.ReadRequest, r
183186 if ! data .Auth .IsNull () {
184187 resp .Diagnostics .Append (readAuthConfig (ctx , & data , r .client )... )
185188 }
189+ if ! data .Storage .IsNull () {
190+ resp .Diagnostics .Append (readStorageConfig (ctx , & data , r .client )... )
191+ }
186192 // TODO: read all settings above concurrently
187193 if resp .Diagnostics .HasError () {
188194 return
@@ -223,6 +229,9 @@ func (r *SettingsResource) Update(ctx context.Context, req resource.UpdateReques
223229 if ! planData .Auth .IsNull () && ! planData .Auth .Equal (stateData .Auth ) {
224230 resp .Diagnostics .Append (updateAuthConfig (ctx , & planData , r .client )... )
225231 }
232+ if ! planData .Storage .IsNull () && ! planData .Storage .Equal (stateData .Storage ) {
233+ resp .Diagnostics .Append (updateStorageConfig (ctx , & planData , r .client )... )
234+ }
226235 // TODO: update all settings above concurrently
227236 if resp .Diagnostics .HasError () {
228237 return
@@ -253,6 +262,7 @@ func (r *SettingsResource) ImportState(ctx context.Context, req resource.ImportS
253262 resp .Diagnostics .Append (readNetworkConfig (ctx , & data , r .client )... )
254263 resp .Diagnostics .Append (readApiConfig (ctx , & data , r .client )... )
255264 resp .Diagnostics .Append (readAuthConfig (ctx , & data , r .client )... )
265+ resp .Diagnostics .Append (readStorageConfig (ctx , & data , r .client )... )
256266
257267 resp .Diagnostics .Append (resp .State .Set (ctx , & data )... )
258268}
@@ -432,9 +442,25 @@ func pickConfig(source any, target map[string]any) {
432442 tag := t .Field (i ).Tag .Get ("json" )
433443 k := strings .Split (tag , "," )[0 ]
434444 // Check that tag is picked by target
435- if _ , ok := target [k ]; ok {
436- target [k ] = v .Field (i ).Interface ()
445+ targetVal , ok := target [k ]
446+ if ! ok {
447+ continue
448+ }
449+ sourceField := v .Field (i )
450+ // Recursively merge nested structs so user values survive when API omits fields.
451+ if targetMap , isMap := targetVal .(map [string ]any ); isMap {
452+ if sourceField .Kind () == reflect .Pointer {
453+ if sourceField .IsNil () {
454+ continue
455+ }
456+ sourceField = sourceField .Elem ()
457+ }
458+ if sourceField .Kind () == reflect .Struct {
459+ pickConfig (sourceField .Interface (), targetMap )
460+ continue
461+ }
437462 }
463+ target [k ] = sourceField .Interface ()
438464 }
439465}
440466
@@ -615,3 +641,52 @@ func updateNetworkConfig(ctx context.Context, plan *SettingsResourceModel, clien
615641 }
616642 return nil
617643}
644+
645+ func readStorageConfig (ctx context.Context , state * SettingsResourceModel , client * api.ClientWithResponses ) diag.Diagnostics {
646+ // Use ProjectRef if Id is not set (during Create), otherwise use Id (during Read/Import)
647+ projectRef := state .Id .ValueString ()
648+ if projectRef == "" {
649+ projectRef = state .ProjectRef .ValueString ()
650+ }
651+
652+ httpResp , err := client .V1GetStorageConfigWithResponse (ctx , projectRef )
653+ if err != nil {
654+ msg := fmt .Sprintf ("Unable to read storage settings, got error: %s" , err )
655+ return diag.Diagnostics {diag .NewErrorDiagnostic ("Client Error" , msg )}
656+ }
657+ // Deleted project is an orphan resource, not returning error so it can be destroyed.
658+ switch httpResp .StatusCode () {
659+ case http .StatusNotFound , http .StatusNotAcceptable :
660+ return nil
661+ }
662+ if httpResp .JSON200 == nil {
663+ msg := fmt .Sprintf ("Unable to read storage settings, got status %d: %s" , httpResp .StatusCode (), httpResp .Body )
664+ return diag.Diagnostics {diag .NewErrorDiagnostic ("Client Error" , msg )}
665+ }
666+
667+ if state .Storage , err = parseConfig (state .Storage , * httpResp .JSON200 ); err != nil {
668+ msg := fmt .Sprintf ("Unable to read storage settings, got error: %s" , err )
669+ return diag.Diagnostics {diag .NewErrorDiagnostic ("Client Error" , msg )}
670+ }
671+ return nil
672+ }
673+
674+ func updateStorageConfig (ctx context.Context , plan * SettingsResourceModel , client * api.ClientWithResponses ) diag.Diagnostics {
675+ var body api.UpdateStorageConfigBody
676+ if diags := plan .Storage .Unmarshal (& body ); diags .HasError () {
677+ return diags
678+ }
679+
680+ httpResp , err := client .V1UpdateStorageConfigWithResponse (ctx , plan .ProjectRef .ValueString (), body )
681+ if err != nil {
682+ msg := fmt .Sprintf ("Unable to update storage settings, got error: %s" , err )
683+ return diag.Diagnostics {diag .NewErrorDiagnostic ("Client Error" , msg )}
684+ }
685+ if httpResp .StatusCode () != http .StatusOK {
686+ msg := fmt .Sprintf ("Unable to update storage settings, got status %d: %s" , httpResp .StatusCode (), httpResp .Body )
687+ return diag.Diagnostics {diag .NewErrorDiagnostic ("Client Error" , msg )}
688+ }
689+
690+ // Read back the updated config to get the actual state with correct field names
691+ return readStorageConfig (ctx , plan , client )
692+ }
0 commit comments