2023-01-06 15:15:57 +00:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-06-21 10:58:28 +00:00
|
|
|
"fmt"
|
2023-01-06 15:15:57 +00:00
|
|
|
"time"
|
|
|
|
|
2023-05-16 16:35:39 +00:00
|
|
|
"github.com/databricks/cli/libs/auth"
|
2023-06-21 10:58:28 +00:00
|
|
|
"github.com/databricks/cli/libs/cmdio"
|
|
|
|
"github.com/databricks/cli/libs/databrickscfg"
|
2023-06-21 15:51:59 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go"
|
2023-06-21 10:58:28 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/config"
|
2023-06-21 15:51:59 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/compute"
|
2023-01-06 15:15:57 +00:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
|
|
|
var loginTimeout time.Duration
|
2023-06-21 15:51:59 +00:00
|
|
|
var configureCluster bool
|
2023-01-06 15:15:57 +00:00
|
|
|
|
2023-07-12 15:36:09 +00:00
|
|
|
func configureHost(ctx context.Context, args []string, argIndex int) error {
|
|
|
|
if len(args) > argIndex {
|
|
|
|
persistentAuth.Host = args[argIndex]
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
host, err := promptForHost(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
persistentAuth.Host = host
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-06 15:15:57 +00:00
|
|
|
var loginCmd = &cobra.Command{
|
|
|
|
Use: "login [HOST]",
|
|
|
|
Short: "Authenticate this machine",
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
2023-07-12 15:36:09 +00:00
|
|
|
ctx := cmd.Context()
|
|
|
|
if persistentAuth.Host == "" {
|
|
|
|
configureHost(ctx, args, 0)
|
|
|
|
}
|
|
|
|
defer persistentAuth.Close()
|
|
|
|
|
|
|
|
// We need the config without the profile before it's used to initialise new workspace client below.
|
|
|
|
// Otherwise it will complain about non existing profile because it was not yet saved.
|
|
|
|
cfg := config.Config{
|
|
|
|
Host: persistentAuth.Host,
|
|
|
|
AuthType: "databricks-cli",
|
|
|
|
}
|
|
|
|
if cfg.IsAccountClient() && persistentAuth.AccountID == "" {
|
|
|
|
accountId, err := promptForAccountID(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
persistentAuth.AccountID = accountId
|
2023-01-06 15:15:57 +00:00
|
|
|
}
|
2023-07-12 15:36:09 +00:00
|
|
|
cfg.AccountID = persistentAuth.AccountID
|
2023-06-21 15:51:59 +00:00
|
|
|
|
2023-07-12 15:36:09 +00:00
|
|
|
ctx, cancel := context.WithTimeout(ctx, loginTimeout)
|
2023-01-06 15:15:57 +00:00
|
|
|
defer cancel()
|
2023-06-21 10:58:28 +00:00
|
|
|
|
|
|
|
var profileName string
|
|
|
|
profileFlag := cmd.Flag("profile")
|
|
|
|
if profileFlag != nil && profileFlag.Value.String() != "" {
|
|
|
|
profileName = profileFlag.Value.String()
|
|
|
|
} else {
|
|
|
|
prompt := cmdio.Prompt(ctx)
|
|
|
|
prompt.Label = "Databricks Profile Name"
|
2023-07-12 15:36:09 +00:00
|
|
|
prompt.Default = persistentAuth.ProfileName()
|
2023-06-21 10:58:28 +00:00
|
|
|
prompt.AllowEdit = true
|
|
|
|
profile, err := prompt.Run()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
profileName = profile
|
|
|
|
}
|
2023-07-12 15:36:09 +00:00
|
|
|
err := persistentAuth.Challenge(ctx)
|
2023-06-21 10:58:28 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-06-21 15:51:59 +00:00
|
|
|
if configureCluster {
|
|
|
|
w, err := databricks.NewWorkspaceClient((*databricks.Config)(&cfg))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
ctx := cmd.Context()
|
|
|
|
|
|
|
|
promptSpinner := cmdio.Spinner(ctx)
|
|
|
|
promptSpinner <- "Loading list of clusters to select from"
|
2023-07-03 09:46:45 +00:00
|
|
|
names, err := w.Clusters.ClusterDetailsClusterNameToClusterIdMap(ctx, compute.ListClustersRequest{})
|
2023-06-21 15:51:59 +00:00
|
|
|
close(promptSpinner)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to load clusters list. Original error: %w", err)
|
|
|
|
}
|
|
|
|
clusterId, err := cmdio.Select(ctx, names, "Choose cluster")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cfg.ClusterID = clusterId
|
|
|
|
}
|
2023-06-21 10:58:28 +00:00
|
|
|
|
2023-06-22 15:20:10 +00:00
|
|
|
cfg.Profile = profileName
|
2023-06-21 15:51:59 +00:00
|
|
|
err = databrickscfg.SaveToProfile(ctx, &cfg)
|
2023-06-21 10:58:28 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdio.LogString(ctx, fmt.Sprintf("Profile %s was successfully saved", profileName))
|
|
|
|
return nil
|
2023-01-06 15:15:57 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
authCmd.AddCommand(loginCmd)
|
|
|
|
loginCmd.Flags().DurationVar(&loginTimeout, "timeout", auth.DefaultTimeout,
|
|
|
|
"Timeout for completing login challenge in the browser")
|
2023-06-21 15:51:59 +00:00
|
|
|
|
|
|
|
loginCmd.Flags().BoolVar(&configureCluster, "configure-cluster", false,
|
|
|
|
"Prompts to configure cluster")
|
2023-01-06 15:15:57 +00:00
|
|
|
}
|