@@ -20,27 +20,14 @@ import (
20
20
"github.com/axiomhq/cli/pkg/surveyext"
21
21
)
22
22
23
- const (
24
- oAuth2ClientID = "13c885a8-f46a-4424-82d2-883cf7ccfe49"
25
-
26
- typeCloud = "Cloud"
27
- typeSelfhost = "Selfhost"
28
- )
29
-
30
- var validDeploymentTypes = []string {typeCloud , typeSelfhost }
23
+ const oAuth2ClientID = "13c885a8-f46a-4424-82d2-883cf7ccfe49"
31
24
32
25
type loginOptions struct {
33
26
* cmdutil.Factory
34
27
35
28
// AutoLogin specifies if the CLI redirects to the Axiom UI for
36
29
// authentication.
37
30
AutoLogin bool
38
- // Type of the deployment to authenticate with. Default to "Cloud". Can be
39
- // overwritten by flag.
40
- Type string
41
- // Url of the deployment to authenticate with. Default to the Axiom Cloud
42
- // URL. Can be overwritten by flag.
43
- URL string
44
31
// Alias of the deployment for future reference. If not supplied as a flag,
45
32
// which is optional, the user will be asked for it.
46
33
Alias string
@@ -50,10 +37,15 @@ type loginOptions struct {
50
37
Token string
51
38
// OrganizationID of the organization the supplied token is valid for. If
52
39
// not supplied as a flag, which is optional, the user will be asked for it.
53
- // Only valid for cloud deployments.
54
40
OrganizationID string
55
41
// Force the creation and skip the confirmation prompt.
56
42
Force bool
43
+
44
+ // Alternate deployment support:
45
+
46
+ // URL of the deployment to authenticate with. Default to the Axiom Cloud
47
+ // URL. Can be overwritten by a hidden flag.
48
+ URL string
57
49
}
58
50
59
51
// NewLoginCmd creates ans returns the login command.
@@ -63,7 +55,7 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
63
55
}
64
56
65
57
cmd := & cobra.Command {
66
- Use : "login [(-t|--type)=cloud|selfhost] [(-u|--url) <url>] [(- a|--alias) <alias>] [(-o|--org-id) <organization-id>] [-f|--force]" ,
58
+ Use : "login [(-a|--alias) <alias>] [(-o|--org-id) <organization-id>] [-f|--force]" ,
67
59
Short : "Login to Axiom" ,
68
60
69
61
DisableFlagsInUseLine : true ,
@@ -73,21 +65,13 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
73
65
$ axiom auth login
74
66
75
67
# Provide parameters on the command-line:
76
- $ echo $AXIOM_ACCESS_TOKEN | axiom auth login --alias="axiom-eu-west-1 " --url="https://axiom.eu-west-1.aws.com " -f
68
+ $ echo $AXIOM_TOKEN | axiom auth login --alias="axiom-cloud " --org-id="fancy-horse-1234 " -f
77
69
` ),
78
70
79
71
PreRunE : func (cmd * cobra.Command , _ []string ) error {
80
72
if ! opts .IO .IsStdinTTY () || opts .AutoLogin {
81
73
return nil
82
74
}
83
-
84
- // If the user specifies the url, we assume he wants to authenticate
85
- // against a selfhost deployment unless he explicitly specifies the
86
- // hidden type flag that specifies the type of the deployment.
87
- if cmd .Flag ("url" ).Changed && ! cmd .Flag ("type" ).Changed {
88
- opts .Type = typeSelfhost
89
- }
90
-
91
75
return completeLogin (cmd .Context (), opts )
92
76
},
93
77
@@ -100,58 +84,30 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
100
84
}
101
85
102
86
cmd .Flags ().BoolVar (& opts .AutoLogin , "auto-login" , true , "Login through the Axiom UI" )
103
- cmd .Flags ().StringVarP (& opts .Type , "type" , "t" , strings .ToLower (typeCloud ), "Type of the deployment" )
104
- cmd .Flags ().StringVarP (& opts .URL , "url" , "u" , client .CloudURL , "Url of the deployment" )
105
87
cmd .Flags ().StringVarP (& opts .Alias , "alias" , "a" , "" , "Alias of the deployment" )
106
88
cmd .Flags ().StringVarP (& opts .OrganizationID , "org-id" , "o" , "" , "Organization ID" )
107
89
cmd .Flags ().BoolVarP (& opts .Force , "force" , "f" , false , "Skip the confirmation prompt" )
90
+ cmd .Flags ().StringVarP (& opts .URL , "url" , "u" , client .CloudURL , "Url of the deployment" )
108
91
109
92
_ = cmd .RegisterFlagCompletionFunc ("auto-login" , cmdutil .NoCompletion )
110
- _ = cmd .RegisterFlagCompletionFunc ("type" , cmdutil .NoCompletion )
111
- _ = cmd .RegisterFlagCompletionFunc ("url" , cmdutil .NoCompletion )
112
93
_ = cmd .RegisterFlagCompletionFunc ("alias" , cmdutil .NoCompletion )
113
94
_ = cmd .RegisterFlagCompletionFunc ("org-id" , cmdutil .NoCompletion )
114
95
_ = cmd .RegisterFlagCompletionFunc ("force" , cmdutil .NoCompletion )
96
+ _ = cmd .RegisterFlagCompletionFunc ("url" , cmdutil .NoCompletion )
115
97
116
98
if ! opts .IO .IsStdinTTY () {
117
99
_ = cmd .MarkFlagRequired ("alias" )
100
+ _ = cmd .MarkFlagRequired ("org-id" )
118
101
}
119
102
120
- _ = cmd .PersistentFlags ().MarkHidden ("type " )
103
+ _ = cmd .Flags ().MarkHidden ("url " )
121
104
122
105
return cmd
123
106
}
124
107
125
108
func completeLogin (ctx context.Context , opts * loginOptions ) error {
126
- // 1. Cloud or Selfhost?
127
- if opts .Type == "" {
128
- if err := survey .AskOne (& survey.Select {
129
- Message : "Which kind of Axiom deployment are you using?" ,
130
- Default : validDeploymentTypes [0 ],
131
- Options : validDeploymentTypes ,
132
- }, & opts .Type , opts .IO .SurveyIO ()); err != nil {
133
- return err
134
- }
135
- }
136
-
137
- opts .Type = strings .ToLower (opts .Type )
138
-
139
- // 2. If Cloud mode but no URL, set the correct URL instead of asking the
140
- // user for it.
141
- if opts .Type == strings .ToLower (typeCloud ) && opts .URL == "" {
142
- opts .URL = client .CloudURL
143
- } else if opts .URL == "" {
144
- if err := survey .AskOne (& survey.Input {
145
- Message : "What is the url of the deployment?" ,
146
- }, & opts .URL , survey .WithValidator (survey .ComposeValidators (
147
- survey .Required ,
148
- surveyext .ValidateURL ,
149
- )), opts .IO .SurveyIO ()); err != nil {
150
- return err
151
- }
152
- }
153
-
154
- if opts .URL != "" && ! strings .HasPrefix (opts .URL , "http://" ) && ! strings .HasPrefix (opts .URL , "https://" ) {
109
+ // Make sure to accept urls without a scheme.
110
+ if ! strings .HasPrefix (opts .URL , "http://" ) && ! strings .HasPrefix (opts .URL , "https://" ) {
155
111
opts .URL = "https://" + opts .URL
156
112
}
157
113
@@ -162,7 +118,7 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
162
118
}
163
119
u .Path = "/profile"
164
120
165
- // 3 . Wheather to open the browser or not.
121
+ // 1 . Wheather to open the browser or not.
166
122
askTokenMsg := "What is your personal access token?"
167
123
if ok , err := surveyext .AskConfirm ("You need to retrieve a personal access token from your profile page. Should I open that page in your default browser?" ,
168
124
true , opts .IO .SurveyIO ()); err != nil {
@@ -173,7 +129,7 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
173
129
return err
174
130
}
175
131
176
- // 3 . The token to use.
132
+ // 2 . The token to use.
177
133
if err := survey .AskOne (& survey.Password {
178
134
Message : askTokenMsg ,
179
135
}, & opts .Token , survey .WithValidator (survey .ComposeValidators (
@@ -183,11 +139,10 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
183
139
return err
184
140
}
185
141
186
- // 4. Try to authenticate and fetch the organizations available to the user
187
- // in case the deployment is a cloud deployment. If only one organization is
188
- // available, that one is selected by default, without asking the user for
189
- // it.
190
- if opts .Type == strings .ToLower (typeCloud ) && opts .OrganizationID == "" {
142
+ // 3. Try to authenticate and fetch the organizations available to the user.
143
+ // If only one organization is available, that one is selected by default,
144
+ // without asking the user for it.
145
+ if opts .OrganizationID == "" {
191
146
axiomClient , err := client .New (ctx , opts .URL , opts .Token , "axiom" , opts .Config .Insecure )
192
147
if err != nil {
193
148
return err
@@ -238,11 +193,11 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
238
193
239
194
// Just use "cloud" as the alias if this is their first deployment and they
240
195
// are authenticating against Axiom Cloud.
241
- if hostRef == strings . ToLower ( typeCloud ) {
196
+ if hostRef == "cloud" {
242
197
opts .Alias = hostRef
243
198
}
244
199
245
- // 5 . Ask for an alias to use.
200
+ // 4 . Ask for an alias to use.
246
201
if opts .Alias == "" {
247
202
if err := survey .AskOne (& survey.Input {
248
203
Message : "Under which name should the deployment be referenced in the future?" ,
@@ -260,28 +215,12 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
260
215
}
261
216
262
217
func autoLogin (ctx context.Context , opts * loginOptions ) error {
263
- opts .Type = strings .ToLower (opts .Type )
264
-
265
- // 1. If Cloud mode but no URL, set the correct URL instead of asking the
266
- // user for it.
267
- if opts .Type == strings .ToLower (typeCloud ) && opts .URL == "" {
268
- opts .URL = client .CloudURL
269
- } else if opts .URL == "" {
270
- if err := survey .AskOne (& survey.Input {
271
- Message : "What is the url of the deployment?" ,
272
- }, & opts .URL , survey .WithValidator (survey .ComposeValidators (
273
- survey .Required ,
274
- surveyext .ValidateURL ,
275
- )), opts .IO .SurveyIO ()); err != nil {
276
- return err
277
- }
278
- }
279
-
280
- if opts .URL != "" && ! strings .HasPrefix (opts .URL , "http://" ) && ! strings .HasPrefix (opts .URL , "https://" ) {
218
+ // Make sure to accept urls without a scheme.
219
+ if ! strings .HasPrefix (opts .URL , "http://" ) && ! strings .HasPrefix (opts .URL , "https://" ) {
281
220
opts .URL = "https://" + opts .URL
282
221
}
283
222
284
- // 2 . Wheather to open the browser or not. But the URL to open and have the
223
+ // 1 . Wheather to open the browser or not. But the URL to open and have the
285
224
// user login is presented nonetheless.
286
225
stop := func () {}
287
226
loginFunc := func (_ context.Context , loginURL string ) error {
@@ -311,22 +250,49 @@ func autoLogin(ctx context.Context, opts *loginOptions) error {
311
250
return err
312
251
}
313
252
314
- // 3 . Try to authenticate and fetch the organizations available to the user
315
- // in case the deployment is a cloud deployment. If at least one
316
- // organization is available, the first one is selected .
317
- if opts .Type == strings . ToLower ( typeCloud ) && opts . OrganizationID == "" {
253
+ // 2 . Try to authenticate and fetch the organizations available to the user.
254
+ // If only one organization is available, that one is selected by default,
255
+ // without asking the user for it .
256
+ if opts .OrganizationID == "" {
318
257
axiomClient , err := client .New (ctx , opts .URL , opts .Token , "axiom" , opts .Config .Insecure )
319
258
if err != nil {
320
259
return err
321
260
}
322
261
323
- organizations , err := axiomClient .Organizations .List (ctx )
324
- if err != nil {
262
+ if organizations , err := axiomClient .Organizations .List (ctx ); err != nil {
325
263
return err
326
- }
327
-
328
- if len (organizations ) > 0 {
264
+ } else if len (organizations ) == 1 {
329
265
opts .OrganizationID = organizations [0 ].ID
266
+ } else {
267
+ sort .Slice (organizations , func (i , j int ) bool {
268
+ return strings .ToLower (organizations [i ].Name ) < strings .ToLower (organizations [j ].Name )
269
+ })
270
+
271
+ organizationNames := make ([]string , len (organizations ))
272
+ for i , organization := range organizations {
273
+ organizationNames [i ] = organization .Name
274
+ }
275
+
276
+ stop ()
277
+
278
+ var organizationName string
279
+ if err := survey .AskOne (& survey.Select {
280
+ Message : "Which organization to use?" ,
281
+ Options : organizationNames ,
282
+ Default : organizationNames [0 ],
283
+ Description : func (_ string , idx int ) string {
284
+ return organizations [idx ].ID
285
+ },
286
+ }, & organizationName , opts .IO .SurveyIO ()); err != nil {
287
+ return err
288
+ }
289
+
290
+ for i , organization := range organizations {
291
+ if organization .Name == organizationName {
292
+ opts .OrganizationID = organizations [i ].ID
293
+ break
294
+ }
295
+ }
330
296
}
331
297
}
332
298
@@ -342,11 +308,11 @@ func autoLogin(ctx context.Context, opts *loginOptions) error {
342
308
343
309
// Just use "cloud" as the alias if this is their first deployment and they
344
310
// are authenticating against Axiom Cloud.
345
- if hostRef == strings . ToLower ( typeCloud ) {
311
+ if hostRef == "cloud" {
346
312
opts .Alias = hostRef
347
313
}
348
314
349
- // 4 . Ask for an alias to use.
315
+ // 3 . Ask for an alias to use.
350
316
if opts .Alias == "" {
351
317
if err := survey .AskOne (& survey.Input {
352
318
Message : "Under which name should the deployment be referenced in the future?" ,
@@ -407,27 +373,17 @@ func runLogin(ctx context.Context, opts *loginOptions) error {
407
373
if opts .IO .IsStderrTTY () {
408
374
cs := opts .IO .ColorScheme ()
409
375
410
- if user != nil {
411
- if (client .IsCloudURL (opts .URL ) || opts .Config .ForceCloud ) && client .IsPersonalToken (opts .Token ) {
412
- organization , err := axiomClient .Organizations .Get (ctx , opts .OrganizationID )
413
- if err != nil {
414
- return err
415
- }
416
-
417
- fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to organization %s as %s\n " ,
418
- cs .SuccessIcon (), cs .Bold (organization .Name ), cs .Bold (user .Name ))
419
- } else {
420
- fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to deployment %s as %s\n " ,
421
- cs .SuccessIcon (), cs .Bold (opts .Alias ), cs .Bold (user .Name ))
376
+ if client .IsPersonalToken (opts .Token ) {
377
+ organization , err := axiomClient .Organizations .Get (ctx , opts .OrganizationID )
378
+ if err != nil {
379
+ return err
422
380
}
381
+
382
+ fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to organization %s as %s\n " ,
383
+ cs .SuccessIcon (), cs .Bold (organization .Name ), cs .Bold (user .Name ))
423
384
} else {
424
- if client .IsCloudURL (opts .URL ) || opts .Config .ForceCloud {
425
- fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to organization %s %s\n " ,
426
- cs .SuccessIcon (), cs .Bold (opts .OrganizationID ), cs .Red (cs .Bold ("(ingestion/query only!)" )))
427
- } else {
428
- fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to deployment %s %s\n " ,
429
- cs .SuccessIcon (), cs .Bold (opts .Alias ), cs .Red (cs .Bold ("(ingestion/query only!)" )))
430
- }
385
+ fmt .Fprintf (opts .IO .ErrOut (), "%s Logged in to organization %s %s\n " ,
386
+ cs .SuccessIcon (), cs .Bold (opts .OrganizationID ), cs .Red (cs .Bold ("(ingestion/query only!)" )))
431
387
}
432
388
}
433
389
0 commit comments