@@ -58,8 +58,10 @@ type ClientOptions struct {
5858 ReleasesDir string
5959 // Directory for local SSH keys. Defaults to ~/.databricks/ssh-tunnel-keys
6060 SSHKeysDir string
61- // Name of the client public key file to be used in the ssh-tunnel secrets scope.
61+ // Client public key name located in the ssh-tunnel secrets scope.
6262 ClientPublicKeyName string
63+ // Client private key name located in the ssh-tunnel secrets scope.
64+ ClientPrivateKeyName string
6365 // If true, the CLI will attempt to start the cluster if it is not running.
6466 AutoStartCluster bool
6567 // Optional auth profile name. If present, will be added as --profile flag to the ProxyCommand while spawning ssh client.
@@ -85,21 +87,27 @@ func Run(ctx context.Context, client *databricks.WorkspaceClient, opts ClientOpt
8587 return err
8688 }
8789
88- keyPath , err := keys .GetLocalSSHKeyPath ( opts . ClusterID , opts .SSHKeysDir )
90+ secretScopeName , err := keys .CreateKeysSecretScope ( ctx , client , opts .ClusterID )
8991 if err != nil {
90- return fmt .Errorf ("failed to get local keys folder: %w" , err )
92+ return fmt .Errorf ("failed to create secret scope: %w" , err )
93+ }
94+
95+ privateKeyBytes , publicKeyBytes , err := keys .CheckAndGenerateSSHKeyPairFromSecrets (ctx , client , opts .ClusterID , secretScopeName , opts .ClientPrivateKeyName , opts .ClientPublicKeyName )
96+ if err != nil {
97+ return fmt .Errorf ("failed to get or generate SSH key pair from secrets: %w" , err )
9198 }
92- privateKeyPath , publicKey , err := keys .CheckAndGenerateSSHKeyPair (ctx , keyPath )
99+
100+ keyPath , err := keys .GetLocalSSHKeyPath (opts .ClusterID , opts .SSHKeysDir )
93101 if err != nil {
94- return fmt .Errorf ("failed to check or generate SSH key pair : %w" , err )
102+ return fmt .Errorf ("failed to get local keys folder : %w" , err )
95103 }
96- cmdio .LogString (ctx , "Using SSH key: " + privateKeyPath )
97104
98- keysSecretScopeName , err : = keys .PutSecretInScope ( ctx , client , opts . ClusterID , opts . ClientPublicKeyName , publicKey )
105+ err = keys .SaveSSHKeyPair ( keyPath , privateKeyBytes , publicKeyBytes )
99106 if err != nil {
100- return fmt .Errorf ("failed to store public key in secret scope : %w" , err )
107+ return fmt .Errorf ("failed to save SSH key pair locally : %w" , err )
101108 }
102- cmdio .LogString (ctx , fmt .Sprintf ("Secrets scope: %s, key name: %s" , keysSecretScopeName , opts .ClientPublicKeyName ))
109+ cmdio .LogString (ctx , "Using SSH key: " + keyPath )
110+ cmdio .LogString (ctx , fmt .Sprintf ("Secrets scope: %s, key name: %s" , secretScopeName , opts .ClientPublicKeyName ))
103111
104112 var userName string
105113 var serverPort int
@@ -111,7 +119,7 @@ func Run(ctx context.Context, client *databricks.WorkspaceClient, opts ClientOpt
111119 if err := UploadTunnelReleases (ctx , client , version , opts .ReleasesDir ); err != nil {
112120 return fmt .Errorf ("failed to upload ssh-tunnel binaries: %w" , err )
113121 }
114- userName , serverPort , err = ensureSSHServerIsRunning (ctx , client , version , keysSecretScopeName , opts )
122+ userName , serverPort , err = ensureSSHServerIsRunning (ctx , client , version , secretScopeName , opts )
115123 if err != nil {
116124 return fmt .Errorf ("failed to ensure that ssh server is running: %w" , err )
117125 }
@@ -137,7 +145,7 @@ func Run(ctx context.Context, client *databricks.WorkspaceClient, opts ClientOpt
137145 return runSSHProxy (ctx , client , serverPort , opts )
138146 } else {
139147 cmdio .LogString (ctx , fmt .Sprintf ("Additional SSH arguments: %v" , opts .AdditionalArgs ))
140- return spawnSSHClient (ctx , userName , privateKeyPath , serverPort , opts )
148+ return spawnSSHClient (ctx , userName , keyPath , serverPort , opts )
141149 }
142150}
143151
@@ -175,7 +183,7 @@ func getServerMetadata(ctx context.Context, client *databricks.WorkspaceClient,
175183 return serverPort , string (bodyBytes ), nil
176184}
177185
178- func submitSSHTunnelJob (ctx context.Context , client * databricks.WorkspaceClient , version , keysSecretScopeName string , opts ClientOptions ) (int64 , error ) {
186+ func submitSSHTunnelJob (ctx context.Context , client * databricks.WorkspaceClient , version , secretScopeName string , opts ClientOptions ) (int64 , error ) {
179187 contentDir , err := sshWorkspace .GetWorkspaceContentDir (ctx , client , version , opts .ClusterID )
180188 if err != nil {
181189 return 0 , fmt .Errorf ("failed to get workspace content directory: %w" , err )
@@ -212,7 +220,7 @@ func submitSSHTunnelJob(ctx context.Context, client *databricks.WorkspaceClient,
212220 NotebookPath : jobNotebookPath ,
213221 BaseParameters : map [string ]string {
214222 "version" : version ,
215- "keysSecretScopeName " : keysSecretScopeName ,
223+ "secretScopeName " : secretScopeName ,
216224 "authorizedKeySecretName" : opts .ClientPublicKeyName ,
217225 "shutdownDelay" : opts .ShutdownDelay .String (),
218226 "maxClients" : strconv .Itoa (opts .MaxClients ),
@@ -290,12 +298,12 @@ func checkClusterState(ctx context.Context, client *databricks.WorkspaceClient,
290298 return nil
291299}
292300
293- func ensureSSHServerIsRunning (ctx context.Context , client * databricks.WorkspaceClient , version , keysSecretScopeName string , opts ClientOptions ) (string , int , error ) {
301+ func ensureSSHServerIsRunning (ctx context.Context , client * databricks.WorkspaceClient , version , secretScopeName string , opts ClientOptions ) (string , int , error ) {
294302 serverPort , userName , err := getServerMetadata (ctx , client , opts .ClusterID , version )
295303 if errors .Is (err , errServerMetadata ) {
296304 cmdio .LogString (ctx , "SSH server is not running, starting it now..." )
297305
298- runID , err := submitSSHTunnelJob (ctx , client , version , keysSecretScopeName , opts )
306+ runID , err := submitSSHTunnelJob (ctx , client , version , secretScopeName , opts )
299307 if err != nil {
300308 return "" , 0 , fmt .Errorf ("failed to submit ssh server job: %w" , err )
301309 }
0 commit comments