TUN-3439: 'tunnel validate' command to check ingress rules
This commit is contained in:
parent
1e6399c2f0
commit
2319003e10
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue