@@ -45,6 +45,31 @@ impl Data {
4545 }
4646}
4747
48+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
49+ pub enum ConnectMode {
50+ Public ,
51+ Private ,
52+ Ssm ,
53+ }
54+
55+ impl ConnectMode {
56+ pub fn next ( self ) -> Self {
57+ match self {
58+ ConnectMode :: Public => ConnectMode :: Private ,
59+ ConnectMode :: Private => ConnectMode :: Ssm ,
60+ ConnectMode :: Ssm => ConnectMode :: Public ,
61+ }
62+ }
63+
64+ pub fn toggle ( & mut self ) {
65+ * self = match * self {
66+ ConnectMode :: Public => ConnectMode :: Private ,
67+ ConnectMode :: Private => ConnectMode :: Ssm ,
68+ ConnectMode :: Ssm => ConnectMode :: Public ,
69+ } ;
70+ }
71+ }
72+
4873fn generate_instance_id ( ) -> String {
4974 let hex: String = ( 0 ..17 )
5075 . map ( |_| format ! ( "{:x}" , rand:: random:: <u8 >( ) % 16 ) )
@@ -253,30 +278,52 @@ impl App {
253278 pub async fn ssh ( & mut self ) -> io:: Result < ( ) > {
254279 if let Some ( selected) = self . state . selected ( ) {
255280 if let Some ( item) = self . display_items . get ( selected) {
256- let key_path = match & self . ssh_keys . selected_key {
257- Some ( key) => key,
258- None => {
259- println ! ( "No SSH key selected." ) ;
260- return Ok ( ( ) ) ;
281+ let mut cmd = match self . connect_mode {
282+ ConnectMode :: Public | ConnectMode :: Private => {
283+ let key_path = match & self . ssh_keys . selected_key {
284+ Some ( key) => key,
285+ None => {
286+ eprintln ! ( "No SSH key selected." ) ;
287+ return Ok ( ( ) ) ;
288+ }
289+ } ;
290+ let user = self
291+ . ssh_user
292+ . selected_user
293+ . as_deref ( )
294+ . unwrap_or ( "ec2-user" ) ;
295+ let ip = match self . connect_mode {
296+ ConnectMode :: Public => & item. public_ipv4 ,
297+ ConnectMode :: Private => & item. private_ipv4 ,
298+ _ => unreachable ! ( ) ,
299+ } ;
300+ let mut ssh_cmd = Command :: new ( "ssh" ) ;
301+ ssh_cmd. args ( [ "-i" , key_path] ) ;
302+ ssh_cmd. arg ( format ! ( "{}@{}" , user, ip) ) ;
303+ ssh_cmd
261304 }
262- } ;
305+ ConnectMode :: Ssm => {
306+ let mut ssm_cmd = Command :: new ( "aws" ) ;
307+ ssm_cmd. args ( [
308+ "ssm" ,
309+ "start-session" ,
310+ "--target" ,
311+ & item. instance_id ,
312+ ] ) ;
263313
264- let user = self . ssh_user . selected_user . as_deref ( ) . unwrap_or ( "ec2-user" ) ;
265- let ip = if self . private {
266- & item. private_ipv4
267- } else {
268- & item. public_ipv4
314+ if self . args . region != * "None" {
315+ ssm_cmd. args ( [ "--region" , & self . args . region ] ) ;
316+ }
317+
318+ if self . args . profile != * "None" {
319+ ssm_cmd. args ( [ "--profile" , & self . args . profile ] ) ;
320+ }
321+ ssm_cmd
322+ }
269323 } ;
270324
271- let status = Command :: new ( "ssh" )
272- . arg ( "-i" )
273- . arg ( key_path)
274- . arg ( format ! ( "{}@{}" , user, ip) )
275- . stdin ( std:: process:: Stdio :: inherit ( ) )
276- . stdout ( std:: process:: Stdio :: inherit ( ) )
277- . stderr ( std:: process:: Stdio :: inherit ( ) )
278- . status ( ) ?;
279-
325+ let status = cmd. status ( ) ?;
326+
280327 if !status. success ( ) {
281328 eprintln ! ( "Failed to launch SSH session." ) ;
282329 }
0 commit comments