Skip to content

Commit 92c48a1

Browse files
HCPF-2903: Fix project resource - move logic of waiting in retry func
1 parent 82ec7fe commit 92c48a1

File tree

2 files changed

+44
-54
lines changed

2 files changed

+44
-54
lines changed

internal/clients/project.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package clients
66
import (
77
"context"
88
"fmt"
9+
sharedmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
910

1011
"github.com/cenkalti/backoff/v4"
1112

@@ -61,6 +62,10 @@ func CreateProjectWithRetry(client *Client, params *project_service.ProjectServi
6162
op := func() error {
6263
var err error
6364
res, err = client.Project.ProjectServiceCreate(params, nil)
65+
// Wait for the project to be created, if an operation ID is returned.
66+
if res.Payload.OperationID != "" {
67+
return waitForProjectOperation(params.Context, client, "create project", res.Payload.Project.ID, res.Payload.OperationID)
68+
}
6469
return err
6570
}
6671

@@ -76,6 +81,10 @@ func SetProjectNameWithRetry(client *Client, params *project_service.ProjectServ
7681
op := func() error {
7782
var err error
7883
res, err = client.Project.ProjectServiceSetName(params, nil)
84+
// Wait for the project name to be set, if an operation ID is returned.
85+
if res.Payload.OperationID != "" {
86+
return waitForProjectOperation(params.Context, client, "set project name", params.ID, res.Payload.OperationID)
87+
}
7988
return err
8089
}
8190

@@ -91,6 +100,10 @@ func SetProjectDescriptionWithRetry(client *Client, params *project_service.Proj
91100
op := func() error {
92101
var err error
93102
res, err = client.Project.ProjectServiceSetDescription(params, nil)
103+
// Wait for the project description to be set, if an operation ID is returned.
104+
if res.Payload.OperationID != "" {
105+
return waitForProjectOperation(params.Context, client, "set project description", params.ID, res.Payload.OperationID)
106+
}
94107
return err
95108
}
96109

@@ -99,3 +112,29 @@ func SetProjectDescriptionWithRetry(client *Client, params *project_service.Proj
99112

100113
return res, err
101114
}
115+
116+
// DeleteProjectWithRetry wraps the projects service client with an exponential backoff retry mechanism.
117+
func DeleteProjectWithRetry(client *Client, params *project_service.ProjectServiceDeleteParams) (*project_service.ProjectServiceDeleteOK, error) {
118+
var res *project_service.ProjectServiceDeleteOK
119+
op := func() error {
120+
var err error
121+
res, err = client.Project.ProjectServiceDelete(params, nil)
122+
// Wait for the project to be deleted, if an operation ID is returned.
123+
if res.Payload.Operation.ID != "" {
124+
// For delete operations, the operation is scoped at the organization level
125+
projectID := ""
126+
return waitForProjectOperation(params.Context, client, "delete project", projectID, res.Payload.Operation.ID)
127+
}
128+
return err
129+
}
130+
131+
serviceErr := &project_service.ProjectServiceDeleteDefault{}
132+
err := backoff.Retry(newBackoffOp(op, serviceErr), newBackoff())
133+
134+
return res, err
135+
}
136+
137+
func waitForProjectOperation(ctx context.Context, client *Client, operationName, projectID string, operationID string) error {
138+
loc := &sharedmodels.HashicorpCloudLocationLocation{OrganizationID: client.Config.OrganizationID, ProjectID: projectID}
139+
return WaitForOperation(ctx, client, operationName, loc, operationID)
140+
}

internal/provider/resourcemanager/resource_project.go

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
billingModels "github.com/hashicorp/hcp-sdk-go/clients/cloud-billing/preview/2020-11-05/models"
1414
"github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/stable/2019-12-10/client/project_service"
1515
"github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/stable/2019-12-10/models"
16-
sharedmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
1716
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
1817
"github.com/hashicorp/terraform-plugin-framework/path"
1918
"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -132,15 +131,6 @@ func (r *resourceProject) Create(ctx context.Context, req resource.CreateRequest
132131
return
133132
}
134133

135-
// Wait for the project to be created, if an operation ID is returned.
136-
if res.Payload.OperationID != "" {
137-
err = waitForProjectOperation(ctx, r.client, "create project", res.Payload.Project.ID, res.Payload.OperationID)
138-
if err != nil {
139-
resp.Diagnostics.AddError("Error waiting for project creation", err.Error())
140-
return
141-
}
142-
}
143-
144134
p := res.GetPayload().Project
145135
plan.ResourceID = types.StringValue(p.ID)
146136
plan.ResourceName = types.StringValue(fmt.Sprintf("project/%s", p.ID))
@@ -230,21 +220,11 @@ func (r *resourceProject) Update(ctx context.Context, req resource.UpdateRequest
230220
Name: plan.Name.ValueString(),
231221
}
232222

233-
res, err := clients.SetProjectNameWithRetry(r.client, setNameReq)
223+
_, err := clients.SetProjectNameWithRetry(r.client, setNameReq)
234224
if err != nil {
235225
resp.Diagnostics.AddError("Error updating project name", err.Error())
236226
return
237227
}
238-
239-
// Wait for the project name to be updated, if an operation ID is returned.
240-
if res.Payload.OperationID != "" {
241-
// Wait for the project name to be updated.
242-
err = waitForProjectOperation(ctx, r.client, "update project name", plan.ResourceID.ValueString(), res.Payload.OperationID)
243-
if err != nil {
244-
resp.Diagnostics.AddError("Error waiting for project name update", err.Error())
245-
return
246-
}
247-
}
248228
}
249229

250230
// Check if the description was updated
@@ -255,21 +235,12 @@ func (r *resourceProject) Update(ctx context.Context, req resource.UpdateRequest
255235
Description: plan.Description.ValueString(),
256236
}
257237

258-
res, err := clients.SetProjectDescriptionWithRetry(r.client, setDescReq)
238+
_, err := clients.SetProjectDescriptionWithRetry(r.client, setDescReq)
259239
if err != nil {
260240
resp.Diagnostics.AddError("Error updating project description", err.Error())
261241
return
262242
}
263243

264-
// Wait for the project description to be updated, if an operation ID is returned.
265-
if res.Payload.OperationID != "" {
266-
err = waitForProjectOperation(ctx, r.client, "update project description", plan.ResourceID.ValueString(), res.Payload.OperationID)
267-
if err != nil {
268-
resp.Diagnostics.AddError("Error waiting for project description update", err.Error())
269-
return
270-
}
271-
}
272-
273244
}
274245

275246
// Store the updated values
@@ -283,10 +254,10 @@ func (r *resourceProject) Delete(ctx context.Context, req resource.DeleteRequest
283254
return
284255
}
285256

286-
getParams := project_service.NewProjectServiceDeleteParams()
287-
getParams.ID = state.ResourceID.ValueString()
257+
deleteParams := project_service.NewProjectServiceDeleteParams()
258+
deleteParams.ID = state.ResourceID.ValueString()
288259

289-
res, err := r.client.Project.ProjectServiceDelete(getParams, nil)
260+
_, err := clients.DeleteProjectWithRetry(r.client, deleteParams)
290261
if err != nil {
291262
var deleteErr *project_service.ProjectServiceDeleteDefault
292263
if errors.As(err, &deleteErr) && deleteErr.IsCode(http.StatusNotFound) {
@@ -296,28 +267,8 @@ func (r *resourceProject) Delete(ctx context.Context, req resource.DeleteRequest
296267
resp.Diagnostics.AddError("Error deleting project", err.Error())
297268
return
298269
}
299-
300-
// Wait for the project to be deleted, if an operation ID is returned.
301-
if res.Payload.Operation.ID != "" {
302-
// For delete operations, the operation is scoped at the organization level
303-
projectID := ""
304-
err = waitForProjectOperation(ctx, r.client, "delete project", projectID, res.Payload.Operation.ID)
305-
if err != nil {
306-
resp.Diagnostics.AddError("Error waiting for project deletion", err.Error())
307-
return
308-
}
309-
}
310270
}
311271

312272
func (r *resourceProject) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
313273
resource.ImportStatePassthroughID(ctx, path.Root("resource_id"), req, resp)
314274
}
315-
316-
func waitForProjectOperation(ctx context.Context, client *clients.Client, operationName, projectID string, operationID string) error {
317-
loc := &sharedmodels.HashicorpCloudLocationLocation{
318-
OrganizationID: client.Config.OrganizationID,
319-
ProjectID: projectID,
320-
}
321-
322-
return clients.WaitForOperation(ctx, client, operationName, loc, operationID)
323-
}

0 commit comments

Comments
 (0)