TUN-3291: cloudflared tunnel run -h explains how to use flags from parent command

This commit is contained in:
cthuang 2020-09-16 13:15:49 +01:00 committed by Chung Ting Huang
parent 85d0afd3b0
commit 197d65659a
2 changed files with 115 additions and 65 deletions

View File

@ -182,7 +182,13 @@ func Commands() []*cli.Command {
subcommands = append(subcommands, buildCleanupCommand()) subcommands = append(subcommands, buildCleanupCommand())
subcommands = append(subcommands, buildRouteCommand()) subcommands = append(subcommands, buildRouteCommand())
cmds = append(cmds, &cli.Command{ cmds = append(cmds, buildTunnelCommand(subcommands))
return cmds
}
func buildTunnelCommand(subcommands []*cli.Command) *cli.Command {
return &cli.Command{
Name: "tunnel", Name: "tunnel",
Action: cliutil.ErrorHandler(TunnelCommand), Action: cliutil.ErrorHandler(TunnelCommand),
Before: Before, Before: Before,
@ -198,20 +204,18 @@ func Commands() []*cli.Command {
To use, begin by calling login to download a certificate: To use, begin by calling login to download a certificate:
cloudflared tunnel login $ cloudflared tunnel login
With your certificate installed you can then launch your first tunnel, With your certificate installed you can then launch your first tunnel,
replacing my.site.com with a subdomain of your site: replacing my.site.com with a subdomain of your site:
cloudflared tunnel --hostname my.site.com --url http://localhost:8080 $ cloudflared tunnel --hostname my.site.com --url http://localhost:8080
If you have a web server running on port 8080 (in this example), it will be available on If you have a web server running on port 8080 (in this example), it will be available on
the internet!`, the internet!`,
Subcommands: subcommands, Subcommands: subcommands,
Flags: tunnelFlags(false), Flags: tunnelFlags(false),
}) }
return cmds
} }
func TunnelCommand(c *cli.Context) error { func TunnelCommand(c *cli.Context) error {
@ -748,7 +752,7 @@ func appendFlags(flags []cli.Flag, extraFlags ...cli.Flag) []cli.Flag {
} }
func tunnelFlags(shouldHide bool) []cli.Flag { func tunnelFlags(shouldHide bool) []cli.Flag {
return []cli.Flag{ flags := []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "config", Name: "config",
Usage: "Specifies a config file in YAML format.", Usage: "Specifies a config file in YAML format.",
@ -805,13 +809,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_ORIGIN_CA_POOL"}, EnvVars: []string{"TUNNEL_ORIGIN_CA_POOL"},
Hidden: shouldHide, Hidden: shouldHide,
}), }),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "url",
Value: "http://localhost:8080",
Usage: "Connect to the local webserver at `URL`.",
EnvVars: []string{"TUNNEL_URL"},
Hidden: shouldHide,
}),
altsrc.NewStringFlag(&cli.StringFlag{ altsrc.NewStringFlag(&cli.StringFlag{
Name: "unix-socket", Name: "unix-socket",
Usage: "Path to unix socket to use instead of --url", Usage: "Path to unix socket to use instead of --url",
@ -927,20 +924,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_RETRIES"}, EnvVars: []string{"TUNNEL_RETRIES"},
Hidden: shouldHide, Hidden: shouldHide,
}), }),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "hello-world",
Value: false,
Usage: "Run Hello World Server",
EnvVars: []string{"TUNNEL_HELLO_WORLD"},
Hidden: shouldHide,
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: sshServerFlag,
Value: false,
Usage: "Run an SSH Server",
EnvVars: []string{"TUNNEL_SSH_SERVER"},
Hidden: true, // TODO: remove when feature is complete
}),
altsrc.NewStringFlag(&cli.StringFlag{ altsrc.NewStringFlag(&cli.StringFlag{
Name: "pidfile", Name: "pidfile",
Usage: "Write the application's PID to this file after first successful connection.", Usage: "Write the application's PID to this file after first successful connection.",
@ -1085,6 +1068,54 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"DIAL_EDGE_TIMEOUT"}, EnvVars: []string{"DIAL_EDGE_TIMEOUT"},
Hidden: true, Hidden: true,
}), }),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "stdin-control",
Usage: "Control the process using commands sent through stdin",
EnvVars: []string{"STDIN-CONTROL"},
Hidden: true,
Value: false,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
EnvVars: []string{"TUNNEL_NAME"},
Usage: "Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately",
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: uiFlag,
Usage: "Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.",
Value: false,
Hidden: shouldHide,
}),
urlFlag(shouldHide),
helloWorldFlag(shouldHide),
createSocks5Flag(shouldHide),
}
return append(flags, sshFlags(shouldHide)...)
}
func urlFlag(shouldHide bool) cli.Flag {
return altsrc.NewStringFlag(&cli.StringFlag{
Name: "url",
Value: "http://localhost:8080",
Usage: "Connect to the local webserver at `URL`.",
EnvVars: []string{"TUNNEL_URL"},
Hidden: shouldHide,
})
}
func helloWorldFlag(shouldHide bool) cli.Flag {
return altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "hello-world",
Value: false,
Usage: "Run Hello World Server",
EnvVars: []string{"TUNNEL_HELLO_WORLD"},
Hidden: shouldHide,
})
}
func sshFlags(shouldHide bool) []cli.Flag {
return []cli.Flag{
altsrc.NewStringFlag(&cli.StringFlag{ altsrc.NewStringFlag(&cli.StringFlag{
Name: sshPortFlag, Name: sshPortFlag,
Usage: "Localhost port that cloudflared SSH server will run on", Usage: "Localhost port that cloudflared SSH server will run on",
@ -1116,18 +1147,18 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"REGION_ID"}, EnvVars: []string{"REGION_ID"},
Hidden: true, Hidden: true,
}), }),
altsrc.NewStringFlag(&cli.StringFlag{
Name: accessKeyIDFlag,
Usage: "Access Key ID of where to upload SSH logs",
EnvVars: []string{"ACCESS_CLIENT_ID"},
Hidden: true,
}),
altsrc.NewStringFlag(&cli.StringFlag{ altsrc.NewStringFlag(&cli.StringFlag{
Name: secretIDFlag, Name: secretIDFlag,
Usage: "Secret ID of where to upload SSH logs", Usage: "Secret ID of where to upload SSH logs",
EnvVars: []string{"SECRET_ID"}, EnvVars: []string{"SECRET_ID"},
Hidden: true, Hidden: true,
}), }),
altsrc.NewStringFlag(&cli.StringFlag{
Name: accessKeyIDFlag,
Usage: "Access Key ID of where to upload SSH logs",
EnvVars: []string{"ACCESS_CLIENT_ID"},
Hidden: true,
}),
altsrc.NewStringFlag(&cli.StringFlag{ altsrc.NewStringFlag(&cli.StringFlag{
Name: sessionTokenIDFlag, Name: sessionTokenIDFlag,
Usage: "Session Token to use in the configuration of SSH logs uploading", Usage: "Session Token to use in the configuration of SSH logs uploading",
@ -1147,18 +1178,11 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
Hidden: true, Hidden: true,
}), }),
altsrc.NewBoolFlag(&cli.BoolFlag{ altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "stdin-control", Name: sshServerFlag,
Usage: "Control the process using commands sent through stdin",
EnvVars: []string{"STDIN-CONTROL"},
Hidden: true,
Value: false, Value: false,
}), Usage: "Run an SSH Server",
altsrc.NewBoolFlag(&cli.BoolFlag{ EnvVars: []string{"TUNNEL_SSH_SERVER"},
Name: socks5Flag, Hidden: true, // TODO: remove when feature is complete
Usage: "specify if this tunnel is running as a SOCK5 Server",
EnvVars: []string{"TUNNEL_SOCKS"},
Value: false,
Hidden: shouldHide,
}), }),
altsrc.NewBoolFlag(&cli.BoolFlag{ altsrc.NewBoolFlag(&cli.BoolFlag{
Name: bastionFlag, Name: bastionFlag,
@ -1167,22 +1191,19 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_BASTION"}, EnvVars: []string{"TUNNEL_BASTION"},
Hidden: shouldHide, Hidden: shouldHide,
}), }),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
EnvVars: []string{"TUNNEL_NAME"},
Usage: "Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately",
Hidden: true,
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: uiFlag,
Usage: "Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.",
Value: false,
Hidden: shouldHide,
}),
} }
} }
func createSocks5Flag(shouldHide bool) cli.Flag {
return altsrc.NewBoolFlag(&cli.BoolFlag{
Name: socks5Flag,
Usage: "specify if this tunnel is running as a SOCK5 Server",
EnvVars: []string{"TUNNEL_SOCKS"},
Value: false,
Hidden: shouldHide,
})
}
func stdinControl(reconnectCh chan origin.ReconnectSignal, logger logger.Service) { func stdinControl(reconnectCh chan origin.ReconnectSignal, logger logger.Service) {
for { for {
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)

View File

@ -42,10 +42,10 @@ var (
Usage: "List tunnels with the given `NAME`", Usage: "List tunnels with the given `NAME`",
} }
listExistedAtFlag = &cli.TimestampFlag{ listExistedAtFlag = &cli.TimestampFlag{
Name: "when", Name: "when",
Aliases: []string{"w"}, Aliases: []string{"w"},
Usage: "List tunnels that are active at the given `TIME` in RFC3339 format", Usage: "List tunnels that are active at the given `TIME` in RFC3339 format",
Layout: tunnelstore.TimeLayout, Layout: tunnelstore.TimeLayout,
DefaultText: fmt.Sprintf("current time, %s", time.Now().Format(tunnelstore.TimeLayout)), DefaultText: fmt.Sprintf("current time, %s", time.Now().Format(tunnelstore.TimeLayout)),
} }
listIDFlag = &cli.StringFlag{ listIDFlag = &cli.StringFlag{
@ -293,18 +293,48 @@ func renderOutput(format string, v interface{}) error {
} }
func buildRunCommand() *cli.Command { func buildRunCommand() *cli.Command {
flags := []cli.Flag{
forceFlag,
credentialsFileFlag,
urlFlag(false),
helloWorldFlag(false),
createSocks5Flag(false),
}
flags = append(flags, sshFlags(false)...)
var runCommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}}
USAGE:
{{.UsageText}}
DESCRIPTION:
{{.Description}}
TUNNEL COMMAND OPTIONS:
See cloudflared tunnel -h
RUN COMMAND OPTIONS:
{{range .VisibleFlags}}{{.}}
{{end}}
`
return &cli.Command{ return &cli.Command{
Name: "run", Name: "run",
Action: cliutil.ErrorHandler(runCommand), Action: cliutil.ErrorHandler(runCommand),
Usage: "Proxy a local web server by running the given tunnel", Usage: "Proxy a local web server by running the given tunnel",
UsageText: "cloudflared tunnel [tunnel command options] run [run command options]",
ArgsUsage: "TUNNEL", ArgsUsage: "TUNNEL",
Description: `Runs the tunnel identified by name or UUUD, creating a highly available connection Description: `Runs the tunnel identified by name or UUUD, creating a highly available connection
between your server and the Cloudflare edge. between your server and the Cloudflare edge.
This command requires the tunnel credentials file created when "cloudflared tunnel create" was run, This command requires the tunnel credentials file created when "cloudflared tunnel create" was run,
however it does not need access to cert.pem from "cloudflared login". If you experience problems running however it does not need access to cert.pem from "cloudflared login". If you experience problems running
the tunnel, "cloudflared tunnel cleanup" may help by removing any old connection records.`, the tunnel, "cloudflared tunnel cleanup" may help by removing any old connection records.
Flags: []cli.Flag{forceFlag, credentialsFileFlag},
All the flags from the tunnel command are available, note that they have to be specified before the run command. There are flags defined both in tunnel and run command. The one in run command will take precedence.
For example cloudflared tunnel --url localhost:3000 run --url localhost:5000 <TUNNEL ID> will proxy requests to localhost:5000.
`,
Flags: flags,
CustomHelpTemplate: runCommandHelpTemplate,
} }
} }
@ -471,4 +501,3 @@ func routeCommand(c *cli.Context) error {
sc.logger.Infof(res.SuccessSummary()) sc.logger.Infof(res.SuccessSummary())
return nil return nil
} }