Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-3.6] Migrate --experimental-set-member-localaddr to using feature flag #19414

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG/CHANGELOG-3.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
- Decreased [`--snapshot-count` default value from 100,000 to 10,000](https://github.com/etcd-io/etcd/pull/15408)
- Add [`etcd --tls-min-version --tls-max-version`](https://github.com/etcd-io/etcd/pull/15156) to enable support for TLS 1.3.
- Add [quota to endpoint status response](https://github.com/etcd-io/etcd/pull/17877)
- Add ['etcd --experimental-set-member-localaddr'](https://github.com/etcd-io/etcd/pull/17661) to enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer.
- Add [feature gate `SetMemberLocalAddr`](https://github.com/etcd-io/etcd/pull/19413) to [enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer]((https://github.com/etcd-io/etcd/pull/17661))
- Add [Support multiple values for allowed client and peer TLS identities](https://github.com/etcd-io/etcd/pull/18015)
- Add [`embed.Config.GRPCAdditionalServerOptions`](https://github.com/etcd-io/etcd/pull/14066) to support updating the default internal gRPC configuration for embedded use cases.

Expand Down
8 changes: 1 addition & 7 deletions server/embed/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,6 @@ type Config struct {
PeerTLSInfo transport.TLSInfo
PeerAutoTLS bool

// ExperimentalSetMemberLocalAddr enables using the first specified and
// non-loopback local address from initial-advertise-peer-urls as the local
// address when communicating with a peer.
ExperimentalSetMemberLocalAddr bool `json:"experimental-set-member-localaddr"`

// SelfSignedCertValidity specifies the validity period of the client and peer certificates
// that are automatically generated by etcd when you specify ClientAutoTLS and PeerAutoTLS,
// the unit is year, and the default is 1
Expand Down Expand Up @@ -814,7 +809,6 @@ func (cfg *Config) AddFlags(fs *flag.FlagSet) {
"initial-advertise-peer-urls",
"List of this member's peer URLs to advertise to the rest of the cluster.",
)
fs.BoolVar(&cfg.ExperimentalSetMemberLocalAddr, "experimental-set-member-localaddr", false, "Enable to have etcd use the first specified and non-loopback host from initial-advertise-peer-urls as the local address when communicating with a peer.")

fs.Var(
flags.NewUniqueURLsWithExceptions(DefaultAdvertiseClientURLs, ""),
Expand Down Expand Up @@ -1475,7 +1469,7 @@ func (cfg *Config) InitialClusterFromName(name string) (ret string) {
// non-loopback address. Otherwise, it defaults to empty string and the
// LocalAddr used will be the default for the Golang HTTP client.
func (cfg *Config) InferLocalAddr() string {
if !cfg.ExperimentalSetMemberLocalAddr {
if !cfg.ServerFeatureGate.Enabled(features.SetMemberLocalAddr) {
return ""
}

Expand Down
66 changes: 45 additions & 21 deletions server/embed/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
},
{
name: "ok to set different multiple experimental flags and feature gate flags",
serverFeatureGatesJSON: "StopGRPCServiceOnDefrag=true,TxnModeWriteWithSharedBuffer=true,LeaseCheckpoint=true",
serverFeatureGatesJSON: "StopGRPCServiceOnDefrag=true,TxnModeWriteWithSharedBuffer=true,LeaseCheckpoint=true,SetMemberLocalAddr=true",
experimentalCompactHashCheckEnabled: "true",
experimentalInitialCorruptCheck: "true",
expectedFeatures: map[featuregate.Feature]bool{
Expand All @@ -158,6 +158,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.InitialCorruptCheck: true,
features.TxnModeWriteWithSharedBuffer: true,
features.LeaseCheckpoint: true,
features.SetMemberLocalAddr: true,
},
},
{
Expand Down Expand Up @@ -440,117 +441,117 @@ func TestInferLocalAddr(t *testing.T) {
tests := []struct {
name string
advertisePeerURLs []string
setMemberLocalAddr bool
serverFeatureGates string
expectedLocalAddr string
}{
{
"defaults, ExperimentalSetMemberLocalAddr=false ",
[]string{DefaultInitialAdvertisePeerURLs},
false,
"SetMemberLocalAddr=false",
"",
},
{
"IPv4 address, ExperimentalSetMemberLocalAddr=false ",
[]string{"https://192.168.100.110:2380"},
false,
"SetMemberLocalAddr=false",
"",
},
{
"defaults, ExperimentalSetMemberLocalAddr=true",
[]string{DefaultInitialAdvertisePeerURLs},
true,
"SetMemberLocalAddr=true",
"",
},
{
"IPv4 unspecified address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://0.0.0.0:2380"},
true,
"SetMemberLocalAddr=true",
"",
},
{
"IPv6 unspecified address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://[::]:2380"},
true,
"SetMemberLocalAddr=true",
"",
},
{
"IPv4 loopback address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://127.0.0.1:2380"},
true,
"SetMemberLocalAddr=true",
"",
},
{
"IPv6 loopback address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://[::1]:2380"},
true,
"SetMemberLocalAddr=true",
"",
},
{
"IPv4 address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://192.168.100.110:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"Hostname only, ExperimentalSetMemberLocalAddr=true",
[]string{"https://123-host-3.corp.internal:2380"},
true,
"SetMemberLocalAddr=true",
"",
},
{
"Hostname and IPv4 address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://123-host-3.corp.internal:2380", "https://192.168.100.110:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"IPv4 address and Hostname, ExperimentalSetMemberLocalAddr=true",
[]string{"https://192.168.100.110:2380", "https://123-host-3.corp.internal:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"IPv4 and IPv6 addresses, ExperimentalSetMemberLocalAddr=true",
[]string{"https://192.168.100.110:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"IPv6 and IPv4 addresses, ExperimentalSetMemberLocalAddr=true",
// IPv4 addresses will always sort before IPv6 ones anyway
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://192.168.100.110:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"Hostname, IPv4 and IPv6 addresses, ExperimentalSetMemberLocalAddr=true",
[]string{"https://123-host-3.corp.internal:2380", "https://192.168.100.110:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"Hostname, IPv6 and IPv4 addresses, ExperimentalSetMemberLocalAddr=true",
// IPv4 addresses will always sort before IPv6 ones anyway
[]string{"https://123-host-3.corp.internal:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://192.168.100.110:2380"},
true,
"SetMemberLocalAddr=true",
"192.168.100.110",
},
{
"IPv6 address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380"},
true,
"SetMemberLocalAddr=true",
"2001:db8:85a3::8a2e:370:7334",
},
{
"Hostname and IPv6 address, ExperimentalSetMemberLocalAddr=true",
[]string{"https://123-host-3.corp.internal:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
true,
"SetMemberLocalAddr=true",
"2001:db8:85a3::8a2e:370:7334",
},
{
"IPv6 address and Hostname, ExperimentalSetMemberLocalAddr=true",
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://123-host-3.corp.internal:2380"},
true,
"SetMemberLocalAddr=true",
"2001:db8:85a3::8a2e:370:7334",
},
}
Expand All @@ -559,14 +560,37 @@ func TestInferLocalAddr(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
cfg := NewConfig()
cfg.AdvertisePeerUrls = types.MustNewURLs(tt.advertisePeerURLs)
cfg.ExperimentalSetMemberLocalAddr = tt.setMemberLocalAddr
cfg.ServerFeatureGate.(featuregate.MutableFeatureGate).Set(tt.serverFeatureGates)

require.NoError(t, cfg.Validate())
require.Equal(t, tt.expectedLocalAddr, cfg.InferLocalAddr())
})
}
}

func TestSetMemberLocalAddrValidate(t *testing.T) {
tcs := []struct {
name string
serverFeatureGates string
}{
{
name: "Default config should pass",
},
{
name: "Enabling SetMemberLocalAddr should pass",
serverFeatureGates: "SetMemberLocalAddr=true",
},
}
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
cfg := *NewConfig()
cfg.ServerFeatureGate.(featuregate.MutableFeatureGate).Set(tc.serverFeatureGates)
err := cfg.Validate()
require.NoError(t, err)
})
}
}

func (s *securityConfig) equals(t *transport.TLSInfo) bool {
return s.CertFile == t.CertFile &&
s.CertAuth == t.ClientCertAuth &&
Expand Down
1 change: 0 additions & 1 deletion server/embed/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ func print(lg *zap.Logger, ec Config, sc config.ServerConfig, memberInitialized
zap.Strings("advertise-client-urls", ec.getAdvertiseClientURLs()),
zap.Strings("listen-client-urls", ec.getListenClientURLs()),
zap.Strings("listen-metrics-urls", ec.getMetricsURLs()),
zap.Bool("experimental-set-member-localaddr", ec.ExperimentalSetMemberLocalAddr),
zap.String("experimental-local-address", sc.ExperimentalLocalAddress),
zap.Strings("cors", cors),
zap.Strings("host-whitelist", hss),
Expand Down
2 changes: 0 additions & 2 deletions server/etcdmain/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ Member:
Clustering:
--initial-advertise-peer-urls 'http://localhost:2380'
List of this member's peer URLs to advertise to the rest of the cluster.
--experimental-set-member-localaddr 'false'
Enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer.
--initial-cluster 'default=http://localhost:2380'
Initial cluster configuration for bootstrapping.
--initial-cluster-state 'new'
Expand Down
7 changes: 7 additions & 0 deletions server/features/etcd_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ const (
// main PR: https://github.com/etcd-io/etcd/pull/13508
// Deprecated: Enabled by default in v3.6, to be removed in v3.7.
LeaseCheckpointPersist featuregate.Feature = "LeaseCheckpointPersist"
// SetMemberLocalAddr enables using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer.
// Requires SetMemberLocalAddr featuragate to be enabled.
// owner: @flawedmatrix
// alpha: v3.6
// main PR: https://github.com/etcd-io/etcd/pull/17661
SetMemberLocalAddr featuregate.Feature = "SetMemberLocalAddr"
)

var (
Expand All @@ -84,6 +90,7 @@ var (
TxnModeWriteWithSharedBuffer: {Default: true, PreRelease: featuregate.Beta},
LeaseCheckpoint: {Default: false, PreRelease: featuregate.Alpha},
LeaseCheckpointPersist: {Default: false, PreRelease: featuregate.Alpha},
SetMemberLocalAddr: {Default: false, PreRelease: featuregate.Alpha},
}
// ExperimentalFlagToFeatureMap is the map from the cmd line flags of experimental features
// to their corresponding feature gates.
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/etcd_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ func TestEtcdPeerLocalAddr(t *testing.T) {
os.RemoveAll(tempDir)
}()

// node 0 (127.0.0.1) does not set `--experimental-set-member-localaddr`,
// node 0 (127.0.0.1) does not set `--feature-gates=SetMemberLocalAddr=true`,
// while nodes 1 and nodes 2 do.
//
// node 0's peer certificate is signed for 127.0.0.1, but it uses the host
Expand All @@ -437,7 +437,7 @@ func TestEtcdPeerLocalAddr(t *testing.T) {
// Both node 1 and node 2's peer certificates are signed for the host IP,
// and they also communicate with peers using the host IP (explicitly set
// with --initial-advertise-peer-urls and
// --experimental-set-member-localaddr), so node 0 has no issue connecting
// --feature-gates=SetMemberLocalAddr=true), so node 0 has no issue connecting
// to them.
//
// Refer to https://github.com/etcd-io/etcd/issues/17068.
Expand Down Expand Up @@ -472,7 +472,7 @@ func TestEtcdPeerLocalAddr(t *testing.T) {
"--peer-key-file", keyFiles[1],
"--peer-trusted-ca-file", caFile,
"--peer-client-cert-auth",
"--experimental-set-member-localaddr",
"--feature-gates=SetMemberLocalAddr=true",
}
}

Expand Down