Skip to content

Commit 9c9ae5f

Browse files
authored
Merge pull request #24 from andrewsykim/namespace-discovery
discover in cluster namespace for leader election
2 parents 2d2f98b + c4ce8f5 commit 9c9ae5f

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

leaderelection/leader_election.go

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ package leaderelection
1919
import (
2020
"context"
2121
"fmt"
22+
"io/ioutil"
2223
"os"
2324
"regexp"
25+
"strings"
2426
"time"
2527

2628
"k8s.io/api/core/v1"
@@ -62,16 +64,15 @@ type leaderElection struct {
6264
}
6365

6466
// NewLeaderElection returns the default & preferred leader election type
65-
func NewLeaderElection(clientset kubernetes.Interface, lockName, lockNamespace string, runFunc func(ctx context.Context)) *leaderElection {
66-
return NewLeaderElectionWithLeases(clientset, lockName, lockNamespace, runFunc)
67+
func NewLeaderElection(clientset kubernetes.Interface, lockName string, runFunc func(ctx context.Context)) *leaderElection {
68+
return NewLeaderElectionWithLeases(clientset, lockName, runFunc)
6769
}
6870

6971
// NewLeaderElectionWithLeases returns an implementation of leader election using Leases
70-
func NewLeaderElectionWithLeases(clientset kubernetes.Interface, lockName, lockNamespace string, runFunc func(ctx context.Context)) *leaderElection {
72+
func NewLeaderElectionWithLeases(clientset kubernetes.Interface, lockName string, runFunc func(ctx context.Context)) *leaderElection {
7173
return &leaderElection{
7274
runFunc: runFunc,
7375
lockName: lockName,
74-
namespace: lockNamespace,
7576
resourceLock: resourcelock.LeasesResourceLock,
7677
leaseDuration: defaultLeaseDuration,
7778
renewDeadline: defaultRenewDeadline,
@@ -81,11 +82,10 @@ func NewLeaderElectionWithLeases(clientset kubernetes.Interface, lockName, lockN
8182
}
8283

8384
// NewLeaderElectionWithEndpoints returns an implementation of leader election using Endpoints
84-
func NewLeaderElectionWithEndpoints(clientset kubernetes.Interface, lockName, lockNamespace string, runFunc func(ctx context.Context)) *leaderElection {
85+
func NewLeaderElectionWithEndpoints(clientset kubernetes.Interface, lockName string, runFunc func(ctx context.Context)) *leaderElection {
8586
return &leaderElection{
8687
runFunc: runFunc,
8788
lockName: lockName,
88-
namespace: lockNamespace,
8989
resourceLock: resourcelock.EndpointsResourceLock,
9090
leaseDuration: defaultLeaseDuration,
9191
renewDeadline: defaultRenewDeadline,
@@ -95,11 +95,10 @@ func NewLeaderElectionWithEndpoints(clientset kubernetes.Interface, lockName, lo
9595
}
9696

9797
// NewLeaderElectionWithConfigMaps returns an implementation of leader election using ConfigMaps
98-
func NewLeaderElectionWithConfigMaps(clientset kubernetes.Interface, lockName, lockNamespace string, runFunc func(ctx context.Context)) *leaderElection {
98+
func NewLeaderElectionWithConfigMaps(clientset kubernetes.Interface, lockName string, runFunc func(ctx context.Context)) *leaderElection {
9999
return &leaderElection{
100100
runFunc: runFunc,
101101
lockName: lockName,
102-
namespace: lockNamespace,
103102
resourceLock: resourcelock.ConfigMapsResourceLock,
104103
leaseDuration: defaultLeaseDuration,
105104
renewDeadline: defaultRenewDeadline,
@@ -108,20 +107,29 @@ func NewLeaderElectionWithConfigMaps(clientset kubernetes.Interface, lockName, l
108107
}
109108
}
110109

111-
func (l *leaderElection) WithIdentity(identity string) {
110+
func (l *leaderElection) WithIdentity(identity string) *leaderElection {
112111
l.identity = identity
112+
return l
113113
}
114114

115-
func (l *leaderElection) WithLeaseDuration(leaseDuration time.Duration) {
115+
func (l *leaderElection) WithNamespace(namespace string) *leaderElection {
116+
l.namespace = namespace
117+
return l
118+
}
119+
120+
func (l *leaderElection) WithLeaseDuration(leaseDuration time.Duration) *leaderElection {
116121
l.leaseDuration = leaseDuration
122+
return l
117123
}
118124

119-
func (l *leaderElection) WithRenewDeadline(renewDeadline time.Duration) {
125+
func (l *leaderElection) WithRenewDeadline(renewDeadline time.Duration) *leaderElection {
120126
l.renewDeadline = renewDeadline
127+
return l
121128
}
122129

123-
func (l *leaderElection) WithRetryPeriod(retryPeriod time.Duration) {
130+
func (l *leaderElection) WithRetryPeriod(retryPeriod time.Duration) *leaderElection {
124131
l.retryPeriod = retryPeriod
132+
return l
125133
}
126134

127135
func (l *leaderElection) Run() error {
@@ -134,6 +142,10 @@ func (l *leaderElection) Run() error {
134142
l.identity = id
135143
}
136144

145+
if l.namespace == "" {
146+
l.namespace = inClusterNamespace()
147+
}
148+
137149
broadcaster := record.NewBroadcaster()
138150
broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: l.clientset.CoreV1().Events(l.namespace)})
139151
eventRecorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: fmt.Sprintf("%s/%s", l.lockName, string(l.identity))})
@@ -185,3 +197,20 @@ func sanitizeName(name string) string {
185197
}
186198
return name
187199
}
200+
201+
// inClusterNamespace returns the namespace in which the pod is running in by checking
202+
// the env var POD_NAMESPACE, then the file /var/run/secrets/kubernetes.io/serviceaccount/namespace.
203+
// if neither returns a valid namespace, the "default" namespace is returned
204+
func inClusterNamespace() string {
205+
if ns := os.Getenv("POD_NAMESPACE"); ns != "" {
206+
return ns
207+
}
208+
209+
if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
210+
if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
211+
return ns
212+
}
213+
}
214+
215+
return "default"
216+
}

0 commit comments

Comments
 (0)