diff --git a/cmd/labs/project/entrypoint.go b/cmd/labs/project/entrypoint.go index 113bf321..96f46d4b 100644 --- a/cmd/labs/project/entrypoint.go +++ b/cmd/labs/project/entrypoint.go @@ -18,6 +18,7 @@ import ( "github.com/databricks/cli/libs/log" "github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go/config" + "github.com/databricks/databricks-sdk-go/logger" "github.com/spf13/cobra" ) @@ -231,6 +232,8 @@ func (e *Entrypoint) validLogin(cmd *cobra.Command) (*config.Config, error) { if err != nil { return nil, err } + ctx := cmd.Context() + logger.Debugf(ctx, "Resolved login: %s", config.ConfigAttributes.DebugString(cfg)) // merge ~/.databrickscfg and ~/.databricks/labs/x/config/login.json when // it comes to project-specific configuration if e.NeedsCluster() && cfg.ClusterID == "" { @@ -239,8 +242,35 @@ func (e *Entrypoint) validLogin(cmd *cobra.Command) (*config.Config, error) { if e.NeedsWarehouse() && cfg.WarehouseID == "" { cfg.WarehouseID = lc.WarehouseID } + // there's a lot of end-user friction for projects, that require account-level commands. + // this is mainly related to the fact, that, as of January 2024, workspace administrators + // do not necessarily have access to call account-level APIs. There are ongoing discussions + // on how to best implement this on a platform level. + // + // Current temporary workaround is creating dummy ~/.databrickscfg profile with `account_id` + // field, though it doesn't really remove the end-user friction, hence we don't require + // an account profile during installation (anymore) and just prompt for it, when context + // does require it. This also means that we always prompt for account-level commands, unless + // users specify a `--profile` flag. isACC := cfg.IsAccountClient() - if e.IsAccountLevel && !isACC { + if e.IsAccountLevel && cfg.Profile == "" { + if !cmdio.IsPromptSupported(ctx) { + return nil, config.ErrCannotConfigureAuth + } + replaceCfg, err := e.envAwareConfig(ctx) + if err != nil { + return nil, fmt.Errorf("replace config: %w", err) + } + err = lc.askAccountProfile(ctx, replaceCfg) + if err != nil { + return nil, fmt.Errorf("account: %w", err) + } + err = replaceCfg.EnsureResolved() + if err != nil { + return nil, fmt.Errorf("resolve: %w", err) + } + return replaceCfg, nil + } else if e.IsAccountLevel && !isACC { return nil, databricks.ErrNotAccountClient } if e.NeedsCluster() && !isACC && cfg.ClusterID == "" { diff --git a/cmd/labs/project/installer.go b/cmd/labs/project/installer.go index 7ba2830e..235d29bc 100644 --- a/cmd/labs/project/installer.go +++ b/cmd/labs/project/installer.go @@ -178,10 +178,6 @@ func (i *installer) login(ctx context.Context) (*databricks.WorkspaceClient, err if err != nil { return nil, fmt.Errorf("ask for workspace: %w", err) } - err = lc.askAccountProfile(ctx, cfg) - if err != nil { - return nil, fmt.Errorf("ask for account: %w", err) - } err = lc.save(ctx) if err != nil { return nil, fmt.Errorf("save: %w", err) diff --git a/cmd/labs/project/login.go b/cmd/labs/project/login.go index fc872bcf..232b7e1e 100644 --- a/cmd/labs/project/login.go +++ b/cmd/labs/project/login.go @@ -103,6 +103,7 @@ func (lc *loginConfig) askAccountProfile(ctx context.Context, cfg *config.Config return ErrNotInTTY } lc.AccountProfile, err = root.AskForAccountProfile(ctx) + cfg.Profile = lc.AccountProfile return }