mirror of
https://github.com/status-im/consul.git
synced 2025-02-23 02:48: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
|
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)
|
enterpriseConsulConfig(cfg, runtimeCfg)
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
@ -541,6 +541,49 @@ func DefaultConfig() *Config {
|
|||||||
return conf
|
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
|
// RPCConfig settings for the RPC server
|
||||||
//
|
//
|
||||||
// TODO: move many settings to this struct.
|
// 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