mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
Refactor redundancy_zone/upgrade_version out of client meta
This commit is contained in:
@@ -163,6 +163,12 @@ func convertServerConfig(agentConfig *Config, logOutput io.Writer) (*nomad.Confi
|
||||
if agentConfig.Server.NonVotingServer {
|
||||
conf.NonVoter = true
|
||||
}
|
||||
if agentConfig.Server.RedundancyZone != "" {
|
||||
conf.RedundancyZone = agentConfig.Server.RedundancyZone
|
||||
}
|
||||
if agentConfig.Server.UpgradeVersion != "" {
|
||||
conf.UpgradeVersion = agentConfig.Server.UpgradeVersion
|
||||
}
|
||||
if agentConfig.Autopilot != nil {
|
||||
if agentConfig.Autopilot.CleanupDeadServers != nil {
|
||||
conf.AutopilotConfig.CleanupDeadServers = *agentConfig.Autopilot.CleanupDeadServers
|
||||
@@ -176,14 +182,14 @@ func convertServerConfig(agentConfig *Config, logOutput io.Writer) (*nomad.Confi
|
||||
if agentConfig.Autopilot.MaxTrailingLogs != 0 {
|
||||
conf.AutopilotConfig.MaxTrailingLogs = uint64(agentConfig.Autopilot.MaxTrailingLogs)
|
||||
}
|
||||
if agentConfig.Autopilot.RedundancyZoneTag != "" {
|
||||
conf.AutopilotConfig.RedundancyZoneTag = agentConfig.Autopilot.RedundancyZoneTag
|
||||
if agentConfig.Autopilot.EnableRedundancyZones != nil {
|
||||
conf.AutopilotConfig.EnableRedundancyZones = *agentConfig.Autopilot.EnableRedundancyZones
|
||||
}
|
||||
if agentConfig.Autopilot.DisableUpgradeMigration != nil {
|
||||
conf.AutopilotConfig.DisableUpgradeMigration = *agentConfig.Autopilot.DisableUpgradeMigration
|
||||
}
|
||||
if agentConfig.Autopilot.UpgradeVersionTag != "" {
|
||||
conf.AutopilotConfig.UpgradeVersionTag = agentConfig.Autopilot.UpgradeVersionTag
|
||||
if agentConfig.Autopilot.EnableCustomUpgrades != nil {
|
||||
conf.AutopilotConfig.EnableCustomUpgrades = *agentConfig.Autopilot.EnableCustomUpgrades
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ server {
|
||||
retry_interval = "15s"
|
||||
rejoin_after_leave = true
|
||||
non_voting_server = true
|
||||
redundancy_zone = "foo"
|
||||
upgrade_version = "0.8.0"
|
||||
encrypt = "abc"
|
||||
}
|
||||
acl {
|
||||
@@ -166,7 +168,7 @@ autopilot {
|
||||
disable_upgrade_migration = true
|
||||
last_contact_threshold = "12705s"
|
||||
max_trailing_logs = 17849
|
||||
redundancy_zone_tag = "foo"
|
||||
enable_redundancy_zones = true
|
||||
server_stabilization_time = "23057s"
|
||||
upgrade_version_tag = "bar"
|
||||
enable_custom_upgrades = true
|
||||
}
|
||||
|
||||
@@ -330,10 +330,17 @@ type ServerConfig struct {
|
||||
// true, we ignore the leave, and rejoin the cluster on start.
|
||||
RejoinAfterLeave bool `mapstructure:"rejoin_after_leave"`
|
||||
|
||||
// NonVotingServer is whether this server will act as a non-voting member
|
||||
// of the cluster to help provide read scalability. (Enterprise-only)
|
||||
// (Enterprise-only) NonVotingServer is whether this server will act as a
|
||||
// non-voting member of the cluster to help provide read scalability.
|
||||
NonVotingServer bool `mapstructure:"non_voting_server"`
|
||||
|
||||
// (Enterprise-only) RedundancyZone is the redundancy zone to use for this server.
|
||||
RedundancyZone string `mapstructure:"redundancy_zone"`
|
||||
|
||||
// (Enterprise-only) UpgradeVersion is the custom upgrade version to use when
|
||||
// performing upgrade migrations.
|
||||
UpgradeVersion string `mapstructure:"upgrade_version"`
|
||||
|
||||
// Encryption key to use for the Serf communication
|
||||
EncryptKey string `mapstructure:"encrypt" json:"-"`
|
||||
}
|
||||
@@ -1034,6 +1041,12 @@ func (a *ServerConfig) Merge(b *ServerConfig) *ServerConfig {
|
||||
if b.NonVotingServer {
|
||||
result.NonVotingServer = true
|
||||
}
|
||||
if b.RedundancyZone != "" {
|
||||
result.RedundancyZone = b.RedundancyZone
|
||||
}
|
||||
if b.UpgradeVersion != "" {
|
||||
result.UpgradeVersion = b.UpgradeVersion
|
||||
}
|
||||
if b.EncryptKey != "" {
|
||||
result.EncryptKey = b.EncryptKey
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
@@ -536,6 +537,8 @@ func parseServer(result **ServerConfig, list *ast.ObjectList) error {
|
||||
"encrypt",
|
||||
"authoritative_region",
|
||||
"non_voting_server",
|
||||
"redundancy_zone",
|
||||
"upgrade_version",
|
||||
}
|
||||
if err := helper.CheckHCLKeys(listVal, valid); err != nil {
|
||||
return err
|
||||
@@ -559,6 +562,12 @@ func parseServer(result **ServerConfig, list *ast.ObjectList) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.UpgradeVersion != "" {
|
||||
if _, err := version.NewVersion(config.UpgradeVersion); err != nil {
|
||||
return fmt.Errorf("error parsing upgrade_version: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
*result = &config
|
||||
return nil
|
||||
}
|
||||
@@ -865,9 +874,9 @@ func parseAutopilot(result **config.AutopilotConfig, list *ast.ObjectList) error
|
||||
"server_stabilization_time",
|
||||
"last_contact_threshold",
|
||||
"max_trailing_logs",
|
||||
"redundancy_zone_tag",
|
||||
"enable_redundancy_zones",
|
||||
"disable_upgrade_migration",
|
||||
"upgrade_version_tag",
|
||||
"enable_custom_upgrades",
|
||||
}
|
||||
|
||||
if err := helper.CheckHCLKeys(listVal, valid); err != nil {
|
||||
|
||||
@@ -104,6 +104,8 @@ func TestConfig_Parse(t *testing.T) {
|
||||
RejoinAfterLeave: true,
|
||||
RetryMaxAttempts: 3,
|
||||
NonVotingServer: true,
|
||||
RedundancyZone: "foo",
|
||||
UpgradeVersion: "0.8.0",
|
||||
EncryptKey: "abc",
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
@@ -193,9 +195,9 @@ func TestConfig_Parse(t *testing.T) {
|
||||
ServerStabilizationTime: 23057 * time.Second,
|
||||
LastContactThreshold: 12705 * time.Second,
|
||||
MaxTrailingLogs: 17849,
|
||||
RedundancyZoneTag: "foo",
|
||||
EnableRedundancyZones: &trueValue,
|
||||
DisableUpgradeMigration: &trueValue,
|
||||
UpgradeVersionTag: "bar",
|
||||
EnableCustomUpgrades: &trueValue,
|
||||
},
|
||||
},
|
||||
false,
|
||||
|
||||
@@ -107,6 +107,8 @@ func TestConfig_Merge(t *testing.T) {
|
||||
HeartbeatGrace: 30 * time.Second,
|
||||
MinHeartbeatTTL: 30 * time.Second,
|
||||
MaxHeartbeatsPerSecond: 30.0,
|
||||
RedundancyZone: "foo",
|
||||
UpgradeVersion: "foo",
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
Enabled: true,
|
||||
@@ -165,9 +167,9 @@ func TestConfig_Merge(t *testing.T) {
|
||||
ServerStabilizationTime: 1 * time.Second,
|
||||
LastContactThreshold: 1 * time.Second,
|
||||
MaxTrailingLogs: 1,
|
||||
RedundancyZoneTag: "1",
|
||||
EnableRedundancyZones: &falseValue,
|
||||
DisableUpgradeMigration: &falseValue,
|
||||
UpgradeVersionTag: "1",
|
||||
EnableCustomUpgrades: &falseValue,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -260,6 +262,8 @@ func TestConfig_Merge(t *testing.T) {
|
||||
RetryInterval: "10s",
|
||||
retryInterval: time.Second * 10,
|
||||
NonVotingServer: true,
|
||||
RedundancyZone: "bar",
|
||||
UpgradeVersion: "bar",
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
Enabled: true,
|
||||
@@ -328,9 +332,9 @@ func TestConfig_Merge(t *testing.T) {
|
||||
ServerStabilizationTime: 2 * time.Second,
|
||||
LastContactThreshold: 2 * time.Second,
|
||||
MaxTrailingLogs: 2,
|
||||
RedundancyZoneTag: "2",
|
||||
EnableRedundancyZones: &trueValue,
|
||||
DisableUpgradeMigration: &trueValue,
|
||||
UpgradeVersionTag: "2",
|
||||
EnableCustomUpgrades: &trueValue,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -104,19 +104,19 @@ func (s *HTTPServer) OperatorAutopilotConfiguration(resp http.ResponseWriter, re
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var reply autopilot.Config
|
||||
var reply structs.AutopilotConfig
|
||||
if err := s.agent.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := api.AutopilotConfiguration{
|
||||
CleanupDeadServers: reply.CleanupDeadServers,
|
||||
LastContactThreshold: api.NewReadableDuration(reply.LastContactThreshold),
|
||||
LastContactThreshold: reply.LastContactThreshold,
|
||||
MaxTrailingLogs: reply.MaxTrailingLogs,
|
||||
ServerStabilizationTime: api.NewReadableDuration(reply.ServerStabilizationTime),
|
||||
RedundancyZoneTag: reply.RedundancyZoneTag,
|
||||
ServerStabilizationTime: reply.ServerStabilizationTime,
|
||||
EnableRedundancyZones: reply.EnableRedundancyZones,
|
||||
DisableUpgradeMigration: reply.DisableUpgradeMigration,
|
||||
UpgradeVersionTag: reply.UpgradeVersionTag,
|
||||
EnableCustomUpgrades: reply.EnableCustomUpgrades,
|
||||
CreateIndex: reply.CreateIndex,
|
||||
ModifyIndex: reply.ModifyIndex,
|
||||
}
|
||||
@@ -129,21 +129,20 @@ func (s *HTTPServer) OperatorAutopilotConfiguration(resp http.ResponseWriter, re
|
||||
s.parseToken(req, &args.AuthToken)
|
||||
|
||||
var conf api.AutopilotConfiguration
|
||||
durations := NewDurationFixer("lastcontactthreshold", "serverstabilizationtime")
|
||||
if err := decodeBodyFunc(req, &conf, durations.FixupDurations); err != nil {
|
||||
if err := decodeBody(req, &conf); err != nil {
|
||||
resp.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(resp, "Error parsing autopilot config: %v", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
args.Config = autopilot.Config{
|
||||
args.Config = structs.AutopilotConfig{
|
||||
CleanupDeadServers: conf.CleanupDeadServers,
|
||||
LastContactThreshold: conf.LastContactThreshold.Duration(),
|
||||
LastContactThreshold: conf.LastContactThreshold,
|
||||
MaxTrailingLogs: conf.MaxTrailingLogs,
|
||||
ServerStabilizationTime: conf.ServerStabilizationTime.Duration(),
|
||||
RedundancyZoneTag: conf.RedundancyZoneTag,
|
||||
ServerStabilizationTime: conf.ServerStabilizationTime,
|
||||
EnableRedundancyZones: conf.EnableRedundancyZones,
|
||||
DisableUpgradeMigration: conf.DisableUpgradeMigration,
|
||||
UpgradeVersionTag: conf.UpgradeVersionTag,
|
||||
EnableCustomUpgrades: conf.EnableCustomUpgrades,
|
||||
}
|
||||
|
||||
// Check for cas value
|
||||
@@ -210,7 +209,7 @@ func (s *HTTPServer) OperatorServerHealth(resp http.ResponseWriter, req *http.Re
|
||||
Version: server.Version,
|
||||
Leader: server.Leader,
|
||||
SerfStatus: server.SerfStatus.String(),
|
||||
LastContact: api.NewReadableDuration(server.LastContact),
|
||||
LastContact: server.LastContact,
|
||||
LastTerm: server.LastTerm,
|
||||
LastIndex: server.LastIndex,
|
||||
Healthy: server.Healthy,
|
||||
@@ -221,56 +220,3 @@ func (s *HTTPServer) OperatorServerHealth(resp http.ResponseWriter, req *http.Re
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type durationFixer map[string]bool
|
||||
|
||||
func NewDurationFixer(fields ...string) durationFixer {
|
||||
d := make(map[string]bool)
|
||||
for _, field := range fields {
|
||||
d[field] = true
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// FixupDurations is used to handle parsing any field names in the map to time.Durations
|
||||
func (d durationFixer) FixupDurations(raw interface{}) error {
|
||||
rawMap, ok := raw.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
for key, val := range rawMap {
|
||||
switch val.(type) {
|
||||
case map[string]interface{}:
|
||||
if err := d.FixupDurations(val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
for _, v := range val.([]interface{}) {
|
||||
if err := d.FixupDurations(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case []map[string]interface{}:
|
||||
for _, v := range val.([]map[string]interface{}) {
|
||||
if err := d.FixupDurations(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if d[strings.ToLower(key)] {
|
||||
// Convert a string value into an integer
|
||||
if vStr, ok := val.(string); ok {
|
||||
dur, err := time.ParseDuration(vStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawMap[key] = dur
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/agent/consul/autopilot"
|
||||
"github.com/hashicorp/consul/testutil/retry"
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
@@ -112,7 +111,7 @@ func TestOperator_AutopilotSetConfiguration(t *testing.T) {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp.Code != 200 {
|
||||
t.Fatalf("bad code: %d", resp.Code)
|
||||
t.Fatalf("bad code: %d, %q", resp.Code, resp.Body.String())
|
||||
}
|
||||
|
||||
args := structs.GenericRequest{
|
||||
@@ -121,7 +120,7 @@ func TestOperator_AutopilotSetConfiguration(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
var reply autopilot.Config
|
||||
var reply structs.AutopilotConfig
|
||||
if err := s.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -150,7 +149,7 @@ func TestOperator_AutopilotCASConfiguration(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
var reply autopilot.Config
|
||||
var reply structs.AutopilotConfig
|
||||
if err := s.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
@@ -200,7 +199,6 @@ func TestOperator_AutopilotCASConfiguration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOperator_ServerHealth(t *testing.T) {
|
||||
t.Parallel()
|
||||
httpTest(t, func(c *Config) {
|
||||
c.Server.RaftProtocol = 3
|
||||
}, func(s *TestAgent) {
|
||||
@@ -259,47 +257,3 @@ func TestOperator_ServerHealth_Unhealthy(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDurationFixer(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
obj := map[string]interface{}{
|
||||
"key1": []map[string]interface{}{
|
||||
{
|
||||
"subkey1": "10s",
|
||||
},
|
||||
{
|
||||
"subkey2": "5d",
|
||||
},
|
||||
},
|
||||
"key2": map[string]interface{}{
|
||||
"subkey3": "30s",
|
||||
"subkey4": "20m",
|
||||
},
|
||||
"key3": "11s",
|
||||
"key4": "49h",
|
||||
}
|
||||
expected := map[string]interface{}{
|
||||
"key1": []map[string]interface{}{
|
||||
{
|
||||
"subkey1": 10 * time.Second,
|
||||
},
|
||||
{
|
||||
"subkey2": "5d",
|
||||
},
|
||||
},
|
||||
"key2": map[string]interface{}{
|
||||
"subkey3": "30s",
|
||||
"subkey4": 20 * time.Minute,
|
||||
},
|
||||
"key3": "11s",
|
||||
"key4": 49 * time.Hour,
|
||||
}
|
||||
|
||||
fixer := NewDurationFixer("key4", "subkey1", "subkey4")
|
||||
if err := fixer.FixupDurations(obj); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Ensure we only processed the intended fieldnames
|
||||
assert.Equal(obj, expected)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user