Skip to content

Commit eed8ea1

Browse files
authored
Merge pull request #321 from arangodb/feature/scaling-limits
Added scaling limits.
2 parents db4a761 + fa8d693 commit eed8ea1

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

docs/Manual/Deployment/Kubernetes/DeploymentResource.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,14 @@ for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`).
352352
For the `syncworkers` group, it is highly recommended to use the same number
353353
as for the `dbservers` group.
354354

355+
### `spec.<group>.minCount: number`
356+
357+
Specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`.
358+
359+
### `spec.<group>.maxCount: number`
360+
361+
Specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`.
362+
355363
### `spec.<group>.args: []string`
356364

357365
This setting specifies additional commandline arguments passed to all servers of this group.

pkg/apis/deployment/v1alpha/server_group_spec.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package v1alpha
2424

2525
import (
26+
"math"
2627
"strings"
2728

2829
"github.com/pkg/errors"
@@ -39,6 +40,10 @@ import (
3940
type ServerGroupSpec struct {
4041
// Count holds the requested number of servers
4142
Count *int `json:"count,omitempty"`
43+
// MinCount specifies a lower limit for count
44+
MinCount *int `json:"minCount,omitempty"`
45+
// MaxCount specifies a upper limit for count
46+
MaxCount *int `json:"maxCount,omitempty"`
4247
// Args holds additional commandline arguments
4348
Args []string `json:"args,omitempty"`
4449
// StorageClassName specifies the classname for storage of the servers.
@@ -58,6 +63,16 @@ func (s ServerGroupSpec) GetCount() int {
5863
return util.IntOrDefault(s.Count)
5964
}
6065

66+
// GetMinCount returns MinCount or 1 if not set
67+
func (s ServerGroupSpec) GetMinCount() int {
68+
return util.IntOrDefault(s.MinCount, 1)
69+
}
70+
71+
// GetMaxCount returns MaxCount or
72+
func (s ServerGroupSpec) GetMaxCount() int {
73+
return util.IntOrDefault(s.MaxCount, math.MaxInt32)
74+
}
75+
6176
// GetNodeSelector returns the selectors for nodes of this group
6277
func (s ServerGroupSpec) GetNodeSelector() map[string]string {
6378
return s.NodeSelector
@@ -110,8 +125,17 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM
110125
minCount = 2
111126
}
112127
}
128+
if s.GetMinCount() > s.GetMaxCount() {
129+
return maskAny(errors.Wrapf(ValidationError, "Invalid min/maxCount. Min (%d) bigger than Max (%d)", s.GetMinCount(), s.GetMaxCount()))
130+
}
131+
if s.GetCount() < s.GetMinCount() {
132+
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d", s.GetCount(), s.GetMinCount()))
133+
}
134+
if s.GetCount() > s.GetMaxCount() {
135+
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected <= %d", s.GetCount(), s.GetMaxCount()))
136+
}
113137
if s.GetCount() < minCount {
114-
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d", s.GetCount(), minCount))
138+
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d (implicit minimum; by deployment mode)", s.GetCount(), minCount))
115139
}
116140
if s.GetCount() > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle {
117141
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.GetCount()))
@@ -160,6 +184,8 @@ func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode Deploym
160184
}
161185
} else if s.GetCount() > 0 && !used {
162186
s.Count = nil
187+
s.MinCount = nil
188+
s.MaxCount = nil
163189
}
164190
if _, found := s.Resources.Requests[v1.ResourceStorage]; !found {
165191
switch group {
@@ -189,6 +215,12 @@ func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) {
189215
if s.Count == nil {
190216
s.Count = util.NewIntOrNil(source.Count)
191217
}
218+
if s.MinCount == nil {
219+
s.MinCount = util.NewIntOrNil(source.MinCount)
220+
}
221+
if s.MaxCount == nil {
222+
s.MaxCount = util.NewIntOrNil(source.MaxCount)
223+
}
192224
if s.Args == nil {
193225
s.Args = source.Args
194226
}

pkg/apis/deployment/v1alpha/server_group_spec_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ func TestServerGroupSpecValidateCount(t *testing.T) {
4848
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction))
4949
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction))
5050

51+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2), MinCount: util.NewInt(2), MaxCount: util.NewInt(5)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
52+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1), MaxCount: util.NewInt(5)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
53+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(6), MinCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
54+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(5), MinCount: util.NewInt(5), MaxCount: util.NewInt(5)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
55+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
56+
5157
// Invalid
5258
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment))
5359
assert.Error(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment))
@@ -70,6 +76,11 @@ func TestServerGroupSpecValidateCount(t *testing.T) {
7076
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction))
7177
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction))
7278
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction))
79+
80+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(2), MinCount: util.NewInt(5), MaxCount: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
81+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(6), MaxCount: util.NewInt(5)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
82+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1), MinCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment))
83+
7384
}
7485

7586
func TestServerGroupSpecDefault(t *testing.T) {

pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/cluster_scaling_integration.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ func (ci *clusterScalingIntegration) inspectCluster(ctx context.Context, expectS
170170
if dbserversChanged {
171171
newSpec.DBServers.Count = util.NewInt(req.GetDBServers())
172172
}
173+
// Validate will additionally check if
174+
// min <= count <= max holds for the given server groups
173175
if err := newSpec.Validate(); err != nil {
174176
// Log failure & create event
175177
log.Warn().Err(err).Msg("Validation of updated spec has failed")

0 commit comments

Comments
 (0)