@@ -20,7 +20,6 @@ import (
2020 "github.com/hashicorp/terraform-plugin-framework/resource"
2121 "github.com/hashicorp/terraform-plugin-framework/resource/schema"
2222 "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
23- "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
2423 "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
2524 "github.com/hashicorp/terraform-plugin-framework/types"
2625 "github.com/stackitcloud/stackit-sdk-go/core/config"
@@ -202,9 +201,6 @@ func (r *userResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
202201 Description : descriptions ["roles" ],
203202 ElementType : types .StringType ,
204203 Required : true ,
205- PlanModifiers : []planmodifier.Set {
206- setplanmodifier .RequiresReplace (),
207- },
208204 Validators : []validator.Set {
209205 setvalidator .ValueStringsAre (
210206 stringvalidator .OneOf ("login" , "createdb" ),
@@ -344,9 +340,74 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp
344340}
345341
346342// Update updates the resource and sets the updated Terraform state on success.
347- func (r * userResource ) Update (ctx context.Context , _ resource.UpdateRequest , resp * resource.UpdateResponse ) { // nolint:gocritic // function signature required by Terraform
348- // Update shouldn't be called
349- core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , "User can't be updated" )
343+ func (r * userResource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) { // nolint:gocritic // function signature required by Terraform
344+ // Retrieve values from plan
345+ var model Model
346+ diags := req .Plan .Get (ctx , & model )
347+ resp .Diagnostics .Append (diags ... )
348+ if resp .Diagnostics .HasError () {
349+ return
350+ }
351+ projectId := model .ProjectId .ValueString ()
352+ instanceId := model .InstanceId .ValueString ()
353+ userId := model .UserId .ValueString ()
354+ region := model .Region .ValueString ()
355+ ctx = tflog .SetField (ctx , "project_id" , projectId )
356+ ctx = tflog .SetField (ctx , "instance_id" , instanceId )
357+ ctx = tflog .SetField (ctx , "user_id" , userId )
358+ ctx = tflog .SetField (ctx , "region" , region )
359+
360+ // Retrieve values from state
361+ var stateModel Model
362+ diags = req .State .Get (ctx , & stateModel )
363+ resp .Diagnostics .Append (diags ... )
364+ if resp .Diagnostics .HasError () {
365+ return
366+ }
367+
368+ var roles []string
369+ if ! (model .Roles .IsNull () || model .Roles .IsUnknown ()) {
370+ diags = model .Roles .ElementsAs (ctx , & roles , false )
371+ resp .Diagnostics .Append (diags ... )
372+ if resp .Diagnostics .HasError () {
373+ return
374+ }
375+ }
376+
377+ // Generate API request body from model
378+ payload , err := toUpdatePayload (& model , roles )
379+ if err != nil {
380+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Updating API payload: %v" , err ))
381+ return
382+ }
383+
384+ // Update existing instance
385+ err = r .client .UpdateUser (ctx , projectId , region , instanceId , userId ).UpdateUserPayload (* payload ).Execute ()
386+ if err != nil {
387+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , err .Error ())
388+ return
389+ }
390+
391+ userResp , err := r .client .GetUser (ctx , projectId , region , instanceId , userId ).Execute ()
392+ if err != nil {
393+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Calling API: %v" , err ))
394+ return
395+ }
396+
397+ // Map response body to schema
398+ err = mapFields (userResp , & stateModel , region )
399+ if err != nil {
400+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Processing API payload: %v" , err ))
401+ return
402+ }
403+
404+ // Set state to fully populated data
405+ diags = resp .State .Set (ctx , stateModel )
406+ resp .Diagnostics .Append (diags ... )
407+ if resp .Diagnostics .HasError () {
408+ return
409+ }
410+ tflog .Info (ctx , "Postgres Flex user updated" )
350411}
351412
352413// Delete deletes the resource and removes the Terraform state on success.
@@ -515,3 +576,16 @@ func toCreatePayload(model *Model, roles []string) (*postgresflex.CreateUserPayl
515576 Username : conversion .StringValueToPointer (model .Username ),
516577 }, nil
517578}
579+
580+ func toUpdatePayload (model * Model , roles []string ) (* postgresflex.UpdateUserPayload , error ) {
581+ if model == nil {
582+ return nil , fmt .Errorf ("nil model" )
583+ }
584+ if roles == nil {
585+ return nil , fmt .Errorf ("nil roles" )
586+ }
587+
588+ return & postgresflex.UpdateUserPayload {
589+ Roles : & roles ,
590+ }, nil
591+ }
0 commit comments