diff --git a/buildkite/resource_cluster.go b/buildkite/resource_cluster.go index 85c37ab6..330dbeda 100644 --- a/buildkite/resource_cluster.go +++ b/buildkite/resource_cluster.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" ) type clusterResource struct { @@ -86,14 +87,34 @@ func (c *clusterResource) Create(ctx context.Context, req resource.CreateRequest return } - r, err := createCluster( - c.client.genqlient, - c.client.organizationId, - state.Name.ValueString(), - state.Description.ValueStringPointer(), - state.Emoji.ValueStringPointer(), - state.Color.ValueStringPointer(), - ) + timeout, diags := c.client.timeouts.Create(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + var response *createClusterResponse + err := retry.RetryContext(ctx, timeout, func() *retry.RetryError { + var err error + response, err = createCluster( + c.client.genqlient, + c.client.organizationId, + state.Name.ValueString(), + state.Description.ValueStringPointer(), + state.Emoji.ValueStringPointer(), + state.Color.ValueStringPointer(), + ) + if isRetryableError(err) { + return retry.RetryableError(err) + } + if err != nil { + return retry.NonRetryableError(err) + } + + return nil + }) if err != nil { resp.Diagnostics.AddError( @@ -103,8 +124,8 @@ func (c *clusterResource) Create(ctx context.Context, req resource.CreateRequest return } - state.ID = types.StringValue(r.ClusterCreate.Cluster.Id) - state.UUID = types.StringValue(r.ClusterCreate.Cluster.Uuid) + state.ID = types.StringValue(response.ClusterCreate.Cluster.Id) + state.UUID = types.StringValue(response.ClusterCreate.Cluster.Uuid) resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -118,7 +139,26 @@ func (c *clusterResource) Read(ctx context.Context, req resource.ReadRequest, re return } - r, err := getCluster(c.client.genqlient, c.client.organization, state.UUID.ValueString()) + timeout, diags := c.client.timeouts.Read(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + var response *getClusterResponse + err := retry.RetryContext(ctx, timeout, func() *retry.RetryError { + var err error + response, err = getCluster(c.client.genqlient, c.client.organization, state.UUID.ValueString()) + if isRetryableError(err) { + return retry.RetryableError(err) + } + if err != nil { + return retry.NonRetryableError(err) + } + return nil + }) if err != nil { resp.Diagnostics.AddError( @@ -128,7 +168,7 @@ func (c *clusterResource) Read(ctx context.Context, req resource.ReadRequest, re return } - updateClusterResourceState(r.Organization.Cluster, &state) + updateClusterResourceState(response.Organization.Cluster, &state) resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -142,17 +182,35 @@ func (c *clusterResource) Update(ctx context.Context, req resource.UpdateRequest return } + timeout, diags := c.client.timeouts.Update(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + id := state.ID.ValueString() - _, err := updateCluster( - c.client.genqlient, - c.client.organizationId, - id, - plan.Name.ValueString(), - plan.Description.ValueStringPointer(), - plan.Emoji.ValueStringPointer(), - plan.Color.ValueStringPointer(), - ) + err := retry.RetryContext(ctx, timeout, func() *retry.RetryError { + _, err := updateCluster( + c.client.genqlient, + c.client.organizationId, + id, + plan.Name.ValueString(), + plan.Description.ValueStringPointer(), + plan.Emoji.ValueStringPointer(), + plan.Color.ValueStringPointer(), + ) + if isRetryableError(err) { + return retry.RetryableError(err) + } + if err != nil { + return retry.NonRetryableError(err) + } + + return nil + }) if err != nil { resp.Diagnostics.AddError( @@ -174,7 +232,25 @@ func (c *clusterResource) Delete(ctx context.Context, req resource.DeleteRequest return } - _, err := deleteCluster(c.client.genqlient, c.client.organizationId, state.ID.ValueString()) + timeout, diags := c.client.timeouts.Delete(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + err := retry.RetryContext(ctx, timeout, func() *retry.RetryError { + _, err := deleteCluster(c.client.genqlient, c.client.organizationId, state.ID.ValueString()) + if isRetryableError(err) { + return retry.RetryableError(err) + } + if err != nil { + return retry.NonRetryableError(err) + } + + return nil + }) if err != nil { resp.Diagnostics.AddError(