TUN-3439: 'tunnel validate' command to check ingress rules

This commit is contained in:
Adam Chalmers 2020-10-07 13:06:13 -05:00
parent 1e6399c2f0
commit 2319003e10
4 changed files with 52 additions and 7 deletions

View File

@ -2,6 +2,7 @@ package config
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -28,6 +29,8 @@ var (
// Windows default config dir was ~/cloudflare-warp in documentation; let's keep it compatible // Windows default config dir was ~/cloudflare-warp in documentation; let's keep it compatible
defaultUserConfigDirs = []string{"~/.cloudflared", "~/.cloudflare-warp", "~/cloudflare-warp"} defaultUserConfigDirs = []string{"~/.cloudflared", "~/.cloudflare-warp", "~/cloudflare-warp"}
defaultNixConfigDirs = []string{"/etc/cloudflared", DefaultUnixConfigLocation} defaultNixConfigDirs = []string{"/etc/cloudflared", DefaultUnixConfigLocation}
ErrNoConfigFile = fmt.Errorf("Cannot determine default configuration path. No file %v in %v", DefaultConfigFiles, DefaultConfigSearchDirectories())
) )
const DefaultCredentialFile = "cert.pem" const DefaultCredentialFile = "cert.pem"

View File

@ -182,6 +182,7 @@ func Commands() []*cli.Command {
subcommands = append(subcommands, buildRunCommand()) subcommands = append(subcommands, buildRunCommand())
subcommands = append(subcommands, buildCleanupCommand()) subcommands = append(subcommands, buildCleanupCommand())
subcommands = append(subcommands, buildRouteCommand()) subcommands = append(subcommands, buildRouteCommand())
subcommands = append(subcommands, buildValidateCommand())
cmds = append(cmds, buildTunnelCommand(subcommands)) cmds = append(cmds, buildTunnelCommand(subcommands))
@ -334,11 +335,7 @@ func StartServer(
dnsReadySignal := make(chan struct{}) dnsReadySignal := make(chan struct{})
if c.String("config") == "" { if c.String("config") == "" {
log.Infof( log.Infof(config.ErrNoConfigFile.Error())
"Cannot determine default configuration path. No file %v in %v",
config.DefaultConfigFiles,
config.DefaultConfigSearchDirectories(),
)
} }
if c.IsSet("trace-output") { if c.IsSet("trace-output") {
@ -602,7 +599,7 @@ func Before(c *cli.Context) error {
} }
if c.String("config") == "" { if c.String("config") == "" {
logger.Debugf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigSearchDirectories()) logger.Debugf(config.ErrNoConfigFile.Error())
} }
inputSource, err := config.FindInputSourceContext(c) inputSource, err := config.FindInputSourceContext(c)
if err != nil { if err != nil {

View File

@ -95,7 +95,7 @@ func dnsProxyStandAlone(c *cli.Context) bool {
func findOriginCert(c *cli.Context, logger logger.Service) (string, error) { func findOriginCert(c *cli.Context, logger logger.Service) (string, error) {
originCertPath := c.String("origincert") originCertPath := c.String("origincert")
if originCertPath == "" { if originCertPath == "" {
logger.Infof("Cannot determine default origin certificate path. No file %s in %v", config.DefaultCredentialFile, config.DefaultConfigSearchDirectories()) logger.Infof(config.ErrNoConfigFile.Error())
if isRunningFromTerminal() { if isRunningFromTerminal() {
logger.Errorf("You need to specify the origin certificate path with --origincert option, or set TUNNEL_ORIGIN_CERT environment variable. See %s for more information.", argumentsUrl) logger.Errorf("You need to specify the origin certificate path with --origincert option, or set TUNNEL_ORIGIN_CERT environment variable. See %s for more information.", argumentsUrl)
return "", fmt.Errorf("Client didn't specify origincert path when running from terminal") return "", fmt.Errorf("Client didn't specify origincert path when running from terminal")

View File

@ -2,10 +2,16 @@ package tunnel
import ( import (
"fmt" "fmt"
"io/ioutil"
"net/url" "net/url"
"regexp" "regexp"
"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/pkg/errors"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -96,3 +102,42 @@ func parseIngress(rawYAML []byte) ([]rule, error) {
} }
return ing.validate() 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
}
configFilePath := c.String("config")
if configFilePath == "" {
return nil, nil, config.ErrNoConfigFile
}
log.Infof("Validating %s", configFilePath)
configBytes, err := ioutil.ReadFile(configFilePath)
if err != nil {
return nil, nil, err
}
rules, err := parseIngress(configBytes)
return rules, log, err
}
// Validates the ingress rules in the cloudflared config file
func validateCommand(c *cli.Context) error {
_, log, err := ingressContext(c)
if err != nil {
log.Error(err.Error())
return errors.New("Validation failed")
}
log.Infof("OK")
return nil
}
func buildValidateCommand() *cli.Command {
return &cli.Command{
Name: "validate",
Action: cliutil.ErrorHandler(validateCommand),
Usage: "Validate the ingress configuration ",
UsageText: "cloudflared tunnel [--config FILEPATH] ingress validate",
Description: "Validates the configuration file, ensuring your ingress rules are OK.",
}
}