diff --git a/server/etcdmain/config.go b/server/etcdmain/config.go index 8b22ccf21ee..7ee18b86f43 100644 --- a/server/etcdmain/config.go +++ b/server/etcdmain/config.go @@ -36,6 +36,8 @@ import ( "sigs.k8s.io/yaml" ) +const deprecatedWarningMessage = "--%s is deprecated in 3.5 and will be decommissioned in 3.6." + var ( proxyFlagOff = "off" proxyFlagReadonly = "readonly" @@ -62,6 +64,17 @@ var ( "test.coverprofile", "test.outputdir", } + + deprecatedFlags = map[string]struct{}{ + "enable-v2": struct{}{}, + "experimental-enable-v2v3": struct{}{}, + "proxy": struct{}{}, + "proxy-failure-wait": struct{}{}, + "proxy-refresh-interval": struct{}{}, + "proxy-dial-timeout": struct{}{}, + "proxy-write-timeout": struct{}{}, + "proxy-read-timeout": struct{}{}, + } ) type configProxy struct { @@ -207,17 +220,17 @@ func newConfig() *config { fs.BoolVar(&cfg.ec.PreVote, "pre-vote", cfg.ec.PreVote, "Enable to run an additional Raft election phase.") - fs.BoolVar(&cfg.ec.EnableV2, "enable-v2", cfg.ec.EnableV2, "Accept etcd V2 client requests. Deprecated in v3.5. Will be decommission in v3.6.") - fs.StringVar(&cfg.ec.ExperimentalEnableV2V3, "experimental-enable-v2v3", cfg.ec.ExperimentalEnableV2V3, "v3 prefix for serving emulated v2 state. Deprecated in 3.5. Will be decomissioned in 3.6.") + fs.BoolVar(&cfg.ec.EnableV2, "enable-v2", cfg.ec.EnableV2, "Accept etcd V2 client requests. Deprecated in v3.5 and will be decommissioned in v3.6.") + fs.StringVar(&cfg.ec.ExperimentalEnableV2V3, "experimental-enable-v2v3", cfg.ec.ExperimentalEnableV2V3, "v3 prefix for serving emulated v2 state. Deprecated in 3.5 and will be decommissioned in 3.6.") fs.Var(cfg.cf.v2deprecation, "v2-deprecation", fmt.Sprintf("v2store deprecation stage: %q. ", cfg.cf.proxy.Valids())) // proxy fs.Var(cfg.cf.proxy, "proxy", fmt.Sprintf("Valid values include %q", cfg.cf.proxy.Valids())) - fs.UintVar(&cfg.cp.ProxyFailureWaitMs, "proxy-failure-wait", cfg.cp.ProxyFailureWaitMs, "Time (in milliseconds) an endpoint will be held in a failed state.") - fs.UintVar(&cfg.cp.ProxyRefreshIntervalMs, "proxy-refresh-interval", cfg.cp.ProxyRefreshIntervalMs, "Time (in milliseconds) of the endpoints refresh interval.") - fs.UintVar(&cfg.cp.ProxyDialTimeoutMs, "proxy-dial-timeout", cfg.cp.ProxyDialTimeoutMs, "Time (in milliseconds) for a dial to timeout.") - fs.UintVar(&cfg.cp.ProxyWriteTimeoutMs, "proxy-write-timeout", cfg.cp.ProxyWriteTimeoutMs, "Time (in milliseconds) for a write to timeout.") - fs.UintVar(&cfg.cp.ProxyReadTimeoutMs, "proxy-read-timeout", cfg.cp.ProxyReadTimeoutMs, "Time (in milliseconds) for a read to timeout.") + fs.UintVar(&cfg.cp.ProxyFailureWaitMs, "proxy-failure-wait", cfg.cp.ProxyFailureWaitMs, "Time (in milliseconds) an endpoint will be held in a failed state. Deprecated in 3.5 and will be decommissioned in 3.6.") + fs.UintVar(&cfg.cp.ProxyRefreshIntervalMs, "proxy-refresh-interval", cfg.cp.ProxyRefreshIntervalMs, "Time (in milliseconds) of the endpoints refresh interval. Deprecated in 3.5 and will be decommissioned in 3.6.") + fs.UintVar(&cfg.cp.ProxyDialTimeoutMs, "proxy-dial-timeout", cfg.cp.ProxyDialTimeoutMs, "Time (in milliseconds) for a dial to timeout. Deprecated in 3.5 and will be decommissioned in 3.6.") + fs.UintVar(&cfg.cp.ProxyWriteTimeoutMs, "proxy-write-timeout", cfg.cp.ProxyWriteTimeoutMs, "Time (in milliseconds) for a write to timeout. Deprecated in 3.5 and will be decommissioned in 3.6.") + fs.UintVar(&cfg.cp.ProxyReadTimeoutMs, "proxy-read-timeout", cfg.cp.ProxyReadTimeoutMs, "Time (in milliseconds) for a read to timeout. Deprecated in 3.5 and will be decommissioned in 3.6.") // security fs.StringVar(&cfg.ec.ClientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.") @@ -364,6 +377,20 @@ func (cfg *config) parse(arguments []string) error { cfg.ec.V2Deprecation = cconfig.V2_DEPR_DEFAULT } + var warningsForDeprecatedFlags []string + cfg.cf.flagSet.Visit(func(f *flag.Flag) { + if _, ok := deprecatedFlags[f.Name]; ok { + warningsForDeprecatedFlags = append(warningsForDeprecatedFlags, fmt.Sprintf(deprecatedWarningMessage, f.Name)) + } + }) + if len(warningsForDeprecatedFlags) > 0 { + if lg := cfg.ec.GetLogger(); lg != nil { + for _, msg := range warningsForDeprecatedFlags { + lg.Warn(msg) + } + } + } + // now logger is set up return err } diff --git a/server/etcdmain/help.go b/server/etcdmain/help.go index 03e81cc8dba..f6e778ee6dc 100644 --- a/server/etcdmain/help.go +++ b/server/etcdmain/help.go @@ -237,7 +237,7 @@ Experimental distributed tracing: --experimental-distributed-tracing-sampling-rate '0' Number of samples to collect per million spans for distributed tracing. Disabled by default. -v2 Proxy (to be deprecated in v3.6): +v2 Proxy (Deprecated and to be decommissioned in v3.6): --proxy 'off' Proxy mode setting ('off', 'readonly' or 'on'). --proxy-failure-wait 5000 diff --git a/tests/e2e/etcd_config_test.go b/tests/e2e/etcd_config_test.go index 7dc7d5d31ef..a2eb3b4cc1a 100644 --- a/tests/e2e/etcd_config_test.go +++ b/tests/e2e/etcd_config_test.go @@ -549,5 +549,74 @@ func TestEtcdTLSVersion(t *testing.T) { assert.NoError(t, err) assert.NoError(t, e2e.WaitReadyExpectProc(proc, e2e.EtcdServerReadyLines), "did not receive expected output from etcd process") assert.NoError(t, proc.Stop()) +} + +// TestEtcdDeprecatedFlags checks that etcd will print warning messages if deprecated flags are set. +func TestEtcdDeprecatedFlags(t *testing.T) { + e2e.SkipInShortMode(t) + + commonArgs := []string{ + e2e.BinDir + "/etcd", + "--name", "e1", + } + + deprecatedWarningMessage := "--%s is deprecated in 3.5 and will be decommissioned in 3.6." + testCases := []struct { + name string + args []string + expectedMsg string + }{ + { + name: "enable-v2", + args: append(commonArgs, "--enable-v2"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "enable-v2"), + }, + { + name: "experimental-enable-v2v3", + args: append(commonArgs, "--experimental-enable-v2v3", "v3prefix"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "experimental-enable-v2v3"), + }, + { + name: "proxy", + args: append(commonArgs, "--proxy", "off"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy"), + }, + { + name: "proxy-failure-wait", + args: append(commonArgs, "--proxy-failure-wait", "10"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy-failure-wait"), + }, + { + name: "proxy-refresh-interval", + args: append(commonArgs, "--proxy-refresh-interval", "10"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy-refresh-interval"), + }, + { + name: "proxy-dial-timeout", + args: append(commonArgs, "--proxy-dial-timeout", "10"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy-dial-timeout"), + }, + { + name: "proxy-write-timeout", + args: append(commonArgs, "--proxy-write-timeout", "10"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy-write-timeout"), + }, + { + name: "proxy-read-timeout", + args: append(commonArgs, "--proxy-read-timeout", "10"), + expectedMsg: fmt.Sprintf(deprecatedWarningMessage, "proxy-read-timeout"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + proc, err := e2e.SpawnCmd( + tc.args, nil, + ) + require.NoError(t, err) + require.NoError(t, e2e.WaitReadyExpectProc(proc, []string{tc.expectedMsg})) + require.NoError(t, proc.Stop()) + }) + } }