Skip to content

Commit 7633281

Browse files
authored
use "bricks auth profiles" and list host names (#389)
1 parent 999aed8 commit 7633281

File tree

10 files changed

+336
-363
lines changed

10 files changed

+336
-363
lines changed

packages/databricks-sdk-js/src/config/Config.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ describe(__dirname, function () {
7575
}
7676
}
7777

78+
if (!cf.env || !cf.env["HOME"]) {
79+
process.env["HOME"] = "i-dont-exist";
80+
}
81+
7882
try {
7983
config = await configureProviderAndReturnConfig(cf);
8084
} catch (error: any) {

packages/databricks-vscode/package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -572,13 +572,13 @@
572572
"scripts": {
573573
"vscode:prepublish": "rm -rf out && yarn run package:compile && yarn run package:copy-webview-toolkit",
574574
"package": "vsce package",
575-
"package:cli:fetch": "BRICKS_VERSION=v0.0.18 && bash ./scripts/fetch-bricks-cli.sh ${BRICKS_VERSION} ${BRICKS_ARCH:-}",
575+
"package:cli:fetch": "BRICKS_VERSION=v0.0.19 && bash ./scripts/fetch-bricks-cli.sh ${BRICKS_VERSION} ${BRICKS_ARCH:-}",
576576
"package:cli:link": "rm -f ./bin/bricks && ln -s ../../../../bricks/bricks bin",
577577
"package:compile": "yarn run esbuild:base",
578578
"package:copy-webview-toolkit": "cp ./node_modules/@vscode/webview-ui-toolkit/dist/toolkit.js ./out/toolkit.js",
579579
"esbuild:base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node --sourcemap --target=es2019",
580-
"build": "tsc --build",
581-
"watch": "yarn run package:copy-webview-toolkit && tsc --build --watch",
580+
"build": "tsc --build --force",
581+
"watch": "yarn run package:copy-webview-toolkit && tsc --build --watch --force",
582582
"fix": "eslint src --ext ts --fix && prettier . --write",
583583
"test:lint": "eslint src --ext ts && prettier . -c",
584584
"test:unit": "yarn run build && node ./out/test/runTest.js",
@@ -597,7 +597,6 @@
597597
"@vscode/debugadapter": "^1.58.0",
598598
"@vscode/webview-ui-toolkit": "^1.2.1",
599599
"ansi-to-html": "^0.7.2",
600-
"ini": "^3.0.1",
601600
"triple-beam": "^1.3.0",
602601
"winston": "^3.8.2"
603602
},
@@ -606,7 +605,6 @@
606605
"@sinonjs/fake-timers": "^10.0.2",
607606
"@types/fs-extra": "^11.0.1",
608607
"@types/glob": "^8.0.1",
609-
"@types/ini": "^1.3.31",
610608
"@types/mocha": "^10.0.1",
611609
"@types/mock-require": "^2.0.1",
612610
"@types/node": "^18.11.18",
@@ -659,4 +657,4 @@
659657
],
660658
"report-dir": "coverage"
661659
}
662-
}
660+
}

packages/databricks-vscode/src/cli/CliWrapper.test.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ import {Uri} from "vscode";
33
import {SyncDestination} from "../configuration/SyncDestination";
44
import {promisify} from "node:util";
55
import {execFile as execFileCb} from "node:child_process";
6+
import {withFile} from "tmp-promise";
7+
import {writeFile} from "node:fs/promises";
68

79
import {CliWrapper} from "./CliWrapper";
810
import {instance, mock} from "ts-mockito";
911
import {WorkspaceFsRepo} from "@databricks/databricks-sdk";
12+
import path from "node:path";
1013

1114
const execFile = promisify(execFileCb);
1215

@@ -62,4 +65,88 @@ describe(__filename, () => {
6265
"./bin/bricks configure --no-interactive --profile DEFAULT --host https://databricks.com/ --token"
6366
);
6467
});
68+
69+
it("should list profiles when no config file exists", async () => {
70+
const cli = new CliWrapper({
71+
asAbsolutePath(p: string) {
72+
return path.join(__dirname, "..", "..", p);
73+
},
74+
} as any);
75+
76+
const profiles = await cli.listProfiles("/tmp/does-not-exist");
77+
assert.equal(profiles.length, 0);
78+
});
79+
80+
it("should list profiles", async function () {
81+
const cli = new CliWrapper({
82+
asAbsolutePath(p: string) {
83+
return path.join(__dirname, "..", "..", p);
84+
},
85+
} as any);
86+
87+
await withFile(async ({path}) => {
88+
await writeFile(
89+
path,
90+
`
91+
host = https://cloud.databricks.com/
92+
token = dapitest1234
93+
94+
[STAGING]
95+
host = https://staging.cloud.databricks.com/
96+
token = dapitest54321
97+
`
98+
);
99+
100+
const profiles = await cli.listProfiles(path);
101+
102+
assert.equal(profiles.length, 2);
103+
assert.equal(profiles[0].name, "DEFAULT");
104+
assert.equal(profiles[0].host, "https://cloud.databricks.com/");
105+
assert.equal(profiles[0].authType, "pat");
106+
107+
assert.equal(profiles[1].name, "STAGING");
108+
assert.equal(
109+
profiles[1].host,
110+
"https://staging.cloud.databricks.com/"
111+
);
112+
assert.equal(profiles[1].authType, "pat");
113+
});
114+
});
115+
116+
it("should load all valid profiles and return errors for rest", async () => {
117+
const cli = new CliWrapper({
118+
asAbsolutePath(p: string) {
119+
return path.join(__dirname, "..", "..", p);
120+
},
121+
} as any);
122+
123+
await withFile(async ({path}) => {
124+
await writeFile(
125+
path,
126+
`[correct]
127+
host = https://cloud.databricks.com/
128+
token = dapitest1234
129+
130+
[no-host]
131+
token = dapitest54321
132+
133+
[no-token]
134+
host = https://cloud.databricks.com/
135+
136+
[missing-host-token]
137+
nothing = true
138+
`
139+
);
140+
const profiles = await cli.listProfiles(path);
141+
assert.equal(profiles.length, 2);
142+
143+
assert.equal(profiles[0].name, "correct");
144+
assert.equal(profiles[0].host, "https://cloud.databricks.com/");
145+
assert.equal(profiles[0].authType, "pat");
146+
147+
assert.equal(profiles[1].name, "no-token");
148+
assert.equal(profiles[1].host, "https://cloud.databricks.com/");
149+
assert.equal(profiles[1].authType, "");
150+
});
151+
});
65152
});

packages/databricks-vscode/src/cli/CliWrapper.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
import {spawn} from "child_process";
1+
import {execFile as execFileCb, spawn} from "child_process";
22
import {ExtensionContext} from "vscode";
33
import {SyncDestination} from "../configuration/SyncDestination";
44
import {workspaceConfigs} from "../WorkspaceConfigs";
5+
import {promisify} from "node:util";
6+
7+
const execFile = promisify(execFileCb);
58

69
export interface Command {
710
command: string;
811
args: string[];
912
}
1013

14+
export interface ConfigEntry {
15+
name: string;
16+
host?: URL;
17+
accountId?: string;
18+
cloud: "aws" | "azure" | "gcp";
19+
authType: string;
20+
valid: boolean;
21+
}
22+
1123
export type SyncType = "full" | "incremental";
1224
/**
1325
* Entrypoint for all wrapped CLI commands
@@ -48,6 +60,41 @@ export class CliWrapper {
4860
return {command, args};
4961
}
5062

63+
private getListProfilesCommand(): Command {
64+
return {
65+
command: this.context.asAbsolutePath("./bin/bricks"),
66+
args: ["auth", "profiles", "--skip-validate"],
67+
};
68+
}
69+
70+
public async listProfiles(
71+
configfilePath?: string
72+
): Promise<Array<ConfigEntry>> {
73+
const cmd = await this.getListProfilesCommand();
74+
const res = await execFile(cmd.command, cmd.args, {
75+
env: {
76+
// eslint-disable-next-line @typescript-eslint/naming-convention
77+
HOME: process.env.HOME,
78+
// eslint-disable-next-line @typescript-eslint/naming-convention
79+
DATABRICKS_CONFIG_FILE:
80+
configfilePath || process.env.DATABRICKS_CONFIG_FILE,
81+
},
82+
});
83+
const profiles = JSON.parse(res.stdout).profiles || [];
84+
const result = [];
85+
for (const profile of profiles) {
86+
result.push({
87+
name: profile.name,
88+
host: new URL(profile.host),
89+
accountId: profile.account_id,
90+
cloud: profile.cloud,
91+
authType: profile.auth_type,
92+
valid: profile.valid,
93+
});
94+
}
95+
return result;
96+
}
97+
5198
getAddProfileCommand(profile: string, host: URL): Command {
5299
return {
53100
command: this.context.asAbsolutePath("./bin/bricks"),

packages/databricks-vscode/src/configuration/ConnectionManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ export class ConnectionManager {
214214
let config: ProjectConfig | undefined;
215215
while (true) {
216216
config = await configureWorkspaceWizard(
217+
this.cli,
217218
this.databricksWorkspace?.host?.toString() ||
218-
config?.authProvider?.host.toString() ||
219-
process.env.DATABRICKS_HOST
219+
config?.authProvider?.host.toString()
220220
);
221221

222222
if (!config) {

0 commit comments

Comments
 (0)