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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user