Skip to content

Commit 8a983ef

Browse files
authored
fix(okta_request_condition): handle priority mismatch after create (#2786)
1 parent 2eccfc1 commit 8a983ef

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
resource "okta_request_condition" "test_priority_0" {
2+
status = "ACTIVE"
3+
resource_id = "0oasp3g29b1hqkcYE1d7"
4+
approval_sequence_id = "69251ae704a4d0a7fcdb870f"
5+
name = "test-condition-priority-0"
6+
priority = 0
7+
access_scope_settings {
8+
type = "RESOURCE_DEFAULT"
9+
}
10+
requester_settings {
11+
type = "EVERYONE"
12+
}
13+
}
14+
15+
resource "okta_request_condition" "test_priority_1" {
16+
status = "ACTIVE"
17+
resource_id = "0oasp3g29b1hqkcYE1d7"
18+
approval_sequence_id = "69251ae704a4d0a7fcdb870f"
19+
name = "test-condition-priority-1"
20+
priority = 1
21+
access_scope_settings {
22+
type = "RESOURCE_DEFAULT"
23+
}
24+
requester_settings {
25+
type = "EVERYONE"
26+
}
27+
}

okta/services/governance/resource_request_condition.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,36 @@ func (r *requestConditionResource) Create(ctx context.Context, req resource.Crea
226226
}
227227
}
228228

229+
// The API may ignore the priority field on create and return a default
230+
// value (e.g. always 0). Save the planned priority so we can restore it
231+
// after applying the API response to state, since even the follow-up
232+
// PATCH response returns 0 for this field.
233+
plannedPriority := data.Priority
234+
235+
// If the planned priority differs from what the API returned, issue a
236+
// follow-up PATCH to attempt to set the correct value server-side.
237+
if !plannedPriority.IsNull() && plannedPriority.ValueInt32() != requestConditionResp.GetPriority() {
238+
_, _, err = r.OktaGovernanceClient.OktaGovernanceSDKClient().
239+
RequestConditionsAPI.UpdateResourceRequestConditionV2(ctx,
240+
data.ResourceId.ValueString(),
241+
requestConditionResp.GetId()).RequestConditionPatchable(createRequestConditionPatch(data)).Execute()
242+
if err != nil {
243+
resp.Diagnostics.AddError(
244+
"Error setting priority on Request condition",
245+
"Could not update priority after creation: "+err.Error(),
246+
)
247+
return
248+
}
249+
}
250+
229251
resp.Diagnostics.Append(applyRequestConditionToState(ctx, &data, requestConditionResp)...)
252+
253+
// Restore the planned priority: the API always returns 0 for this field,
254+
// even after a successful PATCH, so we preserve the planned value to
255+
// avoid a "Provider produced inconsistent result after apply" error.
256+
if !plannedPriority.IsNull() && data.Priority.ValueInt32() == 0 && plannedPriority.ValueInt32() != 0 {
257+
data.Priority = plannedPriority
258+
}
230259
if resp.Diagnostics.HasError() {
231260
return
232261
}
@@ -245,6 +274,11 @@ func (r *requestConditionResource) Read(ctx context.Context, req resource.ReadRe
245274
return
246275
}
247276

277+
// Save the prior-state priority: the API always returns 0 for this field
278+
// regardless of what was configured, so we preserve the known priority to
279+
// avoid a spurious non-empty plan after apply.
280+
priorPriority := data.Priority
281+
248282
// Read API call logic
249283
readRequestConditionResp, httpResp, err := r.OktaGovernanceClient.OktaGovernanceSDKClient().RequestConditionsAPI.GetResourceRequestConditionV2(ctx, data.ResourceId.ValueString(), data.Id.ValueString()).Execute()
250284
if err != nil {
@@ -265,6 +299,13 @@ func (r *requestConditionResource) Read(ctx context.Context, req resource.ReadRe
265299
if resp.Diagnostics.HasError() {
266300
return
267301
}
302+
303+
// Restore the prior-state priority when the API returns 0 but the
304+
// configuration had a non-zero value.
305+
if !priorPriority.IsNull() && data.Priority.ValueInt32() == 0 && priorPriority.ValueInt32() != 0 {
306+
data.Priority = priorPriority
307+
}
308+
268309
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
269310
}
270311

@@ -283,6 +324,10 @@ func (r *requestConditionResource) Update(ctx context.Context, req resource.Upda
283324
return
284325
}
285326

327+
// Save planned priority before the API call: the update API also returns
328+
// 0 for priority in the response, so we preserve the planned value.
329+
plannedPriority := data.Priority
330+
286331
// Update API call logic
287332
ctx = context.WithValue(ctx, api.RetryOnStatusCodes, []int{http.StatusConflict})
288333
updatedRequestCondition, _, err := r.OktaGovernanceClient.OktaGovernanceSDKClient().RequestConditionsAPI.UpdateResourceRequestConditionV2(ctx, data.ResourceId.ValueString(), state.Id.ValueString()).RequestConditionPatchable(createRequestConditionPatch(data)).Execute()
@@ -333,6 +378,12 @@ func (r *requestConditionResource) Update(ctx context.Context, req resource.Upda
333378
return
334379
}
335380

381+
// Restore the planned priority: the update API also returns 0 for this
382+
// field, so we preserve the planned value to keep state consistent.
383+
if !plannedPriority.IsNull() && data.Priority.ValueInt32() == 0 && plannedPriority.ValueInt32() != 0 {
384+
data.Priority = plannedPriority
385+
}
386+
336387
// Save Data into Terraform state
337388
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
338389
}

okta/services/governance/resource_request_condition_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,31 @@ func TestAccRequestConditionResource_Issue2780(t *testing.T) {
137137
})
138138
}
139139

140+
func TestAccRequestConditionResource_Priority(t *testing.T) {
141+
mgr := newFixtureManager("resources", resources.OktaGovernanceRequestCondition, t.Name())
142+
config := mgr.GetFixtures("priority.tf", t)
143+
resourceName0 := fmt.Sprintf("%s.test_priority_0", resources.OktaGovernanceRequestCondition)
144+
resourceName1 := fmt.Sprintf("%s.test_priority_1", resources.OktaGovernanceRequestCondition)
145+
146+
acctest.OktaResourceTest(t, resource.TestCase{
147+
PreCheck: acctest.AccPreCheck(t),
148+
ErrorCheck: testAccErrorChecks(t),
149+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactoriesForTestAcc(t),
150+
CheckDestroy: checkRequestConditionDestroy,
151+
Steps: []resource.TestStep{
152+
{
153+
Config: config,
154+
Check: resource.ComposeTestCheckFunc(
155+
resource.TestCheckResourceAttr(resourceName0, "name", "test-condition-priority-0"),
156+
resource.TestCheckResourceAttr(resourceName0, "priority", "0"),
157+
resource.TestCheckResourceAttr(resourceName1, "name", "test-condition-priority-1"),
158+
resource.TestCheckResourceAttr(resourceName1, "priority", "1"),
159+
),
160+
},
161+
},
162+
})
163+
}
164+
140165
// checkRequestConditionDestroy verifies that request conditions have been destroyed
141166
func checkRequestConditionDestroy(s *terraform.State) error {
142167
// Skip destroy check in VCR playback mode

0 commit comments

Comments
 (0)