From 4cf43779fc2c93aa76d9ecd99dc45383f649b569 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 16 Sep 2021 21:13:36 +0000 Subject: [PATCH] [Feature] Agent recreation and agency info --- CHANGELOG.md | 1 + pkg/apis/deployment/v1/deployment_status.go | 6 +- .../v1/deployment_status_agency_info.go | 79 ++++++++++++++++ .../deployment/v1/zz_generated.deepcopy.go | 51 ++++++++++ .../deployment/v2alpha1/deployment_status.go | 6 +- .../v2alpha1/deployment_status_agency_info.go | 79 ++++++++++++++++ pkg/apis/deployment/v2alpha1/plan.go | 4 +- .../v2alpha1/zz_generated.deepcopy.go | 51 ++++++++++ pkg/deployment/deployment.go | 5 + pkg/deployment/members.go | 94 ++++++++++++++----- pkg/deployment/reconcile/action_add_member.go | 2 +- .../reconcile/action_mark_to_remove_member.go | 2 +- .../reconcile/plan_builder_rotate_upgrade.go | 8 +- .../reconcile/plan_builder_scale.go | 28 ++++-- pkg/util/k8sutil/names/id.go | 52 ++++++++++ 15 files changed, 426 insertions(+), 42 deletions(-) create mode 100644 pkg/apis/deployment/v1/deployment_status_agency_info.go create mode 100644 pkg/apis/deployment/v2alpha1/deployment_status_agency_info.go create mode 100644 pkg/util/k8sutil/names/id.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a412955b..d7d254a9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Update UBI Image to 8.4 - Fix ArangoSync Liveness Prove - Allow runtime update of Sidecar images +- Allow Agent recreation with preserved IDs ## [1.2.2](https://github.com/arangodb/kube-arangodb/tree/1.2.2) (2021-09-09) - Update 'github.com/arangodb/arangosync-client' dependency to v0.7.0 diff --git a/pkg/apis/deployment/v1/deployment_status.go b/pkg/apis/deployment/v1/deployment_status.go index 3430a0e96..a96ec6fb2 100644 --- a/pkg/apis/deployment/v1/deployment_status.go +++ b/pkg/apis/deployment/v1/deployment_status.go @@ -78,6 +78,9 @@ type DeploymentStatus struct { // ForceStatusReload if set to true forces a reload of the status from the custom resource. ForceStatusReload *bool `json:"force-status-reload,omitempty"` + + // Agency keeps information about agency + Agency *DeploymentStatusAgencyInfo `json:"agency,omitempty"` } // Equal checks for equality @@ -95,7 +98,8 @@ func (ds *DeploymentStatus) Equal(other DeploymentStatus) bool { ds.Conditions.Equal(other.Conditions) && ds.Plan.Equal(other.Plan) && ds.AcceptedSpec.Equal(other.AcceptedSpec) && - ds.SecretHashes.Equal(other.SecretHashes) + ds.SecretHashes.Equal(other.SecretHashes) && + ds.Agency.Equal(other.Agency) } // IsForceReload returns true if ForceStatusReload is set to true diff --git a/pkg/apis/deployment/v1/deployment_status_agency_info.go b/pkg/apis/deployment/v1/deployment_status_agency_info.go new file mode 100644 index 000000000..10c54645c --- /dev/null +++ b/pkg/apis/deployment/v1/deployment_status_agency_info.go @@ -0,0 +1,79 @@ +// +// DISCLAIMER +// +// Copyright 2020 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 v1 + +import ( + "sort" + "strings" +) + +type DeploymentStatusAgencySize int + +func (d *DeploymentStatusAgencySize) Equal(b *DeploymentStatusAgencySize) bool { + if d == nil && b == nil { + return true + } + + if d == nil || b == nil { + return true + } + + return *d == *b +} + +type DeploymentStatusAgencyIDs []string + +func (d DeploymentStatusAgencyIDs) Sort() { + sort.Slice(d, func(i, j int) bool { + return strings.Compare(d[i], d[j]) > 0 + }) +} + +func (d DeploymentStatusAgencyIDs) Equal(b DeploymentStatusAgencyIDs) bool { + if len(d) != len(b) { + return false + } + + for id := range d { + if d[id] != b[id] { + return false + } + } + + return true +} + +type DeploymentStatusAgencyInfo struct { + Size *DeploymentStatusAgencySize `json:"size,omitempty"` + IDs DeploymentStatusAgencyIDs `json:"ids,omitempty"` +} + +func (d *DeploymentStatusAgencyInfo) Equal(b *DeploymentStatusAgencyInfo) bool { + if d == nil && b == nil { + return true + } + + if d == nil || b == nil { + return true + } + + return d.IDs.Equal(b.IDs) && d.Size.Equal(b.Size) +} diff --git a/pkg/apis/deployment/v1/zz_generated.deepcopy.go b/pkg/apis/deployment/v1/zz_generated.deepcopy.go index afffc7f49..c209125e2 100644 --- a/pkg/apis/deployment/v1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1/zz_generated.deepcopy.go @@ -679,6 +679,11 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = new(bool) **out = **in } + if in.Agency != nil { + in, out := &in.Agency, &out.Agency + *out = new(DeploymentStatusAgencyInfo) + (*in).DeepCopyInto(*out) + } return } @@ -692,6 +697,52 @@ func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in DeploymentStatusAgencyIDs) DeepCopyInto(out *DeploymentStatusAgencyIDs) { + { + in := &in + *out = make(DeploymentStatusAgencyIDs, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatusAgencyIDs. +func (in DeploymentStatusAgencyIDs) DeepCopy() DeploymentStatusAgencyIDs { + if in == nil { + return nil + } + out := new(DeploymentStatusAgencyIDs) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentStatusAgencyInfo) DeepCopyInto(out *DeploymentStatusAgencyInfo) { + *out = *in + if in.Size != nil { + in, out := &in.Size, &out.Size + *out = new(DeploymentStatusAgencySize) + **out = **in + } + if in.IDs != nil { + in, out := &in.IDs, &out.IDs + *out = make(DeploymentStatusAgencyIDs, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatusAgencyInfo. +func (in *DeploymentStatusAgencyInfo) DeepCopy() *DeploymentStatusAgencyInfo { + if in == nil { + return nil + } + out := new(DeploymentStatusAgencyInfo) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatusHashes) DeepCopyInto(out *DeploymentStatusHashes) { *out = *in diff --git a/pkg/apis/deployment/v2alpha1/deployment_status.go b/pkg/apis/deployment/v2alpha1/deployment_status.go index 2185064cc..5c8f6b9b6 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_status.go +++ b/pkg/apis/deployment/v2alpha1/deployment_status.go @@ -78,6 +78,9 @@ type DeploymentStatus struct { // ForceStatusReload if set to true forces a reload of the status from the custom resource. ForceStatusReload *bool `json:"force-status-reload,omitempty"` + + // Agency keeps information about agency + Agency *DeploymentStatusAgencyInfo `json:"agency,omitempty"` } // Equal checks for equality @@ -95,7 +98,8 @@ func (ds *DeploymentStatus) Equal(other DeploymentStatus) bool { ds.Conditions.Equal(other.Conditions) && ds.Plan.Equal(other.Plan) && ds.AcceptedSpec.Equal(other.AcceptedSpec) && - ds.SecretHashes.Equal(other.SecretHashes) + ds.SecretHashes.Equal(other.SecretHashes) && + ds.Agency.Equal(other.Agency) } // IsForceReload returns true if ForceStatusReload is set to true diff --git a/pkg/apis/deployment/v2alpha1/deployment_status_agency_info.go b/pkg/apis/deployment/v2alpha1/deployment_status_agency_info.go new file mode 100644 index 000000000..661224714 --- /dev/null +++ b/pkg/apis/deployment/v2alpha1/deployment_status_agency_info.go @@ -0,0 +1,79 @@ +// +// DISCLAIMER +// +// Copyright 2020 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 v2alpha1 + +import ( + "sort" + "strings" +) + +type DeploymentStatusAgencySize int + +func (d *DeploymentStatusAgencySize) Equal(b *DeploymentStatusAgencySize) bool { + if d == nil && b == nil { + return true + } + + if d == nil || b == nil { + return true + } + + return *d == *b +} + +type DeploymentStatusAgencyIDs []string + +func (d DeploymentStatusAgencyIDs) Sort() { + sort.Slice(d, func(i, j int) bool { + return strings.Compare(d[i], d[j]) > 0 + }) +} + +func (d DeploymentStatusAgencyIDs) Equal(b DeploymentStatusAgencyIDs) bool { + if len(d) != len(b) { + return false + } + + for id := range d { + if d[id] != b[id] { + return false + } + } + + return true +} + +type DeploymentStatusAgencyInfo struct { + Size *DeploymentStatusAgencySize `json:"size,omitempty"` + IDs DeploymentStatusAgencyIDs `json:"ids,omitempty"` +} + +func (d *DeploymentStatusAgencyInfo) Equal(b *DeploymentStatusAgencyInfo) bool { + if d == nil && b == nil { + return true + } + + if d == nil || b == nil { + return true + } + + return d.IDs.Equal(b.IDs) && d.Size.Equal(b.Size) +} diff --git a/pkg/apis/deployment/v2alpha1/plan.go b/pkg/apis/deployment/v2alpha1/plan.go index 919c50dd2..b3aa59601 100644 --- a/pkg/apis/deployment/v2alpha1/plan.go +++ b/pkg/apis/deployment/v2alpha1/plan.go @@ -49,7 +49,7 @@ func (a ActionType) String() string { // Priority returns plan priority func (a ActionType) Priority() ActionPriority { switch a { - case ActionTypeMemberPhaseUpdate, ActionTypeMemberRIDUpdate, ActionTypeSetMemberCondition: + case ActionTypeMemberPhaseUpdate, ActionTypeMemberRIDUpdate, ActionTypeSetMemberCondition, ActionTypeBootstrapSetAgencyInfo: return ActionPriorityHigh default: return ActionPriorityNormal @@ -165,6 +165,8 @@ const ( ActionTypeArangoMemberUpdatePodSpec ActionType = "ArangoMemberUpdatePodSpec" // ActionTypeArangoMemberUpdatePodStatus updates pod spec ActionTypeArangoMemberUpdatePodStatus ActionType = "ArangoMemberUpdatePodStatus" + // ActionTypeBootstrapSetAgencyInfo set agency info into state + ActionTypeBootstrapSetAgencyInfo ActionType = "BootstrapSetAgencyInfo" // Runtime Updates // ActionTypeRuntimeContainerImageUpdate updates container image in runtime diff --git a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go index 5a964894c..e74e063a8 100644 --- a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go @@ -679,6 +679,11 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = new(bool) **out = **in } + if in.Agency != nil { + in, out := &in.Agency, &out.Agency + *out = new(DeploymentStatusAgencyInfo) + (*in).DeepCopyInto(*out) + } return } @@ -692,6 +697,52 @@ func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in DeploymentStatusAgencyIDs) DeepCopyInto(out *DeploymentStatusAgencyIDs) { + { + in := &in + *out = make(DeploymentStatusAgencyIDs, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatusAgencyIDs. +func (in DeploymentStatusAgencyIDs) DeepCopy() DeploymentStatusAgencyIDs { + if in == nil { + return nil + } + out := new(DeploymentStatusAgencyIDs) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentStatusAgencyInfo) DeepCopyInto(out *DeploymentStatusAgencyInfo) { + *out = *in + if in.Size != nil { + in, out := &in.Size, &out.Size + *out = new(DeploymentStatusAgencySize) + **out = **in + } + if in.IDs != nil { + in, out := &in.IDs, &out.IDs + *out = make(DeploymentStatusAgencyIDs, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatusAgencyInfo. +func (in *DeploymentStatusAgencyInfo) DeepCopy() *DeploymentStatusAgencyInfo { + if in == nil { + return nil + } + out := new(DeploymentStatusAgencyInfo) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatusHashes) DeepCopyInto(out *DeploymentStatusHashes) { *out = *in diff --git a/pkg/deployment/deployment.go b/pkg/deployment/deployment.go index 57245dd5c..169de5fa6 100644 --- a/pkg/deployment/deployment.go +++ b/pkg/deployment/deployment.go @@ -262,6 +262,11 @@ func (d *Deployment) send(ev *deploymentEvent) { func (d *Deployment) run() { log := d.deps.Log + // Create agency mapping + if err := d.createAgencyMapping(context.TODO()); err != nil { + d.CreateEvent(k8sutil.NewErrorEvent("Failed to create agency mapping members", err, d.GetAPIObject())) + } + if d.GetPhase() == api.DeploymentPhaseNone { // Create service monitor if d.haveServiceMonitorCRD { diff --git a/pkg/deployment/members.go b/pkg/deployment/members.go index 5cf36eb92..50fef5453 100644 --- a/pkg/deployment/members.go +++ b/pkg/deployment/members.go @@ -24,11 +24,11 @@ package deployment import ( "context" - "strings" + + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/names" "github.com/arangodb/kube-arangodb/pkg/util/errors" - "github.com/dchest/uniuri" "github.com/rs/zerolog" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -71,20 +71,79 @@ func (d *Deployment) createInitialMembers(ctx context.Context, apiObject *api.Ar return nil } +func (d *Deployment) createAgencyMapping(ctx context.Context) error { + spec := d.GetSpec() + status, _ := d.GetStatus() + + if !spec.Mode.HasAgents() { + return nil + } + + if status.Agency != nil { + return nil + } + + var i api.DeploymentStatusAgencyInfo + + if spec.Agents.Count == nil { + return nil + } + + agents := status.Members.Agents + + if len(agents) > *spec.Agents.Count { + return errors.Newf("Agency size is bigger than requested size") + } + + c := api.DeploymentStatusAgencySize(*spec.Agents.Count) + + i.Size = &c + + for id := range agents { + i.IDs = append(i.IDs, agents[id].ID) + } + + for len(i.IDs) < *spec.Agents.Count { + i.IDs = append(i.IDs, names.GetArangodID(api.ServerGroupAgents)) + } + + return d.WithStatusUpdate(ctx, func(s *api.DeploymentStatus) bool { + s.Agency = &i + return true + }) +} + // createMember creates member and adds it to the applicable member list. // Note: This does not create any pods of PVCs // Note: The updated status is not yet written to the apiserver. func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.ServerGroup, id string, apiObject *api.ArangoDeployment) (string, error) { - if id == "" { - idPrefix := getArangodIDPrefix(group) - for { - id = idPrefix + strings.ToLower(uniuri.NewLen(8)) // K8s accepts only lowercase, so we use it here as well - if !status.Members.ContainsID(id) { - break + if group == api.ServerGroupAgents { + if status.Agency == nil { + return "", errors.New("Agency is not yet defined") + } + // In case of agents we need to use hardcoded ids + if id == "" { + for _, nid := range status.Agency.IDs { + if !status.Members.ContainsID(nid) { + id = nid + break + } + } + } + } else { + if id == "" { + for { + id = names.GetArangodID(group) + if !status.Members.ContainsID(id) { + break + } + // Duplicate, try again } - // Duplicate, try again } } + if id == "" { + return "nil", errors.New("Unable to get ID") + } deploymentName := apiObject.GetName() role := group.AsRole() @@ -167,20 +226,3 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se return id, nil } - -// getArangodIDPrefix returns the prefix required ID's of arangod servers -// in the given group. -func getArangodIDPrefix(group api.ServerGroup) string { - switch group { - case api.ServerGroupSingle: - return "SNGL-" - case api.ServerGroupCoordinators: - return "CRDN-" - case api.ServerGroupDBServers: - return "PRMR-" - case api.ServerGroupAgents: - return "AGNT-" - default: - return "" - } -} diff --git a/pkg/deployment/reconcile/action_add_member.go b/pkg/deployment/reconcile/action_add_member.go index e3dde538a..8f9aee81e 100644 --- a/pkg/deployment/reconcile/action_add_member.go +++ b/pkg/deployment/reconcile/action_add_member.go @@ -85,7 +85,7 @@ func (a *actionAddMember) ActionPlanAppender(current api.Plan) (api.Plan, bool) app = append(app, api.NewAction(api.ActionTypeWaitForMemberUp, a.action.Group, a.newMemberID, "Wait for member in sync after creation")) } - if _, ok := a.action.Params[api.ActionTypeWaitForMemberUp.String()]; ok { + 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")) } diff --git a/pkg/deployment/reconcile/action_mark_to_remove_member.go b/pkg/deployment/reconcile/action_mark_to_remove_member.go index 8bea24d1a..88afbfe75 100644 --- a/pkg/deployment/reconcile/action_mark_to_remove_member.go +++ b/pkg/deployment/reconcile/action_mark_to_remove_member.go @@ -50,7 +50,7 @@ type actionMarkToRemove struct { } func (a *actionMarkToRemove) Start(ctx context.Context) (bool, error) { - if a.action.Group != api.ServerGroupDBServers { + if a.action.Group != api.ServerGroupDBServers && a.action.Group != api.ServerGroupAgents { return true, nil } diff --git a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go index 75ac734cc..a9ed1061e 100644 --- a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go +++ b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go @@ -188,9 +188,11 @@ func createRotateOrUpgradePlanInternal(log zerolog.Logger, apiObject k8sutil.API } if pod.Annotations != nil { - if _, ok := pod.Annotations[deployment.ArangoDeploymentPodReplaceAnnotation]; ok && group == api.ServerGroupDBServers { - newPlan = api.Plan{api.NewAction(api.ActionTypeMarkToRemoveMember, group, m.ID, "Replace flag present")} - continue + if _, ok := pod.Annotations[deployment.ArangoDeploymentPodReplaceAnnotation]; ok && (group == api.ServerGroupDBServers || group == api.ServerGroupAgents) { + if !m.Conditions.IsTrue(api.ConditionTypeMarkedToRemove) { + newPlan = api.Plan{api.NewAction(api.ActionTypeMarkToRemoveMember, group, m.ID, "Replace flag present")} + continue + } } } } diff --git a/pkg/deployment/reconcile/plan_builder_scale.go b/pkg/deployment/reconcile/plan_builder_scale.go index f4249e616..4f66f78bd 100644 --- a/pkg/deployment/reconcile/plan_builder_scale.go +++ b/pkg/deployment/reconcile/plan_builder_scale.go @@ -111,18 +111,30 @@ func createReplaceMemberPlan(ctx context.Context, return nil } if member.Conditions.IsTrue(api.ConditionTypeMarkedToRemove) { - plan = append(plan, api.NewAction(api.ActionTypeAddMember, group, ""). - AddParam(api.ActionTypeWaitForMemberInSync.String(), ""). - AddParam(api.ActionTypeWaitForMemberUp.String(), "")) - log.Debug(). - Str("role", group.AsRole()). - Msg("Creating replacement plan") - return nil + switch group { + case api.ServerGroupDBServers: + plan = append(plan, api.NewAction(api.ActionTypeAddMember, group, ""). + AddParam(api.ActionTypeWaitForMemberInSync.String(), ""). + AddParam(api.ActionTypeWaitForMemberUp.String(), "")) + 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, ""). + AddParam(api.ActionTypeWaitForMemberInSync.String(), ""). + AddParam(api.ActionTypeWaitForMemberUp.String(), "")) + log.Debug(). + Str("role", group.AsRole()). + Msg("Creating replacement plan") + return nil + } } } return nil - }, api.ServerGroupDBServers) + }, api.ServerGroupAgents, api.ServerGroupDBServers) } return plan diff --git a/pkg/util/k8sutil/names/id.go b/pkg/util/k8sutil/names/id.go new file mode 100644 index 000000000..c42bb6fef --- /dev/null +++ b/pkg/util/k8sutil/names/id.go @@ -0,0 +1,52 @@ +// +// DISCLAIMER +// +// Copyright 2021 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 +// +// Author Adam Janikowski +// + +package names + +import ( + "fmt" + "strings" + + api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/dchest/uniuri" +) + +func GetArangodID(group api.ServerGroup) string { + return fmt.Sprintf("%s%s", GetArangodIDPrefix(group), strings.ToLower(uniuri.NewLen(8))) +} + +// GetArangodIDPrefix returns the prefix required ID's of arangod servers +// in the given group. +func GetArangodIDPrefix(group api.ServerGroup) string { + switch group { + case api.ServerGroupSingle: + return "SNGL-" + case api.ServerGroupCoordinators: + return "CRDN-" + case api.ServerGroupDBServers: + return "PRMR-" + case api.ServerGroupAgents: + return "AGNT-" + default: + return "" + } +}