Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
managedpostgresoperatorhoppscalecomv1alpha1 "github.com/hoppscale/managed-postgres-operator/api/v1alpha1"
"github.com/hoppscale/managed-postgres-operator/internal/controller"
"github.com/hoppscale/managed-postgres-operator/internal/postgresql"
"github.com/hoppscale/managed-postgres-operator/internal/utils"
// +kubebuilder:scaffold:imports
)

Expand Down Expand Up @@ -163,7 +164,7 @@ func main() {
Metrics: metricsServerOptions,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "b707bc79.managed-postgres-operator.hoppscale.com",
LeaderElectionID: utils.GetLeaderElectionID(operatorInstanceName),
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
Expand Down
20 changes: 20 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package utils

import (
"crypto/sha256"
"fmt"
)

const OperatorInstanceAnnotationName string = "managed-postgres-operator.hoppscale.com/instance"

func IsManagedByOperatorInstance(annotations map[string]string, instanceName string) bool {
Expand All @@ -13,3 +18,18 @@ func IsManagedByOperatorInstance(annotations map[string]string, instanceName str

return false
}

func GetLeaderElectionID(instanceName string) string {
leaderName := "default"

if instanceName != "" {
leaderName = instanceName
}

h := sha256.New()
h.Write([]byte(leaderName))
leaderNameHash := fmt.Sprintf("%x", h.Sum(nil))
leaderElectionID := fmt.Sprintf("%.14s-%.8s.managed-postgres-operator.hoppscale.com", leaderName, leaderNameHash)

return leaderElectionID
}
40 changes: 40 additions & 0 deletions internal/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,44 @@ var _ = Describe("Utils functions", func() {
})
})
})

Context("Calling GetLeaderElectionID", func() {
When("operator's instance is not defined", func() {
It("should return the default id", func() {
result := GetLeaderElectionID("")
Expect(result).To(Equal("default-37a8eec1.managed-postgres-operator.hoppscale.com"))
Expect(len(result)).To(BeNumerically("<=", 63))
})
})

When("operator's instance is defined and the name has a standard length", func() {
It("should return the instance name with a unique id", func() {
result := GetLeaderElectionID("foobar")
Expect(result).To(Equal("foobar-c3ab8ff1.managed-postgres-operator.hoppscale.com"))
Expect(len(result)).To(BeNumerically("<=", 63))
})
})

When("operator's instance is defined and the name is too long", func() {
It("should return the first few characters of the instance name and a unique ID", func() {
result := GetLeaderElectionID("myverylonginstancename")
Expect(result).To(Equal("myverylonginst-3b8d6ea3.managed-postgres-operator.hoppscale.com"))
Expect(len(result)).To(BeNumerically("<=", 63))
})
})

When("multiple instances begin with the same characters", func() {
It("shouldn't cause a conflict", func() {
result1 := GetLeaderElectionID("postgresinstance-dev")
result2 := GetLeaderElectionID("postgresinstance-int")
result3 := GetLeaderElectionID("postgresinstance-test")
result4 := GetLeaderElectionID("postgresinstance-prod")

Expect(result1).NotTo(BeElementOf([]string{result2, result3, result4}))
Expect(result2).NotTo(BeElementOf([]string{result1, result3, result4}))
Expect(result3).NotTo(BeElementOf([]string{result1, result2, result4}))
Expect(result4).NotTo(BeElementOf([]string{result1, result2, result3}))
})
})
})
})
Loading