-
Notifications
You must be signed in to change notification settings - Fork 205
feat: Long-running operation improvements for mongodbatlas_flex_cluster
resource
#3525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ecec0cd
09ea70c
4e57721
ab24521
69f0c40
3bed1db
9e51912
342d64a
3cfc917
bb7c257
56b6dc8
b0d39a8
55f67aa
8d2d1f0
37b192a
13b41ce
4ff82b3
d1d777c
66c72ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
```release-note:enhancement | ||
resource/mongodbatlas_flex_cluster: Adds `timeouts` attribute for create, update and delete operations | ||
``` | ||
|
||
```release-note:enhancement | ||
resource/mongodbatlas_flex_cluster: Adds `delete_on_create_timeout` attribute to indicate whether to delete the resource if its creation times out | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package customplanmodifier | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/diag" | ||
"github.com/hashicorp/terraform-plugin-framework/path" | ||
planmodifier "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" | ||
) | ||
|
||
// CreateOnlyStringPlanModifier creates a plan modifier that prevents updates to string attributes. | ||
func CreateOnlyStringPlanModifier() planmodifier.String { | ||
return &createOnlyAttributePlanModifier{} | ||
} | ||
|
||
// CreateOnlyBoolPlanModifier creates a plan modifier that prevents updates to boolean attributes. | ||
func CreateOnlyBoolPlanModifier() planmodifier.Bool { | ||
return &createOnlyAttributePlanModifier{} | ||
} | ||
|
||
// Plan modifier that implements create-only behavior for multiple attribute types | ||
type createOnlyAttributePlanModifier struct{} | ||
|
||
func (d *createOnlyAttributePlanModifier) Description(ctx context.Context) string { | ||
return d.MarkdownDescription(ctx) | ||
} | ||
|
||
func (d *createOnlyAttributePlanModifier) MarkdownDescription(ctx context.Context) string { | ||
return "Ensures that update operations fail when attempting to modify a create-only attribute." | ||
} | ||
|
||
func (d *createOnlyAttributePlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { | ||
validateCreateOnly(req.PlanValue, req.StateValue, req.Path, &resp.Diagnostics) | ||
} | ||
|
||
func (d *createOnlyAttributePlanModifier) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { | ||
validateCreateOnly(req.PlanValue, req.StateValue, req.Path, &resp.Diagnostics) | ||
} | ||
|
||
// validateCreateOnly checks if an attribute value has changed and adds an error if it has | ||
func validateCreateOnly(planValue, stateValue attr.Value, attrPath path.Path, diagnostics *diag.Diagnostics, | ||
) { | ||
if !stateValue.IsNull() && !stateValue.Equal(planValue) { | ||
diagnostics.AddError( | ||
fmt.Sprintf("%s cannot be updated", attrPath), | ||
fmt.Sprintf("%s cannot be updated", attrPath), | ||
) | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -462,7 +462,7 @@ func resourceCreate(ctx context.Context, d *schema.ResourceData, meta any) diag. | |
|
||
if isFlex { | ||
flexClusterReq := advancedclustertpf.NewFlexCreateReq(clusterName, d.Get("termination_protection_enabled").(bool), conversion.ExpandTagsFromSetSchema(d), replicationSpecs) | ||
flexClusterResp, err := flexcluster.CreateFlexCluster(ctx, projectID, clusterName, flexClusterReq, connV2.FlexClustersApi) | ||
flexClusterResp, err := flexcluster.CreateFlexCluster(ctx, projectID, clusterName, flexClusterReq, connV2.FlexClustersApi, &timeout) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we passing timeout only here and not for delete and update? Also this method is called from advanced_cluster. Are we changing something also on that resource? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch, fixed in 56b6dc8. |
||
if err != nil { | ||
return diag.FromErr(fmt.Errorf(flexcluster.ErrorCreateFlex, err)) | ||
} | ||
|
@@ -1326,9 +1326,10 @@ func resourceDelete(ctx context.Context, d *schema.ResourceData, meta any) diag. | |
} | ||
|
||
replicationSpecs := expandAdvancedReplicationSpecs(d.Get("replication_specs").([]any), nil) | ||
timeout := d.Timeout(schema.TimeoutDelete) | ||
|
||
if advancedclustertpf.IsFlex(replicationSpecs) { | ||
err := flexcluster.DeleteFlexCluster(ctx, projectID, clusterName, connV2.FlexClustersApi) | ||
err := flexcluster.DeleteFlexCluster(ctx, projectID, clusterName, connV2.FlexClustersApi, timeout) | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf(flexcluster.ErrorDeleteFlex, clusterName, err)) | ||
} | ||
|
@@ -1433,7 +1434,7 @@ func waitStateTransitionFlexUpgrade(ctx context.Context, client admin.FlexCluste | |
GroupId: projectID, | ||
Name: name, | ||
} | ||
flexClusterResp, err := flexcluster.WaitStateTransition(ctx, flexClusterParams, client, []string{retrystrategy.RetryStrategyUpdatingState}, []string{retrystrategy.RetryStrategyIdleState}, true, &timeout) | ||
flexClusterResp, err := flexcluster.WaitStateTransition(ctx, flexClusterParams, client, []string{retrystrategy.RetryStrategyUpdatingState}, []string{retrystrategy.RetryStrategyIdleState}, true, timeout) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -1539,8 +1540,9 @@ func resourceUpdateFlexCluster(ctx context.Context, flexUpdateRequest *admin.Fle | |
ids := conversion.DecodeStateID(d.Id()) | ||
projectID := ids["project_id"] | ||
clusterName := ids["cluster_name"] | ||
timeout := d.Timeout(schema.TimeoutUpdate) | ||
|
||
_, err := flexcluster.UpdateFlexCluster(ctx, projectID, clusterName, flexUpdateRequest, connV2.FlexClustersApi) | ||
_, err := flexcluster.UpdateFlexCluster(ctx, projectID, clusterName, flexUpdateRequest, connV2.FlexClustersApi, timeout) | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf(flexcluster.ErrorUpdateFlex, err)) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Would improve the details by showing the plan & stateValue.