From 525ff0ee4e52ce6bc5fc1abec1144cdad5e410ea Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Wed, 16 Feb 2022 11:07:10 +0000 Subject: [PATCH] [Bugfix] Add grecefulness to kill action --- CHANGELOG.md | 1 + pkg/deployment/actions/wrapper.go | 70 +++++++++++++++++++ pkg/deployment/reconcile/action.go | 42 ++++++++--- pkg/deployment/reconcile/action_add_member.go | 5 +- .../reconcile/action_rotate_member.go | 6 +- .../reconcile/action_rotate_start_member.go | 4 +- .../reconcile/action_shutdown_member.go | 4 +- pkg/deployment/reconcile/action_test.go | 56 +++++++++++++++ pkg/deployment/reconcile/helper_wrap.go | 17 ++--- .../reconcile/plan_builder_bootstrap.go | 5 +- .../reconcile/plan_builder_clean_out.go | 5 +- .../reconcile/plan_builder_cluster.go | 6 +- .../reconcile/plan_builder_common.go | 7 +- .../reconcile/plan_builder_encryption.go | 13 ++-- pkg/deployment/reconcile/plan_builder_high.go | 19 ++--- pkg/deployment/reconcile/plan_builder_jwt.go | 25 +++---- .../reconcile/plan_builder_license.go | 3 +- .../reconcile/plan_builder_normal.go | 17 ++--- .../reconcile/plan_builder_restore.go | 9 +-- .../reconcile/plan_builder_rotate_upgrade.go | 19 ++--- .../reconcile/plan_builder_scale.go | 11 +-- .../reconcile/plan_builder_storage.go | 21 +++--- pkg/deployment/reconcile/plan_builder_test.go | 37 +++++----- pkg/deployment/reconcile/plan_builder_tls.go | 20 +++--- .../reconcile/plan_builder_tls_sni.go | 6 +- .../reconcile/plan_builder_utils.go | 19 ++--- pkg/deployment/reconcile/utils.go | 16 ++--- .../rotation/arangod_containers_test.go | 7 +- pkg/deployment/rotation/compare.go | 3 +- 29 files changed, 320 insertions(+), 153 deletions(-) create mode 100644 pkg/deployment/actions/wrapper.go create mode 100644 pkg/deployment/reconcile/action_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 82eaad3e2..f1233d4bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - (Feature) Allow to disable external port (sidecar managed connection) - (Bugfix) Fix 3.6 -> 3.7 Upgrade procedure - (Bugfix) Add missing finalizer +- (Bugfix) Add graceful to kill command ## [1.2.7](https://github.com/arangodb/kube-arangodb/tree/1.2.7) (2022-01-17) - Add Plan BackOff functionality diff --git a/pkg/deployment/actions/wrapper.go b/pkg/deployment/actions/wrapper.go new file mode 100644 index 000000000..d6cb6fb35 --- /dev/null +++ b/pkg/deployment/actions/wrapper.go @@ -0,0 +1,70 @@ +// +// DISCLAIMER +// +// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package actions + +import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + +func NewAction(actionType api.ActionType, group api.ServerGroup, member api.MemberStatus, reason ...string) api.Action { + return actionWrap(api.NewAction(actionType, group, member.ID, reason...), &member, actionWrapMemberUID) +} + +func NewClusterAction(actionType api.ActionType, reason ...string) api.Action { + m := api.MemberStatus{} + return NewAction(actionType, api.ServerGroupUnknown, m, reason...) +} + +func NewActionBuilderWrap(group api.ServerGroup, member api.MemberStatus) api.ActionBuilder { + return &actionBuilderWrap{ + group: group, + member: member, + } +} + +type actionBuilderWrap struct { + group api.ServerGroup + member api.MemberStatus +} + +func (a actionBuilderWrap) NewAction(actionType api.ActionType, reason ...string) api.Action { + return NewAction(actionType, a.group, a.member, reason...) +} + +func actionWrap(a api.Action, member *api.MemberStatus, wrap ...actionWrapper) api.Action { + for _, w := range wrap { + a = w(a, member) + } + + return a +} + +func actionWrapMemberUID(a api.Action, member *api.MemberStatus) api.Action { + switch a.Type { + case api.ActionTypeShutdownMember, api.ActionTypeKillMemberPod, api.ActionTypeRotateStartMember, api.ActionTypeUpgradeMember: + if q := member.PodUID; q != "" { + return a.AddParam(api.ParamPodUID, string(q)) + } + return a + default: + return a + } +} + +type actionWrapper func(a api.Action, member *api.MemberStatus) api.Action diff --git a/pkg/deployment/reconcile/action.go b/pkg/deployment/reconcile/action.go index e0891b70b..552fb7784 100644 --- a/pkg/deployment/reconcile/action.go +++ b/pkg/deployment/reconcile/action.go @@ -91,6 +91,30 @@ type ActionStartFailureGracePeriod interface { StartFailureGracePeriod() time.Duration } +func wrapActionStartFailureGracePeriod(action Action, failureGracePeriod time.Duration) Action { + return &actionStartFailureGracePeriod{ + Action: action, + failureGracePeriod: failureGracePeriod, + } +} + +func withActionStartFailureGracePeriod(in actionFactory, failureGracePeriod time.Duration) actionFactory { + return func(log zerolog.Logger, action api.Action, actionCtx ActionContext) Action { + return wrapActionStartFailureGracePeriod(in(log, action, actionCtx), failureGracePeriod) + } +} + +var _ ActionStartFailureGracePeriod = &actionStartFailureGracePeriod{} + +type actionStartFailureGracePeriod struct { + Action + failureGracePeriod time.Duration +} + +func (a actionStartFailureGracePeriod) StartFailureGracePeriod() time.Duration { + return a.failureGracePeriod +} + func getStartFailureGracePeriod(a Action) time.Duration { if c, ok := a.(ActionStartFailureGracePeriod); !ok { return 0 @@ -118,27 +142,27 @@ func getActionPlanAppender(a Action, plan api.Plan) (api.Plan, bool) { type actionFactory func(log zerolog.Logger, action api.Action, actionCtx ActionContext) Action var ( - actions = map[api.ActionType]actionFactory{} - actionsLock sync.Mutex + definedActions = map[api.ActionType]actionFactory{} + definedActionsLock sync.Mutex ) func registerAction(t api.ActionType, f actionFactory) { - actionsLock.Lock() - defer actionsLock.Unlock() + definedActionsLock.Lock() + defer definedActionsLock.Unlock() - _, ok := actions[t] + _, ok := definedActions[t] if ok { panic(fmt.Sprintf("Action already defined %s", t)) } - actions[t] = f + definedActions[t] = f } func getActionFactory(t api.ActionType) (actionFactory, bool) { - actionsLock.Lock() - defer actionsLock.Unlock() + definedActionsLock.Lock() + defer definedActionsLock.Unlock() - f, ok := actions[t] + f, ok := definedActions[t] return f, ok } diff --git a/pkg/deployment/reconcile/action_add_member.go b/pkg/deployment/reconcile/action_add_member.go index bf93e7766..150701fea 100644 --- a/pkg/deployment/reconcile/action_add_member.go +++ b/pkg/deployment/reconcile/action_add_member.go @@ -29,6 +29,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/errors" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) @@ -81,11 +82,11 @@ func (a *actionAddMember) ActionPlanAppender(current api.Plan) (api.Plan, bool) var app api.Plan if _, ok := a.action.Params[api.ActionTypeWaitForMemberUp.String()]; ok { - app = append(app, api.NewAction(api.ActionTypeWaitForMemberUp, a.action.Group, a.newMemberID, "Wait for member in sync after creation")) + app = append(app, actions.NewAction(api.ActionTypeWaitForMemberUp, a.action.Group, withPredefinedMember(a.newMemberID), "Wait for member in sync after creation")) } if _, ok := a.action.Params[api.ActionTypeWaitForMemberInSync.String()]; ok { - app = append(app, api.NewAction(api.ActionTypeWaitForMemberInSync, a.action.Group, a.newMemberID, "Wait for member in sync after creation")) + app = append(app, actions.NewAction(api.ActionTypeWaitForMemberInSync, a.action.Group, withPredefinedMember(a.newMemberID), "Wait for member in sync after creation")) } if len(app) > 0 { diff --git a/pkg/deployment/reconcile/action_rotate_member.go b/pkg/deployment/reconcile/action_rotate_member.go index 096b1b536..d50855518 100644 --- a/pkg/deployment/reconcile/action_rotate_member.go +++ b/pkg/deployment/reconcile/action_rotate_member.go @@ -34,7 +34,7 @@ import ( ) func init() { - registerAction(api.ActionTypeRotateMember, newRotateMemberAction) + registerAction(api.ActionTypeRotateMember, withActionStartFailureGracePeriod(newRotateMemberAction, time.Minute)) } // newRotateMemberAction creates a new Action that implements the given @@ -109,7 +109,3 @@ func (a *actionRotateMember) CheckProgress(ctx context.Context) (bool, bool, err } return true, false, nil } - -func (a *actionRotateMember) StartFailureGracePeriod() time.Duration { - return 30 * time.Second -} diff --git a/pkg/deployment/reconcile/action_rotate_start_member.go b/pkg/deployment/reconcile/action_rotate_start_member.go index 73d861acd..9551ee2d6 100644 --- a/pkg/deployment/reconcile/action_rotate_start_member.go +++ b/pkg/deployment/reconcile/action_rotate_start_member.go @@ -26,13 +26,15 @@ import ( "github.com/rs/zerolog" meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "time" + api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) func init() { - registerAction(api.ActionTypeRotateStartMember, newRotateStartMemberAction) + registerAction(api.ActionTypeRotateStartMember, withActionStartFailureGracePeriod(newRotateStartMemberAction, time.Minute)) } // newRotateStartMemberAction creates a new Action that implements the given diff --git a/pkg/deployment/reconcile/action_shutdown_member.go b/pkg/deployment/reconcile/action_shutdown_member.go index 4d1ac4de6..604094641 100644 --- a/pkg/deployment/reconcile/action_shutdown_member.go +++ b/pkg/deployment/reconcile/action_shutdown_member.go @@ -25,12 +25,14 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/errors" + "time" + api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" "github.com/rs/zerolog" ) func init() { - registerAction(api.ActionTypeShutdownMember, newShutdownMemberAction) + registerAction(api.ActionTypeShutdownMember, withActionStartFailureGracePeriod(newShutdownMemberAction, time.Minute)) } // newShutdownMemberAction creates a new Action that implements the given diff --git a/pkg/deployment/reconcile/action_test.go b/pkg/deployment/reconcile/action_test.go new file mode 100644 index 000000000..04f7e9883 --- /dev/null +++ b/pkg/deployment/reconcile/action_test.go @@ -0,0 +1,56 @@ +// +// DISCLAIMER +// +// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package reconcile + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +type gracefulAction struct { + actionEmpty + + graceful time.Duration +} + +func (g gracefulAction) StartFailureGracePeriod() time.Duration { + return g.graceful +} + +var _ ActionStartFailureGracePeriod = gracefulAction{} + +func Test_GracefulTimeouts(t *testing.T) { + t.Run("Default", func(t *testing.T) { + require.EqualValues(t, 0, getStartFailureGracePeriod(actionEmpty{})) + }) + t.Run("Set", func(t *testing.T) { + require.EqualValues(t, time.Second, getStartFailureGracePeriod(gracefulAction{ + graceful: time.Second, + })) + }) + t.Run("Override", func(t *testing.T) { + require.EqualValues(t, time.Minute, getStartFailureGracePeriod(wrapActionStartFailureGracePeriod(gracefulAction{ + graceful: time.Second, + }, time.Minute))) + }) +} diff --git a/pkg/deployment/reconcile/helper_wrap.go b/pkg/deployment/reconcile/helper_wrap.go index 67066054a..0db9289b7 100644 --- a/pkg/deployment/reconcile/helper_wrap.go +++ b/pkg/deployment/reconcile/helper_wrap.go @@ -22,6 +22,7 @@ package reconcile import ( api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/features" ) @@ -30,7 +31,7 @@ func withMaintenance(plan ...api.Action) api.Plan { return plan } - return withMaintenanceStart(plan...).After(api.NewAction(api.ActionTypeDisableMaintenance, api.ServerGroupUnknown, "", "Disable maintenance after actions")) + return withMaintenanceStart(plan...).After(actions.NewClusterAction(api.ActionTypeDisableMaintenance, "Disable maintenance after actions")) } func withMaintenanceStart(plan ...api.Action) api.Plan { if !features.Maintenance().Enabled() { @@ -38,8 +39,8 @@ func withMaintenanceStart(plan ...api.Action) api.Plan { } return api.AsPlan(plan).Before( - api.NewAction(api.ActionTypeEnableMaintenance, api.ServerGroupUnknown, "", "Enable maintenance before actions"), - api.NewAction(api.ActionTypeSetMaintenanceCondition, api.ServerGroupUnknown, "", "Enable maintenance before actions")) + actions.NewClusterAction(api.ActionTypeEnableMaintenance, "Enable maintenance before actions"), + actions.NewClusterAction(api.ActionTypeSetMaintenanceCondition, "Enable maintenance before actions")) } func withResignLeadership(group api.ServerGroup, member api.MemberStatus, reason string, plan ...api.Action) api.Plan { @@ -47,7 +48,7 @@ func withResignLeadership(group api.ServerGroup, member api.MemberStatus, reason return plan } - return api.AsPlan(plan).Before(api.NewAction(api.ActionTypeResignLeadership, group, member.ID, reason)) + return api.AsPlan(plan).Before(actions.NewAction(api.ActionTypeResignLeadership, group, member, reason)) } func cleanOutMember(group api.ServerGroup, m api.MemberStatus) api.Plan { @@ -55,13 +56,13 @@ func cleanOutMember(group api.ServerGroup, m api.MemberStatus) api.Plan { if group == api.ServerGroupDBServers { plan = append(plan, - api.NewAction(api.ActionTypeCleanOutMember, group, m.ID), + actions.NewAction(api.ActionTypeCleanOutMember, group, m), ) } plan = append(plan, - api.NewAction(api.ActionTypeKillMemberPod, group, m.ID), - api.NewAction(api.ActionTypeShutdownMember, group, m.ID), - api.NewAction(api.ActionTypeRemoveMember, group, m.ID), + actions.NewAction(api.ActionTypeKillMemberPod, group, m), + actions.NewAction(api.ActionTypeShutdownMember, group, m), + actions.NewAction(api.ActionTypeRemoveMember, group, m), ) return plan diff --git a/pkg/deployment/reconcile/plan_builder_bootstrap.go b/pkg/deployment/reconcile/plan_builder_bootstrap.go index ce3211736..32b23cf29 100644 --- a/pkg/deployment/reconcile/plan_builder_bootstrap.go +++ b/pkg/deployment/reconcile/plan_builder_bootstrap.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -54,8 +55,8 @@ func createBootstrapPlan(ctx context.Context, } } - return api.Plan{api.NewAction(api.ActionTypeBootstrapSetPassword, api.ServerGroupUnknown, "", "Updating password").AddParam("user", user)} + return api.Plan{actions.NewClusterAction(api.ActionTypeBootstrapSetPassword, "Updating password").AddParam("user", user)} } - return api.Plan{api.NewAction(api.ActionTypeBootstrapUpdate, api.ServerGroupUnknown, "", "Finalizing bootstrap")} + return api.Plan{actions.NewClusterAction(api.ActionTypeBootstrapUpdate, "Finalizing bootstrap")} } diff --git a/pkg/deployment/reconcile/plan_builder_clean_out.go b/pkg/deployment/reconcile/plan_builder_clean_out.go index 11dca10bd..49e5a8a68 100644 --- a/pkg/deployment/reconcile/plan_builder_clean_out.go +++ b/pkg/deployment/reconcile/plan_builder_clean_out.go @@ -26,10 +26,11 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/globals" - "github.com/arangodb/go-driver" "github.com/rs/zerolog" + "github.com/arangodb/go-driver" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" ) @@ -84,7 +85,7 @@ func createCleanOutPlan(ctx context.Context, log zerolog.Logger, _ k8sutil.APIOb Str("id", string(id)). Msgf("server is cleaned out so operator must do the same") - action := api.NewAction(api.ActionTypeSetMemberCondition, api.ServerGroupDBServers, string(id), + action := actions.NewAction(api.ActionTypeSetMemberCondition, api.ServerGroupDBServers, withPredefinedMember(string(id)), "server is cleaned out so operator must do the same"). AddParam(string(api.ConditionTypeCleanedOut), strconv.FormatBool(true)) diff --git a/pkg/deployment/reconcile/plan_builder_cluster.go b/pkg/deployment/reconcile/plan_builder_cluster.go index 22d68ce69..4190eae7e 100644 --- a/pkg/deployment/reconcile/plan_builder_cluster.go +++ b/pkg/deployment/reconcile/plan_builder_cluster.go @@ -27,8 +27,8 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/globals" "github.com/arangodb/go-driver" - api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -91,7 +91,7 @@ func createClusterOperationPlan(ctx context.Context, if member.LastHeartbeatAcked.Add(coordinatorHealthFailedTimeout).Before(time.Now()) { return api.Plan{ - api.NewAction(api.ActionTypeClusterMemberCleanup, api.ServerGroupCoordinators, string(id)), + actions.NewAction(api.ActionTypeClusterMemberCleanup, api.ServerGroupCoordinators, withPredefinedMember(string(id))), } } case driver.ServerRoleDBServer: @@ -104,7 +104,7 @@ func createClusterOperationPlan(ctx context.Context, } return api.Plan{ - api.NewAction(api.ActionTypeClusterMemberCleanup, api.ServerGroupDBServers, string(id)), + actions.NewAction(api.ActionTypeClusterMemberCleanup, api.ServerGroupDBServers, withPredefinedMember(string(id))), } } } diff --git a/pkg/deployment/reconcile/plan_builder_common.go b/pkg/deployment/reconcile/plan_builder_common.go index 644392e83..76d1d5ad0 100644 --- a/pkg/deployment/reconcile/plan_builder_common.go +++ b/pkg/deployment/reconcile/plan_builder_common.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" @@ -53,18 +54,18 @@ func createMaintenanceManagementPlan(ctx context.Context, if !enabled && spec.Database.GetMaintenance() { log.Info().Msgf("Enabling maintenance mode") - return api.Plan{api.NewAction(api.ActionTypeEnableMaintenance, api.ServerGroupUnknown, ""), api.NewAction(api.ActionTypeSetMaintenanceCondition, api.ServerGroupUnknown, "")} + return api.Plan{actions.NewClusterAction(api.ActionTypeEnableMaintenance), actions.NewClusterAction(api.ActionTypeSetMaintenanceCondition)} } if enabled && !spec.Database.GetMaintenance() { log.Info().Msgf("Disabling maintenance mode") - return api.Plan{api.NewAction(api.ActionTypeDisableMaintenance, api.ServerGroupUnknown, ""), api.NewAction(api.ActionTypeSetMaintenanceCondition, api.ServerGroupUnknown, "")} + return api.Plan{actions.NewClusterAction(api.ActionTypeDisableMaintenance), actions.NewClusterAction(api.ActionTypeSetMaintenanceCondition)} } condition, ok := status.Conditions.Get(api.ConditionTypeMaintenanceMode) if enabled != (ok && condition.IsTrue()) { - return api.Plan{api.NewAction(api.ActionTypeSetMaintenanceCondition, api.ServerGroupUnknown, "")} + return api.Plan{actions.NewClusterAction(api.ActionTypeSetMaintenanceCondition)} } return nil diff --git a/pkg/deployment/reconcile/plan_builder_encryption.go b/pkg/deployment/reconcile/plan_builder_encryption.go index cf3eaa56d..082392146 100644 --- a/pkg/deployment/reconcile/plan_builder_encryption.go +++ b/pkg/deployment/reconcile/plan_builder_encryption.go @@ -37,6 +37,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/deployment/pod" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/rs/zerolog" ) @@ -82,7 +83,7 @@ func createEncryptionKeyStatusPropagatedFieldUpdate(ctx context.Context, if status.Hashes.Encryption.Propagated { plan = append(api.Plan{ - api.NewAction(api.ActionTypeEncryptionKeyPropagated, api.ServerGroupUnknown, "", "Change propagated flag to false").AddParam(propagated, conditionFalse), + actions.NewClusterAction(api.ActionTypeEncryptionKeyPropagated, "Change propagated flag to false").AddParam(propagated, conditionFalse), }, plan...) } @@ -125,7 +126,7 @@ func createEncryptionKey(ctx context.Context, if status.Hashes.Encryption.Propagated { _, ok := keyfolder.Data[name] if !ok { - return api.Plan{api.NewAction(api.ActionTypeEncryptionKeyAdd, api.ServerGroupUnknown, "")} + return api.Plan{actions.NewClusterAction(api.ActionTypeEncryptionKeyAdd)} } } @@ -136,7 +137,7 @@ func createEncryptionKey(ctx context.Context, if !failed && !status.Hashes.Encryption.Propagated { return api.Plan{ - api.NewAction(api.ActionTypeEncryptionKeyPropagated, api.ServerGroupUnknown, "", "Change propagated flag to true").AddParam(propagated, conditionTrue), + actions.NewClusterAction(api.ActionTypeEncryptionKeyPropagated, "Change propagated flag to true").AddParam(propagated, conditionTrue), } } @@ -152,7 +153,7 @@ func createEncryptionKeyStatusUpdate(ctx context.Context, } if createEncryptionKeyStatusUpdateRequired(log, spec, status, cachedStatus, context) { - return api.Plan{api.NewAction(api.ActionTypeEncryptionKeyStatusUpdate, api.ServerGroupUnknown, "")} + return api.Plan{actions.NewClusterAction(api.ActionTypeEncryptionKeyStatusUpdate)} } return nil @@ -221,7 +222,7 @@ func createEncryptionKeyCleanPlan(ctx context.Context, for key := range keyfolder.Data { if key != name { - plan = append(plan, api.NewAction(api.ActionTypeEncryptionKeyRemove, api.ServerGroupUnknown, "").AddParam("key", key)) + plan = append(plan, actions.NewClusterAction(api.ActionTypeEncryptionKeyRemove).AddParam("key", key)) } } @@ -245,7 +246,7 @@ func areEncryptionKeysUpToDate(ctx context.Context, log zerolog.Logger, spec api failed = true continue } else if updateRequired { - plan = append(plan, api.NewAction(api.ActionTypeEncryptionKeyRefresh, group, m.ID)) + plan = append(plan, actions.NewAction(api.ActionTypeEncryptionKeyRefresh, group, withPredefinedMember(m.ID))) continue } } diff --git a/pkg/deployment/reconcile/plan_builder_high.go b/pkg/deployment/reconcile/plan_builder_high.go index 4232772b0..eccf1bec2 100644 --- a/pkg/deployment/reconcile/plan_builder_high.go +++ b/pkg/deployment/reconcile/plan_builder_high.go @@ -27,6 +27,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/deployment/rotation" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -73,7 +74,7 @@ func updateMemberPodTemplateSpec(ctx context.Context, for _, m := range members { if m.Phase != api.MemberPhaseNone { if reason, changed := arangoMemberPodTemplateNeedsUpdate(ctx, log, apiObject, spec, group, status, m, cachedStatus, context); changed { - plan = append(plan, api.NewAction(api.ActionTypeArangoMemberUpdatePodSpec, group, m.ID, reason)) + plan = append(plan, actions.NewAction(api.ActionTypeArangoMemberUpdatePodSpec, group, m, reason)) } } } @@ -97,10 +98,10 @@ func updateMemberPhasePlan(ctx context.Context, var p api.Plan p = append(p, - api.NewAction(api.ActionTypeArangoMemberUpdatePodSpec, group, m.ID, "Propagating spec of pod"), - api.NewAction(api.ActionTypeArangoMemberUpdatePodStatus, group, m.ID, "Propagating status of pod")) + actions.NewAction(api.ActionTypeArangoMemberUpdatePodSpec, group, m, "Propagating spec of pod"), + actions.NewAction(api.ActionTypeArangoMemberUpdatePodStatus, group, m, "Propagating status of pod")) - p = append(p, api.NewAction(api.ActionTypeMemberPhaseUpdate, group, m.ID, + p = append(p, actions.NewAction(api.ActionTypeMemberPhaseUpdate, group, m, "Move to Pending phase").AddParam(actionTypeMemberPhaseUpdatePhaseKey, api.MemberPhasePending.String())) plan = append(plan, p...) @@ -114,7 +115,7 @@ func updateMemberPhasePlan(ctx context.Context, } func pendingRestartMemberConditionAction(group api.ServerGroup, memberID string, reason string) api.Action { - return api.NewAction(api.ActionTypeSetMemberCondition, group, memberID, reason).AddParam(api.ConditionTypePendingRestart.String(), "T") + return actions.NewAction(api.ActionTypeSetMemberCondition, group, withPredefinedMember(memberID), reason).AddParam(api.ConditionTypePendingRestart.String(), "T") } func restartMemberConditionAction(group api.ServerGroup, memberID string, reason string) api.Action { @@ -122,7 +123,7 @@ func restartMemberConditionAction(group api.ServerGroup, memberID string, reason } func tlsRotateConditionAction(group api.ServerGroup, memberID string, reason string) api.Action { - return api.NewAction(api.ActionTypeSetMemberCondition, group, memberID, reason).AddParam(api.ConditionTypePendingTLSRotation.String(), "T") + return actions.NewAction(api.ActionTypeSetMemberCondition, group, withPredefinedMember(memberID), reason).AddParam(api.ConditionTypePendingTLSRotation.String(), "T") } func updateMemberUpdateConditionsPlan(ctx context.Context, @@ -138,7 +139,7 @@ func updateMemberUpdateConditionsPlan(ctx context.Context, if status.Plan.IsEmpty() { // If plan is empty then something went wrong plan = append(plan, - api.NewAction(api.ActionTypeSetMemberCondition, group, m.ID, "Clean update actions after failure"). + actions.NewAction(api.ActionTypeSetMemberCondition, group, m, "Clean update actions after failure"). AddParam(api.ConditionTypePendingUpdate.String(), ""). AddParam(api.ConditionTypeUpdating.String(), ""). AddParam(api.ConditionTypeUpdateFailed.String(), "T"). @@ -218,10 +219,10 @@ func updateMemberRotationConditions(log zerolog.Logger, apiObject k8sutil.APIObj } else if member.Conditions.IsTrue(api.ConditionTypeUpdating) || member.Conditions.IsTrue(api.ConditionTypePendingUpdate) { return nil, nil } - return api.Plan{api.NewAction(api.ActionTypeSetMemberCondition, group, member.ID, reason).AddParam(api.ConditionTypePendingUpdate.String(), "T")}, nil + return api.Plan{actions.NewAction(api.ActionTypeSetMemberCondition, group, member, reason).AddParam(api.ConditionTypePendingUpdate.String(), "T")}, nil case rotation.SilentRotation: // Propagate changes without restart - return api.Plan{api.NewAction(api.ActionTypeArangoMemberUpdatePodStatus, group, member.ID, "Propagating status of pod").AddParam(ActionTypeArangoMemberUpdatePodStatusChecksum, arangoMember.Spec.Template.GetChecksum())}, nil + return api.Plan{actions.NewAction(api.ActionTypeArangoMemberUpdatePodStatus, group, member, "Propagating status of pod").AddParam(ActionTypeArangoMemberUpdatePodStatusChecksum, arangoMember.Spec.Template.GetChecksum())}, nil case rotation.GracefulRotation: if reason != "" { log.Info().Bool("enforced", false).Msgf(reason) diff --git a/pkg/deployment/reconcile/plan_builder_jwt.go b/pkg/deployment/reconcile/plan_builder_jwt.go index af20edcb5..41846f0c9 100644 --- a/pkg/deployment/reconcile/plan_builder_jwt.go +++ b/pkg/deployment/reconcile/plan_builder_jwt.go @@ -37,6 +37,7 @@ import ( core "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/pod" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/constants" @@ -73,17 +74,17 @@ func createJWTKeyUpdate(ctx context.Context, jwtSha := util.SHA256(jwt) if _, ok := folder.Data[jwtSha]; !ok { - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTAdd, api.ServerGroupUnknown, "", "Add JWTRotation key").AddParam(checksum, jwtSha)) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTAdd, "Add JWTRotation key").AddParam(checksum, jwtSha)) } activeKey, ok := folder.Data[pod.ActiveJWTKey] if !ok { - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTSetActive, api.ServerGroupUnknown, "", "Set active key").AddParam(checksum, jwtSha)) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTSetActive, "Set active key").AddParam(checksum, jwtSha)) } tokenKey, ok := folder.Data[constants.SecretKeyToken] if !ok || util.SHA256(activeKey) != util.SHA256(tokenKey) { - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTSetActive, api.ServerGroupUnknown, "", "Set active key and add token field").AddParam(checksum, jwtSha)) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTSetActive, "Set active key and add token field").AddParam(checksum, jwtSha)) } plan, failed := areJWTTokensUpToDate(ctx, log, status, context, folder) @@ -97,7 +98,7 @@ func createJWTKeyUpdate(ctx context.Context, } if util.SHA256(activeKey) != jwtSha { - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTSetActive, api.ServerGroupUnknown, "", "Set active key").AddParam(checksum, jwtSha)) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTSetActive, "Set active key").AddParam(checksum, jwtSha)) } for key := range folder.Data { @@ -109,7 +110,7 @@ func createJWTKeyUpdate(ctx context.Context, continue } - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTClean, api.ServerGroupUnknown, "", "Remove old key").AddParam(checksum, key)) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTClean, "Remove old key").AddParam(checksum, key)) } return addJWTPropagatedPlanAction(status) @@ -124,7 +125,7 @@ func createJWTStatusUpdate(ctx context.Context, } if createJWTStatusUpdateRequired(log, apiObject, spec, status, cachedStatus) { - return addJWTPropagatedPlanAction(status, api.NewAction(api.ActionTypeJWTStatusUpdate, api.ServerGroupUnknown, "", "Update status")) + return addJWTPropagatedPlanAction(status, actions.NewClusterAction(api.ActionTypeJWTStatusUpdate, "Update status")) } return nil @@ -217,7 +218,7 @@ func areJWTTokensUpToDate(ctx context.Context, log zerolog.Logger, status api.De failed = true continue } else if updateRequired { - plan = append(plan, api.NewAction(api.ActionTypeJWTRefresh, group, m.ID)) + plan = append(plan, actions.NewAction(api.ActionTypeJWTRefresh, group, m)) continue } } @@ -256,19 +257,19 @@ func isJWTTokenUpToDate(ctx context.Context, log zerolog.Logger, status api.Depl return false, false } -func addJWTPropagatedPlanAction(s api.DeploymentStatus, actions ...api.Action) api.Plan { - got := len(actions) != 0 +func addJWTPropagatedPlanAction(s api.DeploymentStatus, acts ...api.Action) api.Plan { + got := len(acts) != 0 cond := conditionFalse if !got { cond = conditionTrue } if s.Hashes.JWT.Propagated == got { - p := api.Plan{api.NewAction(api.ActionTypeJWTPropagated, api.ServerGroupUnknown, "", "Change propagated flag").AddParam(propagated, cond)} - return append(p, actions...) + p := api.Plan{actions.NewClusterAction(api.ActionTypeJWTPropagated, "Change propagated flag").AddParam(propagated, cond)} + return append(p, acts...) } - return actions + return acts } func isMemberJWTTokenInvalid(ctx context.Context, c client.Client, data map[string][]byte, refresh bool) (bool, error) { diff --git a/pkg/deployment/reconcile/plan_builder_license.go b/pkg/deployment/reconcile/plan_builder_license.go index 14eaca29e..b563d1c1a 100644 --- a/pkg/deployment/reconcile/plan_builder_license.go +++ b/pkg/deployment/reconcile/plan_builder_license.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/client" "github.com/arangodb/kube-arangodb/pkg/util/arangod" "github.com/arangodb/kube-arangodb/pkg/util/globals" @@ -89,5 +90,5 @@ func updateClusterLicense(ctx context.Context, return nil } - return api.Plan{removeConditionActionV2("License is not set", api.ConditionTypeLicenseSet), api.NewAction(api.ActionTypeLicenseSet, member.Group, member.Member.ID, "Setting license")} + return api.Plan{removeConditionActionV2("License is not set", api.ConditionTypeLicenseSet), actions.NewAction(api.ActionTypeLicenseSet, member.Group, member.Member, "Setting license")} } diff --git a/pkg/deployment/reconcile/plan_builder_normal.go b/pkg/deployment/reconcile/plan_builder_normal.go index 1503146d9..c67a14fdc 100644 --- a/pkg/deployment/reconcile/plan_builder_normal.go +++ b/pkg/deployment/reconcile/plan_builder_normal.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -115,7 +116,7 @@ func createMemberFailedRestorePlan(ctx context.Context, // DBServer still exists in agency plan! Will not be removed, but needs to be recreated memberLog.Msg("Recreating DBServer - it cannot be removed gracefully") plan = append(plan, - api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) + actions.NewAction(api.ActionTypeRecreateMember, group, m)) continue } @@ -127,24 +128,24 @@ func createMemberFailedRestorePlan(ctx context.Context, // For agents just recreate member do not rotate ID, do not remove PVC or service memberLog.Msg("Restoring old member. For agency members recreation of PVC is not supported - to prevent DataLoss") plan = append(plan, - api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) + actions.NewAction(api.ActionTypeRecreateMember, group, m)) case api.ServerGroupSingle: // Do not remove data for singles memberLog.Msg("Restoring old member. Rotation for single servers is not safe") plan = append(plan, - api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) + actions.NewAction(api.ActionTypeRecreateMember, group, m)) default: if spec.GetAllowMemberRecreation(group) { memberLog.Msg("Creating member replacement plan because member has failed") plan = append(plan, - api.NewAction(api.ActionTypeRemoveMember, group, m.ID), - api.NewAction(api.ActionTypeAddMember, group, ""), - api.NewAction(api.ActionTypeWaitForMemberUp, group, api.MemberIDPreviousAction), + actions.NewAction(api.ActionTypeRemoveMember, group, m), + actions.NewAction(api.ActionTypeAddMember, group, withPredefinedMember("")), + actions.NewAction(api.ActionTypeWaitForMemberUp, group, withPredefinedMember(api.MemberIDPreviousAction)), ) } else { memberLog.Msg("Restoring old member. Recreation is disabled for group") plan = append(plan, - api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) + actions.NewAction(api.ActionTypeRecreateMember, group, m)) } } } @@ -155,7 +156,7 @@ func createMemberFailedRestorePlan(ctx context.Context, if len(plan) == 0 && !agencyOK { log.Warn().Msgf("unable to build further plan without access to agency") plan = append(plan, - api.NewAction(api.ActionTypeIdle, api.ServerGroupUnknown, "")) + actions.NewClusterAction(api.ActionTypeIdle)) } return plan diff --git a/pkg/deployment/reconcile/plan_builder_restore.go b/pkg/deployment/reconcile/plan_builder_restore.go index 78ed60e58..fa43f49c4 100644 --- a/pkg/deployment/reconcile/plan_builder_restore.go +++ b/pkg/deployment/reconcile/plan_builder_restore.go @@ -29,6 +29,7 @@ import ( inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/pod" "github.com/rs/zerolog" ) @@ -41,7 +42,7 @@ func createRestorePlan(ctx context.Context, cachedStatus inspectorInterface.Inspector, context PlanBuilderContext) api.Plan { if spec.RestoreFrom == nil && status.Restore != nil { return api.Plan{ - api.NewAction(api.ActionTypeBackupRestoreClean, api.ServerGroupUnknown, ""), + actions.NewClusterAction(api.ActionTypeBackupRestoreClean), } } @@ -80,7 +81,7 @@ func createRestorePlan(ctx context.Context, func restorePlan(spec api.DeploymentSpec) api.Plan { p := api.Plan{ - api.NewAction(api.ActionTypeBackupRestore, api.ServerGroupUnknown, ""), + actions.NewClusterAction(api.ActionTypeBackupRestore), } switch spec.Mode.Get() { @@ -121,8 +122,8 @@ func createRestorePlanEncryption(ctx context.Context, log zerolog.Logger, spec a if !status.Hashes.Encryption.Keys.ContainsSHA256(name) { return true, api.Plan{ - api.NewAction(api.ActionTypeEncryptionKeyPropagated, api.ServerGroupUnknown, "").AddParam(propagated, conditionFalse), - api.NewAction(api.ActionTypeEncryptionKeyAdd, api.ServerGroupUnknown, "").AddParam(secretActionParam, secret), + actions.NewClusterAction(api.ActionTypeEncryptionKeyPropagated).AddParam(propagated, conditionFalse), + actions.NewClusterAction(api.ActionTypeEncryptionKeyAdd).AddParam(secretActionParam, secret), } } diff --git a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go index 9cfdf0adf..628f64e5c 100644 --- a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go +++ b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go @@ -33,6 +33,7 @@ import ( upgraderules "github.com/arangodb/go-upgrade-rules" "github.com/arangodb/kube-arangodb/pkg/apis/deployment" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -74,7 +75,7 @@ func createRotateOrUpgradePlan(ctx context.Context, newPlan, idle := createRotateOrUpgradePlanInternal(log, apiObject, spec, status, cachedStatus, context) if idle { plan = append(plan, - api.NewAction(api.ActionTypeIdle, api.ServerGroupUnknown, "")) + actions.NewClusterAction(api.ActionTypeIdle)) } else { plan = append(plan, newPlan...) } @@ -102,7 +103,7 @@ func createMarkToRemovePlan(ctx context.Context, if pod.Annotations != nil { if _, ok := pod.Annotations[deployment.ArangoDeploymentPodReplaceAnnotation]; ok && (group == api.ServerGroupDBServers || group == api.ServerGroupAgents || group == api.ServerGroupCoordinators) { if !m.Conditions.IsTrue(api.ConditionTypeMarkedToRemove) { - plan = append(plan, api.NewAction(api.ActionTypeMarkToRemoveMember, group, m.ID, "Replace flag present")) + plan = append(plan, actions.NewAction(api.ActionTypeMarkToRemoveMember, group, m, "Replace flag present")) continue } } @@ -211,17 +212,17 @@ func createRotateOrUpgradePlanInternal(log zerolog.Logger, apiObject k8sutil.API log.Err(err).Str("member", m.Member.ID).Msgf("Error while generating update plan") continue } else if mode != rotation.InPlaceRotation { - return api.Plan{api.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member.ID, "Cleaning update"). + return api.Plan{actions.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member, "Cleaning update"). AddParam(api.ConditionTypePendingUpdate.String(), ""). AddParam(api.ConditionTypeUpdating.String(), "T")}, false } else { p = p.After( - api.NewAction(api.ActionTypeWaitForMemberUp, m.Group, m.Member.ID), - api.NewAction(api.ActionTypeWaitForMemberInSync, m.Group, m.Member.ID)) + actions.NewAction(api.ActionTypeWaitForMemberUp, m.Group, m.Member), + actions.NewAction(api.ActionTypeWaitForMemberInSync, m.Group, m.Member)) - p = p.Wrap(api.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member.ID, reason). + p = p.Wrap(actions.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member, reason). AddParam(api.ConditionTypePendingUpdate.String(), "").AddParam(api.ConditionTypeUpdating.String(), "T"), - api.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member.ID, reason). + actions.NewAction(api.ActionTypeSetMemberCondition, m.Group, m.Member, reason). AddParam(api.ConditionTypeUpdating.String(), "")) return p, false @@ -426,10 +427,10 @@ func createUpgradeMemberPlan(log zerolog.Logger, member api.MemberStatus, plan := createRotateMemberPlanWithAction(member, group, upgradeAction, spec, reason) if member.Image == nil || member.Image.Image != spec.GetImage() { - plan = plan.Before(api.NewAction(api.ActionTypeSetMemberCurrentImage, group, member.ID, reason).SetImage(spec.GetImage())) + plan = plan.Before(actions.NewAction(api.ActionTypeSetMemberCurrentImage, group, member, reason).SetImage(spec.GetImage())) } if status.CurrentImage == nil || status.CurrentImage.Image != spec.GetImage() { - plan = plan.Before(api.NewAction(api.ActionTypeSetCurrentImage, group, "", reason).SetImage(spec.GetImage())) + plan = plan.Before(actions.NewClusterAction(api.ActionTypeSetCurrentImage, reason).SetImage(spec.GetImage())) } return withSecureWrap(member, group, spec, plan...) diff --git a/pkg/deployment/reconcile/plan_builder_scale.go b/pkg/deployment/reconcile/plan_builder_scale.go index ff9bda3cf..4da70f8e9 100644 --- a/pkg/deployment/reconcile/plan_builder_scale.go +++ b/pkg/deployment/reconcile/plan_builder_scale.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -77,7 +78,7 @@ func createScalePlan(log zerolog.Logger, status api.DeploymentStatus, members ap // Scale up toAdd := count - len(members) for i := 0; i < toAdd; i++ { - plan = append(plan, api.NewAction(api.ActionTypeAddMember, group, "")) + plan = append(plan, actions.NewAction(api.ActionTypeAddMember, group, withPredefinedMember(""))) } log.Debug(). Int("count", count). @@ -123,7 +124,7 @@ func createReplaceMemberPlan(ctx context.Context, if member.Conditions.IsTrue(api.ConditionTypeMarkedToRemove) { switch group { case api.ServerGroupDBServers: - plan = append(plan, api.NewAction(api.ActionTypeAddMember, group, ""). + plan = append(plan, actions.NewAction(api.ActionTypeAddMember, group, withPredefinedMember("")). AddParam(api.ActionTypeWaitForMemberInSync.String(), ""). AddParam(api.ActionTypeWaitForMemberUp.String(), "")) log.Debug(). @@ -131,14 +132,14 @@ func createReplaceMemberPlan(ctx context.Context, Msg("Creating replacement plan") return nil case api.ServerGroupCoordinators: - plan = append(plan, api.NewAction(api.ActionTypeRemoveMember, group, member.ID)) + plan = append(plan, actions.NewAction(api.ActionTypeRemoveMember, group, member)) log.Debug(). Str("role", group.AsRole()). Msg("Creating replacement plan") return nil case api.ServerGroupAgents: - plan = append(plan, api.NewAction(api.ActionTypeRemoveMember, group, member.ID), - api.NewAction(api.ActionTypeAddMember, group, ""). + plan = append(plan, actions.NewAction(api.ActionTypeRemoveMember, group, member), + actions.NewAction(api.ActionTypeAddMember, group, withPredefinedMember("")). AddParam(api.ActionTypeWaitForMemberInSync.String(), ""). AddParam(api.ActionTypeWaitForMemberUp.String(), "")) log.Debug(). diff --git a/pkg/deployment/reconcile/plan_builder_storage.go b/pkg/deployment/reconcile/plan_builder_storage.go index d9d8a0a57..190521f10 100644 --- a/pkg/deployment/reconcile/plan_builder_storage.go +++ b/pkg/deployment/reconcile/plan_builder_storage.go @@ -24,6 +24,7 @@ import ( "context" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -74,7 +75,7 @@ func createRotateServerStorageResizePlan(ctx context.Context, if volumeSize, ok := pvc.Spec.Resources.Requests[core.ResourceStorage]; ok { cmp := volumeSize.Cmp(requestedSize) if cmp < 0 { - plan = append(plan, pvcResizePlan(log, group, groupSpec, m.ID)...) + plan = append(plan, pvcResizePlan(log, group, groupSpec, m)...) } } } @@ -85,22 +86,22 @@ func createRotateServerStorageResizePlan(ctx context.Context, return plan } -func pvcResizePlan(log zerolog.Logger, group api.ServerGroup, groupSpec api.ServerGroupSpec, memberID string) api.Plan { +func pvcResizePlan(log zerolog.Logger, group api.ServerGroup, groupSpec api.ServerGroupSpec, member api.MemberStatus) api.Plan { mode := groupSpec.VolumeResizeMode.Get() switch mode { case api.PVCResizeModeRuntime: return api.Plan{ - api.NewAction(api.ActionTypePVCResize, group, memberID), + actions.NewAction(api.ActionTypePVCResize, group, member), } case api.PVCResizeModeRotate: return api.Plan{ - api.NewAction(api.ActionTypeResignLeadership, group, memberID), - api.NewAction(api.ActionTypeKillMemberPod, group, memberID), - api.NewAction(api.ActionTypeRotateStartMember, group, memberID), - api.NewAction(api.ActionTypePVCResize, group, memberID), - api.NewAction(api.ActionTypePVCResized, group, memberID), - api.NewAction(api.ActionTypeRotateStopMember, group, memberID), - api.NewAction(api.ActionTypeWaitForMemberUp, group, memberID), + actions.NewAction(api.ActionTypeResignLeadership, group, member), + actions.NewAction(api.ActionTypeKillMemberPod, group, member), + actions.NewAction(api.ActionTypeRotateStartMember, group, member), + actions.NewAction(api.ActionTypePVCResize, group, member), + actions.NewAction(api.ActionTypePVCResized, group, member), + actions.NewAction(api.ActionTypeRotateStopMember, group, member), + actions.NewAction(api.ActionTypeWaitForMemberUp, group, member), } default: log.Error().Str("server-group", group.AsRole()).Str("mode", mode.String()). diff --git a/pkg/deployment/reconcile/plan_builder_test.go b/pkg/deployment/reconcile/plan_builder_test.go index ac77e36c7..570436c33 100644 --- a/pkg/deployment/reconcile/plan_builder_test.go +++ b/pkg/deployment/reconcile/plan_builder_test.go @@ -39,11 +39,12 @@ import ( "k8s.io/client-go/kubernetes" "github.com/arangodb/arangosync-client/client" - "github.com/arangodb/go-driver" "github.com/arangodb/go-driver/agency" + "github.com/arangodb/go-driver" backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" agencyCache "github.com/arangodb/kube-arangodb/pkg/deployment/agency" "github.com/arangodb/kube-arangodb/pkg/deployment/patch" pod2 "github.com/arangodb/kube-arangodb/pkg/deployment/pod" @@ -823,7 +824,7 @@ func TestCreatePlan(t *testing.T) { "with reason: Member replacement required", }, ExpectedHighPlan: []api.Action{ - api.NewAction(api.ActionTypeSetMemberConditionV2, api.ServerGroupDBServers, "", "Member replacement required"), + actions.NewAction(api.ActionTypeSetMemberConditionV2, api.ServerGroupDBServers, withPredefinedMember(""), "Member replacement required"), }, ExpectedLog: "Member replacement required", }, @@ -1006,7 +1007,7 @@ func TestCreatePlan(t *testing.T) { ad.Status.Members.Agents[0].PersistentVolumeClaimName = "pvc_test" }, ExpectedHighPlan: []api.Action{ - api.NewAction(api.ActionTypeSetMemberCondition, api.ServerGroupAgents, deploymentTemplate.Status.Members.Agents[0].ID, "PVC Resize pending"), + actions.NewAction(api.ActionTypeSetMemberCondition, api.ServerGroupAgents, deploymentTemplate.Status.Members.Agents[0], "PVC Resize pending"), }, ExpectedLog: "PVC Resize pending", }, @@ -1023,7 +1024,7 @@ func TestCreatePlan(t *testing.T) { ad.Status.Members.Agents[0].ID = "id" }, ExpectedPlan: []api.Action{ - api.NewAction(api.ActionTypeRecreateMember, api.ServerGroupAgents, "id"), + actions.NewAction(api.ActionTypeRecreateMember, api.ServerGroupAgents, withPredefinedMember("id")), }, ExpectedLog: "Restoring old member. For agency members recreation of PVC is not supported - to prevent DataLoss", }, @@ -1040,9 +1041,9 @@ func TestCreatePlan(t *testing.T) { ad.Status.Members.Coordinators[0].ID = "id" }, ExpectedPlan: []api.Action{ - api.NewAction(api.ActionTypeRemoveMember, api.ServerGroupCoordinators, "id"), - api.NewAction(api.ActionTypeAddMember, api.ServerGroupCoordinators, ""), - api.NewAction(api.ActionTypeWaitForMemberUp, api.ServerGroupCoordinators, api.MemberIDPreviousAction), + actions.NewAction(api.ActionTypeRemoveMember, api.ServerGroupCoordinators, withPredefinedMember("id")), + actions.NewAction(api.ActionTypeAddMember, api.ServerGroupCoordinators, withPredefinedMember("")), + actions.NewAction(api.ActionTypeWaitForMemberUp, api.ServerGroupCoordinators, withPredefinedMember(api.MemberIDPreviousAction)), }, ExpectedLog: "Creating member replacement plan because member has failed", }, @@ -1059,9 +1060,9 @@ func TestCreatePlan(t *testing.T) { ad.Status.Members.DBServers[0].ID = "id" }, ExpectedPlan: []api.Action{ - api.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, "id"), - api.NewAction(api.ActionTypeAddMember, api.ServerGroupDBServers, ""), - api.NewAction(api.ActionTypeWaitForMemberUp, api.ServerGroupDBServers, api.MemberIDPreviousAction), + actions.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, withPredefinedMember("id")), + actions.NewAction(api.ActionTypeAddMember, api.ServerGroupDBServers, withPredefinedMember("")), + actions.NewAction(api.ActionTypeWaitForMemberUp, api.ServerGroupDBServers, withPredefinedMember(api.MemberIDPreviousAction)), }, ExpectedLog: "Creating member replacement plan because member has failed", }, @@ -1083,10 +1084,10 @@ func TestCreatePlan(t *testing.T) { } }, ExpectedPlan: []api.Action{ - api.NewAction(api.ActionTypeCleanOutMember, api.ServerGroupDBServers, "id"), - api.NewAction(api.ActionTypeKillMemberPod, api.ServerGroupDBServers, ""), - api.NewAction(api.ActionTypeShutdownMember, api.ServerGroupDBServers, ""), - api.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, ""), + actions.NewAction(api.ActionTypeCleanOutMember, api.ServerGroupDBServers, withPredefinedMember("id")), + actions.NewAction(api.ActionTypeKillMemberPod, api.ServerGroupDBServers, withPredefinedMember("")), + actions.NewAction(api.ActionTypeShutdownMember, api.ServerGroupDBServers, withPredefinedMember("")), + actions.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, withPredefinedMember("")), }, ExpectedLog: "Creating dbserver replacement plan because server is cleanout in created phase", }, @@ -1102,10 +1103,10 @@ func TestCreatePlan(t *testing.T) { ad.Status.Members.DBServers[0].Phase = api.MemberPhaseCreated }, ExpectedPlan: []api.Action{ - api.NewAction(api.ActionTypeCleanOutMember, api.ServerGroupDBServers, "id"), - api.NewAction(api.ActionTypeKillMemberPod, api.ServerGroupDBServers, ""), - api.NewAction(api.ActionTypeShutdownMember, api.ServerGroupDBServers, ""), - api.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, ""), + actions.NewAction(api.ActionTypeCleanOutMember, api.ServerGroupDBServers, withPredefinedMember("id")), + actions.NewAction(api.ActionTypeKillMemberPod, api.ServerGroupDBServers, withPredefinedMember("")), + actions.NewAction(api.ActionTypeShutdownMember, api.ServerGroupDBServers, withPredefinedMember("")), + actions.NewAction(api.ActionTypeRemoveMember, api.ServerGroupDBServers, withPredefinedMember("")), }, ExpectedLog: "Creating scale-down plan", }, diff --git a/pkg/deployment/reconcile/plan_builder_tls.go b/pkg/deployment/reconcile/plan_builder_tls.go index e07f956f2..c76fa8293 100644 --- a/pkg/deployment/reconcile/plan_builder_tls.go +++ b/pkg/deployment/reconcile/plan_builder_tls.go @@ -32,15 +32,15 @@ import ( memberTls "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tls" - "github.com/arangodb/go-driver" - "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/deployment/client" "github.com/arangodb/kube-arangodb/pkg/util/constants" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" + "github.com/arangodb/go-driver" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/resources" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" @@ -75,7 +75,7 @@ func createTLSStatusPropagatedFieldUpdate(ctx context.Context, if status.Hashes.TLS.Propagated { plan = append(api.Plan{ - api.NewAction(api.ActionTypeTLSPropagated, api.ServerGroupUnknown, "", "Change propagated flag to false").AddParam(propagated, conditionFalse), + actions.NewClusterAction(api.ActionTypeTLSPropagated, "Change propagated flag to false").AddParam(propagated, conditionFalse), }, plan...) } @@ -92,7 +92,7 @@ func createTLSStatusUpdate(ctx context.Context, } if createTLSStatusUpdateRequired(log, apiObject, spec, status, cachedStatus) { - return api.Plan{api.NewAction(api.ActionTypeTLSKeyStatusUpdate, api.ServerGroupUnknown, "", "Update status")} + return api.Plan{actions.NewClusterAction(api.ActionTypeTLSKeyStatusUpdate, "Update status")} } return nil @@ -109,7 +109,7 @@ func createTLSStatusPropagated(ctx context.Context, if !status.Hashes.TLS.Propagated { return api.Plan{ - api.NewAction(api.ActionTypeTLSPropagated, api.ServerGroupUnknown, "", "Change propagated flag to true").AddParam(propagated, conditionTrue), + actions.NewClusterAction(api.ActionTypeTLSPropagated, "Change propagated flag to true").AddParam(propagated, conditionTrue), } } @@ -192,7 +192,7 @@ func createCAAppendPlan(ctx context.Context, certSha := util.SHA256(caData) if _, exists := trusted.Data[certSha]; !exists { - return api.Plan{api.NewAction(api.ActionTypeAppendTLSCACertificate, api.ServerGroupUnknown, "", "Append CA to truststore"). + return api.Plan{actions.NewClusterAction(api.ActionTypeAppendTLSCACertificate, "Append CA to truststore"). AddParam(checksum, certSha)} } @@ -228,7 +228,7 @@ func createCARenewalPlan(ctx context.Context, for _, ca := range cas { if time.Now().Add(CertificateRenewalMargin).After(ca.NotAfter) { // CA will expire soon, renewal needed - return api.Plan{api.NewAction(api.ActionTypeRenewTLSCACertificate, api.ServerGroupUnknown, "", "Renew CA Certificate")} + return api.Plan{actions.NewClusterAction(api.ActionTypeRenewTLSCACertificate, "Renew CA Certificate")} } } @@ -277,7 +277,7 @@ func createCACleanPlan(ctx context.Context, for sha := range trusted.Data { if certSha != sha { - return api.Plan{api.NewAction(api.ActionTypeCleanTLSCACertificate, api.ServerGroupUnknown, "", "Clean CA from truststore"). + return api.Plan{actions.NewClusterAction(api.ActionTypeCleanTLSCACertificate, "Clean CA from truststore"). AddParam(checksum, sha)} } } @@ -342,9 +342,9 @@ func createKeyfileRenewalPlanInPlace(ctx context.Context, if renew, recreate := keyfileRenewalRequired(lCtx, log, apiObject, spec, cachedStatus, planCtx, group, member, api.TLSRotateModeInPlace); renew { log.Info().Msg("Renewal of keyfile required - InPlace") if recreate { - plan = append(plan, api.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member.ID, "Remove server keyfile and enforce renewal")) + plan = append(plan, actions.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member, "Remove server keyfile and enforce renewal")) } - plan = append(plan, api.NewAction(api.ActionTypeRefreshTLSKeyfileCertificate, group, member.ID, "Renew Member Keyfile")) + plan = append(plan, actions.NewAction(api.ActionTypeRefreshTLSKeyfileCertificate, group, member, "Renew Member Keyfile")) } } diff --git a/pkg/deployment/reconcile/plan_builder_tls_sni.go b/pkg/deployment/reconcile/plan_builder_tls_sni.go index 3dfa43ef7..8f4e69c95 100644 --- a/pkg/deployment/reconcile/plan_builder_tls_sni.go +++ b/pkg/deployment/reconcile/plan_builder_tls_sni.go @@ -25,15 +25,15 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/globals" - "github.com/arangodb/go-driver" - "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/arangodb/kube-arangodb/pkg/deployment/pod" + "github.com/arangodb/go-driver" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/rs/zerolog" ) @@ -108,7 +108,7 @@ func createRotateTLSServerSNIPlan(ctx context.Context, plan = append(plan, tlsRotateConditionAction(group, m.ID, "SNI Secret needs update")) case api.TLSRotateModeInPlace: plan = append(plan, - api.NewAction(api.ActionTypeUpdateTLSSNI, group, m.ID, "SNI Secret needs update")) + actions.NewAction(api.ActionTypeUpdateTLSSNI, group, m, "SNI Secret needs update")) default: log.Warn().Msg("SNI mode rotation is unknown") continue diff --git a/pkg/deployment/reconcile/plan_builder_utils.go b/pkg/deployment/reconcile/plan_builder_utils.go index 064c76db0..0640ef774 100644 --- a/pkg/deployment/reconcile/plan_builder_utils.go +++ b/pkg/deployment/reconcile/plan_builder_utils.go @@ -26,6 +26,7 @@ import ( core "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" "github.com/rs/zerolog" @@ -49,15 +50,15 @@ func createRotateMemberPlanWithAction(member api.MemberStatus, group api.ServerGroup, action api.ActionType, spec api.DeploymentSpec, reason string) api.Plan { var plan = api.Plan{ - api.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member.ID, "Remove server keyfile and enforce renewal/recreation"), + actions.NewAction(api.ActionTypeCleanTLSKeyfileCertificate, group, member, "Remove server keyfile and enforce renewal/recreation"), } plan = withSecureWrap(member, group, spec, plan...) plan = plan.After( - withMemberPodUID(member, api.NewAction(api.ActionTypeKillMemberPod, group, member.ID, reason)), - withMemberPodUID(member, api.NewAction(action, group, member.ID, reason)), - api.NewAction(api.ActionTypeWaitForMemberUp, group, member.ID), - api.NewAction(api.ActionTypeWaitForMemberInSync, group, member.ID), + actions.NewAction(api.ActionTypeKillMemberPod, group, member, reason), + actions.NewAction(action, group, member, reason), + actions.NewAction(api.ActionTypeWaitForMemberUp, group, member), + actions.NewAction(api.ActionTypeWaitForMemberInSync, group, member), ) return plan @@ -71,7 +72,7 @@ func emptyPlanBuilder(ctx context.Context, } func removeConditionActionV2(actionReason string, conditionType api.ConditionType) api.Action { - return api.NewAction(api.ActionTypeSetConditionV2, api.ServerGroupUnknown, "", actionReason). + return actions.NewClusterAction(api.ActionTypeSetConditionV2, actionReason). AddParam(setConditionActionV2KeyAction, string(conditionType)). AddParam(setConditionActionV2KeyType, setConditionActionV2KeyTypeRemove) } @@ -82,7 +83,7 @@ func updateConditionActionV2(actionReason string, conditionType api.ConditionTyp statusBool = core.ConditionFalse } - return api.NewAction(api.ActionTypeSetConditionV2, api.ServerGroupUnknown, "", actionReason). + return actions.NewClusterAction(api.ActionTypeSetConditionV2, actionReason). AddParam(setConditionActionV2KeyAction, string(conditionType)). AddParam(setConditionActionV2KeyType, setConditionActionV2KeyTypeAdd). AddParam(setConditionActionV2KeyStatus, string(statusBool)). @@ -92,7 +93,7 @@ func updateConditionActionV2(actionReason string, conditionType api.ConditionTyp } func removeMemberConditionActionV2(actionReason string, conditionType api.ConditionType, group api.ServerGroup, member string) api.Action { - return api.NewAction(api.ActionTypeSetMemberConditionV2, group, member, actionReason). + return actions.NewAction(api.ActionTypeSetMemberConditionV2, group, withPredefinedMember(member), actionReason). AddParam(setConditionActionV2KeyAction, string(conditionType)). AddParam(setConditionActionV2KeyType, setConditionActionV2KeyTypeRemove) } @@ -103,7 +104,7 @@ func updateMemberConditionActionV2(actionReason string, conditionType api.Condit statusBool = core.ConditionFalse } - return api.NewAction(api.ActionTypeSetMemberConditionV2, group, member, actionReason). + return actions.NewAction(api.ActionTypeSetMemberConditionV2, group, withPredefinedMember(member), actionReason). AddParam(setConditionActionV2KeyAction, string(conditionType)). AddParam(setConditionActionV2KeyType, setConditionActionV2KeyTypeAdd). AddParam(setConditionActionV2KeyStatus, string(statusBool)). diff --git a/pkg/deployment/reconcile/utils.go b/pkg/deployment/reconcile/utils.go index 61cb93a48..b248f92d0 100644 --- a/pkg/deployment/reconcile/utils.go +++ b/pkg/deployment/reconcile/utils.go @@ -24,11 +24,11 @@ import ( "context" "sort" - "github.com/arangodb/go-driver" "github.com/arangodb/kube-arangodb/pkg/util/globals" core "k8s.io/api/core/v1" + "github.com/arangodb/go-driver" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -71,14 +71,6 @@ func getCluster(ctx context.Context, planCtx PlanBuilderContext) (driver.Cluster return cluster, nil } -func withMemberPodUID(m api.MemberStatus, a api.Action) api.Action { - if q := m.PodUID; q != "" { - return a.AddParam(api.ParamPodUID, string(q)) - } - - return a -} - func ifPodUIDMismatch(m api.MemberStatus, a api.Action, i pod.Inspector) bool { ut, ok := a.GetParam(api.ParamPodUID) if !ok || ut == "" { @@ -98,3 +90,9 @@ func ifPodUIDMismatch(m api.MemberStatus, a api.Action, i pod.Inspector) bool { return u != p.GetUID() } + +func withPredefinedMember(id string) api.MemberStatus { + return api.MemberStatus{ + ID: id, + } +} diff --git a/pkg/deployment/rotation/arangod_containers_test.go b/pkg/deployment/rotation/arangod_containers_test.go index 872c2c404..0d51f3146 100644 --- a/pkg/deployment/rotation/arangod_containers_test.go +++ b/pkg/deployment/rotation/arangod_containers_test.go @@ -27,6 +27,7 @@ import ( v1 "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) @@ -39,7 +40,7 @@ func Test_ArangoDContainers_SidecarImages(t *testing.T) { expectedMode: InPlaceRotation, expectedPlan: api.Plan{ - api.NewAction(api.ActionTypeRuntimeContainerImageUpdate, 0, ""), + actions.NewClusterAction(api.ActionTypeRuntimeContainerImageUpdate), }, }, { @@ -49,7 +50,7 @@ func Test_ArangoDContainers_SidecarImages(t *testing.T) { expectedMode: InPlaceRotation, expectedPlan: api.Plan{ - api.NewAction(api.ActionTypeRuntimeContainerImageUpdate, 0, ""), + actions.NewClusterAction(api.ActionTypeRuntimeContainerImageUpdate), }, }, } @@ -219,7 +220,7 @@ func Test_Container_Args(t *testing.T) { status: buildPodSpec(addContainerWithCommand(k8sutil.ServerContainerName, []string{"--log.level=INFO"})), expectedMode: InPlaceRotation, expectedPlan: api.Plan{ - api.NewAction(api.ActionTypeRuntimeContainerArgsLogLevelUpdate, 0, ""), + actions.NewClusterAction(api.ActionTypeRuntimeContainerArgsLogLevelUpdate), }, }, { diff --git a/pkg/deployment/rotation/compare.go b/pkg/deployment/rotation/compare.go index 5bd153733..548f902a2 100644 --- a/pkg/deployment/rotation/compare.go +++ b/pkg/deployment/rotation/compare.go @@ -24,6 +24,7 @@ import ( "encoding/json" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/actions" "github.com/arangodb/kube-arangodb/pkg/deployment/resources" "github.com/rs/zerolog" core "k8s.io/api/core/v1" @@ -65,7 +66,7 @@ func compare(log zerolog.Logger, deploymentSpec api.DeploymentSpec, member api.M podStatus := status.PodSpec.DeepCopy() // Try to fill fields - b := api.NewActionBuilder(group, member.ID) + b := actions.NewActionBuilderWrap(group, member) g := generator(deploymentSpec, group, &spec.PodSpec.Spec, &podStatus.Spec)