Skip to content

Commit

Permalink
[Bugfix] Fix Replaced Member Zone during Replace operation
Browse files Browse the repository at this point in the history
  • Loading branch information
ajanikow committed Nov 15, 2023
1 parent 82cb7f1 commit 5c6655a
Show file tree
Hide file tree
Showing 10 changed files with 1,075 additions and 1,816 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- (Feature) License ArangoDeployment Fetcher
- (Feature) K8S Resources Compare Generic
- (Feature) Add support for CRD validation schemas
- (Bugfix) Fix Replaced Member Zone during Replace operation

## [1.2.35](https://github.com/arangodb/kube-arangodb/tree/1.2.35) (2023-11-06)
- (Maintenance) Update go-driver to v1.6.0, update IsNotFound() checks
Expand Down
51 changes: 41 additions & 10 deletions pkg/apis/deployment/v1/topology_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ import (
"k8s.io/apimachinery/pkg/util/uuid"
)

type TopologyZoneFilter func(g ServerGroup, id string) bool

func TopologyZoneFilterMerge(functions ...TopologyZoneFilter) TopologyZoneFilter {
return func(g ServerGroup, id string) bool {
for _, f := range functions {
if !f(g, id) {
return false
}
}

return true
}
}

type TopologyStatus struct {
ID types.UID `json:"id"`

Expand All @@ -53,25 +67,42 @@ func (t *TopologyStatus) Equal(b *TopologyStatus) bool {
}

func (t *TopologyStatus) GetLeastUsedZone(group ServerGroup) int {
return t.GetLeastUsedZoneWithFilter(group)
}

func (t *TopologyStatus) GetLeastUsedZoneWithFilter(group ServerGroup, filters ...TopologyZoneFilter) int {
if t == nil {
return -1
}

r, m := -1, math.MaxInt64
// If no zones are found
if len(t.Zones) == 0 {
return -1
}

for i, z := range t.Zones {
if n, ok := z.Members[group.AsRoleAbbreviated()]; ok {
if v := len(n); v < m {
r, m = i, v
}
} else {
if v := 0; v < m {
r, m = i, v
counts := make([]int, len(t.Zones))

for id, zone := range t.Zones {
c := 0

for _, member := range zone.Members[group.AsRoleAbbreviated()] {
if TopologyZoneFilterMerge(filters...)(group, member) {
c++
}
}

counts[id] = c
}

max := 0

for id := 1; id < len(counts); id++ {
if counts[id] < counts[max] {
max = id
}
}

return r
return max
}

func (t *TopologyStatus) RegisterTopologyLabel(zone int, label string) bool {
Expand Down
49 changes: 42 additions & 7 deletions pkg/apis/deployment/v2alpha1/arango_member_pod_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,6 @@ type ArangoMemberPodTemplate struct {
Endpoint *string `json:"endpoint,omitempty"`
}

func (a *ArangoMemberPodTemplate) GetChecksum() string {
if a == nil {
return ""
}
return a.Checksum
}

func (a *ArangoMemberPodTemplate) Equals(b *ArangoMemberPodTemplate) bool {
if a == nil && b == nil {
return true
Expand Down Expand Up @@ -100,3 +93,45 @@ func (a *ArangoMemberPodTemplate) EqualPodSpecChecksum(checksum string) bool {
}
return checksum == a.PodSpecChecksum
}

func (a *ArangoMemberPodTemplate) GetTemplate() *core.PodTemplateSpec {
if a == nil {
return nil
}
return a.PodSpec.DeepCopy()
}

func (a *ArangoMemberPodTemplate) SetTemplate(t *core.PodTemplateSpec) {
if a == nil {
return
}
a.PodSpec = t.DeepCopy()
}

func (a *ArangoMemberPodTemplate) GetTemplateChecksum() string {
if a == nil {
return ""
}
return a.PodSpecChecksum
}

func (a *ArangoMemberPodTemplate) SetTemplateChecksum(s string) {
if a == nil {
return
}
a.PodSpecChecksum = s
}

func (a *ArangoMemberPodTemplate) SetChecksum(s string) {
if a == nil {
return
}
a.Checksum = s
}

func (a *ArangoMemberPodTemplate) GetChecksum() string {
if a == nil {
return ""
}
return a.Checksum
}
51 changes: 41 additions & 10 deletions pkg/apis/deployment/v2alpha1/topology_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ import (
"k8s.io/apimachinery/pkg/util/uuid"
)

type TopologyZoneFilter func(g ServerGroup, id string) bool

func TopologyZoneFilterMerge(functions ...TopologyZoneFilter) TopologyZoneFilter {
return func(g ServerGroup, id string) bool {
for _, f := range functions {
if !f(g, id) {
return false
}
}

return true
}
}

type TopologyStatus struct {
ID types.UID `json:"id"`

Expand All @@ -53,25 +67,42 @@ func (t *TopologyStatus) Equal(b *TopologyStatus) bool {
}

func (t *TopologyStatus) GetLeastUsedZone(group ServerGroup) int {
return t.GetLeastUsedZoneWithFilter(group)
}

func (t *TopologyStatus) GetLeastUsedZoneWithFilter(group ServerGroup, filters ...TopologyZoneFilter) int {
if t == nil {
return -1
}

r, m := -1, math.MaxInt64
// If no zones are found
if len(t.Zones) == 0 {
return -1
}

for i, z := range t.Zones {
if n, ok := z.Members[group.AsRoleAbbreviated()]; ok {
if v := len(n); v < m {
r, m = i, v
}
} else {
if v := 0; v < m {
r, m = i, v
counts := make([]int, len(t.Zones))

for id, zone := range t.Zones {
c := 0

for _, member := range zone.Members[group.AsRoleAbbreviated()] {
if TopologyZoneFilterMerge(filters...)(group, member) {
c++
}
}

counts[id] = c
}

max := 0

for id := 1; id < len(counts); id++ {
if counts[id] < counts[max] {
max = id
}
}

return r
return max
}

func (t *TopologyStatus) RegisterTopologyLabel(zone int, label string) bool {
Expand Down
60 changes: 20 additions & 40 deletions pkg/crd/crds/backups-backup.schema.generated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,34 @@ v1:
backoff:
properties:
iterations:
description: Iterations defines number of iterations before reaching
MaxDelay. Default to 5
description: Iterations defines number of iterations before reaching MaxDelay. Default to 5
format: int32
type: integer
max_delay:
description: MaxDelay defines maximum delay in seconds. Default to
600
description: MaxDelay defines maximum delay in seconds. Default to 600
format: int32
type: integer
max_iterations:
description: MaxIterations defines maximum number of iterations after
backoff will be disabled. Default to nil (no limit)
description: MaxIterations defines maximum number of iterations after backoff will be disabled. Default to nil (no limit)
format: int32
type: integer
min_delay:
description: MinDelay defines minimum delay in seconds. Default to
30
description: MinDelay defines minimum delay in seconds. Default to 30
format: int32
type: integer
type: object
deployment:
description: Deployment describes the deployment which should have a backup
properties:
name:
description: Name of the ArangoDeployment Custom Resource within same
namespace as ArangoBackup Custom Resource.
description: Name of the ArangoDeployment Custom Resource within same namespace as ArangoBackup Custom Resource.
type: string
type: object
download:
description: Download Backup download settings
properties:
credentialsSecretName:
description: CredentialsSecretName is the name of the secret used
while accessing repository
description: CredentialsSecretName is the name of the secret used while accessing repository
type: string
id:
description: ID of the ArangoBackup to be downloaded
Expand All @@ -52,8 +46,7 @@ v1:
type: string
type: object
lifetime:
description: 'Lifetime is the time after which the backup will be deleted.
Format: "1.5h" or "2h45m".'
description: 'Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".'
type: string
options:
description: Options specifies backup options
Expand All @@ -64,23 +57,20 @@ v1:
If this value is set to true, backup is taken even if we are not able to acquire lock.
type: boolean
timeout:
description: Timeout for Backup creation request in seconds. Works
only when AsyncBackupCreation feature is set to false.
description: Timeout for Backup creation request in seconds. Works only when AsyncBackupCreation feature is set to false.
format: float
type: number
type: object
policyName:
description: PolicyName name of the ArangoBackupPolicy which created this
Custom Resource
description: PolicyName name of the ArangoBackupPolicy which created this Custom Resource
type: string
upload:
description: |-
Upload Backup upload settings.
This field can be removed and created again with different values. This operation will trigger upload again.
properties:
credentialsSecretName:
description: CredentialsSecretName is the name of the secret used
while accessing repository
description: CredentialsSecretName is the name of the secret used while accessing repository
type: string
repositoryURL:
description: |-
Expand All @@ -100,40 +90,34 @@ v1alpha:
backoff:
properties:
iterations:
description: Iterations defines number of iterations before reaching
MaxDelay. Default to 5
description: Iterations defines number of iterations before reaching MaxDelay. Default to 5
format: int32
type: integer
max_delay:
description: MaxDelay defines maximum delay in seconds. Default to
600
description: MaxDelay defines maximum delay in seconds. Default to 600
format: int32
type: integer
max_iterations:
description: MaxIterations defines maximum number of iterations after
backoff will be disabled. Default to nil (no limit)
description: MaxIterations defines maximum number of iterations after backoff will be disabled. Default to nil (no limit)
format: int32
type: integer
min_delay:
description: MinDelay defines minimum delay in seconds. Default to
30
description: MinDelay defines minimum delay in seconds. Default to 30
format: int32
type: integer
type: object
deployment:
description: Deployment describes the deployment which should have a backup
properties:
name:
description: Name of the ArangoDeployment Custom Resource within same
namespace as ArangoBackup Custom Resource.
description: Name of the ArangoDeployment Custom Resource within same namespace as ArangoBackup Custom Resource.
type: string
type: object
download:
description: Download Backup download settings
properties:
credentialsSecretName:
description: CredentialsSecretName is the name of the secret used
while accessing repository
description: CredentialsSecretName is the name of the secret used while accessing repository
type: string
id:
description: ID of the ArangoBackup to be downloaded
Expand All @@ -146,8 +130,7 @@ v1alpha:
type: string
type: object
lifetime:
description: 'Lifetime is the time after which the backup will be deleted.
Format: "1.5h" or "2h45m".'
description: 'Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".'
type: string
options:
description: Options specifies backup options
Expand All @@ -158,23 +141,20 @@ v1alpha:
If this value is set to true, backup is taken even if we are not able to acquire lock.
type: boolean
timeout:
description: Timeout for Backup creation request in seconds. Works
only when AsyncBackupCreation feature is set to false.
description: Timeout for Backup creation request in seconds. Works only when AsyncBackupCreation feature is set to false.
format: float
type: number
type: object
policyName:
description: PolicyName name of the ArangoBackupPolicy which created this
Custom Resource
description: PolicyName name of the ArangoBackupPolicy which created this Custom Resource
type: string
upload:
description: |-
Upload Backup upload settings.
This field can be removed and created again with different values. This operation will trigger upload again.
properties:
credentialsSecretName:
description: CredentialsSecretName is the name of the secret used
while accessing repository
description: CredentialsSecretName is the name of the secret used while accessing repository
type: string
repositoryURL:
description: |-
Expand Down
Loading

0 comments on commit 5c6655a

Please sign in to comment.