TUN-4359: Warn about unused keys in 'tunnel ingress validate'
This commit is contained in:
parent
b87cb9aee8
commit
4bd17766a9
|
@ -13,27 +13,38 @@ func Action(actionFunc cli.ActionFunc) cli.ActionFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfiguredAction(actionFunc cli.ActionFunc) cli.ActionFunc {
|
func ConfiguredAction(actionFunc cli.ActionFunc) cli.ActionFunc {
|
||||||
|
// Adapt actionFunc to the type signature required by ConfiguredActionWithWarnings
|
||||||
|
f := func(context *cli.Context, _ string) error {
|
||||||
|
return actionFunc(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConfiguredActionWithWarnings(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just like ConfiguredAction, but accepts a second parameter with configuration warnings.
|
||||||
|
func ConfiguredActionWithWarnings(actionFunc func(*cli.Context, string) error) cli.ActionFunc {
|
||||||
return WithErrorHandler(func(c *cli.Context) error {
|
return WithErrorHandler(func(c *cli.Context) error {
|
||||||
if err := setFlagsFromConfigFile(c); err != nil {
|
warnings, err := setFlagsFromConfigFile(c)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return actionFunc(c)
|
return actionFunc(c, warnings)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFlagsFromConfigFile(c *cli.Context) error {
|
func setFlagsFromConfigFile(c *cli.Context) (configWarnings string, err error) {
|
||||||
const errorExitCode = 1
|
const errorExitCode = 1
|
||||||
log := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)
|
log := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)
|
||||||
inputSource, err := config.ReadConfigFile(c, log)
|
inputSource, warnings, err := config.ReadConfigFile(c, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == config.ErrNoConfigFile {
|
if err == config.ErrNoConfigFile {
|
||||||
return nil
|
return "", nil
|
||||||
}
|
}
|
||||||
return cli.Exit(err, errorExitCode)
|
return "", cli.Exit(err, errorExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := altsrc.ApplyInputSource(c, inputSource); err != nil {
|
if err := altsrc.ApplyInputSource(c, inputSource); err != nil {
|
||||||
return cli.Exit(err, errorExitCode)
|
return "", cli.Exit(err, errorExitCode)
|
||||||
}
|
}
|
||||||
return nil
|
return warnings, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ func installLinuxService(c *cli.Context) error {
|
||||||
"--origincert", serviceConfigDir + "/" + serviceCredentialFile,
|
"--origincert", serviceConfigDir + "/" + serviceCredentialFile,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
src, err := config.ReadConfigFile(c, log)
|
src, _, err := config.ReadConfigFile(c, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,7 +699,7 @@ func configureProxyFlags(shouldHide bool) []cli.Flag {
|
||||||
Hidden: shouldHide,
|
Hidden: shouldHide,
|
||||||
}),
|
}),
|
||||||
altsrc.NewDurationFlag(&cli.DurationFlag{
|
altsrc.NewDurationFlag(&cli.DurationFlag{
|
||||||
Name: ingress.ProxyTCPKeepAlive,
|
Name: ingress.ProxyTCPKeepAliveFlag,
|
||||||
Usage: "HTTP proxy TCP keepalive duration",
|
Usage: "HTTP proxy TCP keepalive duration",
|
||||||
Value: time.Second * 30,
|
Value: time.Second * 30,
|
||||||
Hidden: shouldHide,
|
Hidden: shouldHide,
|
||||||
|
|
|
@ -45,7 +45,7 @@ func buildIngressSubcommand() *cli.Command {
|
||||||
func buildValidateIngressCommand() *cli.Command {
|
func buildValidateIngressCommand() *cli.Command {
|
||||||
return &cli.Command{
|
return &cli.Command{
|
||||||
Name: "validate",
|
Name: "validate",
|
||||||
Action: cliutil.ConfiguredAction(validateIngressCommand),
|
Action: cliutil.ConfiguredActionWithWarnings(validateIngressCommand),
|
||||||
Usage: "Validate the ingress configuration ",
|
Usage: "Validate the ingress configuration ",
|
||||||
UsageText: "cloudflared tunnel [--config FILEPATH] ingress validate",
|
UsageText: "cloudflared tunnel [--config FILEPATH] ingress validate",
|
||||||
Description: "Validates the configuration file, ensuring your ingress rules are OK.",
|
Description: "Validates the configuration file, ensuring your ingress rules are OK.",
|
||||||
|
@ -68,7 +68,7 @@ func buildTestURLCommand() *cli.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateIngressCommand check the syntax of the ingress rules in the cloudflared config file
|
// validateIngressCommand check the syntax of the ingress rules in the cloudflared config file
|
||||||
func validateIngressCommand(c *cli.Context) error {
|
func validateIngressCommand(c *cli.Context, warnings string) error {
|
||||||
conf := config.GetConfiguration()
|
conf := config.GetConfiguration()
|
||||||
if conf.Source() == "" {
|
if conf.Source() == "" {
|
||||||
fmt.Println("No configuration file was found. Please create one, or use the --config flag to specify its filepath. You can use the help command to learn more about configuration files")
|
fmt.Println("No configuration file was found. Please create one, or use the --config flag to specify its filepath. You can use the help command to learn more about configuration files")
|
||||||
|
@ -81,6 +81,11 @@ func validateIngressCommand(c *cli.Context) error {
|
||||||
if c.IsSet("url") {
|
if c.IsSet("url") {
|
||||||
return ingress.ErrURLIncompatibleWithIngress
|
return ingress.ErrURLIncompatibleWithIngress
|
||||||
}
|
}
|
||||||
|
if warnings != "" {
|
||||||
|
fmt.Println("Warning: unused keys detected in your config file. Here is a list of unused keys:")
|
||||||
|
fmt.Println(warnings)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
fmt.Println("OK")
|
fmt.Println("OK")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,13 +358,13 @@ func GetConfiguration() *Configuration {
|
||||||
// ReadConfigFile returns InputSourceContext initialized from the configuration file.
|
// ReadConfigFile returns InputSourceContext initialized from the configuration file.
|
||||||
// On repeat calls returns with the same file, returns without reading the file again; however,
|
// On repeat calls returns with the same file, returns without reading the file again; however,
|
||||||
// if value of "config" flag changes, will read the new config file
|
// if value of "config" flag changes, will read the new config file
|
||||||
func ReadConfigFile(c *cli.Context, log *zerolog.Logger) (*configFileSettings, error) {
|
func ReadConfigFile(c *cli.Context, log *zerolog.Logger) (settings *configFileSettings, warnings string, err error) {
|
||||||
configFile := c.String("config")
|
configFile := c.String("config")
|
||||||
if configuration.Source() == configFile || configFile == "" {
|
if configuration.Source() == configFile || configFile == "" {
|
||||||
if configuration.Source() == "" {
|
if configuration.Source() == "" {
|
||||||
return nil, ErrNoConfigFile
|
return nil, "", ErrNoConfigFile
|
||||||
}
|
}
|
||||||
return &configuration, nil
|
return &configuration, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().Msgf("Loading configuration from %s", configFile)
|
log.Debug().Msgf("Loading configuration from %s", configFile)
|
||||||
|
@ -373,16 +373,27 @@ func ReadConfigFile(c *cli.Context, log *zerolog.Logger) (*configFileSettings, e
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = ErrNoConfigFile
|
err = ErrNoConfigFile
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
if err := yaml.NewDecoder(file).Decode(&configuration); err != nil {
|
if err := yaml.NewDecoder(file).Decode(&configuration); err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
log.Error().Msgf("Configuration file %s was empty", configFile)
|
log.Error().Msgf("Configuration file %s was empty", configFile)
|
||||||
return &configuration, nil
|
return &configuration, "", nil
|
||||||
}
|
}
|
||||||
return nil, errors.Wrap(err, "error parsing YAML in config file at "+configFile)
|
return nil, "", errors.Wrap(err, "error parsing YAML in config file at "+configFile)
|
||||||
}
|
}
|
||||||
configuration.sourceFile = configFile
|
configuration.sourceFile = configFile
|
||||||
return &configuration, nil
|
|
||||||
|
// Parse it again, with strict mode, to find warnings.
|
||||||
|
if file, err := os.Open(configFile); err == nil {
|
||||||
|
decoder := yaml.NewDecoder(file)
|
||||||
|
decoder.SetStrict(true)
|
||||||
|
var unusedConfig configFileSettings
|
||||||
|
if err := decoder.Decode(&unusedConfig); err != nil {
|
||||||
|
warnings = err.Error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &configuration, warnings, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,7 +402,7 @@ func TestSingleOriginSetsConfig(t *testing.T) {
|
||||||
flagSet.Bool("hello-world", true, "")
|
flagSet.Bool("hello-world", true, "")
|
||||||
flagSet.Duration(ProxyConnectTimeoutFlag, time.Second, "")
|
flagSet.Duration(ProxyConnectTimeoutFlag, time.Second, "")
|
||||||
flagSet.Duration(ProxyTLSTimeoutFlag, time.Second, "")
|
flagSet.Duration(ProxyTLSTimeoutFlag, time.Second, "")
|
||||||
flagSet.Duration(ProxyTCPKeepAlive, time.Second, "")
|
flagSet.Duration(ProxyTCPKeepAliveFlag, time.Second, "")
|
||||||
flagSet.Bool(ProxyNoHappyEyeballsFlag, true, "")
|
flagSet.Bool(ProxyNoHappyEyeballsFlag, true, "")
|
||||||
flagSet.Int(ProxyKeepAliveConnectionsFlag, 10, "")
|
flagSet.Int(ProxyKeepAliveConnectionsFlag, 10, "")
|
||||||
flagSet.Duration(ProxyKeepAliveTimeoutFlag, time.Second, "")
|
flagSet.Duration(ProxyKeepAliveTimeoutFlag, time.Second, "")
|
||||||
|
@ -423,7 +423,7 @@ func TestSingleOriginSetsConfig(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = cliCtx.Set(ProxyTLSTimeoutFlag, "1s")
|
err = cliCtx.Set(ProxyTLSTimeoutFlag, "1s")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = cliCtx.Set(ProxyTCPKeepAlive, "1s")
|
err = cliCtx.Set(ProxyTCPKeepAliveFlag, "1s")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = cliCtx.Set(ProxyNoHappyEyeballsFlag, "true")
|
err = cliCtx.Set(ProxyNoHappyEyeballsFlag, "true")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -22,7 +22,7 @@ const (
|
||||||
Socks5Flag = "socks5"
|
Socks5Flag = "socks5"
|
||||||
ProxyConnectTimeoutFlag = "proxy-connect-timeout"
|
ProxyConnectTimeoutFlag = "proxy-connect-timeout"
|
||||||
ProxyTLSTimeoutFlag = "proxy-tls-timeout"
|
ProxyTLSTimeoutFlag = "proxy-tls-timeout"
|
||||||
ProxyTCPKeepAlive = "proxy-tcp-keepalive"
|
ProxyTCPKeepAliveFlag = "proxy-tcp-keepalive"
|
||||||
ProxyNoHappyEyeballsFlag = "proxy-no-happy-eyeballs"
|
ProxyNoHappyEyeballsFlag = "proxy-no-happy-eyeballs"
|
||||||
ProxyKeepAliveConnectionsFlag = "proxy-keepalive-connections"
|
ProxyKeepAliveConnectionsFlag = "proxy-keepalive-connections"
|
||||||
ProxyKeepAliveTimeoutFlag = "proxy-keepalive-timeout"
|
ProxyKeepAliveTimeoutFlag = "proxy-keepalive-timeout"
|
||||||
|
@ -60,7 +60,7 @@ func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
|
||||||
if flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {
|
if flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {
|
||||||
tlsTimeout = c.Duration(flag)
|
tlsTimeout = c.Duration(flag)
|
||||||
}
|
}
|
||||||
if flag := ProxyTCPKeepAlive; c.IsSet(flag) {
|
if flag := ProxyTCPKeepAliveFlag; c.IsSet(flag) {
|
||||||
tcpKeepAlive = c.Duration(flag)
|
tcpKeepAlive = c.Duration(flag)
|
||||||
}
|
}
|
||||||
if flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {
|
if flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {
|
||||||
|
|
Loading…
Reference in New Issue