iroh_ssh/
cli.rs

1use std::{ffi::OsString, path::PathBuf};
2
3use clap::{ArgAction, Args, Parser, Subcommand, command};
4
5const TARGET_HELP: &str = "Target in the form user@NODE_ID";
6
7#[derive(Parser, Debug)]
8#[command(name = "iroh-ssh", about = "ssh without ip")]
9pub struct Cli {
10    #[command(subcommand)]
11    pub cmd: Option<Cmd>,
12
13    #[arg(help = TARGET_HELP)]
14    pub target: Option<String>,
15
16    #[command(flatten)]
17    pub ssh: SshOpts,
18
19    #[arg(trailing_var_arg = true)]
20    pub remote_cmd: Option<Vec<OsString>>,
21}
22
23#[derive(Subcommand,Debug)]
24pub enum Cmd {
25    Connect(ConnectArgs),
26    #[command(hide = true)]
27    Exec(ExecArgs),
28    Server(ServerArgs),
29    Service {
30        #[command(subcommand)]
31        op: ServiceCmd,
32    },
33    Info,
34    #[command(hide = true)]
35    Proxy(ProxyArgs),
36    #[command(hide = true)]
37    RunService(ServiceArgs),
38}
39
40#[derive(Args, Clone, Debug)]
41pub struct ProxyArgs {
42    #[arg(help = "Proxy node ID")]
43    pub node_id: String,
44}
45
46#[derive(Args, Clone, Debug)]
47pub struct ConnectArgs {
48    #[arg(help = TARGET_HELP)]
49    pub target: String,
50
51    #[command(flatten)]
52    pub ssh: SshOpts,
53
54    #[arg(trailing_var_arg = true)]
55    pub remote_cmd: Vec<OsString>,
56}
57
58#[derive(Args, Clone, Debug)]
59pub struct ExecArgs {
60    #[arg(help = TARGET_HELP)]
61    pub target: String,
62
63    #[command(flatten)]
64    pub ssh: SshOpts,
65
66    #[arg(trailing_var_arg = true, required = true)]
67    pub remote_cmd: Vec<OsString>,
68}
69
70#[derive(Args, Clone, Default, Debug)]
71pub struct SshOpts {
72    #[arg(
73        short = 'i',
74        long,
75        value_name = "PATH",
76        help = "Identity file for publickey auth"
77    )]
78    pub identity_file: Option<PathBuf>,
79
80    #[arg(short = 'L', value_name = "LPORT:HOST:RPORT",
81        help = "Local forward [bind_addr:]lport:host:rport (host can't be node_id yet)", action = ArgAction::Append)]
82    pub local_forward: Vec<String>,
83
84    #[arg(short = 'R', value_name = "RPORT:HOST:LPORT",
85        help = "Remote forward [bind_addr:]rport:host:lport  (host can't be node_id yet)", action = ArgAction::Append)]
86    pub remote_forward: Vec<String>,
87
88    #[arg(
89        short = 'p',
90        long,
91        value_name = "PORT",
92        help = "Remote sshd port (default 22)"
93    )]
94    pub port: Option<u16>,
95
96    #[arg(short = 'o', value_name = "KEY=VALUE",
97        help = "Pass an ssh option (repeatable)", action = ArgAction::Append)]
98    pub options: Vec<String>,
99
100    #[arg(short = 'A', help = "Enable agent forwarding", action = ArgAction::SetTrue)]
101    pub agent: bool,
102
103    #[arg(short = 'a', help = "Disable agent forwarding", action = ArgAction::SetTrue)]
104    pub no_agent: bool,
105
106    #[arg(short = 'X', help = "Enable X11 forwarding", action = ArgAction::SetTrue)]
107    pub x11: bool,
108
109    #[arg(short = 'Y', help = "Enable trusted X11 forwarding", action = ArgAction::SetTrue)]
110    pub x11_trusted: bool,
111
112    #[arg(short = 'N', help = "Do not execute remote command", action = ArgAction::SetTrue)]
113    pub no_cmd: bool,
114
115    #[arg(short = 't', help = "Force pseudo-terminal", action = ArgAction::SetTrue)]
116    pub force_tty: bool,
117
118    #[arg(short = 'T', help = "Disable pseudo-terminal", action = ArgAction::SetTrue)]
119    pub no_tty: bool,
120
121    #[arg(short = 'v', help = "Increase verbosity",
122        action = ArgAction::Count)]
123    pub verbose: u8,
124
125    #[arg(short = 'q', help = "Quiet mode", action = ArgAction::SetTrue)]
126    pub quiet: bool,
127}
128
129#[derive(Args, Clone, Debug)]
130pub struct ServerArgs {
131    #[arg(long, default_value = "22")]
132    pub ssh_port: u16,
133
134    #[arg(short, long, default_value_t = false)]
135    pub persist: bool,
136}
137
138#[derive(Subcommand, Clone, Debug)]
139pub enum ServiceCmd {
140    Install {
141        #[arg(long, default_value = "22")]
142        ssh_port: u16,
143    },
144    Uninstall,
145}
146
147#[derive(Args, Clone, Debug)]
148pub struct ServiceArgs {
149    #[arg(long, default_value = "22")]
150    pub ssh_port: u16,
151}