-
Notifications
You must be signed in to change notification settings - Fork 233
Add Docker credential token command #6194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
yolocs
wants to merge
1
commit into
databricks:main
from
yolocs:chen-shou_data/stack/dar-configure-docker
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| * Add experimental `databricks auth docker token` to generate Docker credentials for Databricks Artifact Registry. ([#6194](https://github.com/databricks/cli/pull/6194)) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
|
|
||
| >>> [CLI] auth --help | ||
| Authentication related commands. For more information regarding how | ||
| authentication for the Databricks CLI and SDKs work please refer to the documentation | ||
| linked below. | ||
|
|
||
| AWS: https://docs.databricks.com/dev-tools/auth/index.html | ||
| Azure: https://learn.microsoft.com/azure/databricks/dev-tools/auth | ||
| GCP: https://docs.gcp.databricks.com/dev-tools/auth/index.html | ||
|
|
||
| Usage: | ||
| databricks auth [command] | ||
|
|
||
| Available Commands: | ||
| describe Describes the credentials and the source of those credentials, being used by the CLI to authenticate | ||
| docker (Experimental) Manage Docker authentication for Databricks Artifact Registry | ||
| login Log into a Databricks workspace or account | ||
| logout Log out of a Databricks profile | ||
| profiles Lists profiles from ~/.databrickscfg | ||
| switch Set the default profile | ||
| token Get authentication token | ||
|
|
||
| Flags: | ||
| --account-id string Databricks Account ID | ||
| -h, --help help for auth | ||
| --host string Databricks Host | ||
| --workspace-id string Databricks Workspace ID | ||
|
|
||
| Global Flags: | ||
| --debug enable debug logging | ||
| -o, --output type output type: text or json (default text) | ||
| -p, --profile string ~/.databrickscfg profile | ||
| -t, --target string bundle target to use (if applicable) | ||
|
|
||
| Use "databricks auth [command] --help" for more information about a command. | ||
|
|
||
| >>> [CLI] auth docker --help | ||
| (Experimental) Manage Docker authentication for Databricks Artifact Registry | ||
|
|
||
| Usage: | ||
| databricks auth docker [command] | ||
|
|
||
| Available Commands: | ||
| token (Experimental) Generate a Docker credential | ||
|
|
||
| Flags: | ||
| -h, --help help for docker | ||
|
|
||
| Global Flags: | ||
| --account-id string Databricks Account ID | ||
| --debug enable debug logging | ||
| --host string Databricks Host | ||
| -o, --output type output type: text or json (default text) | ||
| -p, --profile string ~/.databrickscfg profile | ||
| -t, --target string bundle target to use (if applicable) | ||
| --workspace-id string Databricks Workspace ID | ||
|
|
||
| Use "databricks auth docker [command] --help" for more information about a command. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| trace "$CLI" auth --help | ||
| trace "$CLI" auth docker --help |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| setup_docker_auth() { | ||
| export DATABRICKS_HOST_ORIG="$DATABRICKS_HOST" | ||
| sethome "./home" | ||
|
|
||
| unset DATABRICKS_ACCOUNT_ID | ||
| unset DATABRICKS_AUTH_TYPE | ||
| unset DATABRICKS_CLIENT_ID | ||
| unset DATABRICKS_CLIENT_SECRET | ||
| unset DATABRICKS_CONFIG_FILE | ||
| unset DATABRICKS_CONFIG_PROFILE | ||
| unset DATABRICKS_DISCOVERY_URL | ||
| unset DATABRICKS_HOST | ||
| unset DATABRICKS_TOKEN | ||
| unset DATABRICKS_WORKSPACE_ID | ||
|
|
||
| export DATABRICKS_AUTH_STORAGE=plaintext | ||
| export DATABRICKS_LOG_LEVEL=error | ||
| export TEST_DAR_REGISTRY_HOST=123456789.container.us-west-2.cloud.databricks.com | ||
|
|
||
| cat > "$HOME/.databrickscfg" <<ENDCFG | ||
| [docker-test] | ||
| host = $DATABRICKS_HOST_ORIG | ||
| auth_type = databricks-cli | ||
| workspace_id = 123456789 | ||
| ENDCFG | ||
|
|
||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
|
|
||
| >>> [CLI] auth docker token | ||
| { | ||
| "Secret": "oauth-token", | ||
| "Username": "oauthtoken" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| setup_docker_auth | ||
|
|
||
| mkdir -p "$HOME/.databricks" | ||
| cp token-cache.json "$HOME/.databricks/token-cache.json" | ||
|
|
||
| printf '%s\n' "$TEST_DAR_REGISTRY_HOST" | trace "$CLI" auth docker token | jq -S . | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Ignore = [ | ||
| "home", | ||
| ] | ||
|
|
||
| EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] | ||
|
|
||
| Timeout = "15s" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "version": 1, | ||
| "tokens": { | ||
| "docker-test": { | ||
| "access_token": "cached-access-token", | ||
| "token_type": "Bearer", | ||
| "refresh_token": "test-refresh-token", | ||
| "expiry": "2099-01-01T00:00:00Z" | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package auth | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| authdocker "github.com/databricks/cli/cmd/auth/docker" | ||
| "github.com/databricks/cli/libs/auth" | ||
| "github.com/databricks/cli/libs/auth/storage" | ||
| "github.com/databricks/cli/libs/databrickscfg/profile" | ||
| "github.com/spf13/cobra" | ||
| "golang.org/x/oauth2" | ||
| ) | ||
|
|
||
| func newDockerCommand() *cobra.Command { | ||
| return authdocker.New(loadDockerToken) | ||
| } | ||
|
|
||
| func loadDockerToken(ctx context.Context, req authdocker.TokenRequest) (*oauth2.Token, error) { | ||
| tokenStore, mode, err := storage.ResolveStore(ctx, storage.StorageModeUnknown) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return loadToken(ctx, loadTokenArgs{ | ||
| authArguments: &auth.AuthArguments{ | ||
| Host: req.Profile.Host, | ||
| AccountID: req.Profile.AccountID, | ||
| WorkspaceID: req.Profile.WorkspaceID, | ||
| }, | ||
| profileName: req.Profile.Name, | ||
| tokenTimeout: req.Timeout, | ||
| forceRefresh: req.ForceRefresh, | ||
| profiler: profile.DefaultProfiler, | ||
| tokenStore: tokenStore, | ||
| mode: mode, | ||
| }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package docker | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/databricks/cli/libs/databrickscfg/profile" | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const defaultTokenTimeout = time.Hour | ||
|
|
||
| // New returns the Docker authentication command. | ||
| func New(load TokenLoader) *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "docker", | ||
| Short: "(Experimental) Manage Docker authentication for Databricks Artifact Registry", | ||
| } | ||
| cmd.AddCommand(newDockerTokenCommand(load)) | ||
| return cmd | ||
| } | ||
|
|
||
| func newDockerTokenCommand(load TokenLoader) *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "token", | ||
| Short: "(Experimental) Generate a Docker credential", | ||
| } | ||
|
|
||
| var tokenTimeout time.Duration | ||
| cmd.Flags().DurationVar(&tokenTimeout, "timeout", defaultTokenTimeout, "Timeout for acquiring a token.") | ||
| var noForceRefresh bool | ||
| cmd.Flags().BoolVar(&noForceRefresh, "no-force-refresh", false, "Use a valid cached token instead of forcing a refresh.") | ||
|
|
||
| cmd.PreRunE = validateDockerTokenRequest | ||
| cmd.RunE = func(cmd *cobra.Command, _ []string) error { | ||
| ctx := cmd.Context() | ||
| return runDockerToken(ctx, cmd, tokenOptions{ | ||
| tokenTimeout: tokenTimeout, | ||
| // Docker may reuse one credential for a long upload, so maximize its lifetime by refreshing it by default. | ||
| forceRefresh: !noForceRefresh, | ||
| profiler: profile.DefaultProfiler, | ||
| }, load) | ||
| } | ||
| return cmd | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package docker | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| authlib "github.com/databricks/cli/libs/auth" | ||
| "github.com/databricks/cli/libs/databrickscfg/profile" | ||
| "github.com/databricks/databricks-sdk-go/config" | ||
| ) | ||
|
|
||
| func validateDockerCredentialProfile(p profile.Profile) error { | ||
| if p.HasClientCredentials { | ||
| return fmt.Errorf("profile %q uses client credentials. Docker credential helper requires a profile created by databricks auth login", p.Name) | ||
| } | ||
| if p.AuthType != authlib.AuthTypeDatabricksCli { | ||
| return fmt.Errorf("profile %q uses auth_type %q. Docker credential helper requires a profile created by databricks auth login", p.Name, p.AuthType) | ||
| } | ||
| if isDockerCredentialAccountOnlyProfile(p) { | ||
| return fmt.Errorf("profile %q does not target a workspace. Run databricks auth login --host <workspace-url> and retry with that profile", p.Name) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func isDockerCredentialAccountOnlyProfile(p profile.Profile) bool { | ||
| if p.Host == "" { | ||
| return true | ||
| } | ||
| cfg := &config.Config{Host: p.Host, AccountID: p.AccountID, WorkspaceID: p.WorkspaceID} | ||
| if authlib.IsClassicAccountHost(cfg.CanonicalHostName()) { | ||
| return true | ||
| } | ||
| return p.AccountID != "" && (p.WorkspaceID == "" || p.WorkspaceID == authlib.WorkspaceIDNone) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| package docker | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/databricks/cli/libs/auth" | ||
| "github.com/databricks/cli/libs/databrickscfg/profile" | ||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestValidateDockerCredentialProfile(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| profile profile.Profile | ||
| wantError string | ||
| }{ | ||
| { | ||
| name: "workspace", | ||
| profile: profile.Profile{ | ||
| Name: "workspace", | ||
| Host: "https://workspace.cloud.databricks.test", | ||
| WorkspaceID: "123456789", | ||
| AuthType: auth.AuthTypeDatabricksCli, | ||
| }, | ||
| }, | ||
| { | ||
| name: "client credentials", | ||
| profile: profile.Profile{ | ||
| Name: "m2m", | ||
| Host: "https://workspace.cloud.databricks.test", | ||
| WorkspaceID: "123456789", | ||
| HasClientCredentials: true, | ||
| }, | ||
| wantError: "requires a profile created by databricks auth login", | ||
| }, | ||
| { | ||
| name: "unsupported auth type", | ||
| profile: profile.Profile{ | ||
| Name: "pat", | ||
| Host: "https://workspace.cloud.databricks.test", | ||
| WorkspaceID: "123456789", | ||
| AuthType: "pat", | ||
| }, | ||
| wantError: "requires a profile created by databricks auth login", | ||
| }, | ||
| { | ||
| name: "classic account", | ||
| profile: profile.Profile{ | ||
| Name: "account", | ||
| Host: "https://accounts.cloud.databricks.test", | ||
| AccountID: "account-id", | ||
| WorkspaceID: "123456789", | ||
| AuthType: auth.AuthTypeDatabricksCli, | ||
| }, | ||
| wantError: "does not target a workspace", | ||
| }, | ||
| { | ||
| name: "unified account", | ||
| profile: profile.Profile{ | ||
| Name: "account", | ||
| Host: "https://workspace.cloud.databricks.test", | ||
| AccountID: "account-id", | ||
| AuthType: auth.AuthTypeDatabricksCli, | ||
| }, | ||
| wantError: "does not target a workspace", | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| err := validateDockerCredentialProfile(tt.profile) | ||
| if tt.wantError == "" { | ||
| assert.NoError(t, err) | ||
| return | ||
| } | ||
| assert.ErrorContains(t, err, tt.wantError) | ||
| }) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose for keeping an existing token cache? What happens if there is no profile (yet)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The token cache represents an existing databricks auth login. A logged-in workspace profile is a prerequisite: the helper extracts the workspace ID from the registry hostname, finds the matching profile, and refreshes its cached OAuth token. Without a matching logged-in profile, it fails with guidance to run databricks auth login.