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