TUN-3452: Fix loading of flags from config file for tunnel run subcommand. This change also cleans up building of tunnel subcommand list, hides deprecated subcommands and improves help.
This commit is contained in:
parent
86a7af3dc4
commit
53a1fa46a8
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v2/altsrc"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/validation"
|
||||
|
@ -91,14 +90,6 @@ func FileExists(path string) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// FindInputSourceContext pulls the input source from the config flag.
|
||||
func FindInputSourceContext(context *cli.Context) (altsrc.InputSourceContext, error) {
|
||||
if context.String("config") != "" {
|
||||
return altsrc.NewYamlSourceFromFile(context.String("config"))
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindDefaultConfigPath returns the first path that contains a config file.
|
||||
// If none of the combination of DefaultConfigSearchDirectories() and DefaultConfigFiles
|
||||
// contains a config file, return empty string.
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
log "github.com/cloudflare/cloudflared/logger"
|
||||
"github.com/cloudflare/cloudflared/metrics"
|
||||
"github.com/cloudflare/cloudflared/overwatch"
|
||||
"github.com/cloudflare/cloudflared/tunneldns"
|
||||
"github.com/cloudflare/cloudflared/watcher"
|
||||
|
||||
raven "github.com/getsentry/raven-go"
|
||||
|
@ -76,7 +77,7 @@ func main() {
|
|||
and configure access control.`
|
||||
app.Flags = flags()
|
||||
app.Action = action(Version, shutdownC, graceShutdownC)
|
||||
app.Before = tunnel.Before
|
||||
app.Before = tunnel.SetFlagsFromConfigFile
|
||||
app.Commands = commands(cli.ShowVersion)
|
||||
|
||||
tunnel.Init(Version, shutdownC, graceShutdownC) // we need this to support the tunnel sub command...
|
||||
|
@ -129,6 +130,7 @@ To determine if an update happened in a script, check for error code 64.`,
|
|||
},
|
||||
}
|
||||
cmds = append(cmds, tunnel.Commands()...)
|
||||
cmds = append(cmds, tunneldns.Command(false))
|
||||
cmds = append(cmds, access.Commands()...)
|
||||
return cmds
|
||||
}
|
||||
|
|
|
@ -113,87 +113,33 @@ func Flags() []cli.Flag {
|
|||
}
|
||||
|
||||
func Commands() []*cli.Command {
|
||||
cmds := []*cli.Command{
|
||||
{
|
||||
Name: "login",
|
||||
Action: cliutil.ErrorHandler(login),
|
||||
Usage: "Generate a configuration file with your login details",
|
||||
ArgsUsage: " ",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "url",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
Hidden: true,
|
||||
},
|
||||
{
|
||||
Name: "proxy-dns",
|
||||
Action: cliutil.ErrorHandler(tunneldns.Run),
|
||||
Usage: "Run a DNS over HTTPS proxy server.",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "metrics",
|
||||
Value: "localhost:",
|
||||
Usage: "Listen address for metrics reporting.",
|
||||
EnvVars: []string{"TUNNEL_METRICS"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Usage: "Listen address for the DNS over HTTPS proxy server.",
|
||||
Value: "localhost",
|
||||
EnvVars: []string{"TUNNEL_DNS_ADDRESS"},
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "Listen on given port for the DNS over HTTPS proxy server.",
|
||||
Value: 53,
|
||||
EnvVars: []string{"TUNNEL_DNS_PORT"},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "upstream",
|
||||
Usage: "Upstream endpoint URL, you can specify multiple endpoints for redundancy.",
|
||||
Value: cli.NewStringSlice("https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"),
|
||||
EnvVars: []string{"TUNNEL_DNS_UPSTREAM"},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "bootstrap",
|
||||
Usage: "bootstrap endpoint URL, you can specify multiple endpoints for redundancy.",
|
||||
Value: cli.NewStringSlice("https://162.159.36.1/dns-query", "https://162.159.46.1/dns-query", "https://[2606:4700:4700::1111]/dns-query", "https://[2606:4700:4700::1001]/dns-query"),
|
||||
EnvVars: []string{"TUNNEL_DNS_BOOTSTRAP"},
|
||||
},
|
||||
},
|
||||
ArgsUsage: " ", // can't be the empty string or we get the default output
|
||||
Hidden: false,
|
||||
},
|
||||
subcommands := []*cli.Command{
|
||||
buildLoginSubcommand(false),
|
||||
buildCreateCommand(),
|
||||
buildRouteCommand(),
|
||||
buildRunCommand(),
|
||||
buildListCommand(),
|
||||
buildIngressSubcommand(),
|
||||
buildDeleteCommand(),
|
||||
buildCleanupCommand(),
|
||||
// for compatibility, allow following as tunnel subcommands
|
||||
tunneldns.Command(true),
|
||||
dbConnectCmd(),
|
||||
}
|
||||
|
||||
var subcommands []*cli.Command
|
||||
for _, cmd := range cmds {
|
||||
c := *cmd
|
||||
c.Hidden = false
|
||||
subcommands = append(subcommands, &c)
|
||||
return []*cli.Command {
|
||||
buildTunnelCommand(subcommands),
|
||||
// for compatibility, allow following as top-level subcommands
|
||||
buildLoginSubcommand(true),
|
||||
dbConnectCmd(),
|
||||
}
|
||||
|
||||
subcommands = append(subcommands, buildCreateCommand())
|
||||
subcommands = append(subcommands, buildListCommand())
|
||||
subcommands = append(subcommands, buildDeleteCommand())
|
||||
subcommands = append(subcommands, buildRunCommand())
|
||||
subcommands = append(subcommands, buildCleanupCommand())
|
||||
subcommands = append(subcommands, buildRouteCommand())
|
||||
subcommands = append(subcommands, buildIngressSubcommand())
|
||||
|
||||
cmds = append(cmds, buildTunnelCommand(subcommands))
|
||||
|
||||
return cmds
|
||||
}
|
||||
|
||||
func buildTunnelCommand(subcommands []*cli.Command) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "tunnel",
|
||||
Action: cliutil.ErrorHandler(TunnelCommand),
|
||||
Before: Before,
|
||||
Before: SetFlagsFromConfigFile,
|
||||
Category: "Tunnel",
|
||||
Usage: "Make a locally-running web service accessible over the internet using Argo Tunnel.",
|
||||
ArgsUsage: " ",
|
||||
|
@ -245,8 +191,7 @@ func buildIngressSubcommand() *cli.Command {
|
|||
rule that matches all traffic. You can validate these rules with the 'ingress validate'
|
||||
command, and test which rule matches a particular URL with 'ingress rule <URL>'.
|
||||
|
||||
Multiple-origin routing is incompatible with the --url flag.
|
||||
`,
|
||||
Multiple-origin routing is incompatible with the --url flag.`,
|
||||
Subcommands: []*cli.Command{buildValidateCommand(), buildRuleCommand()},
|
||||
Flags: tunnelFlags(false),
|
||||
}
|
||||
|
@ -624,26 +569,34 @@ func forceSetFlag(c *cli.Context, name, value string) {
|
|||
}
|
||||
}
|
||||
|
||||
func Before(c *cli.Context) error {
|
||||
func SetFlagsFromConfigFile(c *cli.Context) error {
|
||||
logger, err := createLogger(c, false, false)
|
||||
if err != nil {
|
||||
return cliutil.PrintLoggerSetupError("error setting up logger", err)
|
||||
}
|
||||
|
||||
if c.String("config") == "" {
|
||||
configFile := c.String("config")
|
||||
if configFile == "" {
|
||||
logger.Debugf(config.ErrNoConfigFile.Error())
|
||||
return nil
|
||||
}
|
||||
inputSource, err := config.FindInputSourceContext(c)
|
||||
|
||||
inputSource, err := altsrc.NewYamlSourceFromFile(configFile)
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot load configuration from %s: %s", c.String("config"), err)
|
||||
return err
|
||||
} else if inputSource != nil {
|
||||
err := altsrc.ApplyInputSourceValues(c, inputSource, c.App.Flags)
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot apply configuration from %s: %s", c.String("config"), err)
|
||||
logger.Errorf("Cannot load configuration from %s: %s", configFile, err)
|
||||
return err
|
||||
}
|
||||
logger.Debugf("Applied configuration from %s", c.String("config"))
|
||||
if inputSource != nil {
|
||||
targetFlags := c.Command.Flags
|
||||
if c.Command.Name == "" {
|
||||
targetFlags = c.App.Flags
|
||||
}
|
||||
err := altsrc.ApplyInputSourceValues(c, inputSource, targetFlags)
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot apply configuration from %s: %s", configFile, err)
|
||||
return err
|
||||
}
|
||||
logger.Debugf("Applied configuration from %s", configFile)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -735,7 +688,7 @@ func dbConnectCmd() *cli.Command {
|
|||
|
||||
// Override before to run tunnel validation before dbconnect validation.
|
||||
cmd.Before = func(c *cli.Context) error {
|
||||
err := Before(c)
|
||||
err := SetFlagsFromConfigFile(c)
|
||||
if err == nil {
|
||||
err = dbconnect.CmdBefore(c)
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@ import (
|
|||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/transfer"
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/pkg/errors"
|
||||
cli "github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/transfer"
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -20,6 +22,22 @@ const (
|
|||
callbackStoreURL = "https://login.argotunnel.com/"
|
||||
)
|
||||
|
||||
func buildLoginSubcommand(hidden bool) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "login",
|
||||
Action: cliutil.ErrorHandler(login),
|
||||
Usage: "Generate a configuration file with your login details",
|
||||
ArgsUsage: " ",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "url",
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
Hidden: hidden,
|
||||
}
|
||||
}
|
||||
|
||||
func login(c *cli.Context) error {
|
||||
logger, err := logger.New()
|
||||
if err != nil {
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v2/altsrc"
|
||||
"golang.org/x/net/idna"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
|
@ -58,24 +59,24 @@ var (
|
|||
Aliases: []string{"rd"},
|
||||
Usage: "Include connections that have recently disconnected in the list",
|
||||
}
|
||||
outputFormatFlag = &cli.StringFlag{
|
||||
outputFormatFlag = altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "output",
|
||||
Aliases: []string{"o"},
|
||||
Usage: "Render output using given `FORMAT`. Valid options are 'json' or 'yaml'",
|
||||
}
|
||||
forceFlag = &cli.BoolFlag{
|
||||
})
|
||||
forceFlag = altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "force",
|
||||
Aliases: []string{"f"},
|
||||
Usage: "By default, if a tunnel is currently being run from a cloudflared, you can't " +
|
||||
"simultaneously rerun it again from a second cloudflared. The --force flag lets you " +
|
||||
"overwrite the previous tunnel. If you want to use a single hostname with multiple " +
|
||||
"tunnels, you can do so with Cloudflare's Load Balancer product.",
|
||||
}
|
||||
credentialsFileFlag = &cli.StringFlag{
|
||||
})
|
||||
credentialsFileFlag = altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "credentials-file",
|
||||
Aliases: []string{credFileFlagAlias},
|
||||
Usage: "File path of tunnel credentials",
|
||||
}
|
||||
})
|
||||
forceDeleteFlag = &cli.BoolFlag{
|
||||
Name: "force",
|
||||
Aliases: []string{"f"},
|
||||
|
@ -88,9 +89,13 @@ func buildCreateCommand() *cli.Command {
|
|||
Name: "create",
|
||||
Action: cliutil.ErrorHandler(createCommand),
|
||||
Usage: "Create a new tunnel with given name",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] create [create command options]",
|
||||
Description: "cloudflared tunnel create example will create a tunnel named example, and generate a credential file to run the tunnel",
|
||||
ArgsUsage: "TUNNEL-NAME",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] create [subcommand options] NAME",
|
||||
Description: `Creates a tunnel, registers it with Cloudflare edge and generates credential file used to run this tunnel.
|
||||
Use "cloudflared tunnel route" subcommand to map a DNS name to this tunnel and "cloudflared tunnel run" to start the connection.
|
||||
|
||||
For example, to create a tunnel named 'my-tunnel' run:
|
||||
|
||||
$ cloudflared tunnel create my-tunnel`,
|
||||
Flags: []cli.Flag{outputFormatFlag},
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
}
|
||||
|
@ -156,8 +161,7 @@ func buildListCommand() *cli.Command {
|
|||
Action: cliutil.ErrorHandler(listCommand),
|
||||
Usage: "List existing tunnels",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] list [subcommand options]",
|
||||
Description: "cloudflared tunnel list will return all active tunnels, their created time and associated connections. Use -d flag to include deleted tunnels. See the list of options to filter the list",
|
||||
ArgsUsage: " ",
|
||||
Description: "cloudflared tunnel list will display all active tunnels, their created time and associated connections. Use -d flag to include deleted tunnels. See the list of options to filter the list",
|
||||
Flags: []cli.Flag{outputFormatFlag, showDeletedFlag, listNameFlag, listExistedAtFlag, listIDFlag, showRecentlyDisconnected},
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
}
|
||||
|
@ -262,9 +266,8 @@ func buildDeleteCommand() *cli.Command {
|
|||
Name: "delete",
|
||||
Action: cliutil.ErrorHandler(deleteCommand),
|
||||
Usage: "Delete existing tunnel by UUID or name",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] delete [subcommand options]",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] delete [subcommand options] TUNNEL",
|
||||
Description: "cloudflared tunnel delete will delete tunnels with the given tunnel UUIDs or names. A tunnel cannot be deleted if it has active connections. To delete the tunnel unconditionally, use -f flag.",
|
||||
ArgsUsage: "TUNNEL",
|
||||
Flags: []cli.Flag{credentialsFileFlag, forceDeleteFlag},
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
}
|
||||
|
@ -310,15 +313,16 @@ func buildRunCommand() *cli.Command {
|
|||
return &cli.Command{
|
||||
Name: "run",
|
||||
Action: cliutil.ErrorHandler(runCommand),
|
||||
Before: SetFlagsFromConfigFile,
|
||||
Usage: "Proxy a local web server by running the given tunnel",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] run [subcommand options]",
|
||||
ArgsUsage: "TUNNEL",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] run [subcommand options] TUNNEL",
|
||||
Description: `Runs the tunnel identified by name or UUUD, creating highly available connections
|
||||
between your server and the Cloudflare edge.
|
||||
|
||||
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 identify the tunnel by UUID.
|
||||
If you experience other problems running gitthe tunnel, "cloudflared tunnel cleanup" may help by removing any old connection records.
|
||||
If you experience other problems running the tunnel, "cloudflared tunnel cleanup" may help by removing
|
||||
any old connection records.
|
||||
`,
|
||||
Flags: flags,
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
|
@ -347,9 +351,8 @@ func buildCleanupCommand() *cli.Command {
|
|||
Name: "cleanup",
|
||||
Action: cliutil.ErrorHandler(cleanupCommand),
|
||||
Usage: "Cleanup tunnel connections",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] cleanup [subcommand options]",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] cleanup [subcommand options] TUNNEL",
|
||||
Description: "Delete connections for tunnels with the given UUIDs or names.",
|
||||
ArgsUsage: "TUNNEL",
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
}
|
||||
}
|
||||
|
@ -377,14 +380,13 @@ func buildRouteCommand() *cli.Command {
|
|||
Name: "route",
|
||||
Action: cliutil.ErrorHandler(routeCommand),
|
||||
Usage: "Define what hostname or load balancer can route to this tunnel",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] route [subcommand options]",
|
||||
UsageText: "cloudflared tunnel [tunnel command options] route [subcommand options] dns|lb TUNNEL HOSTNAME [LB-POOL]",
|
||||
Description: `The route defines what hostname or load balancer will proxy requests to this tunnel.
|
||||
|
||||
To route a hostname by creating a CNAME to tunnel's address:
|
||||
cloudflared tunnel route dns <tunnel ID> <hostname>
|
||||
To use this tunnel as a load balancer origin, creating pool and load balancer if necessary:
|
||||
cloudflared tunnel route lb <tunnel ID> <load balancer name> <load balancer pool>`,
|
||||
ArgsUsage: "dns|lb TUNNEL HOSTNAME [LB-POOL]",
|
||||
CustomHelpTemplate: commandHelpTemplate(),
|
||||
}
|
||||
}
|
||||
|
@ -513,8 +515,7 @@ DESCRIPTION:
|
|||
|
||||
TUNNEL COMMAND OPTIONS:
|
||||
%s
|
||||
|
||||
SUBCOMMAND COMMAND OPTIONS:
|
||||
SUBCOMMAND OPTIONS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
`
|
||||
|
|
|
@ -27,6 +27,48 @@ type Listener struct {
|
|||
logger logger.Service
|
||||
}
|
||||
|
||||
func Command(hidden bool) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "proxy-dns",
|
||||
Action: cliutil.ErrorHandler(Run),
|
||||
Usage: "Run a DNS over HTTPS proxy server.",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "metrics",
|
||||
Value: "localhost:",
|
||||
Usage: "Listen address for metrics reporting.",
|
||||
EnvVars: []string{"TUNNEL_METRICS"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Usage: "Listen address for the DNS over HTTPS proxy server.",
|
||||
Value: "localhost",
|
||||
EnvVars: []string{"TUNNEL_DNS_ADDRESS"},
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "Listen on given port for the DNS over HTTPS proxy server.",
|
||||
Value: 53,
|
||||
EnvVars: []string{"TUNNEL_DNS_PORT"},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "upstream",
|
||||
Usage: "Upstream endpoint URL, you can specify multiple endpoints for redundancy.",
|
||||
Value: cli.NewStringSlice("https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"),
|
||||
EnvVars: []string{"TUNNEL_DNS_UPSTREAM"},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "bootstrap",
|
||||
Usage: "bootstrap endpoint URL, you can specify multiple endpoints for redundancy.",
|
||||
Value: cli.NewStringSlice("https://162.159.36.1/dns-query", "https://162.159.46.1/dns-query", "https://[2606:4700:4700::1111]/dns-query", "https://[2606:4700:4700::1001]/dns-query"),
|
||||
EnvVars: []string{"TUNNEL_DNS_BOOTSTRAP"},
|
||||
},
|
||||
},
|
||||
ArgsUsage: " ", // can't be the empty string or we get the default output
|
||||
Hidden: hidden,
|
||||
}
|
||||
}
|
||||
|
||||
// Run implements a foreground runner
|
||||
func Run(c *cli.Context) error {
|
||||
logDirectory, logLevel := config.FindLogSettings()
|
||||
|
|
Loading…
Reference in New Issue