@@ -11,6 +11,8 @@ import (
1111 "github.com/hashicorp/terraform-plugin-framework/path"
1212 "github.com/hashicorp/terraform-plugin-framework/resource"
1313 "github.com/hashicorp/terraform-plugin-framework/resource/schema"
14+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
15+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1416 "github.com/hashicorp/terraform-plugin-framework/types"
1517)
1618
@@ -51,6 +53,9 @@ func (r *policyResource) Schema(_ context.Context, _ resource.SchemaRequest, res
5153 "id" : schema.StringAttribute {
5254 Computed : true ,
5355 Description : "Unique identifier for this resource" ,
56+ PlanModifiers : []planmodifier.String {
57+ stringplanmodifier .UseStateForUnknown (),
58+ },
5459 },
5560 "name" : schema.StringAttribute {
5661 Required : true ,
@@ -76,14 +81,22 @@ func (r *policyResource) Schema(_ context.Context, _ resource.SchemaRequest, res
7681 "created_at" : schema.StringAttribute {
7782 Computed : true ,
7883 Description : "Timestamp when the policy was created" ,
84+ PlanModifiers : []planmodifier.String {
85+ stringplanmodifier .UseStateForUnknown (),
86+ },
7987 },
8088 "creator" : schema.StringAttribute {
8189 Computed : true ,
8290 Description : "User who created the policy" ,
91+ PlanModifiers : []planmodifier.String {
92+ stringplanmodifier .UseStateForUnknown (),
93+ },
8394 },
8495 "etag" : schema.StringAttribute {
85- Computed : true ,
86- Description : "Version identifier used to prevent conflicts from concurrent updates, ensuring safe resource modifications" ,
96+ Computed : true ,
97+ PlanModifiers : []planmodifier.String {
98+ stringplanmodifier .UseStateForUnknown (),
99+ },
87100 },
88101 },
89102 }
@@ -137,18 +150,21 @@ func (r *policyResource) Create(ctx context.Context, req resource.CreateRequest,
137150
138151 createdPolicyWithETag , err := r .client .CreatePolicy (ctx , policy )
139152 if err != nil {
140- resp .Diagnostics .AddError ("Client Error" , fmt . Sprintf ( "Unable to create policy, got error: %s " , err ))
153+ resp .Diagnostics .AddError ("Error creating Policy " , err . Error ( ))
141154 return
142155 }
143156
144- createdPolicy := createdPolicyWithETag .Policy
145- data .ID = types .StringValue (createdPolicy .ID )
146- data .CreatedAt = types .StringValue (createdPolicy .CreatedAt )
147- data .Creator = types .StringValue (createdPolicy .Creator )
157+ data .ID = types .StringValue (createdPolicyWithETag .Policy .ID )
158+ data .CreatedAt = types .StringValue (createdPolicyWithETag .Policy .CreatedAt )
159+ if createdPolicyWithETag .Policy .Creator == "" {
160+ data .Creator = types .StringNull ()
161+ } else {
162+ data .Creator = types .StringValue (createdPolicyWithETag .Policy .Creator )
163+ }
148164 data .ETag = types .StringValue (createdPolicyWithETag .ETag )
149165
150166 // Update role IDs in case the order or values changed
151- roleIDList , diags := types .ListValueFrom (ctx , types .StringType , createdPolicy .RoleIDs )
167+ roleIDList , diags := types .ListValueFrom (ctx , types .StringType , createdPolicyWithETag . Policy .RoleIDs )
152168 resp .Diagnostics .Append (diags ... )
153169 if resp .Diagnostics .HasError () {
154170 return
@@ -181,11 +197,16 @@ func (r *policyResource) Read(ctx context.Context, req resource.ReadRequest, res
181197 policy := policyWithETag .Policy
182198
183199 // Map response to model
200+ data .ID = types .StringValue (policy .ID )
184201 data .Name = types .StringValue (policy .Name )
185202 data .Description = types .StringValue (policy .Description )
186203 data .PrincipalID = types .StringValue (policy .PrincipalID )
187204 data .CreatedAt = types .StringValue (policy .CreatedAt )
188- data .Creator = types .StringValue (policy .Creator )
205+ if policy .Creator == "" {
206+ data .Creator = types .StringNull ()
207+ } else {
208+ data .Creator = types .StringValue (policy .Creator )
209+ }
189210 data .ETag = types .StringValue (policyWithETag .ETag )
190211
191212 // Map role IDs
@@ -195,7 +216,6 @@ func (r *policyResource) Read(ctx context.Context, req resource.ReadRequest, res
195216 return
196217 }
197218 data .RoleIDs = roleIDList
198-
199219 resp .Diagnostics .Append (resp .State .Set (ctx , & data )... )
200220}
201221
@@ -220,38 +240,37 @@ func (r *policyResource) Update(ctx context.Context, req resource.UpdateRequest,
220240 return
221241 }
222242
223- // Create policy with updated data
243+ // Create policy with updated data - use state values for immutable fields
224244 policy := & models.Policy {
225- ID : data .ID .ValueString (),
245+ ID : state .ID .ValueString (), // Use state for immutable ID
226246 Name : data .Name .ValueString (),
227247 Description : data .Description .ValueString (),
228248 PermissionsSystemID : data .PermissionsSystemID .ValueString (),
229249 PrincipalID : data .PrincipalID .ValueString (),
230250 RoleIDs : roleIDs ,
251+ CreatedAt : state .CreatedAt .ValueString (), // Preserve immutable CreatedAt
252+ }
253+
254+ // Handle Creator field - it might be null in state
255+ if ! state .Creator .IsNull () {
256+ policy .Creator = state .Creator .ValueString ()
231257 }
232258
233259 // Coordinate operations to prevent conflicts
234260 permissionSystemID := data .PermissionsSystemID .ValueString ()
235261 r .fgamCoordinator .Lock (permissionSystemID )
236262 defer r .fgamCoordinator .Unlock (permissionSystemID )
237263
238- // Use the ETag from state for optimistic concurrency control
239264 updatedPolicyWithETag , err := r .client .UpdatePolicy (ctx , policy , state .ETag .ValueString ())
240265 if err != nil {
241266 resp .Diagnostics .AddError ("Client Error" , fmt .Sprintf ("Unable to update policy, got error: %s" , err ))
242267 return
243268 }
244269
245270 // Update resource data with the response
246- data .ID = types .StringValue (updatedPolicyWithETag .Policy .ID )
247-
248- // If the ID is empty, preserve the original ID
249- if data .ID .ValueString () == "" {
250- data .ID = state .ID
251- }
252-
253- data .CreatedAt = types .StringValue (updatedPolicyWithETag .Policy .CreatedAt )
254- data .Creator = types .StringValue (updatedPolicyWithETag .Policy .Creator )
271+ data .ID = state .ID
272+ data .CreatedAt = state .CreatedAt
273+ data .Creator = state .Creator
255274 data .ETag = types .StringValue (updatedPolicyWithETag .ETag )
256275
257276 // Update role IDs in case the order or values changed
0 commit comments