Skip to content

Commit

Permalink
chore: drop more selfhost related code
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasmalkmus committed Nov 23, 2022
1 parent 8729f3e commit 507f3d8
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 171 deletions.
5 changes: 4 additions & 1 deletion cmd/axiom/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ func printError(w io.Writer, err error, cmd *cobra.Command) {
// Print some nicer output for Axiom API errors.
if errors.Is(err, axiom.ErrNotFound) || errors.Is(err, axiom.ErrExists) ||
errors.Is(err, axiom.ErrUnauthorized) || errors.Is(err, axiom.ErrUnauthenticated) {
fmt.Fprintf(w, "Error: %s\n", errors.Unwrap(err))
if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil {
err = unwrappedErr
}
fmt.Fprintf(w, "Error: %s\n", err)
return
}

Expand Down
190 changes: 73 additions & 117 deletions internal/cmd/auth/auth_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,14 @@ import (
"github.com/axiomhq/cli/pkg/surveyext"
)

const (
oAuth2ClientID = "13c885a8-f46a-4424-82d2-883cf7ccfe49"

typeCloud = "Cloud"
typeSelfhost = "Selfhost"
)

var validDeploymentTypes = []string{typeCloud, typeSelfhost}
const oAuth2ClientID = "13c885a8-f46a-4424-82d2-883cf7ccfe49"

type loginOptions struct {
*cmdutil.Factory

// AutoLogin specifies if the CLI redirects to the Axiom UI for
// authentication.
AutoLogin bool
// Type of the deployment to authenticate with. Default to "Cloud". Can be
// overwritten by flag.
Type string
// Url of the deployment to authenticate with. Default to the Axiom Cloud
// URL. Can be overwritten by flag.
URL string
// Alias of the deployment for future reference. If not supplied as a flag,
// which is optional, the user will be asked for it.
Alias string
Expand All @@ -50,10 +37,15 @@ type loginOptions struct {
Token string
// OrganizationID of the organization the supplied token is valid for. If
// not supplied as a flag, which is optional, the user will be asked for it.
// Only valid for cloud deployments.
OrganizationID string
// Force the creation and skip the confirmation prompt.
Force bool

// Alternate deployment support:

// URL of the deployment to authenticate with. Default to the Axiom Cloud
// URL. Can be overwritten by a hidden flag.
URL string
}

// NewLoginCmd creates ans returns the login command.
Expand All @@ -63,7 +55,7 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
}

cmd := &cobra.Command{
Use: "login [(-t|--type)=cloud|selfhost] [(-u|--url) <url>] [(-a|--alias) <alias>] [(-o|--org-id) <organization-id>] [-f|--force]",
Use: "login [(-a|--alias) <alias>] [(-o|--org-id) <organization-id>] [-f|--force]",
Short: "Login to Axiom",

DisableFlagsInUseLine: true,
Expand All @@ -73,21 +65,13 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
$ axiom auth login
# Provide parameters on the command-line:
$ echo $AXIOM_ACCESS_TOKEN | axiom auth login --alias="axiom-eu-west-1" --url="https://axiom.eu-west-1.aws.com" -f
$ echo $AXIOM_TOKEN | axiom auth login --alias="axiom-cloud" --org-id="fancy-horse-1234" -f
`),

PreRunE: func(cmd *cobra.Command, _ []string) error {
if !opts.IO.IsStdinTTY() || opts.AutoLogin {
return nil
}

// If the user specifies the url, we assume he wants to authenticate
// against a selfhost deployment unless he explicitly specifies the
// hidden type flag that specifies the type of the deployment.
if cmd.Flag("url").Changed && !cmd.Flag("type").Changed {
opts.Type = typeSelfhost
}

return completeLogin(cmd.Context(), opts)
},

Expand All @@ -100,58 +84,30 @@ func NewLoginCmd(f *cmdutil.Factory) *cobra.Command {
}

cmd.Flags().BoolVar(&opts.AutoLogin, "auto-login", true, "Login through the Axiom UI")
cmd.Flags().StringVarP(&opts.Type, "type", "t", strings.ToLower(typeCloud), "Type of the deployment")
cmd.Flags().StringVarP(&opts.URL, "url", "u", client.CloudURL, "Url of the deployment")
cmd.Flags().StringVarP(&opts.Alias, "alias", "a", "", "Alias of the deployment")
cmd.Flags().StringVarP(&opts.OrganizationID, "org-id", "o", "", "Organization ID")
cmd.Flags().BoolVarP(&opts.Force, "force", "f", false, "Skip the confirmation prompt")
cmd.Flags().StringVarP(&opts.URL, "url", "u", client.CloudURL, "Url of the deployment")

_ = cmd.RegisterFlagCompletionFunc("auto-login", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("type", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("url", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("alias", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("org-id", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("force", cmdutil.NoCompletion)
_ = cmd.RegisterFlagCompletionFunc("url", cmdutil.NoCompletion)

if !opts.IO.IsStdinTTY() {
_ = cmd.MarkFlagRequired("alias")
_ = cmd.MarkFlagRequired("org-id")
}

_ = cmd.PersistentFlags().MarkHidden("type")
_ = cmd.Flags().MarkHidden("url")

return cmd
}

func completeLogin(ctx context.Context, opts *loginOptions) error {
// 1. Cloud or Selfhost?
if opts.Type == "" {
if err := survey.AskOne(&survey.Select{
Message: "Which kind of Axiom deployment are you using?",
Default: validDeploymentTypes[0],
Options: validDeploymentTypes,
}, &opts.Type, opts.IO.SurveyIO()); err != nil {
return err
}
}

opts.Type = strings.ToLower(opts.Type)

// 2. If Cloud mode but no URL, set the correct URL instead of asking the
// user for it.
if opts.Type == strings.ToLower(typeCloud) && opts.URL == "" {
opts.URL = client.CloudURL
} else if opts.URL == "" {
if err := survey.AskOne(&survey.Input{
Message: "What is the url of the deployment?",
}, &opts.URL, survey.WithValidator(survey.ComposeValidators(
survey.Required,
surveyext.ValidateURL,
)), opts.IO.SurveyIO()); err != nil {
return err
}
}

if opts.URL != "" && !strings.HasPrefix(opts.URL, "http://") && !strings.HasPrefix(opts.URL, "https://") {
// Make sure to accept urls without a scheme.
if !strings.HasPrefix(opts.URL, "http://") && !strings.HasPrefix(opts.URL, "https://") {
opts.URL = "https://" + opts.URL
}

Expand All @@ -162,7 +118,7 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
}
u.Path = "/profile"

// 3. Wheather to open the browser or not.
// 1. Wheather to open the browser or not.
askTokenMsg := "What is your personal access token?"
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?",
true, opts.IO.SurveyIO()); err != nil {
Expand All @@ -173,7 +129,7 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
return err
}

// 3. The token to use.
// 2. The token to use.
if err := survey.AskOne(&survey.Password{
Message: askTokenMsg,
}, &opts.Token, survey.WithValidator(survey.ComposeValidators(
Expand All @@ -183,11 +139,10 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
return err
}

// 4. Try to authenticate and fetch the organizations available to the user
// in case the deployment is a cloud deployment. If only one organization is
// available, that one is selected by default, without asking the user for
// it.
if opts.Type == strings.ToLower(typeCloud) && opts.OrganizationID == "" {
// 3. Try to authenticate and fetch the organizations available to the user.
// If only one organization is available, that one is selected by default,
// without asking the user for it.
if opts.OrganizationID == "" {
axiomClient, err := client.New(ctx, opts.URL, opts.Token, "axiom", opts.Config.Insecure)
if err != nil {
return err
Expand Down Expand Up @@ -238,11 +193,11 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {

// Just use "cloud" as the alias if this is their first deployment and they
// are authenticating against Axiom Cloud.
if hostRef == strings.ToLower(typeCloud) {
if hostRef == "cloud" {
opts.Alias = hostRef
}

// 5. Ask for an alias to use.
// 4. Ask for an alias to use.
if opts.Alias == "" {
if err := survey.AskOne(&survey.Input{
Message: "Under which name should the deployment be referenced in the future?",
Expand All @@ -260,28 +215,12 @@ func completeLogin(ctx context.Context, opts *loginOptions) error {
}

func autoLogin(ctx context.Context, opts *loginOptions) error {
opts.Type = strings.ToLower(opts.Type)

// 1. If Cloud mode but no URL, set the correct URL instead of asking the
// user for it.
if opts.Type == strings.ToLower(typeCloud) && opts.URL == "" {
opts.URL = client.CloudURL
} else if opts.URL == "" {
if err := survey.AskOne(&survey.Input{
Message: "What is the url of the deployment?",
}, &opts.URL, survey.WithValidator(survey.ComposeValidators(
survey.Required,
surveyext.ValidateURL,
)), opts.IO.SurveyIO()); err != nil {
return err
}
}

if opts.URL != "" && !strings.HasPrefix(opts.URL, "http://") && !strings.HasPrefix(opts.URL, "https://") {
// Make sure to accept urls without a scheme.
if !strings.HasPrefix(opts.URL, "http://") && !strings.HasPrefix(opts.URL, "https://") {
opts.URL = "https://" + opts.URL
}

// 2. Wheather to open the browser or not. But the URL to open and have the
// 1. Wheather to open the browser or not. But the URL to open and have the
// user login is presented nonetheless.
stop := func() {}
loginFunc := func(_ context.Context, loginURL string) error {
Expand Down Expand Up @@ -311,22 +250,49 @@ func autoLogin(ctx context.Context, opts *loginOptions) error {
return err
}

// 3. Try to authenticate and fetch the organizations available to the user
// in case the deployment is a cloud deployment. If at least one
// organization is available, the first one is selected.
if opts.Type == strings.ToLower(typeCloud) && opts.OrganizationID == "" {
// 2. Try to authenticate and fetch the organizations available to the user.
// If only one organization is available, that one is selected by default,
// without asking the user for it.
if opts.OrganizationID == "" {
axiomClient, err := client.New(ctx, opts.URL, opts.Token, "axiom", opts.Config.Insecure)
if err != nil {
return err
}

organizations, err := axiomClient.Organizations.List(ctx)
if err != nil {
if organizations, err := axiomClient.Organizations.List(ctx); err != nil {
return err
}

if len(organizations) > 0 {
} else if len(organizations) == 1 {
opts.OrganizationID = organizations[0].ID
} else {
sort.Slice(organizations, func(i, j int) bool {
return strings.ToLower(organizations[i].Name) < strings.ToLower(organizations[j].Name)
})

organizationNames := make([]string, len(organizations))
for i, organization := range organizations {
organizationNames[i] = organization.Name
}

stop()

var organizationName string
if err := survey.AskOne(&survey.Select{
Message: "Which organization to use?",
Options: organizationNames,
Default: organizationNames[0],
Description: func(_ string, idx int) string {
return organizations[idx].ID
},
}, &organizationName, opts.IO.SurveyIO()); err != nil {
return err
}

for i, organization := range organizations {
if organization.Name == organizationName {
opts.OrganizationID = organizations[i].ID
break
}
}
}
}

Expand All @@ -342,11 +308,11 @@ func autoLogin(ctx context.Context, opts *loginOptions) error {

// Just use "cloud" as the alias if this is their first deployment and they
// are authenticating against Axiom Cloud.
if hostRef == strings.ToLower(typeCloud) {
if hostRef == "cloud" {
opts.Alias = hostRef
}

// 4. Ask for an alias to use.
// 3. Ask for an alias to use.
if opts.Alias == "" {
if err := survey.AskOne(&survey.Input{
Message: "Under which name should the deployment be referenced in the future?",
Expand Down Expand Up @@ -407,27 +373,17 @@ func runLogin(ctx context.Context, opts *loginOptions) error {
if opts.IO.IsStderrTTY() {
cs := opts.IO.ColorScheme()

if user != nil {
if (client.IsCloudURL(opts.URL) || opts.Config.ForceCloud) && client.IsPersonalToken(opts.Token) {
organization, err := axiomClient.Organizations.Get(ctx, opts.OrganizationID)
if err != nil {
return err
}

fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s as %s\n",
cs.SuccessIcon(), cs.Bold(organization.Name), cs.Bold(user.Name))
} else {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to deployment %s as %s\n",
cs.SuccessIcon(), cs.Bold(opts.Alias), cs.Bold(user.Name))
if client.IsPersonalToken(opts.Token) {
organization, err := axiomClient.Organizations.Get(ctx, opts.OrganizationID)
if err != nil {
return err
}

fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s as %s\n",
cs.SuccessIcon(), cs.Bold(organization.Name), cs.Bold(user.Name))
} else {
if client.IsCloudURL(opts.URL) || opts.Config.ForceCloud {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s %s\n",
cs.SuccessIcon(), cs.Bold(opts.OrganizationID), cs.Red(cs.Bold("(ingestion/query only!)")))
} else {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to deployment %s %s\n",
cs.SuccessIcon(), cs.Bold(opts.Alias), cs.Red(cs.Bold("(ingestion/query only!)")))
}
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s %s\n",
cs.SuccessIcon(), cs.Bold(opts.OrganizationID), cs.Red(cs.Bold("(ingestion/query only!)")))
}
}

Expand Down
1 change: 0 additions & 1 deletion internal/cmd/auth/auth_switch_org.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ func newSwitchOrgCmd(f *cmdutil.Factory) *cobra.Command {
cmdutil.AsksForSetup(f, NewLoginCmd(f)),
cmdutil.NeedsDeployments(f),
cmdutil.NeedsActiveDeployment(f),
cmdutil.NeedsCloudDeployment(f),
cmdutil.NeedsPersonalAccessToken(f),
),

Expand Down
30 changes: 10 additions & 20 deletions internal/cmd/auth/auth_update_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func newUpdateTokenCmd(f *cmdutil.Factory) *cobra.Command {
$ axiom auth update-token
# Provide parameters on the command-line:
$ echo $AXIOM_PERSONAL_ACCESS_TOKEN | axiom auth update-token
$ echo $AXIOM_TOKEN | axiom auth update-token
`),

PersistentPreRunE: cmdutil.ChainRunFuncs(
Expand Down Expand Up @@ -122,27 +122,17 @@ func runUpdateToken(ctx context.Context, opts *updateTokenOptions) error {
if opts.IO.IsStderrTTY() {
cs := opts.IO.ColorScheme()

if user != nil {
if client.IsCloudURL(activeDeployment.URL) || opts.Config.ForceCloud {
organization, err := axiomClient.Organizations.Get(ctx, activeDeployment.OrganizationID)
if err != nil {
return err
}

fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s as %s\n",
cs.SuccessIcon(), cs.Bold(organization.Name), cs.Bold(user.Name))
} else {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to deployment %s as %s\n",
cs.SuccessIcon(), cs.Bold(opts.Config.ActiveDeployment), cs.Bold(user.Name))
if client.IsPersonalToken(opts.Token) {
organization, err := axiomClient.Organizations.Get(ctx, activeDeployment.OrganizationID)
if err != nil {
return err
}

fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s as %s\n",
cs.SuccessIcon(), cs.Bold(organization.Name), cs.Bold(user.Name))
} else {
if client.IsCloudURL(activeDeployment.URL) || opts.Config.ForceCloud {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s %s\n",
cs.SuccessIcon(), cs.Bold(activeDeployment.OrganizationID), cs.Red(cs.Bold("(ingestion only!)")))
} else {
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to deployment %s %s\n",
cs.SuccessIcon(), cs.Bold(opts.Config.ActiveDeployment), cs.Red(cs.Bold("(ingestion only!)")))
}
fmt.Fprintf(opts.IO.ErrOut(), "%s Logged in to organization %s %s\n",
cs.SuccessIcon(), cs.Bold(activeDeployment.OrganizationID), cs.Red(cs.Bold("(ingestion/query only!)")))
}
}

Expand Down
Loading

0 comments on commit 507f3d8

Please sign in to comment.