diff --git a/pkg/apis/coordination/types.go b/pkg/apis/coordination/types.go index 72d0a3a6218..ed29380829a 100644 --- a/pkg/apis/coordination/types.go +++ b/pkg/apis/coordination/types.go @@ -108,6 +108,8 @@ type LeaseCandidate struct { // LeaseCandidateSpec is a specification of a Lease. type LeaseCandidateSpec struct { // LeaseName is the name of the lease for which this candidate is contending. + // The limits on this field are the same as on Lease.name. Multiple lease candidates + // may reference the same Lease.name. // This field is immutable. // +required LeaseName string diff --git a/pkg/controlplane/apiserver/aggregator.go b/pkg/controlplane/apiserver/aggregator.go index 5edb9976dcb..37d5265d59d 100644 --- a/pkg/controlplane/apiserver/aggregator.go +++ b/pkg/controlplane/apiserver/aggregator.go @@ -285,6 +285,7 @@ func DefaultGenericAPIServicePriorities() map[schema.GroupVersion]APIServicePrio {Group: "admissionregistration.k8s.io", Version: "v1beta1"}: {Group: 16700, Version: 12}, {Group: "admissionregistration.k8s.io", Version: "v1alpha1"}: {Group: 16700, Version: 9}, {Group: "coordination.k8s.io", Version: "v1"}: {Group: 16500, Version: 15}, + {Group: "coordination.k8s.io", Version: "v1beta1"}: {Group: 16500, Version: 13}, {Group: "coordination.k8s.io", Version: "v1alpha2"}: {Group: 16500, Version: 12}, {Group: "discovery.k8s.io", Version: "v1"}: {Group: 16200, Version: 15}, {Group: "discovery.k8s.io", Version: "v1beta1"}: {Group: 16200, Version: 12}, diff --git a/pkg/controlplane/apiserver/server.go b/pkg/controlplane/apiserver/server.go index dd36d9977f7..45bc55bc7b8 100644 --- a/pkg/controlplane/apiserver/server.go +++ b/pkg/controlplane/apiserver/server.go @@ -166,7 +166,7 @@ func (c completedConfig) New(name string, delegationTarget genericapiserver.Dele if utilfeature.DefaultFeatureGate.Enabled(apiserverfeatures.CoordinatedLeaderElection) { leaseInformer := s.VersionedInformers.Coordination().V1().Leases() - lcInformer := s.VersionedInformers.Coordination().V1alpha2().LeaseCandidates() + lcInformer := s.VersionedInformers.Coordination().V1beta1().LeaseCandidates() // Ensure that informers are registered before starting. Coordinated Leader Election leader-elected // and may register informer handlers after they are started. _ = leaseInformer.Informer() @@ -177,7 +177,7 @@ func (c completedConfig) New(name string, delegationTarget genericapiserver.Dele leaseInformer, lcInformer, client.CoordinationV1(), - client.CoordinationV1alpha2(), + client.CoordinationV1beta1(), ) gccontroller := leaderelection.NewLeaseCandidateGC( client, diff --git a/pkg/controlplane/controller/leaderelection/election.go b/pkg/controlplane/controller/leaderelection/election.go index 9b77345f76c..3c4814d4523 100644 --- a/pkg/controlplane/controller/leaderelection/election.go +++ b/pkg/controlplane/controller/leaderelection/election.go @@ -22,12 +22,12 @@ import ( "github.com/blang/semver/v4" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" "k8s.io/utils/clock" ) -func pickBestLeaderOldestEmulationVersion(candidates []*v1alpha2.LeaseCandidate) *v1alpha2.LeaseCandidate { - var electee *v1alpha2.LeaseCandidate +func pickBestLeaderOldestEmulationVersion(candidates []*v1beta1.LeaseCandidate) *v1beta1.LeaseCandidate { + var electee *v1beta1.LeaseCandidate for _, c := range candidates { if !validLeaseCandidateForOldestEmulationVersion(c) { continue @@ -39,7 +39,7 @@ func pickBestLeaderOldestEmulationVersion(candidates []*v1alpha2.LeaseCandidate) return electee } -func pickBestStrategy(candidates []*v1alpha2.LeaseCandidate) (v1.CoordinatedLeaseStrategy, error) { +func pickBestStrategy(candidates []*v1beta1.LeaseCandidate) (v1.CoordinatedLeaseStrategy, error) { nilStrategy := v1.CoordinatedLeaseStrategy("") if len(candidates) == 0 { return nilStrategy, fmt.Errorf("no candidates") @@ -62,7 +62,7 @@ func pickBestStrategy(candidates []*v1alpha2.LeaseCandidate) (v1.CoordinatedLeas return strategy, nil } -func validLeaseCandidateForOldestEmulationVersion(l *v1alpha2.LeaseCandidate) bool { +func validLeaseCandidateForOldestEmulationVersion(l *v1beta1.LeaseCandidate) bool { _, err := semver.ParseTolerant(l.Spec.EmulationVersion) if err != nil { return false @@ -71,7 +71,7 @@ func validLeaseCandidateForOldestEmulationVersion(l *v1alpha2.LeaseCandidate) bo return err == nil } -func getEmulationVersionOrZero(l *v1alpha2.LeaseCandidate) semver.Version { +func getEmulationVersionOrZero(l *v1beta1.LeaseCandidate) semver.Version { value := l.Spec.EmulationVersion v, err := semver.ParseTolerant(value) if err != nil { @@ -80,7 +80,7 @@ func getEmulationVersionOrZero(l *v1alpha2.LeaseCandidate) semver.Version { return v } -func getBinaryVersionOrZero(l *v1alpha2.LeaseCandidate) semver.Version { +func getBinaryVersionOrZero(l *v1beta1.LeaseCandidate) semver.Version { value := l.Spec.BinaryVersion v, err := semver.ParseTolerant(value) if err != nil { @@ -90,7 +90,7 @@ func getBinaryVersionOrZero(l *v1alpha2.LeaseCandidate) semver.Version { } // -1: lhs better, 1: rhs better -func compare(lhs, rhs *v1alpha2.LeaseCandidate) int { +func compare(lhs, rhs *v1beta1.LeaseCandidate) int { l := getEmulationVersionOrZero(lhs) r := getEmulationVersionOrZero(rhs) result := l.Compare(r) @@ -115,7 +115,7 @@ func isLeaseExpired(clock clock.Clock, lease *v1.Lease) bool { lease.Spec.RenewTime.Add(time.Duration(*lease.Spec.LeaseDurationSeconds)*time.Second).Before(currentTime) } -func isLeaseCandidateExpired(clock clock.Clock, lease *v1alpha2.LeaseCandidate) bool { +func isLeaseCandidateExpired(clock clock.Clock, lease *v1beta1.LeaseCandidate) bool { currentTime := clock.Now() return lease.Spec.RenewTime == nil || lease.Spec.RenewTime.Add(leaseCandidateValidDuration).Before(currentTime) diff --git a/pkg/controlplane/controller/leaderelection/election_test.go b/pkg/controlplane/controller/leaderelection/election_test.go index f055ea4a9fa..e72f0cbdf57 100644 --- a/pkg/controlplane/controller/leaderelection/election_test.go +++ b/pkg/controlplane/controller/leaderelection/election_test.go @@ -22,42 +22,42 @@ import ( "github.com/blang/semver/v4" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { tests := []struct { name string - candidates []*v1alpha2.LeaseCandidate - want *v1alpha2.LeaseCandidate + candidates []*v1beta1.LeaseCandidate + want *v1beta1.LeaseCandidate }{ { name: "empty", - candidates: []*v1alpha2.LeaseCandidate{}, + candidates: []*v1beta1.LeaseCandidate{}, want: nil, }, { name: "single candidate", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, }, }, - want: &v1alpha2.LeaseCandidate{ + want: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -65,14 +65,14 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { }, { name: "multiple candidates, different emulation versions", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now().Add(-1 * time.Hour)}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -83,18 +83,18 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.2.0", BinaryVersion: "0.2.0", }, }, }, - want: &v1alpha2.LeaseCandidate{ + want: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "v1", BinaryVersion: "v1", }, @@ -102,14 +102,14 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { }, { name: "multiple candidates, same emulation versions, different binary versions", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now().Add(-1 * time.Hour)}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -120,18 +120,18 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.2.0", }, }, }, - want: &v1alpha2.LeaseCandidate{ + want: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -139,14 +139,14 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { }, { name: "multiple candidates, same emulation versions, same binary versions, different creation timestamps", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now().Add(-1 * time.Hour)}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -157,18 +157,18 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, }, }, - want: &v1alpha2.LeaseCandidate{ + want: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -192,13 +192,13 @@ func TestPickBestLeaderOldestEmulationVersion(t *testing.T) { func TestValidLeaseCandidateForOldestEmulationVersion(t *testing.T) { tests := []struct { name string - candidate *v1alpha2.LeaseCandidate + candidate *v1beta1.LeaseCandidate want bool }{ { name: "valid emulation and binary versions", - candidate: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + candidate: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "0.1.0", }, @@ -207,8 +207,8 @@ func TestValidLeaseCandidateForOldestEmulationVersion(t *testing.T) { }, { name: "invalid emulation version", - candidate: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + candidate: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "invalid", BinaryVersion: "0.1.0", }, @@ -217,8 +217,8 @@ func TestValidLeaseCandidateForOldestEmulationVersion(t *testing.T) { }, { name: "invalid binary version", - candidate: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + candidate: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", BinaryVersion: "invalid", }, @@ -239,13 +239,13 @@ func TestValidLeaseCandidateForOldestEmulationVersion(t *testing.T) { func TestGetEmulationVersion(t *testing.T) { tests := []struct { name string - candidate *v1alpha2.LeaseCandidate + candidate *v1beta1.LeaseCandidate want semver.Version }{ { name: "valid emulation version", - candidate: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + candidate: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "0.1.0", }, }, @@ -265,13 +265,13 @@ func TestGetEmulationVersion(t *testing.T) { func TestGetBinaryVersion(t *testing.T) { tests := []struct { name string - candidate *v1alpha2.LeaseCandidate + candidate *v1beta1.LeaseCandidate want semver.Version }{ { name: "valid binary version", - candidate: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + candidate: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ BinaryVersion: "0.3.0", }, }, @@ -292,14 +292,14 @@ func TestCompare(t *testing.T) { nowTime := time.Now() cases := []struct { name string - lhs *v1alpha2.LeaseCandidate - rhs *v1alpha2.LeaseCandidate + lhs *v1beta1.LeaseCandidate + rhs *v1beta1.LeaseCandidate expectedResult int }{ { name: "identical versions earlier timestamp", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, @@ -307,8 +307,8 @@ func TestCompare(t *testing.T) { CreationTimestamp: metav1.Time{Time: nowTime.Add(time.Duration(1))}, }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, @@ -320,9 +320,9 @@ func TestCompare(t *testing.T) { }, { name: "no lhs version", - lhs: &v1alpha2.LeaseCandidate{}, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{}, + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, @@ -331,25 +331,25 @@ func TestCompare(t *testing.T) { }, { name: "no rhs version", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, }, - rhs: &v1alpha2.LeaseCandidate{}, + rhs: &v1beta1.LeaseCandidate{}, expectedResult: 1, }, { name: "invalid lhs version", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "xyz", BinaryVersion: "xyz", }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, @@ -358,14 +358,14 @@ func TestCompare(t *testing.T) { }, { name: "invalid rhs version", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.21.0", }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "xyz", BinaryVersion: "xyz", }, @@ -374,14 +374,14 @@ func TestCompare(t *testing.T) { }, { name: "lhs less than rhs", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.20.0", }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.20.0", }, @@ -390,14 +390,14 @@ func TestCompare(t *testing.T) { }, { name: "rhs less than lhs", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.20.0", BinaryVersion: "1.20.0", }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.20.0", }, @@ -406,14 +406,14 @@ func TestCompare(t *testing.T) { }, { name: "lhs less than rhs, lexographical order check", - lhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + lhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.2.0", BinaryVersion: "1.20.0", }, }, - rhs: &v1alpha2.LeaseCandidate{ - Spec: v1alpha2.LeaseCandidateSpec{ + rhs: &v1beta1.LeaseCandidate{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.20.0", }, @@ -434,18 +434,18 @@ func TestCompare(t *testing.T) { func TestShouldReelect(t *testing.T) { cases := []struct { name string - candidates []*v1alpha2.LeaseCandidate - currentLeader *v1alpha2.LeaseCandidate + candidates []*v1beta1.LeaseCandidate + currentLeader *v1beta1.LeaseCandidate expectResult bool }{ { name: "candidate with newer binary version", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, @@ -455,18 +455,18 @@ func TestShouldReelect(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.20.0", Strategy: v1.OldestEmulationVersion, }, }, }, - currentLeader: &v1alpha2.LeaseCandidate{ + currentLeader: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, @@ -476,12 +476,12 @@ func TestShouldReelect(t *testing.T) { }, { name: "no newer candidates", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, @@ -491,18 +491,18 @@ func TestShouldReelect(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, }, }, }, - currentLeader: &v1alpha2.LeaseCandidate{ + currentLeader: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, @@ -512,12 +512,12 @@ func TestShouldReelect(t *testing.T) { }, { name: "no candidates", - candidates: []*v1alpha2.LeaseCandidate{}, - currentLeader: &v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{}, + currentLeader: &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", Strategy: v1.OldestEmulationVersion, @@ -539,19 +539,19 @@ func TestShouldReelect(t *testing.T) { func TestPickBestStrategy(t *testing.T) { tests := []struct { name string - candidates []*v1alpha2.LeaseCandidate + candidates []*v1beta1.LeaseCandidate wantStrategy v1.CoordinatedLeaseStrategy wantError bool }{ { name: "single candidate, single preferred strategy", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", Strategy: v1.OldestEmulationVersion, }, @@ -562,13 +562,13 @@ func TestPickBestStrategy(t *testing.T) { }, { name: "multiple candidates, different preferred strategies should fail", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", Strategy: v1.OldestEmulationVersion, }, @@ -578,7 +578,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", Strategy: v1.CoordinatedLeaseStrategy("foo.com/bar"), }, @@ -588,13 +588,13 @@ func TestPickBestStrategy(t *testing.T) { }, { name: "multiple candidates, different preferred strategy different binary version should resolve", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.32.0", Strategy: v1.OldestEmulationVersion, @@ -605,7 +605,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.CoordinatedLeaseStrategy("foo.com/bar"), @@ -617,13 +617,13 @@ func TestPickBestStrategy(t *testing.T) { }, { name: "multiple candidates, different preferred strategy different binary version should resolve, order agnostic", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.CoordinatedLeaseStrategy("foo.com/bar"), @@ -634,7 +634,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.32.0", Strategy: v1.OldestEmulationVersion, @@ -646,13 +646,13 @@ func TestPickBestStrategy(t *testing.T) { }, { name: "multiple candidates, different preferred strategy different binary version string comparison check", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.1.10", Strategy: v1.OldestEmulationVersion, @@ -663,7 +663,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.1.2", Strategy: v1.CoordinatedLeaseStrategy("foo.com/bar"), @@ -676,13 +676,13 @@ func TestPickBestStrategy(t *testing.T) { { name: "multiple candidates, same preferred strategy", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.OldestEmulationVersion, @@ -693,7 +693,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.OldestEmulationVersion, @@ -705,13 +705,13 @@ func TestPickBestStrategy(t *testing.T) { }, { name: "multiple candidates, conflicting preferred strategy", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.OldestEmulationVersion, @@ -722,7 +722,7 @@ func TestPickBestStrategy(t *testing.T) { Name: "candidate2", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", BinaryVersion: "1.31.0", Strategy: v1.CoordinatedLeaseStrategy("foo.com/bar"), @@ -748,7 +748,7 @@ func TestPickBestStrategy(t *testing.T) { } } -func shouldReelect(candidates []*v1alpha2.LeaseCandidate, currentLeader *v1alpha2.LeaseCandidate) bool { +func shouldReelect(candidates []*v1beta1.LeaseCandidate, currentLeader *v1beta1.LeaseCandidate) bool { pickedLeader := pickBestLeaderOldestEmulationVersion(candidates) if pickedLeader == nil { return false diff --git a/pkg/controlplane/controller/leaderelection/leaderelection_controller.go b/pkg/controlplane/controller/leaderelection/leaderelection_controller.go index eebebfd2966..0df141a29ae 100644 --- a/pkg/controlplane/controller/leaderelection/leaderelection_controller.go +++ b/pkg/controlplane/controller/leaderelection/leaderelection_controller.go @@ -24,7 +24,7 @@ import ( "golang.org/x/sync/errgroup" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -32,9 +32,9 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" coordinationv1informers "k8s.io/client-go/informers/coordination/v1" - coordinationv1alpha2 "k8s.io/client-go/informers/coordination/v1alpha2" + coordinationv1beta1 "k8s.io/client-go/informers/coordination/v1beta1" coordinationv1client "k8s.io/client-go/kubernetes/typed/coordination/v1" - coordinationv1alpha2client "k8s.io/client-go/kubernetes/typed/coordination/v1alpha2" + coordinationv1beta1client "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" @@ -65,8 +65,8 @@ type Controller struct { leaseClient coordinationv1client.CoordinationV1Interface leaseRegistration cache.ResourceEventHandlerRegistration - leaseCandidateInformer coordinationv1alpha2.LeaseCandidateInformer - leaseCandidateClient coordinationv1alpha2client.CoordinationV1alpha2Interface + leaseCandidateInformer coordinationv1beta1.LeaseCandidateInformer + leaseCandidateClient coordinationv1beta1client.CoordinationV1beta1Interface leaseCandidateRegistration cache.ResourceEventHandlerRegistration queue workqueue.TypedRateLimitingInterface[types.NamespacedName] @@ -110,7 +110,7 @@ func (c *Controller) Run(ctx context.Context, workers int) { <-ctx.Done() } -func NewController(leaseInformer coordinationv1informers.LeaseInformer, leaseCandidateInformer coordinationv1alpha2.LeaseCandidateInformer, leaseClient coordinationv1client.CoordinationV1Interface, leaseCandidateClient coordinationv1alpha2client.CoordinationV1alpha2Interface) (*Controller, error) { +func NewController(leaseInformer coordinationv1informers.LeaseInformer, leaseCandidateInformer coordinationv1beta1.LeaseCandidateInformer, leaseClient coordinationv1client.CoordinationV1Interface, leaseCandidateClient coordinationv1beta1client.CoordinationV1beta1Interface) (*Controller, error) { c := &Controller{ leaseInformer: leaseInformer, leaseCandidateInformer: leaseCandidateInformer, @@ -175,7 +175,7 @@ func (c *Controller) processNextElectionItem(ctx context.Context) bool { } func (c *Controller) enqueueCandidate(obj any) { - lc, ok := obj.(*v1alpha2.LeaseCandidate) + lc, ok := obj.(*v1beta1.LeaseCandidate) if !ok { return } @@ -197,7 +197,7 @@ func (c *Controller) enqueueLease(obj any) { c.queue.Add(types.NamespacedName{Namespace: lease.Namespace, Name: lease.Name}) } -func (c *Controller) electionNeeded(candidates []*v1alpha2.LeaseCandidate, leaseNN types.NamespacedName) (bool, error) { +func (c *Controller) electionNeeded(candidates []*v1beta1.LeaseCandidate, leaseNN types.NamespacedName) (bool, error) { lease, err := c.leaseInformer.Lister().Leases(leaseNN.Namespace).Get(leaseNN.Name) if err != nil && !apierrors.IsNotFound(err) { return false, fmt.Errorf("error reading lease: %w", err) @@ -316,7 +316,7 @@ func (c *Controller) reconcileElectionStep(ctx context.Context, leaseNN types.Na } } - var ackedCandidates []*v1alpha2.LeaseCandidate + var ackedCandidates []*v1beta1.LeaseCandidate for _, candidate := range candidates { if candidate.Spec.RenewTime.Add(electionDuration).After(now) { ackedCandidates = append(ackedCandidates, candidate) @@ -422,12 +422,12 @@ func (c *Controller) reconcileElectionStep(ctx context.Context, leaseNN types.Na return defaultRequeueInterval, nil } -func (c *Controller) listAdmissableCandidates(leaseNN types.NamespacedName) ([]*v1alpha2.LeaseCandidate, error) { +func (c *Controller) listAdmissableCandidates(leaseNN types.NamespacedName) ([]*v1beta1.LeaseCandidate, error) { leases, err := c.leaseCandidateInformer.Lister().LeaseCandidates(leaseNN.Namespace).List(labels.Everything()) if err != nil { return nil, err } - var results []*v1alpha2.LeaseCandidate + var results []*v1beta1.LeaseCandidate for _, l := range leases { if l.Spec.LeaseName != leaseNN.Name { continue diff --git a/pkg/controlplane/controller/leaderelection/leaderelection_controller_test.go b/pkg/controlplane/controller/leaderelection/leaderelection_controller_test.go index d0f14225581..e3f3d80dea2 100644 --- a/pkg/controlplane/controller/leaderelection/leaderelection_controller_test.go +++ b/pkg/controlplane/controller/leaderelection/leaderelection_controller_test.go @@ -25,7 +25,7 @@ import ( "time" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -42,7 +42,7 @@ func TestReconcileElectionStep(t *testing.T) { tests := []struct { name string leaseNN types.NamespacedName - candidates []*v1alpha2.LeaseCandidate + candidates []*v1beta1.LeaseCandidate existingLease *v1.Lease expectLease bool expectedHolderIdentity *string @@ -55,7 +55,7 @@ func TestReconcileElectionStep(t *testing.T) { { name: "no candidates, no lease, noop", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{}, + candidates: []*v1beta1.LeaseCandidate{}, existingLease: nil, expectLease: false, expectedHolderIdentity: nil, @@ -66,7 +66,7 @@ func TestReconcileElectionStep(t *testing.T) { { name: "no candidates, lease exists. noop, not managed by CLE", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{}, + candidates: []*v1beta1.LeaseCandidate{}, existingLease: &v1.Lease{}, expectLease: false, expectedHolderIdentity: nil, @@ -77,13 +77,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, no existing lease should create lease", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -102,13 +102,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, lease exists, unoptimal should set preferredHolder", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -121,7 +121,7 @@ func TestReconcileElectionStep(t *testing.T) { Namespace: "default", Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.18.0", BinaryVersion: "1.18.0", @@ -151,13 +151,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, should only elect leader from acked candidates", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -171,7 +171,7 @@ func TestReconcileElectionStep(t *testing.T) { Namespace: "default", Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.20.0", BinaryVersion: "1.20.0", @@ -191,13 +191,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, lease exists, lease expired", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -226,13 +226,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, no acked candidates should return error", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -251,13 +251,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, should ping on election", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -277,13 +277,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidate exist, pinged candidate should have until electionDuration until election decision is made", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -302,13 +302,13 @@ func TestReconcileElectionStep(t *testing.T) { { name: "candidates exist, lease exists, lease expired, 3rdparty strategy", leaseNN: types.NamespacedName{Namespace: "default", Name: "component-A"}, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -344,9 +344,9 @@ func TestReconcileElectionStep(t *testing.T) { controller, err := NewController( informerFactory.Coordination().V1().Leases(), - informerFactory.Coordination().V1alpha2().LeaseCandidates(), + informerFactory.Coordination().V1beta1().LeaseCandidates(), client.CoordinationV1(), - client.CoordinationV1alpha2(), + client.CoordinationV1beta1(), ) controller.clock = fakeClock if err != nil { @@ -363,7 +363,7 @@ func TestReconcileElectionStep(t *testing.T) { // Set up the fake client with the candidates for _, candidate := range tc.candidates { - _, err = client.CoordinationV1alpha2().LeaseCandidates(candidate.Namespace).Create(ctx, candidate, metav1.CreateOptions{}) + _, err = client.CoordinationV1beta1().LeaseCandidates(candidate.Namespace).Create(ctx, candidate, metav1.CreateOptions{}) if err != nil { t.Fatal(err) } @@ -414,11 +414,11 @@ func TestReconcileElectionStep(t *testing.T) { // Verify that ping to candidate was issued if tc.candidatesPinged { pinged := false - candidatesList, err := client.CoordinationV1alpha2().LeaseCandidates(tc.leaseNN.Namespace).List(ctx, metav1.ListOptions{}) + candidatesList, err := client.CoordinationV1beta1().LeaseCandidates(tc.leaseNN.Namespace).List(ctx, metav1.ListOptions{}) if err != nil { t.Fatal(err) } - oldCandidateMap := make(map[string]*v1alpha2.LeaseCandidate) + oldCandidateMap := make(map[string]*v1beta1.LeaseCandidate) for _, candidate := range tc.candidates { oldCandidateMap[candidate.Name] = candidate } @@ -443,20 +443,20 @@ func TestController(t *testing.T) { cases := []struct { name string leases []*v1.Lease - candidates []*v1alpha2.LeaseCandidate - createAfterControllerStart []*v1alpha2.LeaseCandidate + candidates []*v1beta1.LeaseCandidate + createAfterControllerStart []*v1beta1.LeaseCandidate deleteLeaseAfterControllerStart []types.NamespacedName expectedLeaderLeases []*v1.Lease }{ { name: "single candidate leader election", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -479,13 +479,13 @@ func TestController(t *testing.T) { }, { name: "multiple candidate leader election", - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -498,7 +498,7 @@ func TestController(t *testing.T) { Namespace: "kube-system", Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.20.0", @@ -511,7 +511,7 @@ func TestController(t *testing.T) { Namespace: "kube-system", Name: "component-identity-3", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.20.0", BinaryVersion: "1.20.0", @@ -547,13 +547,13 @@ func TestController(t *testing.T) { }, }, }, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -593,13 +593,13 @@ func TestController(t *testing.T) { }, }, }, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -636,13 +636,13 @@ func TestController(t *testing.T) { }, }, }, - candidates: []*v1alpha2.LeaseCandidate{ + candidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-1", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.20.0", BinaryVersion: "1.20.0", @@ -651,13 +651,13 @@ func TestController(t *testing.T) { }, }, }, - createAfterControllerStart: []*v1alpha2.LeaseCandidate{ + createAfterControllerStart: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Namespace: "kube-system", Name: "component-identity-2", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -693,9 +693,9 @@ func TestController(t *testing.T) { informerFactory := informers.NewSharedInformerFactory(client, 0) controller, err := NewController( informerFactory.Coordination().V1().Leases(), - informerFactory.Coordination().V1alpha2().LeaseCandidates(), + informerFactory.Coordination().V1beta1().LeaseCandidates(), client.CoordinationV1(), - client.CoordinationV1alpha2(), + client.CoordinationV1beta1(), ) if err != nil { t.Fatal(err) @@ -710,7 +710,7 @@ func TestController(t *testing.T) { } for _, obj := range tc.candidates { t.Logf("Pre-creating lease candidate %s/%s", obj.Namespace, obj.Name) - _, err := client.CoordinationV1alpha2().LeaseCandidates(obj.Namespace).Create(ctx, obj, metav1.CreateOptions{}) + _, err := client.CoordinationV1beta1().LeaseCandidates(obj.Namespace).Create(ctx, obj, metav1.CreateOptions{}) if err != nil { t.Fatalf("Error pre-creating lease candidate %s/%s: %v", obj.Namespace, obj.Name, err) } @@ -748,7 +748,7 @@ func TestController(t *testing.T) { if *ph == *l.Spec.HolderIdentity { continue } - if _, err := client.CoordinationV1alpha2().LeaseCandidates(expectedLease.Namespace).Get(ctx, *l.Spec.HolderIdentity, metav1.GetOptions{}); err != nil { + if _, err := client.CoordinationV1beta1().LeaseCandidates(expectedLease.Namespace).Get(ctx, *l.Spec.HolderIdentity, metav1.GetOptions{}); err != nil { continue // only candidate-aware controllers will follow preferredHolder } @@ -772,7 +772,7 @@ func TestController(t *testing.T) { case <-ctx.Done(): return case <-ticker.C: - cs, err := client.CoordinationV1alpha2().LeaseCandidates("").List(ctx, metav1.ListOptions{}) + cs, err := client.CoordinationV1beta1().LeaseCandidates("").List(ctx, metav1.ListOptions{}) if err != nil { t.Logf("Error listing lease candidates: %v", err) continue @@ -781,7 +781,7 @@ func TestController(t *testing.T) { if c.Spec.PingTime != nil && (c.Spec.RenewTime == nil || c.Spec.PingTime.Time.After(c.Spec.RenewTime.Time)) { t.Logf("Answering ping for %s/%s", c.Namespace, c.Name) c.Spec.RenewTime = &metav1.MicroTime{Time: time.Now()} - _, err = client.CoordinationV1alpha2().LeaseCandidates(c.Namespace).Update(ctx, &c, metav1.UpdateOptions{}) + _, err = client.CoordinationV1beta1().LeaseCandidates(c.Namespace).Update(ctx, &c, metav1.UpdateOptions{}) if err != nil { t.Logf("Error updating lease candidate %s/%s: %v", c.Namespace, c.Name, err) } @@ -793,7 +793,7 @@ func TestController(t *testing.T) { for _, obj := range tc.createAfterControllerStart { t.Logf("Post-creating lease candidate %s/%s", obj.Namespace, obj.Name) - _, err := client.CoordinationV1alpha2().LeaseCandidates(obj.Namespace).Create(ctx, obj, metav1.CreateOptions{}) + _, err := client.CoordinationV1beta1().LeaseCandidates(obj.Namespace).Create(ctx, obj, metav1.CreateOptions{}) if err != nil { t.Fatalf("Error post-creating lease candidate %s/%s: %v", obj.Namespace, obj.Name, err) } diff --git a/pkg/controlplane/controller/leaderelection/leasecandidategc_controller.go b/pkg/controlplane/controller/leaderelection/leasecandidategc_controller.go index a5e10f3cc5b..bcc4f89fdca 100644 --- a/pkg/controlplane/controller/leaderelection/leasecandidategc_controller.go +++ b/pkg/controlplane/controller/leaderelection/leasecandidategc_controller.go @@ -26,9 +26,9 @@ import ( "k8s.io/apimachinery/pkg/labels" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" - coordinationv1alpha2informers "k8s.io/client-go/informers/coordination/v1alpha2" + coordinationv1beta1informers "k8s.io/client-go/informers/coordination/v1beta1" "k8s.io/client-go/kubernetes" - listers "k8s.io/client-go/listers/coordination/v1alpha2" + listers "k8s.io/client-go/listers/coordination/v1beta1" "k8s.io/client-go/tools/cache" "k8s.io/utils/clock" @@ -39,7 +39,7 @@ type LeaseCandidateGCController struct { kubeclientset kubernetes.Interface leaseCandidateLister listers.LeaseCandidateLister - leaseCandidateInformer coordinationv1alpha2informers.LeaseCandidateInformer + leaseCandidateInformer coordinationv1beta1informers.LeaseCandidateInformer leaseCandidatesSynced cache.InformerSynced gcCheckPeriod time.Duration @@ -48,7 +48,7 @@ type LeaseCandidateGCController struct { } // NewLeaseCandidateGC creates a new LeaseCandidateGCController. -func NewLeaseCandidateGC(clientset kubernetes.Interface, gcCheckPeriod time.Duration, leaseCandidateInformer coordinationv1alpha2informers.LeaseCandidateInformer) *LeaseCandidateGCController { +func NewLeaseCandidateGC(clientset kubernetes.Interface, gcCheckPeriod time.Duration, leaseCandidateInformer coordinationv1beta1informers.LeaseCandidateInformer) *LeaseCandidateGCController { return &LeaseCandidateGCController{ kubeclientset: clientset, leaseCandidateLister: leaseCandidateInformer.Lister(), @@ -87,7 +87,7 @@ func (c *LeaseCandidateGCController) gc(ctx context.Context) { if !isLeaseCandidateExpired(c.clock, leaseCandidate) { continue } - lc, err := c.kubeclientset.CoordinationV1alpha2().LeaseCandidates(leaseCandidate.Namespace).Get(ctx, leaseCandidate.Name, metav1.GetOptions{}) + lc, err := c.kubeclientset.CoordinationV1beta1().LeaseCandidates(leaseCandidate.Namespace).Get(ctx, leaseCandidate.Name, metav1.GetOptions{}) if err != nil { klog.ErrorS(err, "Error getting lc") continue @@ -96,7 +96,7 @@ func (c *LeaseCandidateGCController) gc(ctx context.Context) { if !isLeaseCandidateExpired(c.clock, lc) { continue } - if err := c.kubeclientset.CoordinationV1alpha2().LeaseCandidates(lc.Namespace).Delete( + if err := c.kubeclientset.CoordinationV1beta1().LeaseCandidates(lc.Namespace).Delete( ctx, lc.Name, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { klog.ErrorS(err, "Error deleting lease") } diff --git a/pkg/controlplane/controller/leaderelection/leasecandidategc_controller_test.go b/pkg/controlplane/controller/leaderelection/leasecandidategc_controller_test.go index 92b18b02d93..283bbcaa99a 100644 --- a/pkg/controlplane/controller/leaderelection/leasecandidategc_controller_test.go +++ b/pkg/controlplane/controller/leaderelection/leasecandidategc_controller_test.go @@ -22,7 +22,7 @@ import ( "time" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/informers" @@ -33,19 +33,19 @@ import ( func TestLeaseCandidateGCController(t *testing.T) { tests := []struct { name string - leaseCandidates []*v1alpha2.LeaseCandidate + leaseCandidates []*v1beta1.LeaseCandidate expectedDeletedCount int }{ { name: "delete expired lease candidates", - leaseCandidates: []*v1alpha2.LeaseCandidate{ + leaseCandidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now().Add(-1 * leaseCandidateValidDuration)}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -59,7 +59,7 @@ func TestLeaseCandidateGCController(t *testing.T) { Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now().Add(-1 * leaseCandidateValidDuration)}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-B", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -73,7 +73,7 @@ func TestLeaseCandidateGCController(t *testing.T) { Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-C", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -86,14 +86,14 @@ func TestLeaseCandidateGCController(t *testing.T) { }, { name: "no expired lease candidates", - leaseCandidates: []*v1alpha2.LeaseCandidate{ + leaseCandidates: []*v1beta1.LeaseCandidate{ { ObjectMeta: metav1.ObjectMeta{ Name: "candidate1", Namespace: "default", CreationTimestamp: metav1.Time{Time: time.Now()}, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "component-A", EmulationVersion: "1.19.0", BinaryVersion: "1.19.0", @@ -111,12 +111,12 @@ func TestLeaseCandidateGCController(t *testing.T) { ctx := context.Background() client := fake.NewSimpleClientset() informerFactory := informers.NewSharedInformerFactory(client, 0) - leaseCandidateInformer := informerFactory.Coordination().V1alpha2().LeaseCandidates() + leaseCandidateInformer := informerFactory.Coordination().V1beta1().LeaseCandidates() controller := NewLeaseCandidateGC(client, 10*time.Millisecond, leaseCandidateInformer) // Create lease candidates for _, lc := range tc.leaseCandidates { - _, err := client.CoordinationV1alpha2().LeaseCandidates(lc.Namespace).Create(ctx, lc, metav1.CreateOptions{}) + _, err := client.CoordinationV1beta1().LeaseCandidates(lc.Namespace).Create(ctx, lc, metav1.CreateOptions{}) if err != nil { t.Fatal(err) } @@ -127,7 +127,7 @@ func TestLeaseCandidateGCController(t *testing.T) { go controller.Run(ctx) err := wait.PollUntilContextTimeout(ctx, 100*time.Millisecond, 600*time.Second, true, func(ctx context.Context) (done bool, err error) { - lcs, err := client.CoordinationV1alpha2().LeaseCandidates("default").List(ctx, metav1.ListOptions{}) + lcs, err := client.CoordinationV1beta1().LeaseCandidates("default").List(ctx, metav1.ListOptions{}) if err != nil { return true, err } diff --git a/pkg/controlplane/instance.go b/pkg/controlplane/instance.go index 70953db9f0a..faf0b01219c 100644 --- a/pkg/controlplane/instance.go +++ b/pkg/controlplane/instance.go @@ -40,6 +40,7 @@ import ( certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationapiv1 "k8s.io/api/coordination/v1" coordinationv1alpha2 "k8s.io/api/coordination/v1alpha2" + coordinationv1beta1 "k8s.io/api/coordination/v1beta1" apiv1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" eventsv1 "k8s.io/api/events/v1" @@ -459,6 +460,7 @@ var ( admissionregistrationv1beta1.SchemeGroupVersion, authenticationv1beta1.SchemeGroupVersion, certificatesv1beta1.SchemeGroupVersion, + coordinationv1beta1.SchemeGroupVersion, storageapiv1beta1.SchemeGroupVersion, flowcontrolv1beta1.SchemeGroupVersion, flowcontrolv1beta2.SchemeGroupVersion, diff --git a/pkg/kubeapiserver/default_storage_factory_builder.go b/pkg/kubeapiserver/default_storage_factory_builder.go index 7ac6039db0c..f012ce11e08 100644 --- a/pkg/kubeapiserver/default_storage_factory_builder.go +++ b/pkg/kubeapiserver/default_storage_factory_builder.go @@ -79,7 +79,7 @@ func NewStorageFactoryConfigEffectiveVersion(effectiveVersion basecompatibility. // // TODO (https://github.com/kubernetes/kubernetes/issues/108451): remove the override in 1.25. // apisstorage.Resource("csistoragecapacities").WithVersion("v1beta1"), - coordination.Resource("leasecandidates").WithVersion("v1alpha2"), + coordination.Resource("leasecandidates").WithVersion("v1beta1"), // TODO(aojea) ipaddresses and servicecidrs are v1 in 1.33 // remove them in 1.34 when all apiserver understand the v1 version. networking.Resource("ipaddresses").WithVersion("v1beta1"), diff --git a/pkg/registry/coordination/rest/storage_coordination.go b/pkg/registry/coordination/rest/storage_coordination.go index 16261f75779..90ee6fcb949 100644 --- a/pkg/registry/coordination/rest/storage_coordination.go +++ b/pkg/registry/coordination/rest/storage_coordination.go @@ -19,6 +19,7 @@ package rest import ( coordinationv1 "k8s.io/api/coordination/v1" coordinationv1alpha2 "k8s.io/api/coordination/v1alpha2" + coordinationv1beta1 "k8s.io/api/coordination/v1beta1" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" @@ -42,6 +43,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag apiGroupInfo.VersionedResourcesStorageMap[coordinationv1.SchemeGroupVersion.Version] = storageMap } + if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { + return genericapiserver.APIGroupInfo{}, err + } else if len(storageMap) > 0 { + apiGroupInfo.VersionedResourcesStorageMap[coordinationv1beta1.SchemeGroupVersion.Version] = storageMap + } + if storageMap, err := p.v1alpha2Storage(apiResourceConfigSource, restOptionsGetter); err != nil { return genericapiserver.APIGroupInfo{}, err } else if len(storageMap) > 0 { @@ -65,6 +72,20 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API return storage, nil } +func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { + storage := map[string]rest.Storage{} + + // identity + if resource := "leasecandidates"; apiResourceConfigSource.ResourceEnabled(coordinationv1beta1.SchemeGroupVersion.WithResource(resource)) { + leaseCandidateStorage, err := leasecandidatestorage.NewREST(restOptionsGetter) + if err != nil { + return storage, err + } + storage[resource] = leaseCandidateStorage + } + return storage, nil +} + func (p RESTStorageProvider) v1alpha2Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} diff --git a/staging/src/k8s.io/api/coordination/v1beta1/register.go b/staging/src/k8s.io/api/coordination/v1beta1/register.go index 85efaa64e75..bd00164233b 100644 --- a/staging/src/k8s.io/api/coordination/v1beta1/register.go +++ b/staging/src/k8s.io/api/coordination/v1beta1/register.go @@ -46,6 +46,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Lease{}, &LeaseList{}, + &LeaseCandidate{}, + &LeaseCandidateList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/staging/src/k8s.io/api/coordination/v1beta1/types.go b/staging/src/k8s.io/api/coordination/v1beta1/types.go index d63fc30a9e7..781d29efce1 100644 --- a/staging/src/k8s.io/api/coordination/v1beta1/types.go +++ b/staging/src/k8s.io/api/coordination/v1beta1/types.go @@ -91,3 +91,76 @@ type LeaseList struct { // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// LeaseCandidate defines a candidate for a Lease object. +// Candidates are created such that coordinated leader election will pick the best leader from the list of candidates. +type LeaseCandidate struct { + metav1.TypeMeta `json:",inline"` + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // spec contains the specification of the Lease. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec LeaseCandidateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// LeaseCandidateSpec is a specification of a Lease. +type LeaseCandidateSpec struct { + // LeaseName is the name of the lease for which this candidate is contending. + // The limits on this field are the same as on Lease.name. Multiple lease candidates + // may reference the same Lease.name. + // This field is immutable. + // +required + LeaseName string `json:"leaseName" protobuf:"bytes,1,name=leaseName"` + // PingTime is the last time that the server has requested the LeaseCandidate + // to renew. It is only done during leader election to check if any + // LeaseCandidates have become ineligible. When PingTime is updated, the + // LeaseCandidate will respond by updating RenewTime. + // +optional + PingTime *metav1.MicroTime `json:"pingTime,omitempty" protobuf:"bytes,2,opt,name=pingTime"` + // RenewTime is the time that the LeaseCandidate was last updated. + // Any time a Lease needs to do leader election, the PingTime field + // is updated to signal to the LeaseCandidate that they should update + // the RenewTime. + // Old LeaseCandidate objects are also garbage collected if it has been hours + // since the last renew. The PingTime field is updated regularly to prevent + // garbage collection for still active LeaseCandidates. + // +optional + RenewTime *metav1.MicroTime `json:"renewTime,omitempty" protobuf:"bytes,3,opt,name=renewTime"` + // BinaryVersion is the binary version. It must be in a semver format without leading `v`. + // This field is required. + // +required + BinaryVersion string `json:"binaryVersion" protobuf:"bytes,4,name=binaryVersion"` + // EmulationVersion is the emulation version. It must be in a semver format without leading `v`. + // EmulationVersion must be less than or equal to BinaryVersion. + // This field is required when strategy is "OldestEmulationVersion" + // +optional + EmulationVersion string `json:"emulationVersion,omitempty" protobuf:"bytes,5,opt,name=emulationVersion"` + // Strategy is the strategy that coordinated leader election will use for picking the leader. + // If multiple candidates for the same Lease return different strategies, the strategy provided + // by the candidate with the latest BinaryVersion will be used. If there is still conflict, + // this is a user error and coordinated leader election will not operate the Lease until resolved. + // +required + Strategy v1.CoordinatedLeaseStrategy `json:"strategy,omitempty" protobuf:"bytes,6,opt,name=strategy"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// LeaseCandidateList is a list of Lease objects. +type LeaseCandidateList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // items is a list of schema objects. + Items []LeaseCandidate `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate.go b/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate.go index 6ccd4cfbeed..9aaf779eaae 100644 --- a/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate.go +++ b/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate.go @@ -22,14 +22,14 @@ import ( "time" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" - coordinationv1alpha2client "k8s.io/client-go/kubernetes/typed/coordination/v1alpha2" + coordinationv1beta1client "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" @@ -43,7 +43,7 @@ type CacheSyncWaiter interface { } type LeaseCandidate struct { - leaseClient coordinationv1alpha2client.LeaseCandidateInterface + leaseClient coordinationv1beta1client.LeaseCandidateInterface leaseCandidateInformer cache.SharedIndexInformer informerFactory informers.SharedInformerFactory hasSynced cache.InformerSynced @@ -84,10 +84,10 @@ func NewCandidate(clientset kubernetes.Interface, options.FieldSelector = fieldSelector }), ) - leaseCandidateInformer := informerFactory.Coordination().V1alpha2().LeaseCandidates().Informer() + leaseCandidateInformer := informerFactory.Coordination().V1beta1().LeaseCandidates().Informer() lc := &LeaseCandidate{ - leaseClient: clientset.CoordinationV1alpha2().LeaseCandidates(candidateNamespace), + leaseClient: clientset.CoordinationV1beta1().LeaseCandidates(candidateNamespace), leaseCandidateInformer: leaseCandidateInformer, informerFactory: informerFactory, name: candidateName, @@ -102,7 +102,7 @@ func NewCandidate(clientset kubernetes.Interface, h, err := leaseCandidateInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ UpdateFunc: func(oldObj, newObj interface{}) { - if leasecandidate, ok := newObj.(*v1alpha2.LeaseCandidate); ok { + if leasecandidate, ok := newObj.(*v1beta1.LeaseCandidate); ok { if leasecandidate.Spec.PingTime != nil && leasecandidate.Spec.PingTime.After(leasecandidate.Spec.RenewTime.Time) { lc.enqueueLease() } @@ -184,13 +184,13 @@ func (c *LeaseCandidate) ensureLease(ctx context.Context) error { return nil } -func (c *LeaseCandidate) newLeaseCandidate() *v1alpha2.LeaseCandidate { - lc := &v1alpha2.LeaseCandidate{ +func (c *LeaseCandidate) newLeaseCandidate() *v1beta1.LeaseCandidate { + lc := &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: c.name, Namespace: c.namespace, }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: c.leaseName, BinaryVersion: c.binaryVersion, EmulationVersion: c.emulationVersion, diff --git a/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate_test.go b/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate_test.go index 661643a1e83..3099a4ea3c9 100644 --- a/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate_test.go +++ b/staging/src/k8s.io/client-go/tools/leaderelection/leasecandidate_test.go @@ -101,12 +101,12 @@ func TestLeaseCandidateAck(t *testing.T) { // Update PingTime and verify that the client renews ensureAfter := &metav1.MicroTime{Time: time.Now()} - lc, err := client.CoordinationV1alpha2().LeaseCandidates(tc.candidateNamespace).Get(ctx, tc.candidateName, metav1.GetOptions{}) + lc, err := client.CoordinationV1beta1().LeaseCandidates(tc.candidateNamespace).Get(ctx, tc.candidateName, metav1.GetOptions{}) if err == nil { if lc.Spec.PingTime == nil { c := lc.DeepCopy() c.Spec.PingTime = &metav1.MicroTime{Time: time.Now()} - _, err = client.CoordinationV1alpha2().LeaseCandidates(tc.candidateNamespace).Update(ctx, c, metav1.UpdateOptions{}) + _, err = client.CoordinationV1beta1().LeaseCandidates(tc.candidateNamespace).Update(ctx, c, metav1.UpdateOptions{}) if err != nil { t.Error(err) } @@ -120,7 +120,7 @@ func TestLeaseCandidateAck(t *testing.T) { func pollForLease(ctx context.Context, tc testcase, client *fake.Clientset, t *metav1.MicroTime) error { return wait.PollUntilContextTimeout(ctx, 100*time.Millisecond, 10*time.Second, true, func(ctx context.Context) (done bool, err error) { - lc, err := client.CoordinationV1alpha2().LeaseCandidates(tc.candidateNamespace).Get(ctx, tc.candidateName, metav1.GetOptions{}) + lc, err := client.CoordinationV1beta1().LeaseCandidates(tc.candidateNamespace).Get(ctx, tc.candidateName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { return false, nil diff --git a/test/e2e/apimachinery/coordinatedleaderelection.go b/test/e2e/apimachinery/coordinatedleaderelection.go index a6d35218c53..adae9e807ea 100644 --- a/test/e2e/apimachinery/coordinatedleaderelection.go +++ b/test/e2e/apimachinery/coordinatedleaderelection.go @@ -58,7 +58,7 @@ var _ = SIGDescribe("CoordinatedLeaderElection", feature.CoordinatedLeaderElecti _ = clientset.CoordinationV1().Leases(ns).Delete(ctx, "baz", metav1.DeleteOptions{}) _ = clientset.CoordinationV1().Leases(ns).Delete(ctx, "bar", metav1.DeleteOptions{}) _ = clientset.CoordinationV1().Leases(ns).Delete(ctx, "foobar", metav1.DeleteOptions{}) - _ = clientset.CoordinationV1alpha2().LeaseCandidates(ns).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{}) + _ = clientset.CoordinationV1beta1().LeaseCandidates(ns).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{}) }) /* diff --git a/test/integration/apiserver/coordinated_leader_election_test.go b/test/integration/apiserver/coordinated_leader_election_test.go index 0cd1b487936..8523341bba6 100644 --- a/test/integration/apiserver/coordinated_leader_election_test.go +++ b/test/integration/apiserver/coordinated_leader_election_test.go @@ -24,7 +24,7 @@ import ( "time" v1 "k8s.io/api/coordination/v1" - v1alpha2 "k8s.io/api/coordination/v1alpha2" + v1beta1 "k8s.io/api/coordination/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" @@ -56,7 +56,7 @@ func TestSingleLeaseCandidate(t *testing.T) { } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -95,7 +95,7 @@ func TestSingleLeaseCandidateUsingThirdPartyStrategy(t *testing.T) { }, } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -133,7 +133,7 @@ func TestMultipleLeaseCandidate(t *testing.T) { } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -175,7 +175,7 @@ func TestMultipleLeaseCandidateUsingThirdPartyStrategy(t *testing.T) { }, } featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { @@ -204,7 +204,7 @@ func TestMultipleLeaseCandidateUsingThirdPartyStrategy(t *testing.T) { func TestLeaseSwapIfBetterAvailable(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -227,7 +227,7 @@ func TestLeaseSwapIfBetterAvailable(t *testing.T) { func TestUpgradeSkew(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CoordinatedLeaderElection, true) - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -257,7 +257,7 @@ func TestLeaseCandidateCleanup(t *testing.T) { apiserver.LeaseCandidateGCPeriod = 30 * time.Minute }() - flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1alpha2.SchemeGroupVersion)} + flags := []string{fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion)} server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), flags, framework.SharedEtcd()) if err != nil { t.Fatal(err) @@ -268,12 +268,12 @@ func TestLeaseCandidateCleanup(t *testing.T) { if err != nil { t.Fatal(err) } - expiredLC := &v1alpha2.LeaseCandidate{ + expiredLC := &v1beta1.LeaseCandidate{ ObjectMeta: metav1.ObjectMeta{ Name: "expired", Namespace: "default", }, - Spec: v1alpha2.LeaseCandidateSpec{ + Spec: v1beta1.LeaseCandidateSpec{ LeaseName: "foobaz", BinaryVersion: "0.1.0", EmulationVersion: "0.1.0", @@ -283,13 +283,13 @@ func TestLeaseCandidateCleanup(t *testing.T) { }, } ctx := context.Background() - _, err = clientset.CoordinationV1alpha2().LeaseCandidates("default").Create(ctx, expiredLC, metav1.CreateOptions{}) + _, err = clientset.CoordinationV1beta1().LeaseCandidates("default").Create(ctx, expiredLC, metav1.CreateOptions{}) if err != nil { t.Fatal(err) } err = wait.PollUntilContextTimeout(ctx, 1000*time.Millisecond, 5*time.Second, true, func(ctx context.Context) (done bool, err error) { - _, err = clientset.CoordinationV1alpha2().LeaseCandidates("default").Get(ctx, "expired", metav1.GetOptions{}) + _, err = clientset.CoordinationV1beta1().LeaseCandidates("default").Get(ctx, "expired", metav1.GetOptions{}) if apierrors.IsNotFound(err) { return true, nil } diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index 5712c83dedb..737bf9daa68 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -241,10 +241,20 @@ func GetEtcdStorageDataForNamespaceServedAt(namespace string, v string, removeAl }, // -- + // k8s.io/kubernetes/pkg/apis/coordination/v1beta1 + gvr("coordination.k8s.io", "v1beta1", "leasecandidates"): { + Stub: `{"metadata": {"name": "leasecandidatev1beta1"}, "spec": {"leaseName": "lease", "binaryVersion": "0.1.0", "emulationVersion": "0.1.0", "strategy": "OldestEmulationVersion"}}`, + ExpectedEtcdPath: "/registry/leasecandidates/" + namespace + "/leasecandidatev1beta1", + IntroducedVersion: "1.33", + RemovedVersion: "1.39", + }, + // -- + // k8s.io/kubernetes/pkg/apis/coordination/v1alpha2 gvr("coordination.k8s.io", "v1alpha2", "leasecandidates"): { Stub: `{"metadata": {"name": "leasecandidatev1alpha2"}, "spec": {"leaseName": "lease", "binaryVersion": "0.1.0", "emulationVersion": "0.1.0", "strategy": "OldestEmulationVersion"}}`, ExpectedEtcdPath: "/registry/leasecandidates/" + namespace + "/leasecandidatev1alpha2", + ExpectedGVK: gvkP("coordination.k8s.io", "v1beta1", "LeaseCandidate"), IntroducedVersion: "1.32", RemovedVersion: "1.38", },