Skip to content

Commit 8ba3d21

Browse files
authored
init: Provide alternative API validation call (#197)
Changes the message returned when the API call to validate the API key cannot be made, and tries a different api (GET /deployments) before returning a more curated error. Signed-off-by: Marc Lopez <marc5.12@outlook.com>
1 parent 0352d8e commit 8ba3d21

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

pkg/ecctl/init.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"strconv"
2929
"strings"
3030

31+
"github.com/elastic/ecctl/pkg/deployment"
3132
"github.com/elastic/ecctl/pkg/user"
3233

3334
"github.com/elastic/cloud-sdk-go/pkg/input"
@@ -102,7 +103,9 @@ const (
102103
//nolint
103104
passMsg = "Type in your password: "
104105

105-
validCredentialsMsg = "Your credentials seem to be valid, and show you're authenticated as \"%s\".\n\n"
106+
validCredentialsMsg = "Your credentials seem to be valid, and show you're authenticated as \"%s\".\n\n"
107+
validCredentialsAlternativeMsg = "Your credentials seem to be valid.\n\n"
108+
invalidCredentialsMsg = "Your credentials couldn't be validated. Make sure they're correct and try again"
106109
)
107110

108111
var (
@@ -166,7 +169,6 @@ Please enter a choice: `
166169

167170
finalMsg = `
168171
You're all set! Here are some commands to try:
169-
$ ecctl auth user key list
170172
$ ecctl deployment elasticsearch list`[1:]
171173

172174
// Remove once we have an endpoint available to list regions.
@@ -480,7 +482,14 @@ func validateAuth(cfg Config, writer io.Writer) error {
480482

481483
u, err := user.GetCurrent(user.GetCurrentParams{API: a.API})
482484
if err != nil {
483-
return err
485+
if _, e := deployment.List(deployment.ListParams{
486+
API: a.API,
487+
}); e != nil {
488+
// nolint
489+
return errors.New(invalidCredentialsMsg)
490+
}
491+
fmt.Fprint(writer, validCredentialsAlternativeMsg)
492+
return nil
484493
}
485494

486495
fmt.Fprintf(writer, validCredentialsMsg, *u.UserName)

pkg/ecctl/init_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,85 @@ func TestInitConfig(t *testing.T) {
306306
authChoiceMsg + "\n" + userMsg + passMsg + "\n" + formatChoiceMsg +
307307
"\n" + "\n" + fmt.Sprintf(validCredentialsMsg, "auser") + finalMsg + "\n",
308308
},
309+
{
310+
name: "doesn't find a config file and user creates a new one with user/pass, GET user fails, but deployment list succeeds",
311+
args: args{params: InitConfigParams{
312+
Viper: emptyViperToCreateConfigUserPass,
313+
FilePath: filepath.Join(testFiles, "newConfigUserPass"),
314+
Reader: io.MultiReader(
315+
strings.NewReader("y\n"),
316+
strings.NewReader("2\n"),
317+
strings.NewReader("https://ahost\n"),
318+
strings.NewReader("2\n"),
319+
strings.NewReader("auser\n"),
320+
strings.NewReader("1\n"),
321+
),
322+
Writer: new(bytes.Buffer),
323+
ErrWriter: new(bytes.Buffer),
324+
PasswordReadFunc: func(int) ([]byte, error) {
325+
return []byte("apassword"), nil
326+
},
327+
Client: mock.NewClient(
328+
mock.New200Response(mock.NewStructBody(models.TokenResponse{
329+
Token: ec.String("atoken"),
330+
})),
331+
mock.New404Response(mock.NewStructBody(models.User{
332+
UserName: ec.String("auser"),
333+
})),
334+
mock.New200Response(mock.NewStructBody(models.DeploymentsListResponse{})),
335+
),
336+
}},
337+
wantSettings: map[string]interface{}{
338+
"host": "https://ahost",
339+
"insecure": true,
340+
"output": "text",
341+
"pass": "apassword",
342+
"user": "auser",
343+
},
344+
wantOutput: disclaimer + missingConfigMsg + hostChoiceMsg + "\n" + eceHostMsg +
345+
authChoiceMsg + "\n" + userMsg + passMsg + "\n" + formatChoiceMsg +
346+
"\n" + "\n" + validCredentialsAlternativeMsg + finalMsg + "\n",
347+
},
348+
{
349+
name: "doesn't find a config file and user creates a new one with user/pass, and returns error on API test",
350+
args: args{params: InitConfigParams{
351+
Viper: emptyViperToCreateConfigUserPass,
352+
FilePath: filepath.Join(testFiles, "newConfigUserPass"),
353+
Reader: io.MultiReader(
354+
strings.NewReader("y\n"),
355+
strings.NewReader("2\n"),
356+
strings.NewReader("https://ahost\n"),
357+
strings.NewReader("2\n"),
358+
strings.NewReader("auser\n"),
359+
strings.NewReader("1\n"),
360+
),
361+
Writer: new(bytes.Buffer),
362+
ErrWriter: new(bytes.Buffer),
363+
PasswordReadFunc: func(int) ([]byte, error) {
364+
return []byte("apassword"), nil
365+
},
366+
Client: mock.NewClient(
367+
mock.New200Response(mock.NewStructBody(models.TokenResponse{
368+
Token: ec.String("atoken"),
369+
})),
370+
mock.New404Response(mock.NewStructBody(models.User{
371+
UserName: ec.String("auser"),
372+
})),
373+
mock.New404Response(mock.NewStructBody(models.DeploymentsListResponse{})),
374+
),
375+
}},
376+
wantSettings: map[string]interface{}{
377+
"host": "https://ahost",
378+
"insecure": true,
379+
"output": "text",
380+
"pass": "apassword",
381+
"user": "auser",
382+
},
383+
err: errors.New(invalidCredentialsMsg),
384+
wantOutput: disclaimer + missingConfigMsg + hostChoiceMsg + "\n" + eceHostMsg +
385+
authChoiceMsg + "\n" + userMsg + passMsg + "\n" + formatChoiceMsg +
386+
"\n" + "\n",
387+
},
309388
{
310389
name: "finds a config file and user changes the values",
311390
args: args{params: InitConfigParams{

0 commit comments

Comments
 (0)