Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

### CLI
* Added the `databricks quickstart` command, a short introduction to the CLI that prints a human-friendly guide interactively and an agent-oriented version when run non-interactively ([#5464](https://github.com/databricks/cli/pull/5464)).
* `databricks auth login` no longer prompts for workspace selection when logging in to an account console host (`https://accounts.*`). Pass `--workspace-id` explicitly to store a workspace ID on such a profile ([#5504](https://github.com/databricks/cli/pull/5504)).
* `databricks auth profiles --skip-validate` no longer makes any network calls; the host metadata fetch is skipped along with validation ([#5530](https://github.com/databricks/cli/pull/5530)).


### Bundles
* Set the default `data_security_mode` to `DATA_SECURITY_MODE_AUTO` in bundle templates ([#5452](https://github.com/databricks/cli/pull/5452)).
Expand Down
8 changes: 4 additions & 4 deletions acceptance/auth/host-metadata-cache/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"name": "cached",
"host": "[DATABRICKS_URL]",
"cloud": "aws",
"auth_type": "",
"valid": false
"auth_type": "pat",
"valid": true
}
]
}
Expand All @@ -19,8 +19,8 @@
"name": "cached",
"host": "[DATABRICKS_URL]",
"cloud": "aws",
"auth_type": "",
"valid": false
"auth_type": "pat",
"valid": true
}
]
}
Expand Down
7 changes: 4 additions & 3 deletions acceptance/auth/host-metadata-cache/script
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ sethome "./home"
export DATABRICKS_CACHE_DIR="$TEST_TMP_DIR/cache"

# Point a profile at the mock server so auth profiles triggers a host metadata
# fetch. Without a profile the command does nothing and the cache is never read.
# fetch. Validation must stay on: --skip-validate resolves offline and would
# never fetch or populate the cache.
cat > "./home/.databrickscfg" <<EOF
[cached]
host = ${DATABRICKS_HOST}
token = test-token
EOF

title "First invocation populates the cache\n"
$CLI auth profiles --skip-validate --output json
$CLI auth profiles --output json

title "Second invocation should read from the cache\n"
$CLI auth profiles --skip-validate --output json
$CLI auth profiles --output json

title "Only one /.well-known/databricks-config request recorded\n"
print_requests.py //.well-known/databricks-config --get --sort
1 change: 0 additions & 1 deletion acceptance/cmd/auth/profiles/output.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

=== Profiles with workspace_id (JSON output)
Warn: [hostmetadata] failed to fetch host metadata for https://test.cloud.databricks.com, will skip for 1m0s
{
"profiles": [
{
Expand Down
9 changes: 9 additions & 0 deletions cmd/auth/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ func (c *profileMetadata) Load(ctx context.Context, configFilePath string, skipV
Profile: c.Name,
DatabricksCliPath: env.Get(ctx, "DATABRICKS_CLI_PATH"),
}
if skipValidate {
// EnsureResolved fetches <host>/.well-known/databricks-config to enrich
// the config, so without this stub a skip-validate listing still makes
// one network call per profile (and warns when offline). Resolve from
// the config file alone; cloud detection falls back to the host pattern.
cfg.HostMetadataResolver = func(context.Context, string) (*config.HostMetadata, error) {
return nil, nil
}
}
_ = cfg.EnsureResolved()
if cfg.IsAws() {
c.Cloud = "aws"
Expand Down
30 changes: 30 additions & 0 deletions cmd/auth/profiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"runtime"
"sync/atomic"
"testing"

"github.com/databricks/cli/libs/databrickscfg"
Expand Down Expand Up @@ -48,6 +49,35 @@ func TestProfiles(t *testing.T) {
assert.Equal(t, "pat", profile.AuthType)
}

// TestProfileLoadSkipValidateMakesNoRequests guards the --skip-validate
// contract: EnsureResolved would otherwise fetch /.well-known/databricks-config
// for every profile, so the handler counts every request it receives.
func TestProfileLoadSkipValidateMakesNoRequests(t *testing.T) {
var requests atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requests.Add(1)
w.WriteHeader(http.StatusNotFound)
}))
t.Cleanup(server.Close)

dir := t.TempDir()
configFile := filepath.Join(dir, ".databrickscfg")
t.Setenv("HOME", dir)
if runtime.GOOS == "windows" {
t.Setenv("USERPROFILE", dir)
}

content := "[offline-profile]\nhost = " + server.URL + "\ntoken = test-token\n"
require.NoError(t, os.WriteFile(configFile, []byte(content), 0o600))

p := &profileMetadata{Name: "offline-profile", Host: server.URL}
p.Load(t.Context(), configFile, true)

assert.Zero(t, requests.Load(), "expected no network calls with skipValidate")
assert.Equal(t, server.URL, p.Host)
assert.False(t, p.Valid)
}

func TestProfilesDefaultMarker(t *testing.T) {
ctx := t.Context()
dir := t.TempDir()
Expand Down
Loading