@@ -133,32 +133,80 @@ impl Config {
133133 ///
134134 /// Empty string (`""`) explicitly disables jump host inheritance.
135135 pub fn get_jump_host ( & self , cluster_name : & str , node_index : usize ) -> Option < String > {
136+ self . get_jump_host_with_key ( cluster_name, node_index)
137+ . map ( |( conn_str, _) | conn_str)
138+ }
139+
140+ /// Get jump host with SSH key for a specific node in a cluster.
141+ ///
142+ /// Resolution priority (highest to lowest):
143+ /// 1. Node-level `jump_host` (in `NodeConfig::Detailed`)
144+ /// 2. Cluster-level `jump_host` (in `ClusterDefaults`)
145+ /// 3. Global default `jump_host` (in `Defaults`)
146+ ///
147+ /// Empty string (`""`) explicitly disables jump host inheritance.
148+ /// Returns tuple of (connection_string, optional_ssh_key_path)
149+ pub fn get_jump_host_with_key (
150+ & self ,
151+ cluster_name : & str ,
152+ node_index : usize ,
153+ ) -> Option < ( String , Option < String > ) > {
136154 if let Some ( cluster) = self . get_cluster ( cluster_name) {
137155 // Check node-level first
138156 if let Some ( NodeConfig :: Detailed {
139157 jump_host : Some ( jh) ,
140158 ..
141159 } ) = cluster. nodes . get ( node_index)
142160 {
143- if jh. is_empty ( ) {
144- return None ; // Explicitly disabled
145- }
146- return Some ( expand_env_vars ( jh) ) ;
161+ return self . process_jump_host_config ( jh) ;
147162 }
148163 // Check cluster-level
149164 if let Some ( jh) = & cluster. defaults . jump_host {
150- if jh. is_empty ( ) {
151- return None ; // Explicitly disabled
152- }
153- return Some ( expand_env_vars ( jh) ) ;
165+ return self . process_jump_host_config ( jh) ;
154166 }
155167 }
156168 // Fall back to global default
157169 self . defaults
158170 . jump_host
159171 . as_ref ( )
160- . filter ( |s| !s. is_empty ( ) )
161- . map ( |s| expand_env_vars ( s) )
172+ . and_then ( |jh| self . process_jump_host_config ( jh) )
173+ }
174+
175+ /// Process a JumpHostConfig and return (connection_string, optional_ssh_key_path)
176+ fn process_jump_host_config (
177+ & self ,
178+ config : & super :: types:: JumpHostConfig ,
179+ ) -> Option < ( String , Option < String > ) > {
180+ use super :: types:: JumpHostConfig ;
181+
182+ match config {
183+ JumpHostConfig :: Simple ( s) => {
184+ if s. is_empty ( ) {
185+ None // Explicitly disabled
186+ } else {
187+ Some ( ( expand_env_vars ( s) , None ) )
188+ }
189+ }
190+ JumpHostConfig :: Detailed {
191+ host,
192+ user,
193+ port,
194+ ssh_key,
195+ } => {
196+ let mut conn_str = String :: new ( ) ;
197+ if let Some ( u) = user {
198+ conn_str. push_str ( & expand_env_vars ( u) ) ;
199+ conn_str. push ( '@' ) ;
200+ }
201+ conn_str. push_str ( & expand_env_vars ( host) ) ;
202+ if let Some ( p) = port {
203+ conn_str. push ( ':' ) ;
204+ conn_str. push_str ( & p. to_string ( ) ) ;
205+ }
206+ let key = ssh_key. as_ref ( ) . map ( |k| expand_env_vars ( k) ) ;
207+ Some ( ( conn_str, key) )
208+ }
209+ }
162210 }
163211
164212 /// Get jump host for a cluster (cluster-level default).
@@ -169,22 +217,34 @@ impl Config {
169217 ///
170218 /// Empty string (`""`) explicitly disables jump host inheritance.
171219 pub fn get_cluster_jump_host ( & self , cluster_name : Option < & str > ) -> Option < String > {
220+ self . get_cluster_jump_host_with_key ( cluster_name)
221+ . map ( |( conn_str, _) | conn_str)
222+ }
223+
224+ /// Get jump host with SSH key for a cluster (cluster-level default).
225+ ///
226+ /// Resolution priority (highest to lowest):
227+ /// 1. Cluster-level `jump_host` (in `ClusterDefaults`)
228+ /// 2. Global default `jump_host` (in `Defaults`)
229+ ///
230+ /// Empty string (`""`) explicitly disables jump host inheritance.
231+ /// Returns tuple of (connection_string, optional_ssh_key_path)
232+ pub fn get_cluster_jump_host_with_key (
233+ & self ,
234+ cluster_name : Option < & str > ,
235+ ) -> Option < ( String , Option < String > ) > {
172236 if let Some ( cluster_name) = cluster_name {
173237 if let Some ( cluster) = self . get_cluster ( cluster_name) {
174238 if let Some ( jh) = & cluster. defaults . jump_host {
175- if jh. is_empty ( ) {
176- return None ; // Explicitly disabled
177- }
178- return Some ( expand_env_vars ( jh) ) ;
239+ return self . process_jump_host_config ( jh) ;
179240 }
180241 }
181242 }
182243 // Fall back to global default
183244 self . defaults
184245 . jump_host
185246 . as_ref ( )
186- . filter ( |s| !s. is_empty ( ) )
187- . map ( |s| expand_env_vars ( s) )
247+ . and_then ( |jh| self . process_jump_host_config ( jh) )
188248 }
189249
190250 /// Get SSH keepalive interval for a cluster.
0 commit comments