Skip to content

Commit 6c72b69

Browse files
authored
chore: Handles auto-scaling in output plans (#3126)
* changes from PR 3122 * split compute and memory logic un auto-scaling, and use plan/state instead of config
1 parent 3a6fd7e commit 6c72b69

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

internal/service/advancedclustertpf/plan_modifier.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/hashicorp/terraform-plugin-framework/diag"
99
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1011
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/schemafunc"
1112
)
1213

@@ -37,6 +38,7 @@ func useStateForUnknowns(ctx context.Context, diags *diag.Diagnostics, state, pl
3738
attributeChanges := schemafunc.NewAttributeChanges(ctx, state, plan)
3839
keepUnknown := []string{"connection_strings", "state_name"} // Volatile attributes, should not be copied from state
3940
keepUnknown = append(keepUnknown, attributeChanges.KeepUnknown(attributeRootChangeMapping)...)
41+
keepUnknown = append(keepUnknown, determineKeepUnknownsAutoScaling(ctx, diags, state, plan)...)
4042
schemafunc.CopyUnknowns(ctx, state, plan, keepUnknown)
4143
if slices.Contains(keepUnknown, "replication_specs") {
4244
useStateForUnknownsReplicationSpecs(ctx, diags, state, plan, &attributeChanges)
@@ -51,6 +53,7 @@ func useStateForUnknownsReplicationSpecs(ctx context.Context, diags *diag.Diagno
5153
}
5254
planWithUnknowns := []TFReplicationSpecsModel{}
5355
keepUnknownsUnchangedSpec := determineKeepUnknownsUnchangedReplicationSpecs(ctx, diags, state, plan, attrChanges)
56+
keepUnknownsUnchangedSpec = append(keepUnknownsUnchangedSpec, determineKeepUnknownsAutoScaling(ctx, diags, state, plan)...)
5457
if diags.HasError() {
5558
return
5659
}
@@ -95,6 +98,48 @@ func determineKeepUnknownsUnchangedReplicationSpecs(ctx context.Context, diags *
9598
return keepUnknowns
9699
}
97100

101+
func determineKeepUnknownsAutoScaling(ctx context.Context, diags *diag.Diagnostics, state, plan *TFModel) []string {
102+
var keepUnknown []string
103+
computedUsed, diskUsed := autoScalingUsed(ctx, diags, state, plan)
104+
if computedUsed {
105+
keepUnknown = append(keepUnknown, "instance_size")
106+
keepUnknown = append(keepUnknown, attributeReplicationSpecChangeMapping["instance_size"]...)
107+
}
108+
if diskUsed {
109+
keepUnknown = append(keepUnknown, "disk_size_gb")
110+
keepUnknown = append(keepUnknown, attributeReplicationSpecChangeMapping["disk_size_gb"]...)
111+
}
112+
return keepUnknown
113+
}
114+
115+
// autoScalingUsed checks is auto-scaling was enabled (state) or will be enabled (plan).
116+
func autoScalingUsed(ctx context.Context, diags *diag.Diagnostics, state, plan *TFModel) (computedUsed, diskUsed bool) {
117+
for _, model := range []*TFModel{state, plan} {
118+
repSpecsTF := TFModelList[TFReplicationSpecsModel](ctx, diags, model.ReplicationSpecs)
119+
for i := range repSpecsTF {
120+
regiongConfigsTF := TFModelList[TFRegionConfigsModel](ctx, diags, repSpecsTF[i].RegionConfigs)
121+
for j := range regiongConfigsTF {
122+
for _, autoScalingTF := range []types.Object{regiongConfigsTF[j].AutoScaling, regiongConfigsTF[j].AnalyticsAutoScaling} {
123+
if autoScalingTF.IsNull() || autoScalingTF.IsUnknown() {
124+
continue
125+
}
126+
autoscaling := TFModelObject[TFAutoScalingModel](ctx, diags, autoScalingTF)
127+
if autoscaling == nil {
128+
continue
129+
}
130+
if autoscaling.ComputeEnabled.ValueBool() {
131+
computedUsed = true
132+
}
133+
if autoscaling.DiskGBEnabled.ValueBool() {
134+
diskUsed = true
135+
}
136+
}
137+
}
138+
}
139+
}
140+
return
141+
}
142+
98143
func TFModelList[T any](ctx context.Context, diags *diag.Diagnostics, input types.List) []T {
99144
elements := make([]T, len(input.Elements()))
100145
if localDiags := input.ElementsAs(ctx, &elements, false); len(localDiags) > 0 {
@@ -103,3 +148,12 @@ func TFModelList[T any](ctx context.Context, diags *diag.Diagnostics, input type
103148
}
104149
return elements
105150
}
151+
152+
func TFModelObject[T any](ctx context.Context, diags *diag.Diagnostics, input types.Object) *T {
153+
item := new(T)
154+
if localDiags := input.As(ctx, item, basetypes.ObjectAsOptions{}); len(localDiags) > 0 {
155+
diags.Append(localDiags...)
156+
return nil
157+
}
158+
return item
159+
}

internal/service/advancedclustertpf/resource.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ type rs struct {
9999
// 1. UseStateForUnknown always copies the state for unknown values. However, that leads to `Error: Provider produced inconsistent result after apply` in some cases (see implementation below).
100100
// 2. Adding the different UseStateForUnknown is very verbose.
101101
func (r *rs) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
102-
if req.Plan.Raw.IsNull() || req.State.Raw.IsNull() { // Don't do anything if plan or state is null, this happens in Create, Delete or Import
102+
if req.Plan.Raw.IsNull() || req.State.Raw.IsNull() { // Return early unless it is an Update
103103
return
104104
}
105105
var plan, state TFModel

0 commit comments

Comments
 (0)