Skip to content

Commit 137f768

Browse files
authored
[Feature] Change Rotation by Annotation order (#608)
1 parent 12c810a commit 137f768

File tree

4 files changed

+159
-18
lines changed

4 files changed

+159
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
44
- Add Labels and Annotations to ServiceMonitor
55
- Allow to expose Exporter in HTTP with secured Deployments
6+
- Change rotation by annotation order (coordinator before dbserver)
67

78
## [1.0.4](https://github.com/arangodb/kube-arangodb/tree/1.0.4) (2020-07-28)
89
- Add Encryption Key rotation feature for ArangoDB EE 3.7+

pkg/apis/deployment/v1/deployment_status_members.go

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,45 @@ func (ds DeploymentStatusMembers) ElementByID(id string) (MemberStatus, ServerGr
8484
// If the callback returns an error, this error is returned and the callback is
8585
// not called for the remaining groups.
8686
func (ds DeploymentStatusMembers) ForeachServerGroup(cb func(group ServerGroup, list MemberStatusList) error) error {
87-
if err := cb(ServerGroupSingle, ds.Single); err != nil {
88-
return maskAny(err)
89-
}
90-
if err := cb(ServerGroupAgents, ds.Agents); err != nil {
91-
return maskAny(err)
92-
}
93-
if err := cb(ServerGroupDBServers, ds.DBServers); err != nil {
94-
return maskAny(err)
95-
}
96-
if err := cb(ServerGroupCoordinators, ds.Coordinators); err != nil {
97-
return maskAny(err)
98-
}
99-
if err := cb(ServerGroupSyncMasters, ds.SyncMasters); err != nil {
100-
return maskAny(err)
87+
return ds.ForeachServerInGroups(cb, AllServerGroups...)
88+
}
89+
90+
func (ds DeploymentStatusMembers) ForeachServerInGroups(cb func(group ServerGroup, list MemberStatusList) error, groups ...ServerGroup) error {
91+
for _, group := range groups {
92+
if err := ds.ForServerGroup(cb, group); err != nil {
93+
return err
94+
}
10195
}
102-
if err := cb(ServerGroupSyncWorkers, ds.SyncWorkers); err != nil {
103-
return maskAny(err)
96+
97+
return nil
98+
}
99+
100+
func (ds DeploymentStatusMembers) ForServerGroup(cb func(group ServerGroup, list MemberStatusList) error, group ServerGroup) error {
101+
switch group {
102+
case ServerGroupSingle:
103+
if err := cb(ServerGroupSingle, ds.Single); err != nil {
104+
return maskAny(err)
105+
}
106+
case ServerGroupAgents:
107+
if err := cb(ServerGroupAgents, ds.Agents); err != nil {
108+
return maskAny(err)
109+
}
110+
case ServerGroupDBServers:
111+
if err := cb(ServerGroupDBServers, ds.DBServers); err != nil {
112+
return maskAny(err)
113+
}
114+
case ServerGroupCoordinators:
115+
if err := cb(ServerGroupCoordinators, ds.Coordinators); err != nil {
116+
return maskAny(err)
117+
}
118+
case ServerGroupSyncMasters:
119+
if err := cb(ServerGroupSyncMasters, ds.SyncMasters); err != nil {
120+
return maskAny(err)
121+
}
122+
case ServerGroupSyncWorkers:
123+
if err := cb(ServerGroupSyncWorkers, ds.SyncWorkers); err != nil {
124+
return maskAny(err)
125+
}
104126
}
105127
return nil
106128
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Adam Janikowski
21+
//
22+
23+
package v1
24+
25+
import (
26+
"testing"
27+
28+
"github.com/stretchr/testify/require"
29+
)
30+
31+
func newMemberList() DeploymentStatusMembers {
32+
return DeploymentStatusMembers{
33+
Single: MemberStatusList{{ID: ServerGroupSingle.AsRole()}},
34+
Agents: MemberStatusList{{ID: ServerGroupAgents.AsRole()}},
35+
DBServers: MemberStatusList{{ID: ServerGroupDBServers.AsRole()}},
36+
Coordinators: MemberStatusList{{ID: ServerGroupCoordinators.AsRole()}},
37+
SyncMasters: MemberStatusList{{ID: ServerGroupSyncMasters.AsRole()}},
38+
SyncWorkers: MemberStatusList{{ID: ServerGroupSyncWorkers.AsRole()}},
39+
}
40+
}
41+
42+
func Test_StatusMemberList_EnsureDefaultExecutionOrder(t *testing.T) {
43+
statusMembers := newMemberList()
44+
45+
order := AllServerGroups
46+
47+
orderIndex := 0
48+
49+
statusMembers.ForeachServerGroup(func(group ServerGroup, list MemberStatusList) error {
50+
require.True(t, orderIndex < len(order))
51+
52+
require.Equal(t, order[orderIndex], group)
53+
54+
require.Len(t, list, 1)
55+
56+
require.Equal(t, order[orderIndex].AsRole(), list[0].ID)
57+
58+
orderIndex += 1
59+
60+
return nil
61+
})
62+
}
63+
64+
func Test_StatusMemberList_CustomExecutionOrder(t *testing.T) {
65+
statusMembers := newMemberList()
66+
67+
order := []ServerGroup{
68+
ServerGroupDBServers,
69+
}
70+
71+
orderIndex := 0
72+
73+
statusMembers.ForeachServerInGroups(func(group ServerGroup, list MemberStatusList) error {
74+
require.True(t, orderIndex < len(order))
75+
76+
require.Equal(t, order[orderIndex], group)
77+
78+
require.Len(t, list, 1)
79+
80+
require.Equal(t, order[orderIndex].AsRole(), list[0].ID)
81+
82+
orderIndex += 1
83+
84+
return nil
85+
}, order...)
86+
}

pkg/deployment/reconcile/plan_builder_rotate_upgrade.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,19 @@ import (
3737
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3838
)
3939

40-
// createRotateOrUpgradePlan goes over all pods to check if an upgrade or rotate is needed.
40+
var (
41+
// rotationByAnnotationOrder - Change order of execution - Coordinators and Agents should be executed before DBServer to save time
42+
rotationByAnnotationOrder = []api.ServerGroup{
43+
api.ServerGroupSingle,
44+
api.ServerGroupAgents,
45+
api.ServerGroupCoordinators,
46+
api.ServerGroupDBServers,
47+
api.ServerGroupSyncMasters,
48+
api.ServerGroupSyncWorkers,
49+
}
50+
)
4151

52+
// createRotateOrUpgradePlan goes over all pods to check if an upgrade or rotate is needed.
4253
func createRotateOrUpgradePlan(ctx context.Context,
4354
log zerolog.Logger, apiObject k8sutil.APIObject,
4455
spec api.DeploymentSpec, status api.DeploymentStatus,
@@ -109,15 +120,36 @@ func createRotateOrUpgradePlanInternal(log zerolog.Logger, apiObject k8sutil.API
109120
// Only rotate/upgrade 1 pod at a time
110121
continue
111122
}
123+
}
124+
return nil
125+
})
126+
127+
status.Members.ForeachServerInGroups(func(group api.ServerGroup, members api.MemberStatusList) error {
128+
for _, m := range members {
129+
if m.Phase != api.MemberPhaseCreated || m.PodName == "" {
130+
// Only rotate when phase is created
131+
continue
132+
}
133+
134+
if !newPlan.IsEmpty() {
135+
// Only rotate/upgrade 1 pod at a time
136+
continue
137+
}
138+
139+
pod, found := cachedStatus.Pod(m.PodName)
140+
if !found {
141+
continue
142+
}
112143

113144
if pod.Annotations != nil {
114145
if _, ok := pod.Annotations[deployment.ArangoDeploymentPodRotateAnnotation]; ok {
115146
newPlan = createRotateMemberPlan(log, m, group, "Rotation flag present")
116147
}
117148
}
118149
}
150+
119151
return nil
120-
})
152+
}, rotationByAnnotationOrder...)
121153

122154
if upgradeNotAllowed {
123155
context.CreateEvent(k8sutil.NewUpgradeNotAllowedEvent(apiObject, fromVersion, toVersion, fromLicense, toLicense))

0 commit comments

Comments
 (0)