databricks-cli/cmd/auth/logout.go

111 lines
3.0 KiB
Go
Raw Normal View History

2024-08-25 21:53:44 +00:00
package auth
import (
"context"
"errors"
"fmt"
"io/fs"
2024-09-01 16:22:18 +00:00
"github.com/databricks/cli/libs/auth"
2024-09-01 22:15:48 +00:00
"github.com/databricks/cli/libs/auth/cache"
2024-08-25 21:53:44 +00:00
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/databrickscfg/profile"
"github.com/databricks/databricks-sdk-go/config"
"github.com/spf13/cobra"
)
2024-09-23 18:37:53 +00:00
type logoutSession struct {
profile string
file config.File
persistentAuth *auth.PersistentAuth
2024-08-25 21:53:44 +00:00
}
2024-09-23 18:37:53 +00:00
func (l *logoutSession) load(ctx context.Context, profileName string, persistentAuth *auth.PersistentAuth) error {
l.profile = profileName
l.persistentAuth = persistentAuth
2024-08-25 21:53:44 +00:00
iniFile, err := profile.DefaultProfiler.Get(ctx)
if errors.Is(err, fs.ErrNotExist) {
return err
} else if err != nil {
return fmt.Errorf("cannot parse config file: %w", err)
}
2024-09-23 18:37:53 +00:00
l.file = *iniFile
2024-09-01 22:15:48 +00:00
if err := l.setHostAndAccountIdFromProfile(); err != nil {
return err
}
return nil
}
2024-09-23 18:37:53 +00:00
func (l *logoutSession) setHostAndAccountIdFromProfile() error {
2024-09-01 22:15:48 +00:00
sectionMap, err := l.getConfigSectionMap()
if err != nil {
return err
}
if sectionMap["host"] == "" {
2024-09-23 18:37:53 +00:00
return fmt.Errorf("no host configured for profile %s", l.profile)
2024-09-01 22:15:48 +00:00
}
2024-09-23 18:37:53 +00:00
l.persistentAuth.Host = sectionMap["host"]
l.persistentAuth.AccountID = sectionMap["account_id"]
2024-08-25 21:53:44 +00:00
return nil
}
2024-09-23 18:37:53 +00:00
func (l *logoutSession) getConfigSectionMap() (map[string]string, error) {
section, err := l.file.GetSection(l.profile)
2024-08-25 21:53:44 +00:00
if err != nil {
return map[string]string{}, fmt.Errorf("profile does not exist in config file: %w", err)
}
return section.KeysHash(), nil
}
// clear token from ~/.databricks/token-cache.json
2024-09-23 18:37:53 +00:00
func (l *logoutSession) clearTokenCache(ctx context.Context) error {
return l.persistentAuth.ClearToken(ctx)
2024-08-25 21:53:44 +00:00
}
2024-09-01 16:22:18 +00:00
func newLogoutCommand(persistentAuth *auth.PersistentAuth) *cobra.Command {
2024-08-25 21:53:44 +00:00
cmd := &cobra.Command{
Use: "logout [PROFILE]",
Short: "Logout from specified profile",
Long: "Removes the OAuth token from the token-cache",
2024-08-25 21:53:44 +00:00
}
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
2024-09-01 22:15:48 +00:00
profileNameFromFlag := cmd.Flag("profile").Value.String()
// If both [PROFILE] and --profile are provided, return an error.
if len(args) > 0 && profileNameFromFlag != "" {
return fmt.Errorf("please only provide a profile as an argument or a flag, not both")
}
// Determine the profile name from either args or the flag.
profileName := profileNameFromFlag
if len(args) > 0 {
profileName = args[0]
}
2024-09-01 16:22:18 +00:00
// If the user has not specified a profile name, prompt for one.
if profileName == "" {
var err error
profileName, err = promptForProfile(ctx, persistentAuth.ProfileName())
if err != nil {
return err
}
2024-08-25 21:53:44 +00:00
}
2024-09-01 16:22:18 +00:00
defer persistentAuth.Close()
2024-09-23 18:37:53 +00:00
logoutSession := &logoutSession{}
err := logoutSession.load(ctx, profileName, persistentAuth)
2024-09-01 16:22:18 +00:00
if err != nil {
return err
}
2024-09-01 22:15:48 +00:00
err = logoutSession.clearTokenCache(ctx)
2024-09-01 18:17:07 +00:00
if err != nil {
if errors.Is(err, cache.ErrNotConfigured) {
// It is OK to not have OAuth configured
2024-09-01 18:17:07 +00:00
} else {
return err
}
2024-08-25 21:53:44 +00:00
}
cmdio.LogString(ctx, fmt.Sprintf("Profile %s is logged out", profileName))
2024-08-25 21:53:44 +00:00
return nil
}
return cmd
}