Skip to content

Commit ac25b32

Browse files
authored
CLOUDP-54305: CLI: Atlas cluster update via config file (#31)
1 parent 824df5c commit ac25b32

File tree

5 files changed

+122
-42
lines changed

5 files changed

+122
-42
lines changed

internal/cli/atlas_clusters_create.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package cli
1616

1717
import (
18-
"errors"
19-
2018
atlas "github.com/mongodb/go-client-mongodb-atlas/mongodbatlas"
2119
"github.com/mongodb/mcli/internal/file"
2220
"github.com/mongodb/mcli/internal/flags"
@@ -159,7 +157,7 @@ func AtlasClustersCreateBuilder() *cobra.Command {
159157
_ = cmd.MarkFlagRequired(flags.Region)
160158

161159
if len(args) == 0 {
162-
return errors.New("cluster name missing")
160+
return errMissingClusterName
163161
}
164162
opts.name = args[0]
165163
}
@@ -177,7 +175,7 @@ func AtlasClustersCreateBuilder() *cobra.Command {
177175
cmd.Flags().Float64Var(&opts.diskSizeGB, flags.DiskSizeGB, 2, usage.DiskSizeGB)
178176
cmd.Flags().StringVar(&opts.mdbVersion, flags.MDBVersion, currentMDBVersion, usage.MDBVersion)
179177
cmd.Flags().BoolVar(&opts.backup, flags.Backup, false, usage.Backup)
180-
cmd.Flags().StringVarP(&opts.filename, flags.File, flags.FileShort, "", "Filename to use to deploy a new cluster")
178+
cmd.Flags().StringVarP(&opts.filename, flags.File, flags.FileShort, "", usage.Filename)
181179

182180
cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID)
183181

internal/cli/atlas_clusters_update.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ package cli
1616

1717
import (
1818
atlas "github.com/mongodb/go-client-mongodb-atlas/mongodbatlas"
19+
"github.com/mongodb/mcli/internal/file"
1920
"github.com/mongodb/mcli/internal/flags"
2021
"github.com/mongodb/mcli/internal/json"
2122
"github.com/mongodb/mcli/internal/store"
2223
"github.com/mongodb/mcli/internal/usage"
24+
"github.com/spf13/afero"
2325
"github.com/spf13/cobra"
2426
)
2527

@@ -29,6 +31,8 @@ type atlasClustersUpdateOpts struct {
2931
instanceSize string
3032
diskSizeGB float64
3133
mdbVersion string
34+
filename string
35+
fs afero.Fs
3236
store store.ClusterStore
3337
}
3438

@@ -42,15 +46,17 @@ func (opts *atlasClustersUpdateOpts) init() error {
4246
}
4347

4448
func (opts *atlasClustersUpdateOpts) Run() error {
45-
current, err := opts.store.Cluster(opts.projectID, opts.name)
46-
49+
cluster, err := opts.cluster()
4750
if err != nil {
4851
return err
4952
}
53+
if opts.filename == "" {
54+
opts.patchOpts(cluster)
55+
} else {
56+
cluster.GroupID = opts.ProjectID()
57+
}
5058

51-
opts.update(current)
52-
53-
result, err := opts.store.UpdateCluster(current)
59+
result, err := opts.store.UpdateCluster(cluster)
5460

5561
if err != nil {
5662
return err
@@ -59,7 +65,19 @@ func (opts *atlasClustersUpdateOpts) Run() error {
5965
return json.PrettyPrint(result)
6066
}
6167

62-
func (opts *atlasClustersUpdateOpts) update(out *atlas.Cluster) {
68+
func (opts *atlasClustersUpdateOpts) cluster() (*atlas.Cluster, error) {
69+
var cluster *atlas.Cluster
70+
var err error
71+
if opts.filename != "" {
72+
cluster = new(atlas.Cluster)
73+
err = file.Load(opts.fs, opts.filename, cluster)
74+
} else {
75+
cluster, err = opts.store.Cluster(opts.projectID, opts.name)
76+
}
77+
return cluster, err
78+
}
79+
80+
func (opts *atlasClustersUpdateOpts) patchOpts(out *atlas.Cluster) {
6381
// There can only be one
6482
if out.ReplicationSpecs != nil {
6583
out.ReplicationSpec = nil
@@ -74,11 +92,9 @@ func (opts *atlasClustersUpdateOpts) update(out *atlas.Cluster) {
7492
if opts.mdbVersion != "" {
7593
out.MongoDBMajorVersion = opts.mdbVersion
7694
}
77-
7895
if opts.diskSizeGB > 0 {
7996
out.DiskSizeGB = &opts.diskSizeGB
8097
}
81-
8298
if opts.instanceSize != "" {
8399
out.ProviderSettings.InstanceSizeName = opts.instanceSize
84100
}
@@ -88,24 +104,31 @@ func (opts *atlasClustersUpdateOpts) update(out *atlas.Cluster) {
88104
func AtlasClustersUpdateBuilder() *cobra.Command {
89105
opts := &atlasClustersUpdateOpts{
90106
globalOpts: newGlobalOpts(),
107+
fs: afero.NewOsFs(),
91108
}
92109
cmd := &cobra.Command{
93110
Use: "update [name]",
94111
Short: "Update a MongoDB cluster in Atlas.",
95112
Example: ` mcli atlas cluster update myCluster --projectId=1 --instanceSize M2 --mdbVersion 4.2 --diskSizeGB 2`,
96-
Args: cobra.ExactArgs(1),
113+
Args: cobra.MaximumNArgs(1),
97114
PreRunE: func(cmd *cobra.Command, args []string) error {
115+
if opts.filename == "" {
116+
if len(args) == 0 {
117+
return errMissingClusterName
118+
}
119+
opts.name = args[0]
120+
}
98121
return opts.init()
99122
},
100123
RunE: func(cmd *cobra.Command, args []string) error {
101-
opts.name = args[0]
102124
return opts.Run()
103125
},
104126
}
105127

106128
cmd.Flags().StringVar(&opts.instanceSize, flags.InstanceSize, "", usage.InstanceSize)
107129
cmd.Flags().Float64Var(&opts.diskSizeGB, flags.DiskSizeGB, 0, usage.DiskSizeGB)
108130
cmd.Flags().StringVar(&opts.mdbVersion, flags.MDBVersion, "", usage.MDBVersion)
131+
cmd.Flags().StringVarP(&opts.filename, flags.File, flags.FileShort, "", usage.Filename)
109132

110133
cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID)
111134

internal/cli/atlas_clusters_update_test.go

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/golang/mock/gomock"
2121
"github.com/mongodb/mcli/internal/fixtures"
2222
"github.com/mongodb/mcli/internal/mocks"
23+
"github.com/spf13/afero"
2324
)
2425

2526
func TestAtlasClustersUpdate_Run(t *testing.T) {
@@ -28,32 +29,87 @@ func TestAtlasClustersUpdate_Run(t *testing.T) {
2829

2930
defer ctrl.Finish()
3031

31-
expected := fixtures.Cluster()
32-
33-
createOpts := &atlasClustersUpdateOpts{
34-
globalOpts: newGlobalOpts(),
35-
name: "ProjectBar",
36-
instanceSize: atlasM2,
37-
diskSizeGB: 10,
38-
mdbVersion: currentMDBVersion,
39-
store: mockStore,
40-
}
41-
42-
mockStore.
43-
EXPECT().
44-
Cluster(createOpts.projectID, createOpts.name).
45-
Return(expected, nil).
46-
Times(1)
47-
48-
createOpts.update(expected)
49-
50-
mockStore.
51-
EXPECT().
52-
UpdateCluster(expected).Return(expected, nil).
53-
Times(1)
54-
55-
err := createOpts.Run()
56-
if err != nil {
57-
t.Fatalf("Run() unexpected error: %v", err)
58-
}
32+
t.Run("flags run", func(t *testing.T) {
33+
expected := fixtures.Cluster()
34+
35+
createOpts := &atlasClustersUpdateOpts{
36+
globalOpts: newGlobalOpts(),
37+
name: "ProjectBar",
38+
instanceSize: atlasM2,
39+
diskSizeGB: 10,
40+
mdbVersion: currentMDBVersion,
41+
store: mockStore,
42+
}
43+
44+
mockStore.
45+
EXPECT().
46+
Cluster(createOpts.projectID, createOpts.name).
47+
Return(expected, nil).
48+
Times(1)
49+
50+
createOpts.patchOpts(expected)
51+
52+
mockStore.
53+
EXPECT().
54+
UpdateCluster(expected).Return(expected, nil).
55+
Times(1)
56+
57+
err := createOpts.Run()
58+
if err != nil {
59+
t.Fatalf("Run() unexpected error: %v", err)
60+
}
61+
})
62+
63+
t.Run("file run", func(t *testing.T) {
64+
appFS := afero.NewMemMapFs()
65+
// create test file
66+
fileYML := `
67+
{
68+
"name": "ProjectBar",
69+
"diskSizeGB": 10,
70+
"numShards": 1,
71+
"providerSettings": {
72+
"providerName": "AWS",
73+
"instanceSizeName": "M2",
74+
"regionName": "US"
75+
},
76+
"clusterType" : "REPLICASET",
77+
"replicationFactor": 3,
78+
"replicationSpecs": [{
79+
"numShards": 1,
80+
"regionsConfig": {
81+
"US_EAST_1": {
82+
"analyticsNodes": 0,
83+
"electableNodes": 3,
84+
"priority": 7,
85+
"readOnlyNodes": 0
86+
}
87+
},
88+
"zoneName": "Zone 1"
89+
}],
90+
"backupEnabled": false,
91+
"providerBackupEnabled" : false
92+
}`
93+
fileName := "test.json"
94+
_ = afero.WriteFile(appFS, fileName, []byte(fileYML), 0600)
95+
expected := fixtures.Cluster()
96+
97+
createOpts := &atlasClustersUpdateOpts{
98+
globalOpts: newGlobalOpts(),
99+
filename: fileName,
100+
fs: appFS,
101+
store: mockStore,
102+
}
103+
104+
cluster, _ := createOpts.cluster()
105+
mockStore.
106+
EXPECT().
107+
UpdateCluster(cluster).Return(expected, nil).
108+
Times(1)
109+
110+
err := createOpts.Run()
111+
if err != nil {
112+
t.Fatalf("Run() unexpected error: %v", err)
113+
}
114+
})
59115
}

internal/cli/errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package cli
1616

1717
import (
18+
"errors"
1819
"fmt"
1920

2021
"github.com/mongodb/mcli/internal/flags"
@@ -24,3 +25,4 @@ const requiredF = `required flag(s) "%s" not set`
2425

2526
var errMissingProjectID = fmt.Errorf(requiredF, flags.ProjectID)
2627
var errMissingOrgID = fmt.Errorf(requiredF, flags.OrgID)
28+
var errMissingClusterName = errors.New("cluster name missing")

internal/usage/usage.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const (
3333
Email = "User’s email address."
3434
FirstName = "User’s first name."
3535
LastName = "User’s last name."
36+
Filename = "Filename to use"
3637
WhitelistIps = "IP addresses to add to the new user’s whitelist."
3738
WhitelistType = `Type of whitelist entry.
3839
Valid values: cidrBlock|ipAddress`

0 commit comments

Comments
 (0)