Skip to content

Commit 73c6f8e

Browse files
authored
Merge pull request #12 from hoppscale/set-dynamic-leader-election-id
feat(manager): use dynamic leader election id
2 parents b2a8a74 + 578db5a commit 73c6f8e

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

cmd/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
managedpostgresoperatorhoppscalecomv1alpha1 "github.com/hoppscale/managed-postgres-operator/api/v1alpha1"
2727
"github.com/hoppscale/managed-postgres-operator/internal/controller"
2828
"github.com/hoppscale/managed-postgres-operator/internal/postgresql"
29+
"github.com/hoppscale/managed-postgres-operator/internal/utils"
2930
// +kubebuilder:scaffold:imports
3031
)
3132

@@ -163,7 +164,7 @@ func main() {
163164
Metrics: metricsServerOptions,
164165
HealthProbeBindAddress: probeAddr,
165166
LeaderElection: enableLeaderElection,
166-
LeaderElectionID: "b707bc79.managed-postgres-operator.hoppscale.com",
167+
LeaderElectionID: utils.GetLeaderElectionID(operatorInstanceName),
167168
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
168169
// when the Manager ends. This requires the binary to immediately end when the
169170
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly

internal/utils/utils.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package utils
22

3+
import (
4+
"crypto/sha256"
5+
"fmt"
6+
)
7+
38
const OperatorInstanceAnnotationName string = "managed-postgres-operator.hoppscale.com/instance"
49

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

1419
return false
1520
}
21+
22+
func GetLeaderElectionID(instanceName string) string {
23+
leaderName := "default"
24+
25+
if instanceName != "" {
26+
leaderName = instanceName
27+
}
28+
29+
h := sha256.New()
30+
h.Write([]byte(leaderName))
31+
leaderNameHash := fmt.Sprintf("%x", h.Sum(nil))
32+
leaderElectionID := fmt.Sprintf("%.14s-%.8s.managed-postgres-operator.hoppscale.com", leaderName, leaderNameHash)
33+
34+
return leaderElectionID
35+
}

internal/utils/utils_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,44 @@ var _ = Describe("Utils functions", func() {
5555
})
5656
})
5757
})
58+
59+
Context("Calling GetLeaderElectionID", func() {
60+
When("operator's instance is not defined", func() {
61+
It("should return the default id", func() {
62+
result := GetLeaderElectionID("")
63+
Expect(result).To(Equal("default-37a8eec1.managed-postgres-operator.hoppscale.com"))
64+
Expect(len(result)).To(BeNumerically("<=", 63))
65+
})
66+
})
67+
68+
When("operator's instance is defined and the name has a standard length", func() {
69+
It("should return the instance name with a unique id", func() {
70+
result := GetLeaderElectionID("foobar")
71+
Expect(result).To(Equal("foobar-c3ab8ff1.managed-postgres-operator.hoppscale.com"))
72+
Expect(len(result)).To(BeNumerically("<=", 63))
73+
})
74+
})
75+
76+
When("operator's instance is defined and the name is too long", func() {
77+
It("should return the first few characters of the instance name and a unique ID", func() {
78+
result := GetLeaderElectionID("myverylonginstancename")
79+
Expect(result).To(Equal("myverylonginst-3b8d6ea3.managed-postgres-operator.hoppscale.com"))
80+
Expect(len(result)).To(BeNumerically("<=", 63))
81+
})
82+
})
83+
84+
When("multiple instances begin with the same characters", func() {
85+
It("shouldn't cause a conflict", func() {
86+
result1 := GetLeaderElectionID("postgresinstance-dev")
87+
result2 := GetLeaderElectionID("postgresinstance-int")
88+
result3 := GetLeaderElectionID("postgresinstance-test")
89+
result4 := GetLeaderElectionID("postgresinstance-prod")
90+
91+
Expect(result1).NotTo(BeElementOf([]string{result2, result3, result4}))
92+
Expect(result2).NotTo(BeElementOf([]string{result1, result3, result4}))
93+
Expect(result3).NotTo(BeElementOf([]string{result1, result2, result4}))
94+
Expect(result4).NotTo(BeElementOf([]string{result1, result2, result3}))
95+
})
96+
})
97+
})
5898
})

0 commit comments

Comments
 (0)