Skip to content

Commit 92094c2

Browse files
authored
CLOUDP-87818: add validations for quickstart (#672)
1 parent 4b0f40c commit 92094c2

File tree

6 files changed

+262
-51
lines changed

6 files changed

+262
-51
lines changed

internal/cli/atlas/quickstart/prompt.go

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/mongodb/mongocli/internal/randgen"
2424
"github.com/mongodb/mongocli/internal/store"
2525
"github.com/mongodb/mongocli/internal/usage"
26+
"github.com/mongodb/mongocli/internal/validate"
2627
)
2728

2829
const (
@@ -32,14 +33,27 @@ const (
3233
passwordLength = 12
3334
)
3435

35-
func newAccessListQuestion(publicIP, message string) *survey.Question {
36+
func newClusterNameQuestion(clusterName, message string) *survey.Question {
3637
return &survey.Question{
37-
Name: "ipAddress",
38+
Name: "clusterName",
3839
Prompt: &survey.Input{
39-
Message: fmt.Sprintf("Access List Entry%s:", message),
40-
Help: usage.NetworkAccessListIPEntry,
41-
Default: publicIP,
40+
Message: fmt.Sprintf("Cluster Name%s:", message),
41+
Help: usage.ClusterName,
42+
Default: clusterName,
43+
},
44+
Validate: survey.ComposeValidators(survey.Required, validate.ClusterName),
45+
}
46+
}
47+
48+
func newClusterProviderQuestion() *survey.Question {
49+
return &survey.Question{
50+
Name: "provider",
51+
Prompt: &survey.Select{
52+
Message: "Cloud Provider:",
53+
Help: usage.Provider,
54+
Options: []string{"AWS", "GCP", "AZURE"},
4255
},
56+
Validate: survey.Required,
4357
}
4458
}
4559

@@ -51,17 +65,31 @@ func newRegionQuestions(defaultRegions []string) *survey.Question {
5165
Help: usage.Region,
5266
Options: defaultRegions,
5367
},
68+
Validate: survey.Required,
5469
}
5570
}
56-
func newDBUsernameQuestion(dbUser, message string, validation func(val interface{}) error) *survey.Question {
71+
72+
func newAccessListQuestion(publicIP, message string) *survey.Question {
73+
return &survey.Question{
74+
Name: "ipAddress",
75+
Prompt: &survey.Input{
76+
Message: fmt.Sprintf("Access List Entry%s:", message),
77+
Help: usage.NetworkAccessListIPEntry,
78+
Default: publicIP,
79+
},
80+
Validate: survey.Required,
81+
}
82+
}
83+
84+
func newDBUsernameQuestion(dbUser, message string, validation survey.Validator) *survey.Question {
5785
q := &survey.Question{
58-
Validate: validation,
59-
Name: "dbUsername",
86+
Name: "dbUsername",
6087
Prompt: &survey.Input{
6188
Message: fmt.Sprintf("Database User Username%s:", message),
6289
Help: usage.DBUsername,
6390
Default: dbUser,
6491
},
92+
Validate: survey.ComposeValidators(survey.Required, validate.DBUsername, validation),
6593
}
6694
return q
6795
}
@@ -74,17 +102,7 @@ func newDBUserPasswordQuestion(password, message string) *survey.Question {
74102
Help: usage.Password,
75103
Default: password,
76104
},
77-
}
78-
}
79-
80-
func newClusterNameQuestion(clusterName, message string) *survey.Question {
81-
return &survey.Question{
82-
Name: "clusterName",
83-
Prompt: &survey.Input{
84-
Message: fmt.Sprintf("Cluster Name%s:", message),
85-
Help: usage.ClusterName,
86-
Default: clusterName,
87-
},
105+
Validate: survey.Required,
88106
}
89107
}
90108

@@ -95,17 +113,6 @@ func newSampleDataQuestion(clusterName string) *survey.Confirm {
95113
}
96114
}
97115

98-
func newClusterProviderQuestion() *survey.Question {
99-
return &survey.Question{
100-
Name: "provider",
101-
Prompt: &survey.Select{
102-
Message: "Cloud Provider:",
103-
Help: usage.Provider,
104-
Options: []string{"AWS", "GCP", "AZURE"},
105-
},
106-
}
107-
}
108-
109116
func newMongoShellQuestionAccessDeployment(clusterName string) *survey.Confirm {
110117
return &survey.Confirm{
111118
Message: fmt.Sprintf("Do you want to access %s with MongoDB Shell?", clusterName),
@@ -126,15 +133,15 @@ func newIsMongoShellInstalledQuestion() *survey.Confirm {
126133
}
127134
}
128135

129-
func newMongoShellPathInput(defaultValue string, validation func(val interface{}) error) *survey.Question {
136+
func newMongoShellPathInput(defaultValue string) *survey.Question {
130137
return &survey.Question{
131-
Validate: validation,
132-
Name: "mongoShellPath",
138+
Name: "mongoShellPath",
133139
Prompt: &survey.Input{
134140
Message: "Default MongoDB Shell Path:",
135141
Help: mongoShellHelp,
136142
Default: defaultValue,
137143
},
144+
Validate: validate.Path,
138145
}
139146
}
140147

@@ -192,7 +199,7 @@ func dbUserPasswordQuestion(password string) (string, *survey.Question) {
192199
return pwd, newDBUserPasswordQuestion(pwd, message)
193200
}
194201

195-
func dbUsernameQuestion(dbUser string, validation func(val interface{}) error) *survey.Question {
202+
func dbUsernameQuestion(dbUser string, validation survey.Validator) *survey.Question {
196203
if dbUser != "" {
197204
return nil
198205
}

internal/cli/atlas/quickstart/quick_start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ func askOpenBrowserQuestion() (bool, error) {
515515

516516
func askMongoShellAndSetConfig() error {
517517
var mongoShellPath string
518-
q := newMongoShellPathInput(mongosh.Path(), validate.Path)
518+
q := newMongoShellPathInput(mongosh.Path())
519519
if err := survey.Ask([]*survey.Question{q}, &mongoShellPath); err != nil {
520520
return err
521521
}

internal/store/store.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,26 @@ func NetworkPresets(c TransportConfigGetter) Option {
263263
return Options(options...)
264264
}
265265

266+
// ServiceGetter is a basic interface for service and base url settings
267+
type ServiceGetter interface {
268+
Service() string
269+
OpsManagerURL() string
270+
}
271+
266272
// Config an interface of the methods needed to set up a Store
267-
type Config interface {
273+
type AuthenticatedConfig interface {
268274
CredentialsGetter
269275
TransportConfigGetter
270-
Service() string
271-
OpsManagerURL() string
276+
ServiceGetter
277+
}
278+
279+
type BasicConfig interface {
280+
TransportConfigGetter
281+
ServiceGetter
272282
}
273283

274284
// PublicAuthenticatedPreset is the default Option when connecting to the public API with authentication.
275-
func PublicAuthenticatedPreset(c Config) Option {
285+
func PublicAuthenticatedPreset(c AuthenticatedConfig) Option {
276286
options := []Option{Service(c.Service()), WithAuthentication(c)}
277287
if configURL := c.OpsManagerURL(); configURL != "" {
278288
options = append(options, WithBaseURL(configURL), WithPublicPathBaseURL())
@@ -282,7 +292,7 @@ func PublicAuthenticatedPreset(c Config) Option {
282292
}
283293

284294
// PublicUnauthenticatedPreset is the default Option when connecting to the public API without authentication.
285-
func PublicUnauthenticatedPreset(c Config) Option {
295+
func PublicUnauthenticatedPreset(c AuthenticatedConfig) Option {
286296
options := []Option{Service(c.Service())}
287297
if configURL := c.OpsManagerURL(); configURL != "" {
288298
options = append(options, WithBaseURL(configURL), WithPublicPathBaseURL())
@@ -292,8 +302,9 @@ func PublicUnauthenticatedPreset(c Config) Option {
292302
}
293303

294304
// PrivateAuthenticatedPreset is the default Option when connecting to the private API with authentication.
295-
func PrivateAuthenticatedPreset(c Config) Option {
296-
options := []Option{Service(c.Service()), WithAuthentication(c)}
305+
func PrivateAuthenticatedPreset(c AuthenticatedConfig) Option {
306+
// Default to cloud
307+
options := []Option{Service(c.Service()), WithBaseURL(atlas.CloudURL), WithAuthentication(c)}
297308
if configURL := c.OpsManagerURL(); configURL != "" {
298309
options = append(options, WithBaseURL(configURL))
299310
}
@@ -302,8 +313,9 @@ func PrivateAuthenticatedPreset(c Config) Option {
302313
}
303314

304315
// PrivateUnauthenticatedPreset is the default Option when connecting to the private API without authentication.
305-
func PrivateUnauthenticatedPreset(c Config) Option {
306-
options := []Option{Service(c.Service())}
316+
func PrivateUnauthenticatedPreset(c BasicConfig) Option {
317+
// Default to cloud
318+
options := []Option{Service(c.Service()), WithBaseURL(atlas.CloudURL)}
307319
if configURL := c.OpsManagerURL(); configURL != "" {
308320
options = append(options, WithBaseURL(configURL))
309321
}

internal/store/store_test.go

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package store
1919
import (
2020
"testing"
2121

22+
"github.com/mongodb/mongocli/internal/config"
2223
"go.mongodb.org/atlas/mongodbatlas"
2324
)
2425

@@ -38,18 +39,18 @@ func (a auth) PrivateAPIKey() string {
3839
var _ CredentialsGetter = &auth{}
3940

4041
func TestService(t *testing.T) {
41-
c, err := New(Service("cloud"))
42+
c, err := New(Service(config.CloudService))
4243
if err != nil {
4344
t.Fatalf("New() unexpected error: %v", err)
4445
}
4546

46-
if c.service != "cloud" {
47+
if c.service != config.CloudService {
4748
t.Errorf("New() service = %s; expected %s", c.service, "cloud")
4849
}
4950
}
5051

5152
func TestWithBaseURL(t *testing.T) {
52-
c, err := New(Service("cloud"), WithBaseURL("http://test"))
53+
c, err := New(Service(config.CloudService), WithBaseURL("http://test"))
5354
if err != nil {
5455
t.Fatalf("New() unexpected error: %v", err)
5556
}
@@ -60,7 +61,7 @@ func TestWithBaseURL(t *testing.T) {
6061
}
6162

6263
func TestSkipVerify(t *testing.T) {
63-
c, err := New(Service("cloud"), SkipVerify())
64+
c, err := New(Service(config.CloudService), SkipVerify())
6465
if err != nil {
6566
t.Fatalf("New() unexpected error: %v", err)
6667
}
@@ -71,7 +72,7 @@ func TestSkipVerify(t *testing.T) {
7172
}
7273

7374
func TestWithPublicPathBaseURL(t *testing.T) {
74-
c, err := New(Service("cloud"), WithBaseURL("http://test"), WithPublicPathBaseURL())
75+
c, err := New(Service(config.CloudService), WithBaseURL("http://test"), WithPublicPathBaseURL())
7576
if err != nil {
7677
t.Fatalf("New() unexpected error: %v", err)
7778
}
@@ -82,6 +83,77 @@ func TestWithPublicPathBaseURL(t *testing.T) {
8283
}
8384
}
8485

86+
type testConfig struct {
87+
url string
88+
auth
89+
}
90+
91+
func (c testConfig) OpsManagerCACertificate() string {
92+
return ""
93+
}
94+
95+
func (c testConfig) OpsManagerSkipVerify() string {
96+
return "false"
97+
}
98+
99+
func (c testConfig) Service() string {
100+
return config.CloudService
101+
}
102+
103+
func (c testConfig) OpsManagerURL() string {
104+
return c.url
105+
}
106+
107+
var _ AuthenticatedConfig = &testConfig{}
108+
109+
func TestPrivateAuthenticatedPreset(t *testing.T) {
110+
t.Run("default", func(t *testing.T) {
111+
c, err := New(PrivateAuthenticatedPreset(testConfig{}))
112+
if err != nil {
113+
t.Fatalf("New() unexpected error: %v", err)
114+
}
115+
116+
if c.baseURL != mongodbatlas.CloudURL {
117+
t.Errorf("New() baseURL = %s; expected %s", c.baseURL, mongodbatlas.CloudURL)
118+
}
119+
})
120+
t.Run("with a base url", func(t *testing.T) {
121+
const url = "http://test"
122+
c, err := New(PrivateAuthenticatedPreset(testConfig{url: url}))
123+
if err != nil {
124+
t.Fatalf("New() unexpected error: %v", err)
125+
}
126+
127+
if c.baseURL != url {
128+
t.Errorf("New() baseURL = %s; expected %s", c.baseURL, url)
129+
}
130+
})
131+
}
132+
133+
func TestPrivateUnauthenticatedPreset(t *testing.T) {
134+
t.Run("default", func(t *testing.T) {
135+
c, err := New(PrivateUnauthenticatedPreset(testConfig{}))
136+
if err != nil {
137+
t.Fatalf("New() unexpected error: %v", err)
138+
}
139+
140+
if c.baseURL != mongodbatlas.CloudURL {
141+
t.Errorf("New() baseURL = %s; expected %s", c.baseURL, mongodbatlas.CloudURL)
142+
}
143+
})
144+
t.Run("with a base url", func(t *testing.T) {
145+
const url = "http://test"
146+
c, err := New(PrivateUnauthenticatedPreset(testConfig{url: url}))
147+
if err != nil {
148+
t.Fatalf("New() unexpected error: %v", err)
149+
}
150+
151+
if c.baseURL != url {
152+
t.Errorf("New() baseURL = %s; expected %s", c.baseURL, url)
153+
}
154+
})
155+
}
156+
85157
func TestWithAuthentication(t *testing.T) {
86158
a := auth{
87159
username: "username",

0 commit comments

Comments
 (0)