From 0011bf6b0b6014e2b6cb79ffb917314a7cb4c1a5 Mon Sep 17 00:00:00 2001 From: Johan Oskarsson Date: Tue, 16 May 2023 09:41:18 -0700 Subject: [PATCH] Validate lock identity Ensure that the lock identity is not empty. This can cause unexpected issues during leader election. Kubernetes-commit: 5519b89a28eeea5a5b134092242aff770fcc07eb --- tools/leaderelection/leaderelection.go | 5 +++ tools/leaderelection/leaderelection_test.go | 37 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tools/leaderelection/leaderelection.go b/tools/leaderelection/leaderelection.go index 940e7161..c1151baf 100644 --- a/tools/leaderelection/leaderelection.go +++ b/tools/leaderelection/leaderelection.go @@ -99,6 +99,11 @@ func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) { if lec.Lock == nil { return nil, fmt.Errorf("Lock must not be nil.") } + id := lec.Lock.Identity() + if id == "" { + return nil, fmt.Errorf("Lock identity is empty") + } + le := LeaderElector{ config: lec, clock: clock.RealClock{}, diff --git a/tools/leaderelection/leaderelection_test.go b/tools/leaderelection/leaderelection_test.go index 41368503..02fa6a1d 100644 --- a/tools/leaderelection/leaderelection_test.go +++ b/tools/leaderelection/leaderelection_test.go @@ -37,6 +37,8 @@ import ( rl "k8s.io/client-go/tools/leaderelection/resourcelock" "k8s.io/client-go/tools/record" "k8s.io/utils/clock" + + "github.com/stretchr/testify/assert" ) func createLockObject(t *testing.T, objectType, namespace, name string, record *rl.LeaderElectionRecord) (obj runtime.Object) { @@ -753,6 +755,41 @@ func testReleaseOnCancellation(t *testing.T, objectType string) { } } +func TestLeaderElectionConfigValidation(t *testing.T) { + resourceLockConfig := rl.ResourceLockConfig{ + Identity: "baz", + } + + lock := &rl.LeaseLock{ + LockConfig: resourceLockConfig, + } + + lec := LeaderElectionConfig{ + Lock: lock, + LeaseDuration: 15 * time.Second, + RenewDeadline: 2 * time.Second, + RetryPeriod: 1 * time.Second, + + ReleaseOnCancel: true, + + Callbacks: LeaderCallbacks{ + OnNewLeader: func(identity string) {}, + OnStoppedLeading: func() {}, + OnStartedLeading: func(context.Context) {}, + }, + } + + _, err := NewLeaderElector(lec) + assert.NoError(t, err) + + // Invalid lock identity + resourceLockConfig.Identity = "" + lock.LockConfig = resourceLockConfig + lec.Lock = lock + _, err = NewLeaderElector(lec) + assert.Error(t, err, fmt.Errorf("Lock identity is empty")) +} + func assertEqualEvents(t *testing.T, expected []string, actual <-chan string) { c := time.After(wait.ForeverTestTimeout) for _, e := range expected {