Coordinated Leader Election Alpha API
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/coordination/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination/v1beta1"
|
||||
)
|
||||
|
||||
@@ -34,7 +35,8 @@ func init() {
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(coordination.AddToScheme(scheme))
|
||||
utilruntime.Must(v1alpha1.AddToScheme(scheme))
|
||||
utilruntime.Must(v1beta1.AddToScheme(scheme))
|
||||
utilruntime.Must(v1.AddToScheme(scheme))
|
||||
utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta1.SchemeGroupVersion))
|
||||
utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta1.SchemeGroupVersion, v1alpha1.SchemeGroupVersion))
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Lease{},
|
||||
&LeaseList{},
|
||||
&LeaseCandidate{},
|
||||
&LeaseCandidateList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,18 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type CoordinatedLeaseStrategy string
|
||||
|
||||
// CoordinatedLeaseStrategy defines the strategy for picking the leader for coordinated leader election.
|
||||
const (
|
||||
// OldestEmulationVersion picks the oldest LeaseCandidate, where "oldest" is defined as follows
|
||||
// 1) Select the candidate(s) with the lowest emulation version
|
||||
// 2) If multiple candidates have the same emulation version, select the candidate(s) with the lowest binary version. (Note that binary version must be greater or equal to emulation version)
|
||||
// 3) If multiple candidates have the same binary version, select the candidate with the oldest creationTimestamp.
|
||||
// If a candidate does not specify the emulationVersion and binaryVersion fields, it will not be considered a candidate for the lease.
|
||||
OldestEmulationVersion CoordinatedLeaseStrategy = "OldestEmulationVersion"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Lease defines a lease concept.
|
||||
@@ -36,6 +48,8 @@ type Lease struct {
|
||||
// LeaseSpec is a specification of a Lease.
|
||||
type LeaseSpec struct {
|
||||
// holderIdentity contains the identity of the holder of a current lease.
|
||||
// If Coordinated Leader Election is used, the holder identity must be
|
||||
// equal to the elected LeaseCandidate.metadata.name field.
|
||||
// +optional
|
||||
HolderIdentity *string
|
||||
// leaseDurationSeconds is a duration that candidates for a lease need
|
||||
@@ -54,6 +68,18 @@ type LeaseSpec struct {
|
||||
// holders.
|
||||
// +optional
|
||||
LeaseTransitions *int32
|
||||
// Strategy indicates the strategy for picking the leader for coordinated leader election.
|
||||
// If the field is not specified, there is no active coordination for this lease.
|
||||
// (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.
|
||||
// +featureGate=CoordinatedLeaderElection
|
||||
// +optional
|
||||
Strategy *CoordinatedLeaseStrategy
|
||||
// PreferredHolder signals to a lease holder that the lease has a
|
||||
// more optimal holder and should be given up.
|
||||
// This field can only be set if Strategy is also set.
|
||||
// +featureGate=CoordinatedLeaderElection
|
||||
// +optional
|
||||
PreferredHolder *string
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -67,3 +93,68 @@ type LeaseList struct {
|
||||
// items is a list of schema objects.
|
||||
Items []Lease
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// 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
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
Spec LeaseCandidateSpec
|
||||
}
|
||||
|
||||
// LeaseCandidateSpec is a specification of a Lease.
|
||||
type LeaseCandidateSpec struct {
|
||||
// LeaseName is the name of the lease for which this candidate is contending.
|
||||
// This field is immutable.
|
||||
LeaseName string
|
||||
// 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
|
||||
// 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.
|
||||
// +optional
|
||||
RenewTime *metav1.MicroTime
|
||||
// BinaryVersion is the binary version. It must be in a semver format without leadig `v`.
|
||||
// This field is required when Strategy is "OldestEmulationVersion"
|
||||
// +optional
|
||||
BinaryVersion string
|
||||
// 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
|
||||
// PreferredStrategies indicates the list of strategies for picking the leader for coordinated leader election.
|
||||
// The list is ordered, and the first strategy supersedes all other strategies. The list is used by coordinated
|
||||
// leader election to make a decision about the final election strategy. This follows as
|
||||
// - If all clients have strategy X as the first element in this list, strategy X will be used.
|
||||
// - If a candidate has strategy [X] and another candidate has strategy [Y, X], Y supersedes X and strategy Y
|
||||
// will be used
|
||||
// - If a candidate has strategy [X, Y] and another candidate has strategy [Y, X], this is a user error and leader
|
||||
// election will not operate the Lease until resolved.
|
||||
// (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.
|
||||
// +featureGate=CoordinatedLeaderElection
|
||||
// +listType=atomic
|
||||
// +required
|
||||
PreferredStrategies []CoordinatedLeaseStrategy
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// LeaseCandidateList is a list of LeaseCandidate objects.
|
||||
type LeaseCandidateList struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
metav1.ListMeta
|
||||
|
||||
// items is a list of schema objects.
|
||||
Items []LeaseCandidate
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ func autoConvert_v1_LeaseSpec_To_coordination_LeaseSpec(in *v1.LeaseSpec, out *c
|
||||
out.AcquireTime = (*metav1.MicroTime)(unsafe.Pointer(in.AcquireTime))
|
||||
out.RenewTime = (*metav1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.LeaseTransitions = (*int32)(unsafe.Pointer(in.LeaseTransitions))
|
||||
out.Strategy = (*coordination.CoordinatedLeaseStrategy)(unsafe.Pointer(in.Strategy))
|
||||
out.PreferredHolder = (*string)(unsafe.Pointer(in.PreferredHolder))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,6 +141,8 @@ func autoConvert_coordination_LeaseSpec_To_v1_LeaseSpec(in *coordination.LeaseSp
|
||||
out.AcquireTime = (*metav1.MicroTime)(unsafe.Pointer(in.AcquireTime))
|
||||
out.RenewTime = (*metav1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.LeaseTransitions = (*int32)(unsafe.Pointer(in.LeaseTransitions))
|
||||
out.Strategy = (*v1.CoordinatedLeaseStrategy)(unsafe.Pointer(in.Strategy))
|
||||
out.PreferredHolder = (*string)(unsafe.Pointer(in.PreferredHolder))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
24
pkg/apis/coordination/v1alpha1/doc.go
Normal file
24
pkg/apis/coordination/v1alpha1/doc.go
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/coordination
|
||||
// +k8s:conversion-gen-external-types=k8s.io/api/coordination/v1alpha1
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:defaulter-gen-input=k8s.io/api/coordination/v1alpha1
|
||||
|
||||
// +groupName=coordination.k8s.io
|
||||
|
||||
package v1alpha1 // import "k8s.io/kubernetes/pkg/apis/coordination/v1alpha1"
|
||||
46
pkg/apis/coordination/v1alpha1/register.go
Normal file
46
pkg/apis/coordination/v1alpha1/register.go
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
coordinationv1alpha1 "k8s.io/api/coordination/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "coordination.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
localSchemeBuilder = &coordinationv1alpha1.SchemeBuilder
|
||||
// AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(RegisterDefaults)
|
||||
}
|
||||
151
pkg/apis/coordination/v1alpha1/zz_generated.conversion.go
generated
Normal file
151
pkg/apis/coordination/v1alpha1/zz_generated.conversion.go
generated
Normal file
@@ -0,0 +1,151 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by conversion-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
v1alpha1 "k8s.io/api/coordination/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
coordination "k8s.io/kubernetes/pkg/apis/coordination"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.LeaseCandidate)(nil), (*coordination.LeaseCandidate)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_LeaseCandidate_To_coordination_LeaseCandidate(a.(*v1alpha1.LeaseCandidate), b.(*coordination.LeaseCandidate), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*coordination.LeaseCandidate)(nil), (*v1alpha1.LeaseCandidate)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_coordination_LeaseCandidate_To_v1alpha1_LeaseCandidate(a.(*coordination.LeaseCandidate), b.(*v1alpha1.LeaseCandidate), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.LeaseCandidateList)(nil), (*coordination.LeaseCandidateList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_LeaseCandidateList_To_coordination_LeaseCandidateList(a.(*v1alpha1.LeaseCandidateList), b.(*coordination.LeaseCandidateList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*coordination.LeaseCandidateList)(nil), (*v1alpha1.LeaseCandidateList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_coordination_LeaseCandidateList_To_v1alpha1_LeaseCandidateList(a.(*coordination.LeaseCandidateList), b.(*v1alpha1.LeaseCandidateList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.LeaseCandidateSpec)(nil), (*coordination.LeaseCandidateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec(a.(*v1alpha1.LeaseCandidateSpec), b.(*coordination.LeaseCandidateSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*coordination.LeaseCandidateSpec)(nil), (*v1alpha1.LeaseCandidateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec(a.(*coordination.LeaseCandidateSpec), b.(*v1alpha1.LeaseCandidateSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_LeaseCandidate_To_coordination_LeaseCandidate(in *v1alpha1.LeaseCandidate, out *coordination.LeaseCandidate, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_LeaseCandidate_To_coordination_LeaseCandidate is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_LeaseCandidate_To_coordination_LeaseCandidate(in *v1alpha1.LeaseCandidate, out *coordination.LeaseCandidate, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_LeaseCandidate_To_coordination_LeaseCandidate(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_coordination_LeaseCandidate_To_v1alpha1_LeaseCandidate(in *coordination.LeaseCandidate, out *v1alpha1.LeaseCandidate, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_coordination_LeaseCandidate_To_v1alpha1_LeaseCandidate is an autogenerated conversion function.
|
||||
func Convert_coordination_LeaseCandidate_To_v1alpha1_LeaseCandidate(in *coordination.LeaseCandidate, out *v1alpha1.LeaseCandidate, s conversion.Scope) error {
|
||||
return autoConvert_coordination_LeaseCandidate_To_v1alpha1_LeaseCandidate(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_LeaseCandidateList_To_coordination_LeaseCandidateList(in *v1alpha1.LeaseCandidateList, out *coordination.LeaseCandidateList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]coordination.LeaseCandidate)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_LeaseCandidateList_To_coordination_LeaseCandidateList is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_LeaseCandidateList_To_coordination_LeaseCandidateList(in *v1alpha1.LeaseCandidateList, out *coordination.LeaseCandidateList, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_LeaseCandidateList_To_coordination_LeaseCandidateList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_coordination_LeaseCandidateList_To_v1alpha1_LeaseCandidateList(in *coordination.LeaseCandidateList, out *v1alpha1.LeaseCandidateList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]v1alpha1.LeaseCandidate)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_coordination_LeaseCandidateList_To_v1alpha1_LeaseCandidateList is an autogenerated conversion function.
|
||||
func Convert_coordination_LeaseCandidateList_To_v1alpha1_LeaseCandidateList(in *coordination.LeaseCandidateList, out *v1alpha1.LeaseCandidateList, s conversion.Scope) error {
|
||||
return autoConvert_coordination_LeaseCandidateList_To_v1alpha1_LeaseCandidateList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec(in *v1alpha1.LeaseCandidateSpec, out *coordination.LeaseCandidateSpec, s conversion.Scope) error {
|
||||
out.LeaseName = in.LeaseName
|
||||
out.PingTime = (*v1.MicroTime)(unsafe.Pointer(in.PingTime))
|
||||
out.RenewTime = (*v1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.BinaryVersion = in.BinaryVersion
|
||||
out.EmulationVersion = in.EmulationVersion
|
||||
out.PreferredStrategies = *(*[]coordination.CoordinatedLeaseStrategy)(unsafe.Pointer(&in.PreferredStrategies))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec(in *v1alpha1.LeaseCandidateSpec, out *coordination.LeaseCandidateSpec, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_LeaseCandidateSpec_To_coordination_LeaseCandidateSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec(in *coordination.LeaseCandidateSpec, out *v1alpha1.LeaseCandidateSpec, s conversion.Scope) error {
|
||||
out.LeaseName = in.LeaseName
|
||||
out.PingTime = (*v1.MicroTime)(unsafe.Pointer(in.PingTime))
|
||||
out.RenewTime = (*v1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.BinaryVersion = in.BinaryVersion
|
||||
out.EmulationVersion = in.EmulationVersion
|
||||
out.PreferredStrategies = *(*[]coordinationv1.CoordinatedLeaseStrategy)(unsafe.Pointer(&in.PreferredStrategies))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec is an autogenerated conversion function.
|
||||
func Convert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec(in *coordination.LeaseCandidateSpec, out *v1alpha1.LeaseCandidateSpec, s conversion.Scope) error {
|
||||
return autoConvert_coordination_LeaseCandidateSpec_To_v1alpha1_LeaseCandidateSpec(in, out, s)
|
||||
}
|
||||
33
pkg/apis/coordination/v1alpha1/zz_generated.defaults.go
generated
Normal file
33
pkg/apis/coordination/v1alpha1/zz_generated.defaults.go
generated
Normal file
@@ -0,0 +1,33 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package v1beta1
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
v1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
@@ -125,6 +126,8 @@ func autoConvert_v1beta1_LeaseSpec_To_coordination_LeaseSpec(in *v1beta1.LeaseSp
|
||||
out.AcquireTime = (*v1.MicroTime)(unsafe.Pointer(in.AcquireTime))
|
||||
out.RenewTime = (*v1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.LeaseTransitions = (*int32)(unsafe.Pointer(in.LeaseTransitions))
|
||||
out.Strategy = (*coordination.CoordinatedLeaseStrategy)(unsafe.Pointer(in.Strategy))
|
||||
out.PreferredHolder = (*string)(unsafe.Pointer(in.PreferredHolder))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,6 +142,8 @@ func autoConvert_coordination_LeaseSpec_To_v1beta1_LeaseSpec(in *coordination.Le
|
||||
out.AcquireTime = (*v1.MicroTime)(unsafe.Pointer(in.AcquireTime))
|
||||
out.RenewTime = (*v1.MicroTime)(unsafe.Pointer(in.RenewTime))
|
||||
out.LeaseTransitions = (*int32)(unsafe.Pointer(in.LeaseTransitions))
|
||||
out.Strategy = (*coordinationv1.CoordinatedLeaseStrategy)(unsafe.Pointer(in.Strategy))
|
||||
out.PreferredHolder = (*string)(unsafe.Pointer(in.PreferredHolder))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,20 @@ limitations under the License.
|
||||
package validation
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"k8s.io/apimachinery/pkg/api/validation"
|
||||
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
)
|
||||
|
||||
var validLeaseStrategies = []coordination.CoordinatedLeaseStrategy{coordination.OldestEmulationVersion}
|
||||
|
||||
// ValidateLease validates a Lease.
|
||||
func ValidateLease(lease *coordination.Lease) field.ErrorList {
|
||||
allErrs := validation.ValidateObjectMeta(&lease.ObjectMeta, true, validation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||
@@ -48,5 +57,119 @@ func ValidateLeaseSpec(spec *coordination.LeaseSpec, fldPath *field.Path) field.
|
||||
fld := fldPath.Child("leaseTransitions")
|
||||
allErrs = append(allErrs, field.Invalid(fld, spec.LeaseTransitions, "must be greater than or equal to 0"))
|
||||
}
|
||||
if spec.Strategy != nil {
|
||||
allErrs = append(allErrs, ValidateCoordinatedLeaseStrategy(*spec.Strategy, fldPath.Child("strategy"))...)
|
||||
}
|
||||
if spec.PreferredHolder != nil && *spec.PreferredHolder != "" && (spec.Strategy == nil || *spec.Strategy == "") {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("preferredHolder"), "may only be specified if `strategy` is defined"))
|
||||
}
|
||||
// spec.RenewTime is a MicroTime and doesn't need further validation
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLeaseCandidate validates a LeaseCandidate.
|
||||
func ValidateLeaseCandidate(lease *coordination.LeaseCandidate) field.ErrorList {
|
||||
allErrs := validation.ValidateObjectMeta(&lease.ObjectMeta, true, ValidLeaseCandidateName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateLeaseCandidateSpec(&lease.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidLeaseCandidateName(name string, prefix bool) []string {
|
||||
// prefix is already handled by IsConfigMapKey, a trailing - is permitted.
|
||||
return utilvalidation.IsConfigMapKey(name)
|
||||
}
|
||||
|
||||
func ValidateLeaseCandidateSpecUpdate(leaseCandidateSpec, oldLeaseCandidateSpec *coordination.LeaseCandidateSpec) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(leaseCandidateSpec.LeaseName, oldLeaseCandidateSpec.LeaseName, field.NewPath("spec").Child("leaseName"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLeaseCandidateUpdate validates an update of LeaseCandidate object.
|
||||
func ValidateLeaseCandidateUpdate(leaseCandidate, oldLeaseCandidate *coordination.LeaseCandidate) field.ErrorList {
|
||||
allErrs := validation.ValidateObjectMetaUpdate(&leaseCandidate.ObjectMeta, &oldLeaseCandidate.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateLeaseCandidateSpec(&leaseCandidate.Spec, field.NewPath("spec"))...)
|
||||
allErrs = append(allErrs, ValidateLeaseCandidateSpecUpdate(&leaseCandidate.Spec, &oldLeaseCandidate.Spec)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLeaseCandidateSpec validates spec of LeaseCandidate.
|
||||
func ValidateLeaseCandidateSpec(spec *coordination.LeaseCandidateSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(spec.LeaseName) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("leaseName"), ""))
|
||||
}
|
||||
|
||||
ev := semver.Version{}
|
||||
if spec.EmulationVersion != "" {
|
||||
var err error
|
||||
ev, err = semver.Parse(spec.EmulationVersion)
|
||||
if err != nil {
|
||||
fld := fldPath.Child("emulationVersion")
|
||||
allErrs = append(allErrs, field.Invalid(fld, spec.EmulationVersion, "must be a valid semantic version"))
|
||||
}
|
||||
}
|
||||
bv := semver.Version{}
|
||||
if spec.BinaryVersion != "" {
|
||||
var err error
|
||||
bv, err = semver.Parse(spec.BinaryVersion)
|
||||
if err != nil {
|
||||
fld := fldPath.Child("binaryVersion")
|
||||
allErrs = append(allErrs, field.Invalid(fld, spec.BinaryVersion, "must be a valid semantic version"))
|
||||
}
|
||||
}
|
||||
if spec.BinaryVersion != "" && spec.EmulationVersion != "" && bv.LT(ev) {
|
||||
fld := fldPath.Child("binaryVersion")
|
||||
allErrs = append(allErrs, field.Invalid(fld, spec.BinaryVersion, "must be greater than or equal to `emulationVersion`"))
|
||||
}
|
||||
|
||||
strategySeen := make(map[coordination.CoordinatedLeaseStrategy]bool)
|
||||
|
||||
if len(spec.PreferredStrategies) > 0 {
|
||||
for i, strategy := range spec.PreferredStrategies {
|
||||
fld := fldPath.Child("preferredStrategies").Index(i)
|
||||
if _, ok := strategySeen[strategy]; ok {
|
||||
allErrs = append(allErrs, field.Duplicate(fld, strategy))
|
||||
} else {
|
||||
strategySeen[strategy] = true
|
||||
}
|
||||
|
||||
if strategy == coordination.OldestEmulationVersion {
|
||||
zeroVersion := semver.Version{}
|
||||
if bv.EQ(zeroVersion) {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("binaryVersion"), "must be specified when `strategy` is 'OldestEmulationVersion'"))
|
||||
}
|
||||
if ev.EQ(zeroVersion) {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("emulationVersion"), "must be specified when `strategy` is 'OldestEmulationVersion'"))
|
||||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, ValidateCoordinatedLeaseStrategy(strategy, fld)...)
|
||||
}
|
||||
}
|
||||
// spec.PingTime is a MicroTime and doesn't need further validation
|
||||
// spec.RenewTime is a MicroTime and doesn't need further validation
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLeaseStrategy validates the Strategy field in both the Lease and LeaseCandidate
|
||||
func ValidateCoordinatedLeaseStrategy(strategy coordination.CoordinatedLeaseStrategy, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
parts := strings.Split(string(strategy), "/")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
// Must be a Kubernetes-defined name.
|
||||
if !slices.Contains(validLeaseStrategies, coordination.CoordinatedLeaseStrategy(parts[0])) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("strategy"), strategy, validLeaseStrategies))
|
||||
}
|
||||
default:
|
||||
if msgs := utilvalidation.IsQualifiedName(string(strategy)); len(msgs) > 0 {
|
||||
for _, msg := range msgs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("strategy"), strategy, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestValidateLease(t *testing.T) {
|
||||
@@ -41,14 +42,58 @@ func TestValidateLeaseSpec(t *testing.T) {
|
||||
holder := "holder"
|
||||
leaseDuration := int32(0)
|
||||
leaseTransitions := int32(-1)
|
||||
spec := &coordination.LeaseSpec{
|
||||
HolderIdentity: &holder,
|
||||
LeaseDurationSeconds: &leaseDuration,
|
||||
LeaseTransitions: &leaseTransitions,
|
||||
preferredHolder := "holder2"
|
||||
|
||||
testcases := []struct {
|
||||
spec coordination.LeaseSpec
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
// valid
|
||||
coordination.LeaseSpec{
|
||||
HolderIdentity: &holder,
|
||||
LeaseDurationSeconds: ptr.To[int32](10),
|
||||
LeaseTransitions: ptr.To[int32](1),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
// valid with PreferredHolder
|
||||
coordination.LeaseSpec{
|
||||
HolderIdentity: &holder,
|
||||
LeaseDurationSeconds: ptr.To[int32](10),
|
||||
LeaseTransitions: ptr.To[int32](1),
|
||||
Strategy: ptr.To(coordination.OldestEmulationVersion),
|
||||
PreferredHolder: ptr.To("someotherholder"),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
coordination.LeaseSpec{
|
||||
HolderIdentity: &holder,
|
||||
LeaseDurationSeconds: &leaseDuration,
|
||||
LeaseTransitions: &leaseTransitions,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
coordination.LeaseSpec{
|
||||
HolderIdentity: &holder,
|
||||
LeaseDurationSeconds: &leaseDuration,
|
||||
LeaseTransitions: &leaseTransitions,
|
||||
PreferredHolder: &preferredHolder,
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
errs := ValidateLeaseSpec(spec, field.NewPath("foo"))
|
||||
if len(errs) != 2 {
|
||||
t.Errorf("unexpected list of errors: %#v", errs.ToAggregate().Error())
|
||||
|
||||
for _, tc := range testcases {
|
||||
errs := ValidateLeaseSpec(&tc.spec, field.NewPath("foo"))
|
||||
if tc.err && len(errs) == 0 {
|
||||
t.Error("Expected err, got no err")
|
||||
} else if !tc.err && len(errs) != 0 {
|
||||
t.Errorf("Expected no err, got err %v", errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,3 +147,188 @@ func TestValidateLeaseSpecUpdate(t *testing.T) {
|
||||
t.Errorf("unexpected list of errors for valid update: %#v", errs.ToAggregate().Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLeaseCandidate(t *testing.T) {
|
||||
lease := &coordination.LeaseCandidate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "invalidName++",
|
||||
Namespace: "==invalid_Namespace==",
|
||||
},
|
||||
}
|
||||
errs := ValidateLeaseCandidate(lease)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected invalid LeaseCandidate")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLeaseCandidateSpec(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
shouldErr bool
|
||||
spec *coordination.LeaseCandidateSpec
|
||||
}{
|
||||
{
|
||||
"valid",
|
||||
false,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.0",
|
||||
EmulationVersion: "1.30.0",
|
||||
LeaseName: "test",
|
||||
PreferredStrategies: []coordination.CoordinatedLeaseStrategy{coordination.OldestEmulationVersion},
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid custom strategy should not require binaryVersion and emulationVersion",
|
||||
false,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
LeaseName: "test",
|
||||
PreferredStrategies: []coordination.CoordinatedLeaseStrategy{"custom.com/foo"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"no lease name",
|
||||
true,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
EmulationVersion: "1.30.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
"bad binaryVersion",
|
||||
true,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.1.6",
|
||||
LeaseName: "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
"emulation should be greater than or equal to binary version",
|
||||
true,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
EmulationVersion: "1.30.0",
|
||||
BinaryVersion: "1.29.0",
|
||||
LeaseName: "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
"preferredStrategies bad",
|
||||
true,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.1",
|
||||
EmulationVersion: "1.30.1",
|
||||
LeaseName: "test",
|
||||
PreferredStrategies: []coordination.CoordinatedLeaseStrategy{"foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"preferredStrategies good but emulationVersion missing",
|
||||
true,
|
||||
&coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.1",
|
||||
LeaseName: "test",
|
||||
PreferredStrategies: []coordination.CoordinatedLeaseStrategy{coordination.OldestEmulationVersion},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
errs := ValidateLeaseCandidateSpec(tc.spec, field.NewPath("foo"))
|
||||
if len(errs) > 0 && !tc.shouldErr {
|
||||
t.Errorf("unexpected list of errors: %#v", errs.ToAggregate().Error())
|
||||
} else if len(errs) == 0 && tc.shouldErr {
|
||||
t.Errorf("Expected err, got no error for tc: %s", tc.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLeaseCandidateUpdate(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
old coordination.LeaseCandidate
|
||||
update coordination.LeaseCandidate
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "valid update",
|
||||
old: coordination.LeaseCandidate{
|
||||
Spec: coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.0",
|
||||
EmulationVersion: "1.30.0",
|
||||
LeaseName: "test",
|
||||
},
|
||||
},
|
||||
update: coordination.LeaseCandidate{
|
||||
Spec: coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.0",
|
||||
EmulationVersion: "1.30.0",
|
||||
LeaseName: "test",
|
||||
},
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "update LeaseName should fail",
|
||||
old: coordination.LeaseCandidate{
|
||||
Spec: coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.0",
|
||||
EmulationVersion: "1.30.0",
|
||||
LeaseName: "test",
|
||||
},
|
||||
},
|
||||
update: coordination.LeaseCandidate{
|
||||
Spec: coordination.LeaseCandidateSpec{
|
||||
BinaryVersion: "1.30.0",
|
||||
EmulationVersion: "1.30.0",
|
||||
LeaseName: "test-update",
|
||||
},
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc.old.ResourceVersion = "1"
|
||||
tc.update.ResourceVersion = "1"
|
||||
errs := ValidateLeaseCandidateUpdate(&tc.update, &tc.old)
|
||||
if tc.err && len(errs) == 0 {
|
||||
t.Errorf("Expected err, got no err for tc: %s", tc.name)
|
||||
} else if !tc.err && len(errs) != 0 {
|
||||
t.Errorf("Expected no err, got err %v for tc: %s", errs, tc.name)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateCoordinatedLeaseStrategy(t *testing.T) {
|
||||
testcases := []struct {
|
||||
strategy coordination.CoordinatedLeaseStrategy
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
coordination.CoordinatedLeaseStrategy("foobar"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
coordination.CoordinatedLeaseStrategy("example.com/foobar/toomanyslashes"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
||||
coordination.CoordinatedLeaseStrategy(coordination.OldestEmulationVersion),
|
||||
false,
|
||||
},
|
||||
{
|
||||
coordination.CoordinatedLeaseStrategy("example.com/foobar"),
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
errs := ValidateCoordinatedLeaseStrategy(tc.strategy, field.NewPath("foo"))
|
||||
if tc.err && len(errs) == 0 {
|
||||
t.Error("Expected err, got no err")
|
||||
} else if !tc.err && len(errs) != 0 {
|
||||
t.Errorf("Expected no err, got err %v", errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
99
pkg/apis/coordination/zz_generated.deepcopy.go
generated
99
pkg/apis/coordination/zz_generated.deepcopy.go
generated
@@ -52,6 +52,95 @@ func (in *Lease) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaseCandidate) DeepCopyInto(out *LeaseCandidate) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidate.
|
||||
func (in *LeaseCandidate) DeepCopy() *LeaseCandidate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LeaseCandidate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LeaseCandidate) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaseCandidateList) DeepCopyInto(out *LeaseCandidateList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LeaseCandidate, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidateList.
|
||||
func (in *LeaseCandidateList) DeepCopy() *LeaseCandidateList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LeaseCandidateList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LeaseCandidateList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaseCandidateSpec) DeepCopyInto(out *LeaseCandidateSpec) {
|
||||
*out = *in
|
||||
if in.PingTime != nil {
|
||||
in, out := &in.PingTime, &out.PingTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.RenewTime != nil {
|
||||
in, out := &in.RenewTime, &out.RenewTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.PreferredStrategies != nil {
|
||||
in, out := &in.PreferredStrategies, &out.PreferredStrategies
|
||||
*out = make([]CoordinatedLeaseStrategy, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidateSpec.
|
||||
func (in *LeaseCandidateSpec) DeepCopy() *LeaseCandidateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LeaseCandidateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaseList) DeepCopyInto(out *LeaseList) {
|
||||
*out = *in
|
||||
@@ -111,6 +200,16 @@ func (in *LeaseSpec) DeepCopyInto(out *LeaseSpec) {
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Strategy != nil {
|
||||
in, out := &in.Strategy, &out.Strategy
|
||||
*out = new(CoordinatedLeaseStrategy)
|
||||
**out = **in
|
||||
}
|
||||
if in.PreferredHolder != nil {
|
||||
in, out := &in.PreferredHolder, &out.PreferredHolder
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
201
pkg/generated/openapi/zz_generated.openapi.go
generated
201
pkg/generated/openapi/zz_generated.openapi.go
generated
@@ -376,6 +376,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"k8s.io/api/coordination/v1.Lease": schema_k8sio_api_coordination_v1_Lease(ref),
|
||||
"k8s.io/api/coordination/v1.LeaseList": schema_k8sio_api_coordination_v1_LeaseList(ref),
|
||||
"k8s.io/api/coordination/v1.LeaseSpec": schema_k8sio_api_coordination_v1_LeaseSpec(ref),
|
||||
"k8s.io/api/coordination/v1alpha1.LeaseCandidate": schema_k8sio_api_coordination_v1alpha1_LeaseCandidate(ref),
|
||||
"k8s.io/api/coordination/v1alpha1.LeaseCandidateList": schema_k8sio_api_coordination_v1alpha1_LeaseCandidateList(ref),
|
||||
"k8s.io/api/coordination/v1alpha1.LeaseCandidateSpec": schema_k8sio_api_coordination_v1alpha1_LeaseCandidateSpec(ref),
|
||||
"k8s.io/api/coordination/v1beta1.Lease": schema_k8sio_api_coordination_v1beta1_Lease(ref),
|
||||
"k8s.io/api/coordination/v1beta1.LeaseList": schema_k8sio_api_coordination_v1beta1_LeaseList(ref),
|
||||
"k8s.io/api/coordination/v1beta1.LeaseSpec": schema_k8sio_api_coordination_v1beta1_LeaseSpec(ref),
|
||||
@@ -18845,14 +18848,14 @@ func schema_k8sio_api_coordination_v1_LeaseSpec(ref common.ReferenceCallback) co
|
||||
Properties: map[string]spec.Schema{
|
||||
"holderIdentity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "holderIdentity contains the identity of the holder of a current lease.",
|
||||
Description: "holderIdentity contains the identity of the holder of a current lease. If Coordinated Leader Election is used, the holder identity must be equal to the elected LeaseCandidate.metadata.name field.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"leaseDurationSeconds": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed renewTime.",
|
||||
Description: "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measured against the time of last observed renewTime.",
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
@@ -18876,6 +18879,20 @@ func schema_k8sio_api_coordination_v1_LeaseSpec(ref common.ReferenceCallback) co
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"strategy": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Strategy indicates the strategy for picking the leader for coordinated leader election. If the field is not specified, there is no active coordination for this lease. (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"preferredHolder": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PreferredHolder signals to a lease holder that the lease has a more optimal holder and should be given up. This field can only be set if Strategy is also set.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -18884,6 +18901,170 @@ func schema_k8sio_api_coordination_v1_LeaseSpec(ref common.ReferenceCallback) co
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_coordination_v1alpha1_LeaseCandidate(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "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: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "spec contains the specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/api/coordination/v1alpha1.LeaseCandidateSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/api/coordination/v1alpha1.LeaseCandidateSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_coordination_v1alpha1_LeaseCandidateList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "LeaseCandidateList is a list of Lease objects.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "items is a list of schema objects.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/api/coordination/v1alpha1.LeaseCandidate"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"items"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/api/coordination/v1alpha1.LeaseCandidate", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_coordination_v1alpha1_LeaseCandidateSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "LeaseSpec is a specification of a Lease.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"leaseName": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "LeaseName is the name of the lease for which this candidate is contending. This field is immutable.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"pingTime": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "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.",
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime"),
|
||||
},
|
||||
},
|
||||
"renewTime": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "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.",
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime"),
|
||||
},
|
||||
},
|
||||
"binaryVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "BinaryVersion is the binary version. It must be in a semver format without leading `v`. This field is required when Strategy is \"OldestEmulationVersion\"",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"emulationVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "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\"",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"preferredStrategies": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PreferredStrategies indicates the list of strategies for picking the leader for coordinated leader election. The list is ordered, and the first strategy supersedes all other strategies. The list is used by coordinated leader election to make a decision about the final election strategy. This follows as - If all clients have strategy X as the first element in this list, strategy X will be used. - If a candidate has strategy [X] and another candidate has strategy [Y, X], Y supersedes X and strategy Y\n will be used\n- If a candidate has strategy [X, Y] and another candidate has strategy [Y, X], this is a user error and leader\n election will not operate the Lease until resolved.\n(Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"leaseName", "preferredStrategies"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_coordination_v1beta1_Lease(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -18987,7 +19168,7 @@ func schema_k8sio_api_coordination_v1beta1_LeaseSpec(ref common.ReferenceCallbac
|
||||
Properties: map[string]spec.Schema{
|
||||
"holderIdentity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "holderIdentity contains the identity of the holder of a current lease.",
|
||||
Description: "holderIdentity contains the identity of the holder of a current lease. If Coordinated Leader Election is used, the holder identity must be equal to the elected LeaseCandidate.metadata.name field.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
@@ -19018,6 +19199,20 @@ func schema_k8sio_api_coordination_v1beta1_LeaseSpec(ref common.ReferenceCallbac
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"strategy": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Strategy indicates the strategy for picking the leader for coordinated leader election (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"preferredHolder": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PreferredHolder signals to a lease holder that the lease has a more optimal holder and should be given up.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user