Skip to content

Commit 41f076c

Browse files
All AuthProviders must implement a non silent check. (#939)
## Changes * Moving forward, we want to avoid having silent checks to make reasoning about auth easier. This PR makes it so that all AuthProviders must implement the `check` method. * Each check method must handle it's own Retry Loop, error handling and display. Since now checks are always interactive, we do not want calling code to manage the interactions. ## Tests * manual
1 parent 76d7d37 commit 41f076c

File tree

5 files changed

+46
-16
lines changed

5 files changed

+46
-16
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export class ConnectionManager {
142142
}
143143
}
144144

145-
if (!(await projectConfigFile.authProvider.check(true))) {
145+
if (!(await projectConfigFile.authProvider.check())) {
146146
throw new Error(
147147
`Can't login with ${projectConfigFile.authProvider.describe()}.`
148148
);
@@ -277,7 +277,7 @@ export class ConnectionManager {
277277
return;
278278
}
279279

280-
if (!(await config.authProvider.check(false))) {
280+
if (!(await config.authProvider.check())) {
281281
return;
282282
}
283283

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

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import {
33
Config,
44
ProductVersion,
55
WorkspaceClient,
6+
logging,
67
} from "@databricks/databricks-sdk";
8+
import {window} from "vscode";
79
import {normalizeHost} from "../../utils/urlUtils";
810
import {workspaceConfigs} from "../../vscode-objs/WorkspaceConfigs";
911

@@ -13,6 +15,7 @@ const extensionVersion = require("../../../package.json")
1315

1416
import {AzureCliCheck} from "./AzureCliCheck";
1517
import {DatabricksCliCheck} from "./DatabricksCliCheck";
18+
import {Loggers} from "../../logger";
1619

1720
// TODO: Resolve this with SDK's AuthType.
1821
export type AuthType = "azure-cli" | "google-id" | "databricks-cli" | "profile";
@@ -47,10 +50,12 @@ export abstract class AuthProvider {
4750
});
4851
}
4952

50-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
51-
async check(silent: boolean): Promise<boolean> {
52-
return true;
53-
}
53+
/**
54+
* Check if the currently selected auth method can be used to login to Databricks.
55+
* This function should not throw an error and each implementing class must
56+
* handle it's own error messages and retry loops.
57+
*/
58+
abstract check(): Promise<boolean>;
5459

5560
protected abstract getSdkConfig(): Config;
5661

@@ -129,6 +134,25 @@ export class ProfileAuthProvider extends AuthProvider {
129134
env: {},
130135
});
131136
}
137+
138+
async check() {
139+
try {
140+
const workspaceClient = this.getWorkspaceClient();
141+
await workspaceClient.currentUser.me();
142+
return true;
143+
} catch (e) {
144+
let message: string = `Can't login with config profile ${this.profile}`;
145+
if (e instanceof Error) {
146+
message = `Can't login with config profile ${this.profile}: ${e.message}`;
147+
}
148+
logging.NamedLogger.getOrCreate(Loggers.Extension).error(
149+
message,
150+
e
151+
);
152+
window.showErrorMessage(message);
153+
return false;
154+
}
155+
}
132156
}
133157

134158
export class DatabricksCliAuthProvider extends AuthProvider {
@@ -167,9 +191,9 @@ export class DatabricksCliAuthProvider extends AuthProvider {
167191
};
168192
}
169193

170-
async check(silent: boolean): Promise<boolean> {
194+
async check(): Promise<boolean> {
171195
const databricksCliCheck = new DatabricksCliCheck(this);
172-
return databricksCliCheck.check(silent);
196+
return databricksCliCheck.check();
173197
}
174198
}
175199

@@ -225,9 +249,9 @@ export class AzureCliAuthProvider extends AuthProvider {
225249
return envVars;
226250
}
227251

228-
async check(silent: boolean): Promise<boolean> {
252+
async check(): Promise<boolean> {
229253
const cliCheck = new AzureCliCheck(this);
230-
const result = await cliCheck.check(silent);
254+
const result = await cliCheck.check();
231255
this._tenantId = cliCheck.tenantId;
232256
this._appId = cliCheck.azureLoginAppId;
233257
return result;

packages/databricks-vscode/src/configuration/auth/AzureCliCheck.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class AzureCliCheck implements Disposable {
4646
this.disposables = [];
4747
}
4848

49-
public async check(silent = false): Promise<boolean> {
49+
public async check(): Promise<boolean> {
5050
this.tenantId = this.authProvider.tenantId;
5151

5252
let loginAttempts = 0;
@@ -156,11 +156,12 @@ export class AzureCliCheck implements Disposable {
156156
message = e.message;
157157
}
158158

159+
NamedLogger.getOrCreate(Loggers.Extension).error(message, e);
159160
window.showErrorMessage(message);
160161
return false;
161162
}
162163

163-
if (result && !silent) {
164+
if (result) {
164165
window.showInformationMessage(
165166
"Databricks: Successfully logged in with Azure CLI"
166167
);

packages/databricks-vscode/src/configuration/auth/DatabricksCliCheck.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import {
22
ExecUtils,
33
ProductVersion,
44
WorkspaceClient,
5+
logging,
56
} from "@databricks/databricks-sdk";
67
import {Disposable, window} from "vscode";
78
import {DatabricksCliAuthProvider} from "./AuthProvider";
89
import {orchestrate, OrchestrationLoopError, Step} from "./orchestrate";
10+
import {Loggers} from "../../logger";
911

1012
// eslint-disable-next-line @typescript-eslint/no-var-requires
1113
const extensionVersion = require("../../../package.json")
@@ -23,7 +25,7 @@ export class DatabricksCliCheck implements Disposable {
2325
this.disposables = [];
2426
}
2527

26-
async check(silent: boolean): Promise<boolean> {
28+
async check(): Promise<boolean> {
2729
const steps: Record<StepName, Step<boolean, StepName>> = {
2830
tryLogin: async () => {
2931
if (await this.tryLogin()) {
@@ -55,12 +57,15 @@ export class DatabricksCliCheck implements Disposable {
5557
} else {
5658
message = e.message;
5759
}
58-
60+
logging.NamedLogger.getOrCreate(Loggers.Extension).error(
61+
message,
62+
e
63+
);
5964
window.showErrorMessage(message);
6065
return false;
6166
}
6267

63-
if (result && !silent) {
68+
if (result) {
6469
window.showInformationMessage(
6570
"Databricks: Successfully logged in with Databricks CLI"
6671
);

packages/databricks-vscode/src/configuration/auth/orchestrate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function orchestrate<S, KEYS extends string>(
4242
throw new OrchestrationLoopError();
4343
}
4444
const result: StepResult<S, KEYS> = await steps[step]();
45-
logger?.info(`Azire CLI check: ${step}`, result);
45+
logger?.info(`Auth check: ${step}`, result);
4646

4747
if (result.type === "error") {
4848
throw result.error;

0 commit comments

Comments
 (0)