TUN-3451: Cloudflared tunnel ingress command

This commit is contained in:
Adam Chalmers 2020-10-08 13:00:32 -05:00
parent 407c9550d7
commit 86a7af3dc4
3 changed files with 54 additions and 17 deletions

View File

@ -182,8 +182,7 @@ func Commands() []*cli.Command {
subcommands = append(subcommands, buildRunCommand())
subcommands = append(subcommands, buildCleanupCommand())
subcommands = append(subcommands, buildRouteCommand())
subcommands = append(subcommands, buildValidateCommand())
subcommands = append(subcommands, buildRuleCommand())
subcommands = append(subcommands, buildIngressSubcommand())
cmds = append(cmds, buildTunnelCommand(subcommands))
@ -221,6 +220,38 @@ func buildTunnelCommand(subcommands []*cli.Command) *cli.Command {
}
}
func buildIngressSubcommand() *cli.Command {
return &cli.Command{
Name: "ingress",
Category: "Tunnel",
Usage: "Validate and test cloudflared tunnel's ingress configuration",
Hidden: true,
Description: `
Cloudflared lets you route traffic from the internet to multiple different addresses on your
origin. Multiple-origin routing is configured by a set of rules. Each rule matches traffic
by its hostname or path, and routes it to an address. These rules are configured under the
'ingress' key of your config.yaml, for example:
ingress:
- hostname: www.example.com
service: https://localhost:8000
- hostname: *.example.xyz
path: /[a-zA-Z]+.html
service: https://localhost:8001
- hostname: *
service: https://localhost:8002
To ensure cloudflared can route all incoming requests, the last rule must be a catch-all
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.
`,
Subcommands: []*cli.Command{buildValidateCommand(), buildRuleCommand()},
Flags: tunnelFlags(false),
}
}
func TunnelCommand(c *cli.Context) error {
if name := c.String("name"); name != "" { // Start a named tunnel
return adhocNamedTunnel(c, name)

View File

@ -9,7 +9,6 @@ import (
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
"github.com/cloudflare/cloudflared/logger"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
@ -91,6 +90,9 @@ func (ing ingress) validate() ([]rule, error) {
if err != nil {
return nil, err
}
if service.Scheme == "" || service.Hostname() == "" {
return nil, fmt.Errorf("The service %s must have a scheme and a hostname", r.Service)
}
// Ensure that there are no wildcards anywhere except the first character
// of the hostname.
@ -148,32 +150,28 @@ func parseIngress(rawYAML []byte) ([]rule, error) {
return ing.validate()
}
func ingressContext(c *cli.Context) ([]rule, *logger.OutputWriter, error) {
log, err := createLogger(c, false, false)
if err != nil {
return nil, nil, err
}
func ingressContext(c *cli.Context) ([]rule, error) {
configFilePath := c.String("config")
if configFilePath == "" {
return nil, nil, config.ErrNoConfigFile
return nil, config.ErrNoConfigFile
}
log.Infof("Validating %s", configFilePath)
fmt.Printf("Reading from config file %s\n", configFilePath)
configBytes, err := ioutil.ReadFile(configFilePath)
if err != nil {
return nil, nil, err
return nil, err
}
rules, err := parseIngress(configBytes)
return rules, log, err
return rules, err
}
// Validates the ingress rules in the cloudflared config file
func validateCommand(c *cli.Context) error {
_, log, err := ingressContext(c)
_, err := ingressContext(c)
if err != nil {
log.Error(err.Error())
fmt.Println(err.Error())
return errors.New("Validation failed")
}
log.Infof("OK")
fmt.Println("OK")
return nil
}
@ -189,7 +187,7 @@ func buildValidateCommand() *cli.Command {
// Checks which ingress rule matches the given URL.
func ruleCommand(c *cli.Context) error {
rules, log, err := ingressContext(c)
rules, err := ingressContext(c)
if err != nil {
return err
}
@ -206,7 +204,7 @@ func ruleCommand(c *cli.Context) error {
}
for i, r := range rules {
if r.matches(requestURL) {
log.Infof("Matched rule #%d", i+1)
fmt.Printf("Matched rule #%d\n", i+1)
fmt.Println(r.String())
return nil
}

View File

@ -127,6 +127,14 @@ ingress:
service: https://localhost:8000
path: "*/subpath2"
- service: https://localhost:8001
`},
wantErr: true,
},
{
name: "Service must have a scheme",
args: args{rawYAML: `
ingress:
- service: localhost:8000
`},
wantErr: true,
},