mirror of
https://github.com/status-im/consul.git
synced 2025-02-22 18:38:19 +00:00
agent: add a clone function for duplicating the serf lan configuration (#11443)
This commit is contained in:
parent
977be77493
commit
af9ffc214d
@ -1251,6 +1251,10 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co
|
||||
|
||||
cfg.ConfigEntryBootstrap = runtimeCfg.ConfigEntryBootstrap
|
||||
|
||||
// Duplicate our own serf config once to make sure that the duplication
|
||||
// function does not drift.
|
||||
cfg.SerfLANConfig = consul.CloneSerfLANConfig(cfg.SerfLANConfig)
|
||||
|
||||
enterpriseConsulConfig(cfg, runtimeCfg)
|
||||
return cfg, nil
|
||||
}
|
||||
|
@ -541,6 +541,49 @@ func DefaultConfig() *Config {
|
||||
return conf
|
||||
}
|
||||
|
||||
// CloneSerfLANConfig clones an existing serf.Config used on the LAN by
|
||||
// reconstructing it from defaults and re-applying changes made in the agent
|
||||
// configs.
|
||||
//
|
||||
// This function is tricky to keep from rotting so we enforce that it MUST work
|
||||
// by cloning our own serf LAN configuration on startup and only using the
|
||||
// cloned one so any configs we need to change have to be changed here for them
|
||||
// to work at all.
|
||||
func CloneSerfLANConfig(base *serf.Config) *serf.Config {
|
||||
cfg := DefaultConfig().SerfLANConfig
|
||||
|
||||
// from consul.DefaultConfig()
|
||||
cfg.ReconnectTimeout = base.ReconnectTimeout
|
||||
cfg.MemberlistConfig.BindPort = base.MemberlistConfig.BindPort
|
||||
cfg.MemberlistConfig.DeadNodeReclaimTime = base.MemberlistConfig.DeadNodeReclaimTime
|
||||
|
||||
// from agent.newConsulConfig()
|
||||
cfg.MemberlistConfig.BindAddr = base.MemberlistConfig.BindAddr
|
||||
cfg.MemberlistConfig.BindPort = base.MemberlistConfig.BindPort
|
||||
cfg.MemberlistConfig.CIDRsAllowed = base.MemberlistConfig.CIDRsAllowed
|
||||
cfg.MemberlistConfig.AdvertiseAddr = base.MemberlistConfig.AdvertiseAddr
|
||||
cfg.MemberlistConfig.AdvertisePort = base.MemberlistConfig.AdvertisePort
|
||||
cfg.MemberlistConfig.GossipVerifyIncoming = base.MemberlistConfig.GossipVerifyIncoming
|
||||
cfg.MemberlistConfig.GossipVerifyOutgoing = base.MemberlistConfig.GossipVerifyOutgoing
|
||||
cfg.MemberlistConfig.GossipInterval = base.MemberlistConfig.GossipInterval
|
||||
cfg.MemberlistConfig.GossipNodes = base.MemberlistConfig.GossipNodes
|
||||
cfg.MemberlistConfig.ProbeInterval = base.MemberlistConfig.ProbeInterval
|
||||
cfg.MemberlistConfig.ProbeTimeout = base.MemberlistConfig.ProbeTimeout
|
||||
cfg.MemberlistConfig.SuspicionMult = base.MemberlistConfig.SuspicionMult
|
||||
cfg.MemberlistConfig.RetransmitMult = base.MemberlistConfig.RetransmitMult
|
||||
|
||||
// agent/keyring.go
|
||||
cfg.MemberlistConfig.Keyring = base.MemberlistConfig.Keyring
|
||||
|
||||
// tests
|
||||
cfg.KeyringFile = base.KeyringFile
|
||||
cfg.ReapInterval = base.ReapInterval
|
||||
cfg.TombstoneTimeout = base.TombstoneTimeout
|
||||
cfg.MemberlistConfig.SecretKey = base.MemberlistConfig.SecretKey
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// RPCConfig settings for the RPC server
|
||||
//
|
||||
// TODO: move many settings to this struct.
|
||||
|
129
agent/consul/config_test.go
Normal file
129
agent/consul/config_test.go
Normal file
@ -0,0 +1,129 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
fuzz "github.com/google/gofuzz"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCloneSerfLANConfig(t *testing.T) {
|
||||
config := DefaultConfig().SerfLANConfig
|
||||
|
||||
// NOTE: ALL fields on serf.Config and memberlist.Config MUST BE
|
||||
// represented either here or in the CloneSerfLANConfig function body.
|
||||
// Failure to add it to the clone or ignore sections will fail the test.
|
||||
memberlistIgnoreFieldNames := []string{
|
||||
"Alive",
|
||||
"AwarenessMaxMultiplier",
|
||||
"Conflict",
|
||||
"DNSConfigPath",
|
||||
"Delegate",
|
||||
"DelegateProtocolMax",
|
||||
"DelegateProtocolMin",
|
||||
"DelegateProtocolVersion",
|
||||
"DisableTcpPings",
|
||||
"DisableTcpPingsForNode",
|
||||
"EnableCompression",
|
||||
"Events",
|
||||
"GossipToTheDeadTime",
|
||||
"HandoffQueueDepth",
|
||||
"IndirectChecks",
|
||||
"LogOutput",
|
||||
"Logger",
|
||||
"Merge",
|
||||
"Name",
|
||||
"Ping",
|
||||
"ProtocolVersion",
|
||||
"PushPullInterval",
|
||||
"RequireNodeNames",
|
||||
"SuspicionMaxTimeoutMult",
|
||||
"TCPTimeout",
|
||||
"Transport",
|
||||
"UDPBufferSize",
|
||||
}
|
||||
serfIgnoreFieldNames := []string{
|
||||
"BroadcastTimeout",
|
||||
"CoalescePeriod",
|
||||
"DisableCoordinates",
|
||||
"EnableNameConflictResolution",
|
||||
"EventBuffer",
|
||||
"EventCh",
|
||||
"FlapTimeout",
|
||||
"LeavePropagateDelay",
|
||||
"LogOutput",
|
||||
"Logger",
|
||||
"MaxQueueDepth",
|
||||
"MemberlistConfig",
|
||||
"Merge",
|
||||
"MinQueueDepth",
|
||||
"NodeName",
|
||||
"ProtocolVersion",
|
||||
"QueryBuffer",
|
||||
"QueryResponseSizeLimit",
|
||||
"QuerySizeLimit",
|
||||
"QueryTimeoutMult",
|
||||
"QueueCheckInterval",
|
||||
"QueueDepthWarning",
|
||||
"QuiescentPeriod",
|
||||
"RecentIntentTimeout",
|
||||
"ReconnectInterval",
|
||||
"ReconnectTimeoutOverride",
|
||||
"RejoinAfterLeave",
|
||||
"SnapshotPath",
|
||||
"Tags",
|
||||
"UserCoalescePeriod",
|
||||
"UserEventSizeLimit",
|
||||
"UserQuiescentPeriod",
|
||||
"ValidateNodeNames",
|
||||
}
|
||||
|
||||
serfFuzzed := fuzzNonIgnoredFields(config, serfIgnoreFieldNames)
|
||||
t.Logf("Fuzzing serf.Config fields: %v", serfFuzzed)
|
||||
|
||||
memberlistFuzzed := fuzzNonIgnoredFields(config.MemberlistConfig, memberlistIgnoreFieldNames)
|
||||
t.Logf("Fuzzing memberlist.Config fields: %v", memberlistFuzzed)
|
||||
|
||||
clone := CloneSerfLANConfig(config)
|
||||
require.Equal(t, config, clone)
|
||||
}
|
||||
|
||||
func fuzzNonIgnoredFields(value interface{}, ignoredFields []string) []string {
|
||||
ignored := make(map[string]struct{})
|
||||
for _, field := range ignoredFields {
|
||||
ignored[field] = struct{}{}
|
||||
}
|
||||
|
||||
var fuzzed []string
|
||||
|
||||
// Walk the fields of our object to fuzz and selectively only fuzz the
|
||||
// fields that were not ignored.
|
||||
fuzzer := fuzz.NewWithSeed(time.Now().UnixNano())
|
||||
|
||||
v := reflect.ValueOf(value).Elem()
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
if !field.CanInterface() {
|
||||
continue // skip unexported fields
|
||||
}
|
||||
|
||||
fieldName := v.Type().Field(i).Name
|
||||
if _, ok := ignored[fieldName]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
fuzzed = append(fuzzed, fieldName)
|
||||
|
||||
// copy the data somewhere mutable
|
||||
tmp := reflect.New(field.Type())
|
||||
tmp.Elem().Set(field)
|
||||
// fuzz the copy
|
||||
fuzzer.Fuzz(tmp.Interface())
|
||||
// and set the fuzzed copy back to the original location
|
||||
field.Set(reflect.Indirect(tmp))
|
||||
}
|
||||
|
||||
return fuzzed
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user