Skip to content

Commit 91762cc

Browse files
authored
Merge pull request #19413 from henrybear327/feat/add_flag
Migrate --experimental-set-member-localaddr to using feature flag
2 parents 865ed4a + 5fa8c1f commit 91762cc

File tree

7 files changed

+57
-35
lines changed

7 files changed

+57
-35
lines changed

CHANGELOG/CHANGELOG-3.6.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ See [code changes](https://github.com/etcd-io/etcd/compare/v3.5.0...v3.6.0).
7878
- Decreased [`--snapshot-count` default value from 100,000 to 10,000](https://github.com/etcd-io/etcd/pull/15408)
7979
- Add [`etcd --tls-min-version --tls-max-version`](https://github.com/etcd-io/etcd/pull/15156) to enable support for TLS 1.3.
8080
- Add [quota to endpoint status response](https://github.com/etcd-io/etcd/pull/17877)
81-
- 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.
81+
- 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))
8282
- Add [Support multiple values for allowed client and peer TLS identities](https://github.com/etcd-io/etcd/pull/18015)
8383
- Add [`embed.Config.GRPCAdditionalServerOptions`](https://github.com/etcd-io/etcd/pull/14066) to support updating the default internal gRPC configuration for embedded use cases.
8484

server/embed/config.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,6 @@ type Config struct {
285285
PeerTLSInfo transport.TLSInfo
286286
PeerAutoTLS bool
287287

288-
// ExperimentalSetMemberLocalAddr enables using the first specified and
289-
// non-loopback local address from initial-advertise-peer-urls as the local
290-
// address when communicating with a peer.
291-
ExperimentalSetMemberLocalAddr bool `json:"experimental-set-member-localaddr"`
292-
293288
// SelfSignedCertValidity specifies the validity period of the client and peer certificates
294289
// that are automatically generated by etcd when you specify ClientAutoTLS and PeerAutoTLS,
295290
// the unit is year, and the default is 1
@@ -814,7 +809,6 @@ func (cfg *Config) AddFlags(fs *flag.FlagSet) {
814809
"initial-advertise-peer-urls",
815810
"List of this member's peer URLs to advertise to the rest of the cluster.",
816811
)
817-
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.")
818812

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

server/embed/config_test.go

+45-21
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
149149
},
150150
{
151151
name: "ok to set different multiple experimental flags and feature gate flags",
152-
serverFeatureGatesJSON: "StopGRPCServiceOnDefrag=true,TxnModeWriteWithSharedBuffer=true,LeaseCheckpoint=true",
152+
serverFeatureGatesJSON: "StopGRPCServiceOnDefrag=true,TxnModeWriteWithSharedBuffer=true,LeaseCheckpoint=true,SetMemberLocalAddr=true",
153153
experimentalCompactHashCheckEnabled: "true",
154154
experimentalInitialCorruptCheck: "true",
155155
expectedFeatures: map[featuregate.Feature]bool{
@@ -158,6 +158,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
158158
features.InitialCorruptCheck: true,
159159
features.TxnModeWriteWithSharedBuffer: true,
160160
features.LeaseCheckpoint: true,
161+
features.SetMemberLocalAddr: true,
161162
},
162163
},
163164
{
@@ -440,117 +441,117 @@ func TestInferLocalAddr(t *testing.T) {
440441
tests := []struct {
441442
name string
442443
advertisePeerURLs []string
443-
setMemberLocalAddr bool
444+
serverFeatureGates string
444445
expectedLocalAddr string
445446
}{
446447
{
447448
"defaults, ExperimentalSetMemberLocalAddr=false ",
448449
[]string{DefaultInitialAdvertisePeerURLs},
449-
false,
450+
"SetMemberLocalAddr=false",
450451
"",
451452
},
452453
{
453454
"IPv4 address, ExperimentalSetMemberLocalAddr=false ",
454455
[]string{"https://192.168.100.110:2380"},
455-
false,
456+
"SetMemberLocalAddr=false",
456457
"",
457458
},
458459
{
459460
"defaults, ExperimentalSetMemberLocalAddr=true",
460461
[]string{DefaultInitialAdvertisePeerURLs},
461-
true,
462+
"SetMemberLocalAddr=true",
462463
"",
463464
},
464465
{
465466
"IPv4 unspecified address, ExperimentalSetMemberLocalAddr=true",
466467
[]string{"https://0.0.0.0:2380"},
467-
true,
468+
"SetMemberLocalAddr=true",
468469
"",
469470
},
470471
{
471472
"IPv6 unspecified address, ExperimentalSetMemberLocalAddr=true",
472473
[]string{"https://[::]:2380"},
473-
true,
474+
"SetMemberLocalAddr=true",
474475
"",
475476
},
476477
{
477478
"IPv4 loopback address, ExperimentalSetMemberLocalAddr=true",
478479
[]string{"https://127.0.0.1:2380"},
479-
true,
480+
"SetMemberLocalAddr=true",
480481
"",
481482
},
482483
{
483484
"IPv6 loopback address, ExperimentalSetMemberLocalAddr=true",
484485
[]string{"https://[::1]:2380"},
485-
true,
486+
"SetMemberLocalAddr=true",
486487
"",
487488
},
488489
{
489490
"IPv4 address, ExperimentalSetMemberLocalAddr=true",
490491
[]string{"https://192.168.100.110:2380"},
491-
true,
492+
"SetMemberLocalAddr=true",
492493
"192.168.100.110",
493494
},
494495
{
495496
"Hostname only, ExperimentalSetMemberLocalAddr=true",
496497
[]string{"https://123-host-3.corp.internal:2380"},
497-
true,
498+
"SetMemberLocalAddr=true",
498499
"",
499500
},
500501
{
501502
"Hostname and IPv4 address, ExperimentalSetMemberLocalAddr=true",
502503
[]string{"https://123-host-3.corp.internal:2380", "https://192.168.100.110:2380"},
503-
true,
504+
"SetMemberLocalAddr=true",
504505
"192.168.100.110",
505506
},
506507
{
507508
"IPv4 address and Hostname, ExperimentalSetMemberLocalAddr=true",
508509
[]string{"https://192.168.100.110:2380", "https://123-host-3.corp.internal:2380"},
509-
true,
510+
"SetMemberLocalAddr=true",
510511
"192.168.100.110",
511512
},
512513
{
513514
"IPv4 and IPv6 addresses, ExperimentalSetMemberLocalAddr=true",
514515
[]string{"https://192.168.100.110:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
515-
true,
516+
"SetMemberLocalAddr=true",
516517
"192.168.100.110",
517518
},
518519
{
519520
"IPv6 and IPv4 addresses, ExperimentalSetMemberLocalAddr=true",
520521
// IPv4 addresses will always sort before IPv6 ones anyway
521522
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://192.168.100.110:2380"},
522-
true,
523+
"SetMemberLocalAddr=true",
523524
"192.168.100.110",
524525
},
525526
{
526527
"Hostname, IPv4 and IPv6 addresses, ExperimentalSetMemberLocalAddr=true",
527528
[]string{"https://123-host-3.corp.internal:2380", "https://192.168.100.110:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
528-
true,
529+
"SetMemberLocalAddr=true",
529530
"192.168.100.110",
530531
},
531532
{
532533
"Hostname, IPv6 and IPv4 addresses, ExperimentalSetMemberLocalAddr=true",
533534
// IPv4 addresses will always sort before IPv6 ones anyway
534535
[]string{"https://123-host-3.corp.internal:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://192.168.100.110:2380"},
535-
true,
536+
"SetMemberLocalAddr=true",
536537
"192.168.100.110",
537538
},
538539
{
539540
"IPv6 address, ExperimentalSetMemberLocalAddr=true",
540541
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380"},
541-
true,
542+
"SetMemberLocalAddr=true",
542543
"2001:db8:85a3::8a2e:370:7334",
543544
},
544545
{
545546
"Hostname and IPv6 address, ExperimentalSetMemberLocalAddr=true",
546547
[]string{"https://123-host-3.corp.internal:2380", "https://[2001:db8:85a3::8a2e:370:7334]:2380"},
547-
true,
548+
"SetMemberLocalAddr=true",
548549
"2001:db8:85a3::8a2e:370:7334",
549550
},
550551
{
551552
"IPv6 address and Hostname, ExperimentalSetMemberLocalAddr=true",
552553
[]string{"https://[2001:db8:85a3::8a2e:370:7334]:2380", "https://123-host-3.corp.internal:2380"},
553-
true,
554+
"SetMemberLocalAddr=true",
554555
"2001:db8:85a3::8a2e:370:7334",
555556
},
556557
}
@@ -559,14 +560,37 @@ func TestInferLocalAddr(t *testing.T) {
559560
t.Run(tt.name, func(t *testing.T) {
560561
cfg := NewConfig()
561562
cfg.AdvertisePeerUrls = types.MustNewURLs(tt.advertisePeerURLs)
562-
cfg.ExperimentalSetMemberLocalAddr = tt.setMemberLocalAddr
563+
cfg.ServerFeatureGate.(featuregate.MutableFeatureGate).Set(tt.serverFeatureGates)
563564

564565
require.NoError(t, cfg.Validate())
565566
require.Equal(t, tt.expectedLocalAddr, cfg.InferLocalAddr())
566567
})
567568
}
568569
}
569570

571+
func TestSetMemberLocalAddrValidate(t *testing.T) {
572+
tcs := []struct {
573+
name string
574+
serverFeatureGates string
575+
}{
576+
{
577+
name: "Default config should pass",
578+
},
579+
{
580+
name: "Enabling SetMemberLocalAddr should pass",
581+
serverFeatureGates: "SetMemberLocalAddr=true",
582+
},
583+
}
584+
for _, tc := range tcs {
585+
t.Run(tc.name, func(t *testing.T) {
586+
cfg := *NewConfig()
587+
cfg.ServerFeatureGate.(featuregate.MutableFeatureGate).Set(tc.serverFeatureGates)
588+
err := cfg.Validate()
589+
require.NoError(t, err)
590+
})
591+
}
592+
}
593+
570594
func (s *securityConfig) equals(t *transport.TLSInfo) bool {
571595
return s.CertFile == t.CertFile &&
572596
s.CertAuth == t.ClientCertAuth &&

server/embed/etcd.go

-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ func print(lg *zap.Logger, ec Config, sc config.ServerConfig, memberInitialized
348348
zap.Strings("advertise-client-urls", ec.getAdvertiseClientURLs()),
349349
zap.Strings("listen-client-urls", ec.getListenClientURLs()),
350350
zap.Strings("listen-metrics-urls", ec.getMetricsURLs()),
351-
zap.Bool("experimental-set-member-localaddr", ec.ExperimentalSetMemberLocalAddr),
352351
zap.String("experimental-local-address", sc.ExperimentalLocalAddress),
353352
zap.Strings("cors", cors),
354353
zap.Strings("host-whitelist", hss),

server/etcdmain/help.go

-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ Member:
113113
Clustering:
114114
--initial-advertise-peer-urls 'http://localhost:2380'
115115
List of this member's peer URLs to advertise to the rest of the cluster.
116-
--experimental-set-member-localaddr 'false'
117-
Enable using the first specified and non-loopback local address from initial-advertise-peer-urls as the local address when communicating with a peer.
118116
--initial-cluster 'default=http://localhost:2380'
119117
Initial cluster configuration for bootstrapping.
120118
--initial-cluster-state 'new'

server/features/etcd_features.go

+7
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ const (
7373
// main PR: https://github.com/etcd-io/etcd/pull/13508
7474
// Deprecated: Enabled by default in v3.6, to be removed in v3.7.
7575
LeaseCheckpointPersist featuregate.Feature = "LeaseCheckpointPersist"
76+
// 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.
77+
// Requires SetMemberLocalAddr featuragate to be enabled.
78+
// owner: @flawedmatrix
79+
// alpha: v3.6
80+
// main PR: https://github.com/etcd-io/etcd/pull/17661
81+
SetMemberLocalAddr featuregate.Feature = "SetMemberLocalAddr"
7682
)
7783

7884
var (
@@ -84,6 +90,7 @@ var (
8490
TxnModeWriteWithSharedBuffer: {Default: true, PreRelease: featuregate.Beta},
8591
LeaseCheckpoint: {Default: false, PreRelease: featuregate.Alpha},
8692
LeaseCheckpointPersist: {Default: false, PreRelease: featuregate.Alpha},
93+
SetMemberLocalAddr: {Default: false, PreRelease: featuregate.Alpha},
8794
}
8895
// ExperimentalFlagToFeatureMap is the map from the cmd line flags of experimental features
8996
// to their corresponding feature gates.

tests/e2e/etcd_config_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ func TestEtcdPeerLocalAddr(t *testing.T) {
427427
os.RemoveAll(tempDir)
428428
}()
429429

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

0 commit comments

Comments
 (0)