diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a8de68d..117541162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) - Fix ArangoMember race with multiple ArangoDeployments within single namespace +- Allow to define Member Recreation Policy within group ## [1.2.0](https://github.com/arangodb/kube-arangodb/tree/1.2.0) (2021-07-16) - Enable "Operator Internal Metrics Exporter" by default diff --git a/pkg/apis/deployment/v1/deployment_spec.go b/pkg/apis/deployment/v1/deployment_spec.go index 5942f798a..42b914088 100644 --- a/pkg/apis/deployment/v1/deployment_spec.go +++ b/pkg/apis/deployment/v1/deployment_spec.go @@ -163,6 +163,26 @@ type DeploymentSpec struct { CommunicationMethod *DeploymentCommunicationMethod `json:"communicationMethod,omitempty"` } +// GetAllowMemberRecreation returns member recreation policy based on group and settings +func (s *DeploymentSpec) GetAllowMemberRecreation(group ServerGroup) bool { + if s == nil { + return false + } + + groupSpec := s.GetServerGroupSpec(group) + + switch group { + case ServerGroupDBServers, ServerGroupCoordinators: + if v := groupSpec.AllowMemberRecreation; v == nil { + return true + } else { + return *v + } + default: + return false + } +} + // GetRestoreFrom returns the restore from string or empty string if not set func (s *DeploymentSpec) GetRestoreFrom() string { return util.StringOrDefault(s.RestoreFrom) diff --git a/pkg/apis/deployment/v1/server_group_spec.go b/pkg/apis/deployment/v1/server_group_spec.go index 5a05a87e1..4f127d9a3 100644 --- a/pkg/apis/deployment/v1/server_group_spec.go +++ b/pkg/apis/deployment/v1/server_group_spec.go @@ -141,6 +141,8 @@ type ServerGroupSpec struct { ShutdownDelay *int `json:"shutdownDelay,omitempty"` // InternalPort define port used in internal communication, can be accessed over localhost via sidecar InternalPort *int `json:"internalPort,omitempty"` + // AllowMemberRecreation allows to recreate member. Value is used only for Coordinator and DBServer with default to True, for all other groups set to false. + AllowMemberRecreation *bool `json:"allowMemberRecreation,omitempty"` } // ServerGroupSpecSecurityContext contains specification for pod security context diff --git a/pkg/apis/deployment/v1/zz_generated.deepcopy.go b/pkg/apis/deployment/v1/zz_generated.deepcopy.go index a8440e6fd..2cbce9277 100644 --- a/pkg/apis/deployment/v1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1/zz_generated.deepcopy.go @@ -1522,6 +1522,11 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = new(int) **out = **in } + if in.AllowMemberRecreation != nil { + in, out := &in.AllowMemberRecreation, &out.AllowMemberRecreation + *out = new(bool) + **out = **in + } return } diff --git a/pkg/apis/deployment/v2alpha1/arango_member_spec.go b/pkg/apis/deployment/v2alpha1/arango_member_spec.go index 9d124334d..ab4af9bc4 100644 --- a/pkg/apis/deployment/v2alpha1/arango_member_spec.go +++ b/pkg/apis/deployment/v2alpha1/arango_member_spec.go @@ -22,11 +22,15 @@ package v2alpha1 -import core "k8s.io/api/core/v1" +import ( + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" +) type ArangoMemberSpec struct { - Group ServerGroup `json:"group,omitempty"` - ID string `json:"id,omitempty"` + Group ServerGroup `json:"group,omitempty"` + ID string `json:"id,omitempty"` + DeploymentUID types.UID `json:"deploymentUID,omitempty"` Template *core.PodTemplate `json:"template,omitempty"` TemplateChecksum string `json:"templateChecksum,omitempty"` diff --git a/pkg/apis/deployment/v2alpha1/deployment_spec.go b/pkg/apis/deployment/v2alpha1/deployment_spec.go index 17b0d94a0..67e010dfd 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_spec.go +++ b/pkg/apis/deployment/v2alpha1/deployment_spec.go @@ -163,6 +163,26 @@ type DeploymentSpec struct { CommunicationMethod *DeploymentCommunicationMethod `json:"communicationMethod,omitempty"` } +// GetAllowMemberRecreation returns member recreation policy based on group and settings +func (s *DeploymentSpec) GetAllowMemberRecreation(group ServerGroup) bool { + if s == nil { + return false + } + + groupSpec := s.GetServerGroupSpec(group) + + switch group { + case ServerGroupDBServers, ServerGroupCoordinators: + if v := groupSpec.AllowMemberRecreation; v == nil { + return true + } else { + return *v + } + default: + return false + } +} + // GetRestoreFrom returns the restore from string or empty string if not set func (s *DeploymentSpec) GetRestoreFrom() string { return util.StringOrDefault(s.RestoreFrom) diff --git a/pkg/apis/deployment/v2alpha1/server_group_spec.go b/pkg/apis/deployment/v2alpha1/server_group_spec.go index 3d32d65a6..4fbc41e54 100644 --- a/pkg/apis/deployment/v2alpha1/server_group_spec.go +++ b/pkg/apis/deployment/v2alpha1/server_group_spec.go @@ -141,6 +141,8 @@ type ServerGroupSpec struct { ShutdownDelay *int `json:"shutdownDelay,omitempty"` // InternalPort define port used in internal communication, can be accessed over localhost via sidecar InternalPort *int `json:"internalPort,omitempty"` + // AllowMemberRecreation allows to recreate member. Value is used only for Coordinator and DBServer with default to True, for all other groups set to false. + AllowMemberRecreation *bool `json:"allowMemberRecreation,omitempty"` } // ServerGroupSpecSecurityContext contains specification for pod security context diff --git a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go index a805456ac..c3db99ac9 100644 --- a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go @@ -1522,6 +1522,11 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = new(int) **out = **in } + if in.AllowMemberRecreation != nil { + in, out := &in.AllowMemberRecreation, &out.AllowMemberRecreation + *out = new(bool) + **out = **in + } return } diff --git a/pkg/deployment/reconcile/plan_builder.go b/pkg/deployment/reconcile/plan_builder.go index f67ab3769..3052a2fc5 100644 --- a/pkg/deployment/reconcile/plan_builder.go +++ b/pkg/deployment/reconcile/plan_builder.go @@ -169,13 +169,18 @@ func createPlan(ctx context.Context, log zerolog.Logger, apiObject k8sutil.APIOb plan = append(plan, api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) default: - 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), - ) - + 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), + ) + } else { + memberLog.Msg("Restoring old member. Recreation is disabled for group") + plan = append(plan, + api.NewAction(api.ActionTypeRecreateMember, group, m.ID)) + } } } return nil