11import { WorkspaceClient , ApiClient , logging } from "@databricks/databricks-sdk" ;
2- import { Cluster , WorkspaceFsEntity , WorkspaceFsUtils } from "../sdk-extensions" ;
2+ import { Cluster } from "../sdk-extensions" ;
33import { EventEmitter , Uri , window , Disposable } from "vscode" ;
44import { CliWrapper } from "../cli/CliWrapper" ;
55import {
66 SyncDestinationMapper ,
77 RemoteUri ,
88 LocalUri ,
99} from "../sync/SyncDestination" ;
10- import { ConfigureWorkspaceWizard } from "./ConfigureWorkspaceWizard " ;
10+ import { LoginWizard , listProfiles } from "./LoginWizard " ;
1111import { ClusterManager } from "../cluster/ClusterManager" ;
1212import { DatabricksWorkspace } from "./DatabricksWorkspace" ;
1313import { CustomWhenContext } from "../vscode-objs/CustomWhenContext" ;
14- import { workspaceConfigs } from "../vscode-objs/WorkspaceConfigs" ;
1514import { ConfigModel } from "./models/ConfigModel" ;
1615import { onError } from "../utils/onErrorDecorator" ;
17- import { AuthProvider } from "./auth/AuthProvider" ;
16+ import { AuthProvider , ProfileAuthProvider } from "./auth/AuthProvider" ;
1817import { Mutex } from "../locking" ;
1918
2019// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -124,21 +123,9 @@ export class ConnectionManager implements Disposable {
124123 this . updateClusterManager ,
125124 this
126125 ) ,
127- this . configModel . onDidChangeTarget ( this . loginWithSavedAuth , this ) ,
128- this . configModel . onDidChangeKey ( "authParams" ) ( async ( ) => {
129- const config = await this . configModel . getS ( "authParams" ) ;
130- if ( config === undefined ) {
131- return ;
132- }
133-
134- // We only react to auth changes coming from the bundle.
135- // If an override is set, then all settings must have gone
136- // through this class, which means that we have already logged in
137- // using those settings, so we don't double login.
138- if ( config . source === "bundle" ) {
139- await this . loginWithSavedAuth ( ) ;
140- }
141- } )
126+ this . configModel . onDidChangeTarget ( this . loginWithSavedAuth , this )
127+ // TODO: We don't react to changes in authProfile from the config model. We instead listen to changes
128+ // in individual models to react to (Overrides and BundlePreValidate)
142129 ) ;
143130 }
144131
@@ -175,16 +162,54 @@ export class ConnectionManager implements Disposable {
175162 return this . _workspaceClient ?. apiClient ;
176163 }
177164
165+ async resolveAuth ( ) {
166+ const host = await this . configModel . get ( "host" ) ;
167+ const target = this . configModel . target ;
168+ if ( host === undefined || target === undefined ) {
169+ return ;
170+ }
171+
172+ // Try to load a profile user had previously selected for this target
173+ const savedProfile = (
174+ await this . configModel . overrideableConfigModel . load ( )
175+ ) . authProfile ;
176+ if ( savedProfile !== undefined ) {
177+ const authProvider = new ProfileAuthProvider ( host , savedProfile ) ;
178+ if ( await authProvider . check ( ) ) {
179+ return authProvider ;
180+ }
181+ }
182+
183+ // Try to load any parameters that are hard coded in the bundle
184+ const bundleAuthParams =
185+ await this . configModel . bundlePreValidateModel . load ( ) ;
186+ if ( bundleAuthParams . authParams !== undefined ) {
187+ throw new Error ( "Bundle auth params not implemented" ) ;
188+ }
189+
190+ // Try to load a unique profile that matches the host
191+ const profiles = ( await listProfiles ( this . cli ) ) . filter (
192+ ( p ) => p . host ?. toString ( ) === host . toString ( )
193+ ) ;
194+ if ( profiles . length !== 1 ) {
195+ return ;
196+ }
197+ const authProvider = new ProfileAuthProvider ( host , profiles [ 0 ] . name ) ;
198+ if ( await authProvider . check ( ) ) {
199+ return authProvider ;
200+ }
201+ }
202+
178203 @onError ( {
179- popup : { prefix : "Can't login with saved auth. " } ,
204+ popup : { prefix : "Can't login with saved auth." } ,
180205 } )
181206 private async loginWithSavedAuth ( ) {
182- const authParams = await this . configModel . get ( "authParams" ) ;
183- if ( authParams === undefined ) {
207+ const authProvider = await this . resolveAuth ( ) ;
208+ if ( authProvider === undefined ) {
184209 await this . logout ( ) ;
185210 return ;
186211 }
187- await this . login ( AuthProvider . fromJSON ( authParams , this . cli . cliPath ) ) ;
212+ await this . login ( authProvider ) ;
188213 }
189214
190215 private async login ( authProvider : AuthProvider ) : Promise < void > {
@@ -211,10 +236,12 @@ export class ConnectionManager implements Disposable {
211236 this . _workspaceClient
212237 ) ;
213238
214- await this . createWsFsRootDirectory ( this . _workspaceClient ) ;
215239 await this . updateSyncDestinationMapper ( ) ;
216240 await this . updateClusterManager ( ) ;
217- await this . configModel . set ( "authParams" , authProvider . toJSON ( ) ) ;
241+ await this . configModel . set (
242+ "authProfile" ,
243+ authProvider . toJSON ( ) . profile as string | undefined
244+ ) ;
218245 await this . configModel . setAuthProvider ( authProvider ) ;
219246 this . updateState ( "CONNECTED" ) ;
220247 } ) ;
@@ -229,35 +256,6 @@ export class ConnectionManager implements Disposable {
229256 }
230257 }
231258
232- async createWsFsRootDirectory ( wsClient : WorkspaceClient ) {
233- if (
234- ! this . databricksWorkspace ||
235- ! workspaceConfigs . enableFilesInWorkspace
236- ) {
237- return ;
238- }
239- const rootDirPath = this . databricksWorkspace . workspaceFsRoot ;
240- const me = this . databricksWorkspace . userName ;
241- let rootDir = await WorkspaceFsEntity . fromPath (
242- wsClient ,
243- rootDirPath . path
244- ) ;
245- if ( rootDir ) {
246- return ;
247- }
248- const meDir = await WorkspaceFsEntity . fromPath (
249- wsClient ,
250- `/Users/${ me } `
251- ) ;
252- if ( WorkspaceFsUtils . isDirectory ( meDir ) ) {
253- rootDir = await meDir . mkdir ( rootDirPath . path ) ;
254- }
255- if ( ! rootDir ) {
256- window . showErrorMessage ( `Can't find or create ${ rootDirPath . path } ` ) ;
257- return ;
258- }
259- }
260-
261259 @onError ( { popup : { prefix : "Can't logout" } } )
262260 @Mutex . synchronise ( "loginLogoutMutex" )
263261 async logout ( ) {
@@ -266,19 +264,16 @@ export class ConnectionManager implements Disposable {
266264 await this . updateClusterManager ( ) ;
267265 await this . updateSyncDestinationMapper ( ) ;
268266 if ( this . configModel . target !== undefined ) {
269- await this . configModel . set ( "authParams " , undefined ) ;
267+ await this . configModel . set ( "authProfile " , undefined ) ;
270268 }
271269 this . updateState ( "DISCONNECTED" ) ;
272270 }
273271
274272 @onError ( {
275273 popup : { prefix : "Can't configure workspace. " } ,
276274 } )
277- async configureWorkspace ( ) {
278- const authProvider = await ConfigureWorkspaceWizard . run (
279- this . cli ,
280- this . configModel
281- ) ;
275+ async configureLogin ( ) {
276+ const authProvider = await LoginWizard . run ( this . cli , this . configModel ) ;
282277 if ( ! authProvider ) {
283278 return ;
284279 }
@@ -315,6 +310,7 @@ export class ConnectionManager implements Disposable {
315310 return ;
316311 }
317312 await this . configModel . set ( "remoteRootPath" , remoteWorkspace . path ) ;
313+ await this . configModel . set ( "remoteRootPath" , remoteWorkspace . path ) ;
318314 }
319315
320316 @onError ( {
0 commit comments