Skip to content

Commit 9f63e37

Browse files
committed
Rotate server on changed arguments
1 parent a924758 commit 9f63e37

File tree

5 files changed

+104
-19
lines changed

5 files changed

+104
-19
lines changed

pkg/deployment/context_impl.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,9 @@ func (d *Deployment) DeleteSecret(secretName string) error {
366366
}
367367
return nil
368368
}
369+
370+
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
371+
func (d *Deployment) GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
372+
agents api.MemberStatusList, id string) []string {
373+
return d.resources.GetExpectedPodArguments(apiObject, deplSpec, group, agents, id)
374+
}

pkg/deployment/reconcile/context.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
driver "github.com/arangodb/go-driver"
3030
"github.com/arangodb/go-driver/agency"
3131
"k8s.io/api/core/v1"
32+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3233

3334
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
3435
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
@@ -89,4 +90,7 @@ type Context interface {
8990
// DeleteSecret removes the Secret with given name.
9091
// If the secret does not exist, the error is ignored.
9192
DeleteSecret(secretName string) error
93+
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
94+
GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
95+
agents api.MemberStatusList, id string) []string
9296
}

pkg/deployment/reconcile/plan_builder.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
package reconcile
2424

2525
import (
26+
"strings"
27+
2628
"github.com/rs/zerolog"
2729
"github.com/rs/zerolog/log"
2830
"k8s.io/api/core/v1"
@@ -54,7 +56,8 @@ func (d *Reconciler) CreatePlan() error {
5456
apiObject := d.context.GetAPIObject()
5557
spec := d.context.GetSpec()
5658
status, lastVersion := d.context.GetStatus()
57-
newPlan, changed := createPlan(d.log, apiObject, status.Plan, spec, status, pods, d.context.GetTLSKeyfile, d.context.GetTLSCA, d.context.GetPvc, d.context.CreateEvent)
59+
ctx := newPlanBuilderContext(d.context)
60+
newPlan, changed := createPlan(d.log, apiObject, status.Plan, spec, status, pods, ctx)
5861

5962
// If not change, we're done
6063
if !changed {
@@ -79,10 +82,7 @@ func (d *Reconciler) CreatePlan() error {
7982
func createPlan(log zerolog.Logger, apiObject k8sutil.APIObject,
8083
currentPlan api.Plan, spec api.DeploymentSpec,
8184
status api.DeploymentStatus, pods []v1.Pod,
82-
getTLSKeyfile func(group api.ServerGroup, member api.MemberStatus) (string, error),
83-
getTLSCA func(string) (string, string, bool, error),
84-
getPVC func(pvcName string) (*v1.PersistentVolumeClaim, error),
85-
createEvent func(evt *k8sutil.Event)) (api.Plan, bool) {
85+
context PlanBuilderContext) (api.Plan, bool) {
8686
if len(currentPlan) > 0 {
8787
// Plan already exists, complete that first
8888
return currentPlan, false
@@ -165,7 +165,7 @@ func createPlan(log zerolog.Logger, apiObject k8sutil.APIObject,
165165
if decision.UpgradeNeeded && decision.UpgradeAllowed {
166166
plan = append(plan, createUpgradeMemberPlan(log, m, group, "Version upgrade")...)
167167
} else {
168-
rotNeeded, reason := podNeedsRotation(*p, apiObject, spec, group, status.Members.Agents, m.ID)
168+
rotNeeded, reason := podNeedsRotation(log, *p, apiObject, spec, group, status.Members.Agents, m.ID, context)
169169
if rotNeeded {
170170
plan = append(plan, createRotateMemberPlan(log, m, group, reason)...)
171171
}
@@ -179,17 +179,17 @@ func createPlan(log zerolog.Logger, apiObject k8sutil.APIObject,
179179

180180
// Check for the need to rotate TLS certificate of a members
181181
if len(plan) == 0 {
182-
plan = createRotateTLSServerCertificatePlan(log, spec, status, getTLSKeyfile)
182+
plan = createRotateTLSServerCertificatePlan(log, spec, status, context.GetTLSKeyfile)
183183
}
184184

185185
// Check for changes storage classes or requirements
186186
if len(plan) == 0 {
187-
plan = createRotateServerStoragePlan(log, apiObject, spec, status, getPVC, createEvent)
187+
plan = createRotateServerStoragePlan(log, apiObject, spec, status, context.GetPvc, context.CreateEvent)
188188
}
189189

190190
// Check for the need to rotate TLS CA certificate and all members
191191
if len(plan) == 0 {
192-
plan = createRotateTLSCAPlan(log, apiObject, spec, status, getTLSCA, createEvent)
192+
plan = createRotateTLSCAPlan(log, apiObject, spec, status, context.GetTLSCA, context.CreateEvent)
193193
}
194194

195195
// Return plan
@@ -241,12 +241,14 @@ func podNeedsUpgrading(p v1.Pod, spec api.DeploymentSpec, images api.ImageInfoLi
241241
// given pod differs from what it should be according to the
242242
// given deployment spec.
243243
// When true is returned, a reason for the rotation is already returned.
244-
func podNeedsRotation(p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec,
245-
group api.ServerGroup, agents api.MemberStatusList, id string) (bool, string) {
244+
func podNeedsRotation(log zerolog.Logger, p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec,
245+
group api.ServerGroup, agents api.MemberStatusList, id string,
246+
context PlanBuilderContext) (bool, string) {
246247
groupSpec := spec.GetServerGroupSpec(group)
247248

248249
// Check image pull policy
249-
if c, found := k8sutil.GetContainerByName(&p, k8sutil.ServerContainerName); found {
250+
c, found := k8sutil.GetContainerByName(&p, k8sutil.ServerContainerName)
251+
if found {
250252
if c.ImagePullPolicy != spec.GetImagePullPolicy() {
251253
return true, "Image pull policy changed"
252254
}
@@ -255,15 +257,15 @@ func podNeedsRotation(p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec
255257
}
256258

257259
// Check arguments
258-
/*expectedArgs := createArangodArgs(apiObject, spec, group, agents, id)
259-
if len(expectedArgs) != len(c.Args) {
260+
expectedArgs := strings.Join(context.GetExpectedPodArguments(apiObject, spec, group, agents, id), " ")
261+
actualArgs := strings.Join(getContainerArgs(c), " ")
262+
if expectedArgs != actualArgs {
263+
log.Debug().
264+
Str("actual-args", actualArgs).
265+
Str("expected-args", expectedArgs).
266+
Msg("Arguments changed. Rotation needed.")
260267
return true, "Arguments changed"
261268
}
262-
for i, a := range expectedArgs {
263-
if c.Args[i] != a {
264-
return true, "Arguments changed"
265-
}
266-
}*/
267269

268270
// Check service account
269271
if normalizeServiceAccountName(p.Spec.ServiceAccountName) != normalizeServiceAccountName(groupSpec.GetServiceAccountName()) {
@@ -352,3 +354,10 @@ func createUpgradeMemberPlan(log zerolog.Logger, member api.MemberStatus,
352354
}
353355
return plan
354356
}
357+
358+
func getContainerArgs(c v1.Container) []string {
359+
if len(c.Command) >= 1 {
360+
return c.Command[1:]
361+
}
362+
return c.Args
363+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 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 Ewout Prangsma
21+
//
22+
23+
package reconcile
24+
25+
import (
26+
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
27+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
28+
"k8s.io/api/core/v1"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+
)
31+
32+
// PlanBuilderContext contains context methods provided to plan builders.
33+
type PlanBuilderContext interface {
34+
// GetTLSKeyfile returns the keyfile encoded TLS certificate+key for
35+
// the given member.
36+
GetTLSKeyfile(group api.ServerGroup, member api.MemberStatus) (string, error)
37+
// GetTLSCA returns the TLS CA certificate in the secret with given name.
38+
// Returns: publicKey, privateKey, ownerByDeployment, error
39+
GetTLSCA(secretName string) (string, string, bool, error)
40+
// CreateEvent creates a given event.
41+
// On error, the error is logged.
42+
CreateEvent(evt *k8sutil.Event)
43+
// GetPvc gets a PVC by the given name, in the samespace of the deployment.
44+
GetPvc(pvcName string) (*v1.PersistentVolumeClaim, error)
45+
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
46+
GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
47+
agents api.MemberStatusList, id string) []string
48+
}
49+
50+
// newPlanBuilderContext creates a PlanBuilderContext from the given context
51+
func newPlanBuilderContext(ctx Context) PlanBuilderContext {
52+
return ctx
53+
}

pkg/deployment/resources/pod_inspector.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,16 @@ func (r *Resources) InspectPods(ctx context.Context) error {
247247
}
248248
return nil
249249
}
250+
251+
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
252+
func (r *Resources) GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
253+
agents api.MemberStatusList, id string) []string {
254+
if group.IsArangod() {
255+
return createArangodArgs(apiObject, deplSpec, group, agents, id, false)
256+
}
257+
if group.IsArangosync() {
258+
groupSpec := deplSpec.GetServerGroupSpec(group)
259+
return createArangoSyncArgs(apiObject, deplSpec, group, groupSpec, agents, id)
260+
}
261+
return nil
262+
}

0 commit comments

Comments
 (0)