Skip to content

Commit 49f3c70

Browse files
authored
chore: Adds initial TPF implementation for advanced_cluster (#2813)
* initial create operation * initial resource implementation * support returning nil when advanced config fields are null * test: Add support for overriding http round tripper to allow mocking http request/responses * minor error renaming * remove mocked responses * test: initial TestAdvancedCluster_configSharded requests * chore: use same admin version as existing cluster * mock: allow re-reading GETs * test: support raising error when mock variables are not set * fix: don't dump GroupID in cluster payloads * test: update test case to match existing * refactor: use full request.id() to keep aligned with generator format (differentiate requests with the distinct payloads) * fix: add `computed` to adv_cluster attributes to avoid provider errors * test: minor mock fixes * feat: support state transitions and pause logic * chore: test data updates * test: Support overriding diff files by using `_manual` suffix * style: fmt * test: delete old mock files * test: rename basic to replicast * fix: Deleted should support IDLE --> DELETED * fix: cluster name update requires replace * test: Add tenant test case * chore: include provider changes * fix(move_state): Use ValueString() and do a proper conversion * test: Support mocking test case * refactor: use new `unit.MockTestCase` to simplify resource_test.go * test: Introduce "live" acceptance test for tpf * refactor: re-use existing retry strategy states * refactor: introduce constant.error_codes * refactor: minor cleanups * test: Refactor MockTestCase to also run and support setting TF_ACC dynamically * chore: increase unit test timeout to enable tpf unit tests * minor improvements * unit test timeout increase. Used 75s locally * ci: support running mocked acceptance tests as part of advanced_cluster_tpf job * ci: as of now, advancedclustertpf unit tests cannot run as part of normal unit test since the resource is not added in provider * test: Skip broken move_state_tests * minor fix * chore: fix imports to latest SDK * estetic change to workflow file * refactor: Use provider_mock instead of customizing existing provider (revert all changes to client.go and provider.go * address PR comments * use `diags` instead of returning summary, detail * only removeResource in read * address immediate PR comments * refactor: Use a higher abstraction level in update * refactor: Return TFModel to make purpose more explicit * refactor: Replace awaitChanges method with AwaitChanges function for improved clarity and consistency * apply suggestion * chore: Add step count assertion * refactor: move out all the unit tests and mocked unit test logic * remove: accidental provider changes * remove last changes for unit tests
1 parent 213dea1 commit 49f3c70

36 files changed

+444
-1781
lines changed
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package retrystrategy
22

33
const (
4-
RetryStrategyPendingState = "PENDING"
5-
RetryStrategyCompletedState = "COMPLETED"
6-
RetryStrategyErrorState = "ERROR"
7-
RetryStrategyPausedState = "PAUSED"
8-
RetryStrategyUpdatingState = "UPDATING"
9-
RetryStrategyDeletingState = "DELETING"
10-
RetryStrategyInitiatingState = "INITIATING"
11-
RetryStrategyIdleState = "IDLE"
12-
RetryStrategyFailedState = "FAILED"
13-
RetryStrategyActiveState = "ACTIVE"
14-
RetryStrategyDeletedState = "DELETED"
15-
RetryStrategyCreatingState = "CREATING"
16-
4+
RetryStrategyActiveState = "ACTIVE"
5+
RetryStrategyCompletedState = "COMPLETED"
6+
RetryStrategyCreatingState = "CREATING"
7+
RetryStrategyDeletedState = "DELETED"
8+
RetryStrategyDeletingState = "DELETING"
9+
RetryStrategyErrorState = "ERROR"
10+
RetryStrategyFailedState = "FAILED"
11+
RetryStrategyIdleState = "IDLE"
12+
RetryStrategyInitiatingState = "INITIATING"
13+
RetryStrategyPausedState = "PAUSED"
1714
RetryStrategyPendingAcceptanceState = "PENDING_ACCEPTANCE"
1815
RetryStrategyPendingRecreationState = "PENDING_RECREATION"
16+
RetryStrategyPendingState = "PENDING"
17+
RetryStrategyRepairingState = "REPAIRING"
18+
RetryStrategyRepeatingState = "REPEATING"
19+
RetryStrategyUpdatingState = "UPDATING"
1920
)

internal/service/advancedclustertpf/model_ClusterDescription20240805.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/hashicorp/terraform-plugin-framework/diag"
88
"github.com/hashicorp/terraform-plugin-framework/types"
99
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
10-
"go.mongodb.org/atlas-sdk/v20241113001/admin"
10+
"go.mongodb.org/atlas-sdk/v20240805005/admin"
1111
)
1212

1313
func NewTFModel(ctx context.Context, input *admin.ClusterDescription20240805, timeout timeouts.Value, diags *diag.Diagnostics) *TFModel {
@@ -120,7 +120,8 @@ func NewReplicationSpecsObjType(ctx context.Context, input *[]admin.ReplicationS
120120

121121
func NewTagsObjType(ctx context.Context, input *[]admin.ResourceTag, diags *diag.Diagnostics) types.Set {
122122
if input == nil {
123-
return types.SetNull(TagsObjType)
123+
// API Response not consistent, even when not set in POST/PATCH `[]` is returned instead of null
124+
return types.SetValueMust(TagsObjType, nil)
124125
}
125126
tfModels := make([]TFTagsModel, len(*input))
126127
for i, item := range *input {

internal/service/advancedclustertpf/model_ClusterDescriptionProcessArgs20240805.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/hashicorp/terraform-plugin-framework/types"
88
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
99
admin20240530 "go.mongodb.org/atlas-sdk/v20240530005/admin"
10-
"go.mongodb.org/atlas-sdk/v20241113001/admin"
10+
"go.mongodb.org/atlas-sdk/v20240805005/admin"
1111
)
1212

1313
func AddAdvancedConfig(ctx context.Context, tfModel *TFModel, input *admin.ClusterDescriptionProcessArgs20240805, inputLegacy *admin20240530.ClusterDescriptionProcessArgs, diags *diag.Diagnostics) {

internal/service/advancedclustertpf/model_to_ClusterDescription20240805.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"github.com/hashicorp/terraform-plugin-framework/types"
99
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1010
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
11-
"go.mongodb.org/atlas-sdk/v20241113001/admin"
11+
"go.mongodb.org/atlas-sdk/v20240805005/admin"
1212
)
1313

1414
func NewAtlasReq(ctx context.Context, input *TFModel, diags *diag.Diagnostics) *admin.ClusterDescription20240805 {
@@ -24,7 +24,6 @@ func NewAtlasReq(ctx context.Context, input *TFModel, diags *diag.Diagnostics) *
2424
ConfigServerManagementMode: conversion.NilForUnknown(input.ConfigServerManagementMode, input.ConfigServerManagementMode.ValueStringPointer()),
2525
EncryptionAtRestProvider: conversion.NilForUnknown(input.EncryptionAtRestProvider, input.EncryptionAtRestProvider.ValueStringPointer()),
2626
GlobalClusterSelfManagedSharding: conversion.NilForUnknown(input.GlobalClusterSelfManagedSharding, input.GlobalClusterSelfManagedSharding.ValueBoolPointer()),
27-
GroupId: input.ProjectID.ValueStringPointer(),
2827
Labels: newComponentLabel(ctx, input.Labels, diags),
2928
MongoDBMajorVersion: conversion.NilForUnknown(input.MongoDBMajorVersion, input.MongoDBMajorVersion.ValueStringPointer()),
3029
Name: input.Name.ValueStringPointer(),

internal/service/advancedclustertpf/model_to_ClusterDescriptionProcessArgs20240805.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/hashicorp/terraform-plugin-framework/types"
88
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
99
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
10-
"go.mongodb.org/atlas-sdk/v20241113001/admin"
10+
"go.mongodb.org/atlas-sdk/v20240805005/admin"
1111
)
1212

1313
func NewAtlasReqAdvancedConfiguration(ctx context.Context, objInput *types.Object, diags *diag.Diagnostics) *admin.ClusterDescriptionProcessArgs20240805 {

internal/service/advancedclustertpf/move_state.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"github.com/hashicorp/terraform-plugin-framework/types"
1515
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
1616
"github.com/hashicorp/terraform-plugin-go/tftypes"
17+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
18+
"go.mongodb.org/atlas-sdk/v20240805005/admin"
1719
)
1820

1921
const (
@@ -140,7 +142,7 @@ func stateMoverTemporaryPreferred(ctx context.Context, req resource.MoveStateReq
140142
if resp.Diagnostics.HasError() {
141143
return
142144
}
143-
setMoveState(ctx, state.ProjectID.String(), state.Username.String(), resp)
145+
setMoveState(ctx, state.ProjectID.ValueString(), state.Username.ValueString(), resp)
144146
}
145147

146148
func stateMoverTemporaryRawState(ctx context.Context, req resource.MoveStateRequest, resp *resource.MoveStateResponse) {
@@ -241,12 +243,16 @@ func setMoveState(ctx context.Context, projectID, clusterName string, resp *reso
241243
}),
242244
}
243245
// TODO: we need to have a good state (all attributes known or null) but not need to be the final ones as Read is called after
244-
tfNewModel, shouldReturn := mockedSDK(ctx, &resp.Diagnostics, timeout)
245-
if shouldReturn {
246+
model := NewTFModel(ctx, &admin.ClusterDescription20240805{
247+
GroupId: conversion.StringPtr(projectID),
248+
Name: conversion.StringPtr(clusterName),
249+
}, timeout, &resp.Diagnostics)
250+
if resp.Diagnostics.HasError() {
251+
return
252+
}
253+
AddAdvancedConfig(ctx, model, nil, nil, &resp.Diagnostics)
254+
if resp.Diagnostics.HasError() {
246255
return
247256
}
248-
// TODO: setting attributed needed by Read, confirm if ClusterID is needed
249-
tfNewModel.ProjectID = types.StringValue(projectID)
250-
tfNewModel.Name = types.StringValue(clusterName)
251-
resp.Diagnostics.Append(resp.TargetState.Set(ctx, tfNewModel)...)
257+
resp.Diagnostics.Append(resp.TargetState.Set(ctx, model)...)
252258
}

internal/service/advancedclustertpf/move_state_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package advancedclustertpf_test
22

33
import (
44
"fmt"
5+
"os"
56
"regexp"
67
"testing"
78

@@ -15,6 +16,7 @@ func TestAccAdvancedCluster_move_preferred(t *testing.T) {
1516
projectID = acc.ProjectIDExecution(t)
1617
clusterName = acc.RandomClusterName()
1718
)
19+
skipIfMoveTestsNotSet(t)
1820
t.Setenv(advancedclustertpf.MoveModeEnvVarName, advancedclustertpf.MoveModeValPreferred)
1921
// TODO: temporary no parallel tests so t.Setenv can be used
2022
resource.Test(t, resource.TestCase{
@@ -34,11 +36,20 @@ func TestAccAdvancedCluster_move_preferred(t *testing.T) {
3436
})
3537
}
3638

39+
// Skip for now as these needs to either run with mock data or be refactored to use a live cluster
40+
func skipIfMoveTestsNotSet(t *testing.T) {
41+
t.Helper()
42+
if os.Getenv("TF_RUN_MOVED_TESTS") == "" {
43+
t.Skip("Move tests are skipped unless TF_RUN_MOVED_TESTS is set")
44+
}
45+
}
46+
3747
func TestAccAdvancedCluster_move_rawstate(t *testing.T) {
3848
var (
3949
projectID = acc.ProjectIDExecution(t)
4050
clusterName = acc.RandomClusterName()
4151
)
52+
skipIfMoveTestsNotSet(t)
4253
t.Setenv(advancedclustertpf.MoveModeEnvVarName, advancedclustertpf.MoveModeValRawState)
4354
resource.Test(t, resource.TestCase{
4455
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
@@ -62,6 +73,7 @@ func TestAccAdvancedCluster_move_json(t *testing.T) {
6273
projectID = acc.ProjectIDExecution(t)
6374
clusterName = acc.RandomClusterName()
6475
)
76+
skipIfMoveTestsNotSet(t)
6577
t.Setenv(advancedclustertpf.MoveModeEnvVarName, advancedclustertpf.MoveModeValJSON)
6678
resource.Test(t, resource.TestCase{
6779
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,

0 commit comments

Comments
 (0)