Skip to content

Commit 3af2fbc

Browse files
authored
CLOUDP-323576: Add autoScalingMode support to atlas clusters update (#3983)
1 parent d61c50c commit 3af2fbc

File tree

84 files changed

+1014
-500
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1014
-500
lines changed

docs/command/atlas-clusters-describe.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ Options
5858
- Type
5959
- Required
6060
- Description
61+
* - --autoScalingMode
62+
- string
63+
- false
64+
- Mode in which the cluster scales. Valid values are clusterWideScaling or independentShardScaling. This value defaults to "clusterWideScaling".
6165
* - -h, --help
6266
-
6367
- false

docs/command/atlas-clusters-update.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ Options
6767
- Type
6868
- Required
6969
- Description
70+
* - --autoScalingMode
71+
- string
72+
- false
73+
- Mode in which the cluster scales. Valid values are clusterWideScaling or independentShardScaling.
74+
75+
Mutually exclusive with --file.
7076
* - --disableTerminationProtection
7177
-
7278
- false
@@ -90,7 +96,7 @@ Options
9096
- false
9197
- Path to an optional JSON configuration file that defines cluster settings. Note: Unsupported fields in the JSON file are ignored. To learn more about cluster configuration files for the Atlas CLI, see https://dochub.mongodb.org/core/cluster-config-file-atlascli.
9298

93-
Mutually exclusive with --tier, --diskSizeGB, --enableTerminationProtection, --disableTerminationProtection, --tag.
99+
Mutually exclusive with --tier, --diskSizeGB, --enableTerminationProtection, --disableTerminationProtection, --tag, --autoScalingMode.
94100
* - -h, --help
95101
-
96102
- false

internal/cli/clusters/clusters.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ import (
2626
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/clusters/onlinearchive"
2727
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/clusters/sampledata"
2828
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/search"
29+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/file"
2930
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/telemetry"
31+
"github.com/spf13/afero"
3032
"github.com/spf13/cobra"
3133
atlasClustersPinned "go.mongodb.org/atlas-sdk/v20240530005/admin"
3234
atlasv2 "go.mongodb.org/atlas-sdk/v20250312003/admin"
@@ -202,6 +204,27 @@ func isClusterWideScaling(mode string) bool {
202204
return strings.EqualFold(mode, clusterWideScalingFlag) || strings.EqualFold(mode, clusterWideScalingResponse)
203205
}
204206

207+
func detectIsFileISS(fs afero.Fs, filename string) string {
208+
// First try to load as a default dedicated cluster in strict mode.
209+
// If it succeeds, it is a default dedicated cluster.
210+
oldCluster := new(atlasClustersPinned.AdvancedClusterDescription)
211+
oldLoadErr := file.StrictLoad(fs, filename, oldCluster)
212+
if oldLoadErr == nil {
213+
return clusterWideScalingFlag
214+
}
215+
216+
// Then try to load as an ISS cluster in strict mode.
217+
// If it succeeds, it is an ISS cluster. If it fails, it is a default dedicated cluster.
218+
cluster := new(atlasv2.ClusterDescription20240805)
219+
latestLoadErr := file.StrictLoad(fs, filename, cluster)
220+
if latestLoadErr == nil {
221+
return independentShardScalingFlag
222+
}
223+
224+
// default to cluster wide scaling
225+
return clusterWideScalingFlag
226+
}
227+
205228
func appendAutoScalingModeTelemetry(mode string) {
206229
if mode == "" {
207230
return

internal/cli/clusters/create.go

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func (opts *CreateOpts) RunDedicatedCluster() error {
195195
}
196196

197197
func (opts *CreateOpts) PostRun() error {
198-
if opts.autoScalingMode == independentShardScalingFlag {
198+
if isIndependentShardScaling(opts.autoScalingMode) {
199199
return opts.PostRunDedicatedClusterLatest()
200200
}
201201

@@ -500,41 +500,17 @@ func (opts *CreateOpts) validateAutoScalingMode() error {
500500
return err
501501
}
502502

503-
if opts.filename != "" && isIndependentShardScaling(opts.autoScalingMode) {
504-
return fmt.Errorf("auto scaling mode %s is not supported for files", opts.autoScalingMode)
505-
}
506-
507503
if opts.isFlexCluster {
508504
return nil
509505
}
510506

511507
if opts.filename != "" {
512-
opts.detectIsFileISS()
508+
opts.autoScalingMode = detectIsFileISS(opts.fs, opts.filename)
513509
}
514510

515511
return nil
516512
}
517513

518-
func (opts *CreateOpts) detectIsFileISS() {
519-
// First try to load as a default dedicated cluster in strict mode.
520-
// If it succeeds, it is a default dedicated cluster.
521-
oldCluster := new(atlasClustersPinned.AdvancedClusterDescription)
522-
oldLoadErr := file.StrictLoad(opts.fs, opts.filename, oldCluster)
523-
if oldLoadErr == nil {
524-
opts.autoScalingMode = clusterWideScalingFlag
525-
return
526-
}
527-
528-
// Then try to load as an ISS cluster in strict mode.
529-
// If it succeeds, it is an ISS cluster. If it fails, it is a default dedicated cluster.
530-
cluster := new(atlasv2.ClusterDescription20240805)
531-
latestLoadErr := file.StrictLoad(opts.fs, opts.filename, cluster)
532-
if latestLoadErr == nil {
533-
opts.autoScalingMode = independentShardScalingFlag
534-
return
535-
}
536-
}
537-
538514
// CreateBuilder builds a cobra.Command that can run as:
539515
// create <name> --projectId projectId --provider AWS|GCP|AZURE --region regionName [--members N] [--tier M#] [--diskSizeGB N] [--backup] [--mdbVersion] [--tag key=value].
540516
func CreateBuilder() *cobra.Command {

internal/cli/clusters/create_test.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -451,21 +451,7 @@ func TestCreateOpts_RunDedicatedClusterLatest(t *testing.T) {
451451
require.NoError(t, createOpts.Run())
452452
})
453453

454-
t.Run("filename and autoScalingMode are not compatible", func(t *testing.T) {
455-
appFS := afero.NewMemMapFs()
456-
_ = afero.WriteFile(appFS, fileName, []byte("invalid"), 0600)
457-
458-
createOpts := &CreateOpts{
459-
filename: fileName,
460-
fs: appFS,
461-
store: mockStore,
462-
autoScalingMode: independentShardScalingFlag,
463-
}
464-
465-
require.Error(t, createOpts.validateAutoScalingMode())
466-
})
467-
468-
t.Run("does not set autoScalingMode if invalid file", func(t *testing.T) {
454+
t.Run("default to clusterWideScaling if invalid file", func(t *testing.T) {
469455
appFS := afero.NewMemMapFs()
470456
_ = afero.WriteFile(appFS, fileName, []byte("invalid"), 0600)
471457

@@ -476,7 +462,7 @@ func TestCreateOpts_RunDedicatedClusterLatest(t *testing.T) {
476462
}
477463

478464
require.NoError(t, createOpts.validateAutoScalingMode())
479-
assert.Empty(t, createOpts.autoScalingMode)
465+
assert.Equal(t, clusterWideScalingFlag, createOpts.autoScalingMode)
480466
})
481467
}
482468

internal/cli/clusters/describe.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ import (
1919
"fmt"
2020

2121
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
22+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/commonerrors"
2223
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/require"
2324
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/config"
25+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/flag"
2426
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/store"
2527
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/usage"
28+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/validate"
2629
"github.com/spf13/cobra"
2730
atlasClustersPinned "go.mongodb.org/atlas-sdk/v20240530005/admin"
2831
atlasv2 "go.mongodb.org/atlas-sdk/v20250312003/admin"
@@ -34,14 +37,14 @@ type ClusterDescriber interface {
3437
AtlasCluster(string, string) (*atlasClustersPinned.AdvancedClusterDescription, error)
3538
FlexCluster(string, string) (*atlasv2.FlexClusterDescription20241113, error)
3639
LatestAtlasCluster(string, string) (*atlasv2.ClusterDescription20240805, error)
37-
GetClusterAutoScalingConfig(string, string) (*atlasv2.ClusterDescriptionAutoScalingModeConfiguration, error)
3840
}
3941

4042
type DescribeOpts struct {
4143
cli.ProjectOpts
4244
cli.OutputOpts
43-
name string
44-
store ClusterDescriber
45+
name string
46+
autoScalingMode string
47+
store ClusterDescriber
4548
}
4649

4750
func (opts *DescribeOpts) initStore(ctx context.Context) func() error {
@@ -57,9 +60,7 @@ var describeTemplate = `ID NAME MDB VER STATE
5760
`
5861

5962
func (opts *DescribeOpts) Run() error {
60-
autoScalingModeConfig, err := opts.store.GetClusterAutoScalingConfig(opts.ConfigProjectID(), opts.name)
61-
appendAutoScalingModeTelemetry(autoScalingModeConfig.GetAutoScalingMode())
62-
if err == nil && isIndependentShardScaling(autoScalingModeConfig.GetAutoScalingMode()) {
63+
if opts.autoScalingMode != "" && isIndependentShardScaling(opts.autoScalingMode) {
6364
r, err := opts.store.LatestAtlasCluster(opts.ConfigProjectID(), opts.name)
6465
if err != nil {
6566
return err
@@ -82,12 +83,12 @@ func (opts *DescribeOpts) RunFlexCluster(err error) error {
8283
}
8384

8485
if *apiError.ErrorCode != cannotUseFlexWithClusterApisErrorCode {
85-
return err
86+
return commonerrors.Check(err)
8687
}
8788

8889
r, err := opts.store.FlexCluster(opts.ConfigProjectID(), opts.name)
8990
if err != nil {
90-
return err
91+
return commonerrors.Check(err)
9192
}
9293

9394
return opts.Print(r)
@@ -114,6 +115,7 @@ func DescribeBuilder() *cobra.Command {
114115
opts.ValidateProjectID,
115116
opts.initStore(cmd.Context()),
116117
opts.InitOutput(cmd.OutOrStdout(), describeTemplate),
118+
validate.AutoScalingMode(opts.autoScalingMode),
117119
)
118120
},
119121
RunE: func(_ *cobra.Command, args []string) error {
@@ -124,6 +126,10 @@ func DescribeBuilder() *cobra.Command {
124126

125127
opts.AddProjectOptsFlags(cmd)
126128
opts.AddOutputOptFlags(cmd)
129+
cmd.Flags().StringVar(&opts.autoScalingMode, flag.AutoScalingMode, clusterWideScalingFlag, usage.AutoScalingMode)
130+
_ = cmd.RegisterFlagCompletionFunc(flag.AutoScalingMode, func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
131+
return []string{clusterWideScalingFlag, independentShardScalingFlag}, cobra.ShellCompDirectiveDefault
132+
})
127133

128134
return cmd
129135
}

internal/cli/clusters/describe_mock_test.go

Lines changed: 0 additions & 39 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/cli/clusters/describe_test.go

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ import (
2828
"go.uber.org/mock/gomock"
2929
)
3030

31-
var clusterWideScalingConfig = &atlasv2.ClusterDescriptionAutoScalingModeConfiguration{AutoScalingMode: pointer.Get(clusterWideScalingResponse)}
32-
var independentShardScalingConfig = &atlasv2.ClusterDescriptionAutoScalingModeConfiguration{AutoScalingMode: pointer.Get(independentShardScalingResponse)}
33-
3431
func TestDescribe_Run(t *testing.T) {
3532
ctrl := gomock.NewController(t)
3633
mockStore := NewMockClusterDescriber(ctrl)
@@ -42,12 +39,6 @@ func TestDescribe_Run(t *testing.T) {
4239
store: mockStore,
4340
}
4441

45-
mockStore.
46-
EXPECT().
47-
GetClusterAutoScalingConfig(describeOpts.ProjectID, describeOpts.name).
48-
Return(clusterWideScalingConfig, nil).
49-
Times(1)
50-
5142
mockStore.
5243
EXPECT().
5344
AtlasCluster(describeOpts.ProjectID, describeOpts.name).
@@ -71,12 +62,6 @@ func TestDescribe_RunFlexCluster(t *testing.T) {
7162
store: mockStore,
7263
}
7364

74-
mockStore.
75-
EXPECT().
76-
GetClusterAutoScalingConfig(describeOpts.ProjectID, describeOpts.name).
77-
Return(clusterWideScalingConfig, nil).
78-
Times(1)
79-
8065
mockStore.
8166
EXPECT().
8267
AtlasCluster(describeOpts.ProjectID, describeOpts.name).
@@ -105,12 +90,6 @@ func TestDescribe_RunFlexCluster_Error(t *testing.T) {
10590
store: mockStore,
10691
}
10792

108-
mockStore.
109-
EXPECT().
110-
GetClusterAutoScalingConfig(describeOpts.ProjectID, describeOpts.name).
111-
Return(clusterWideScalingConfig, nil).
112-
Times(1)
113-
11493
mockStore.
11594
EXPECT().
11695
AtlasCluster(describeOpts.ProjectID, describeOpts.name).
@@ -133,16 +112,11 @@ func TestDescribe_RunDedicatedCluster_IndependentShardScaling(t *testing.T) {
133112
expected := &atlasv2.ClusterDescription20240805{}
134113

135114
describeOpts := &DescribeOpts{
136-
name: "test",
137-
store: mockStore,
115+
name: "test",
116+
store: mockStore,
117+
autoScalingMode: independentShardScalingFlag,
138118
}
139119

140-
mockStore.
141-
EXPECT().
142-
GetClusterAutoScalingConfig(describeOpts.ProjectID, describeOpts.name).
143-
Return(independentShardScalingConfig, nil).
144-
Times(1)
145-
146120
mockStore.
147121
EXPECT().
148122
LatestAtlasCluster(describeOpts.ProjectID, describeOpts.name).

0 commit comments

Comments
 (0)