Skip to content

Commit 1cf255c

Browse files
Fix project.json parsing (#323)
1 parent 161598a commit 1cf255c

File tree

5 files changed

+47
-32
lines changed

5 files changed

+47
-32
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
fromConfigFile,
66
fromToken,
77
} from "@databricks/databricks-sdk";
8+
import {normalizeHost} from "../utils/urlUtils";
89

910
import {AzureCliCheck} from "./AzureCliCheck";
1011

@@ -46,8 +47,11 @@ export abstract class AuthProvider {
4647
}
4748

4849
static fromJSON(json: Record<string, any>): AuthProvider {
49-
const url = json.url instanceof URL ? json.url : new URL(json.host);
50-
if (!url) {
50+
const host =
51+
json.host instanceof URL
52+
? json.host
53+
: normalizeHost(json.host as string);
54+
if (!host) {
5155
throw new Error("Missing host");
5256
}
5357

@@ -57,19 +61,19 @@ export abstract class AuthProvider {
5761

5862
switch (json.authType as AuthType) {
5963
case "azure-cli":
60-
return new AzureCliAuthProvider(url);
64+
return new AzureCliAuthProvider(host);
6165

6266
case "profile":
6367
if (!json.profile) {
6468
throw new Error("Missing profile");
6569
}
66-
return new ProfileAuthProvider(url, json.profile);
70+
return new ProfileAuthProvider(host, json.profile);
6771

6872
case "pat":
6973
if (!json.token) {
7074
throw new Error("Missing token");
7175
}
72-
return new TokenAuthProvider(url, json.token);
76+
return new TokenAuthProvider(host, json.token);
7377

7478
default:
7579
throw new Error(`Unknown auth type: ${json.authType}`);

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import fs from "node:fs/promises";
33
import {AuthProvider, ProfileAuthProvider} from "./AuthProvider";
44
import {fromConfigFile} from "@databricks/databricks-sdk";
55
import {Uri} from "vscode";
6+
import {NamedLogger} from "@databricks/databricks-sdk/dist/logging";
7+
import {Loggers} from "../logger";
68

79
export interface ProjectConfig {
810
authProvider: AuthProvider;
@@ -51,7 +53,7 @@ export class ProjectConfigFile {
5153
try {
5254
const originalConfig = await ProjectConfigFile.load(this.rootPath);
5355
if (
54-
JSON.stringify(originalConfig.config, null, 2) ===
56+
JSON.stringify(originalConfig, null, 2) ===
5557
JSON.stringify(this, null, 2)
5658
) {
5759
return;
@@ -103,6 +105,10 @@ export class ProjectConfigFile {
103105
authProvider = AuthProvider.fromJSON(config);
104106
}
105107
} catch (e) {
108+
NamedLogger.getOrCreate(Loggers.Extension).error(
109+
"Error parsing project config file",
110+
e
111+
);
106112
throw new ConfigFileError("Error parsing project config file");
107113
}
108114
return new ProjectConfigFile(

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

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "@databricks/databricks-sdk";
88
import {commands, QuickPickItem, QuickPickItemKind} from "vscode";
99
import {MultiStepInput} from "../ui/wizard";
10+
import {normalizeHost} from "../utils/urlUtils";
1011
import {AuthProvider, AuthType} from "./AuthProvider";
1112
import {ProjectConfig} from "./ProjectConfigFile";
1213

@@ -199,31 +200,6 @@ export async function configureWorkspaceWizard(
199200
};
200201
}
201202

202-
function normalizeHost(host: string): URL {
203-
let url: URL;
204-
205-
if (!host.startsWith("http")) {
206-
host = `https://${host}`;
207-
}
208-
try {
209-
url = new URL(host);
210-
} catch (e) {
211-
throw new Error("Invalid host name");
212-
}
213-
if (url.protocol !== "https:") {
214-
throw new Error("Invalid protocol");
215-
}
216-
if (
217-
!url.hostname.match(
218-
/(\.azuredatabricks\.net|\.gcp\.databricks\.com|\.cloud\.databricks\.com)$/
219-
)
220-
) {
221-
throw new Error("Not a Databricks host");
222-
}
223-
224-
return new URL(`https://${url.hostname}`);
225-
}
226-
227203
async function validateDatabricksHost(
228204
host: string
229205
): Promise<string | undefined> {

packages/databricks-vscode/src/test/e2e/configure.e2e.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,12 @@ describe("Configure Databricks Extension", async function () {
151151
)
152152
);
153153

154+
const expectedHost = new URL(
155+
host.startsWith("https") ? host : `https://${host}`
156+
).toString();
157+
154158
assert.deepEqual(projectConfig, {
155-
host,
159+
host: expectedHost,
156160
authType: "profile",
157161
profile: "DEFAULT",
158162
clusterId,

packages/databricks-vscode/src/utils/urlUtils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,28 @@ export function addHttpsIfNoProtocol(url: string) {
66
export async function openExternal(url: string) {
77
await env.openExternal(Uri.parse(addHttpsIfNoProtocol(url), true));
88
}
9+
10+
export function normalizeHost(host: string): URL {
11+
let url: URL;
12+
13+
if (!host.startsWith("http")) {
14+
host = `https://${host}`;
15+
}
16+
try {
17+
url = new URL(host);
18+
} catch (e) {
19+
throw new Error("Invalid host name");
20+
}
21+
if (url.protocol !== "https:") {
22+
throw new Error("Invalid protocol");
23+
}
24+
if (
25+
!url.hostname.match(
26+
/(\.azuredatabricks\.net|\.gcp\.databricks\.com|\.cloud\.databricks\.com)$/
27+
)
28+
) {
29+
throw new Error("Not a Databricks host");
30+
}
31+
32+
return new URL(`https://${url.hostname}`);
33+
}

0 commit comments

Comments
 (0)