@@ -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"
@@ -167,9 +166,6 @@ func (r *userResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
167166 Description : descriptions ["roles" ],
168167 ElementType : types .StringType ,
169168 Required : true ,
170- PlanModifiers : []planmodifier.Set {
171- setplanmodifier .RequiresReplace (),
172- },
173169 Validators : []validator.Set {
174170 setvalidator .ValueStringsAre (
175171 stringvalidator .OneOf ("login" , "createdb" ),
@@ -293,9 +289,72 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp
293289}
294290
295291// Update updates the resource and sets the updated Terraform state on success.
296- func (r * userResource ) Update (ctx context.Context , _ resource.UpdateRequest , resp * resource.UpdateResponse ) { // nolint:gocritic // function signature required by Terraform
297- // Update shouldn't be called
298- core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , "User can't be updated" )
292+ func (r * userResource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) { // nolint:gocritic // function signature required by Terraform
293+ // Retrieve values from plan
294+ var model Model
295+ diags := req .Plan .Get (ctx , & model )
296+ resp .Diagnostics .Append (diags ... )
297+ if resp .Diagnostics .HasError () {
298+ return
299+ }
300+ projectId := model .ProjectId .ValueString ()
301+ instanceId := model .InstanceId .ValueString ()
302+ userId := model .UserId .ValueString ()
303+ ctx = tflog .SetField (ctx , "project_id" , projectId )
304+ ctx = tflog .SetField (ctx , "instance_id" , instanceId )
305+ ctx = tflog .SetField (ctx , "user_id" , userId )
306+
307+ // Retrieve values from state
308+ var stateModel Model
309+ diags = req .State .Get (ctx , & stateModel )
310+ resp .Diagnostics .Append (diags ... )
311+ if resp .Diagnostics .HasError () {
312+ return
313+ }
314+
315+ var roles []string
316+ if ! (model .Roles .IsNull () || model .Roles .IsUnknown ()) {
317+ diags = model .Roles .ElementsAs (ctx , & roles , false )
318+ resp .Diagnostics .Append (diags ... )
319+ if resp .Diagnostics .HasError () {
320+ return
321+ }
322+ }
323+
324+ // Generate API request body from model
325+ payload , err := toUpdatePayload (& model , roles )
326+ if err != nil {
327+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Updating API payload: %v" , err ))
328+ return
329+ }
330+
331+ // Update existing instance
332+ err = r .client .UpdateUser (ctx , projectId , instanceId , userId ).UpdateUserPayload (* payload ).Execute ()
333+ if err != nil {
334+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , err .Error ())
335+ return
336+ }
337+
338+ userResp , err := r .client .GetUser (ctx , projectId , instanceId , userId ).Execute ()
339+ if err != nil {
340+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Calling API: %v" , err ))
341+ return
342+ }
343+
344+ // Map response body to schema
345+ err = mapFields (userResp , & stateModel )
346+ if err != nil {
347+ core .LogAndAddError (ctx , & resp .Diagnostics , "Error updating user" , fmt .Sprintf ("Processing API payload: %v" , err ))
348+ return
349+ }
350+
351+ // Set state to fully populated data
352+ diags = resp .State .Set (ctx , stateModel )
353+ resp .Diagnostics .Append (diags ... )
354+ if resp .Diagnostics .HasError () {
355+ return
356+ }
357+ tflog .Info (ctx , "Postgres Flex user updated" )
299358}
300359
301360// Delete deletes the resource and removes the Terraform state on success.
@@ -457,3 +516,16 @@ func toCreatePayload(model *Model, roles []string) (*postgresflex.CreateUserPayl
457516 Username : conversion .StringValueToPointer (model .Username ),
458517 }, nil
459518}
519+
520+ func toUpdatePayload (model * Model , roles []string ) (* postgresflex.UpdateUserPayload , error ) {
521+ if model == nil {
522+ return nil , fmt .Errorf ("nil model" )
523+ }
524+ if roles == nil {
525+ return nil , fmt .Errorf ("nil roles" )
526+ }
527+
528+ return & postgresflex.UpdateUserPayload {
529+ Roles : & roles ,
530+ }, nil
531+ }
0 commit comments