Merge pull request #108016 from jiahuif-forks/feature/leader-migration-v1-api

v1 types for Leader Migration
This commit is contained in:
Kubernetes Prow Robot 2022-03-31 15:49:05 -07:00 committed by GitHub
commit 64e711085b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 376 additions and 0 deletions

View File

@ -0,0 +1,82 @@
/*
Copyright 2022 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 v1
import (
"unsafe"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/controller-manager/config"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
const ResourceLockLeases = "leases"
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope)
}); err != nil {
return err
}
return nil
}
func Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error {
out.LeaderName = in.LeaderName
out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders))
return nil
}
func Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error {
out.LeaderName = in.LeaderName
out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders))
out.ResourceLock = ResourceLockLeases
return nil
}
func Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error {
out.Name = in.Name
out.Component = in.Component
return nil
}
func Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error {
out.Name = in.Name
out.Component = in.Component
return nil
}

View File

@ -0,0 +1,20 @@
/*
Copyright 2022 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:deepcopy-gen=package
// +groupName=controllermanager.config.k8s.io
package v1 // import "k8s.io/controller-manager/config/v1"

View File

@ -0,0 +1,48 @@
/*
Copyright 2022 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 v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the "group" that is needed to uniquely identify the API
const GroupName = "controllermanager.config.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
var (
// SchemeBuilder is the scheme builder with scheme init functions to run for this API package
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package,
// defaulting and conversion init funcs are registered as well.
localSchemeBuilder = &SchemeBuilder
// AddToScheme is a global function that registers this API group & version to a scheme
AddToScheme = localSchemeBuilder.AddToScheme
)
// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&LeaderMigrationConfiguration{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -0,0 +1,47 @@
/*
Copyright 2022 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 v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type LeaderMigrationConfiguration struct {
metav1.TypeMeta `json:",inline"`
// LeaderName is the name of the leader election resource that protects the migration
// E.g. 1-20-KCM-to-1-21-CCM
LeaderName string `json:"leaderName"`
// ControllerLeaders contains a list of migrating leader lock configurations
// +listType=atomic
ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"`
}
// ControllerLeaderConfiguration provides the configuration for a migrating leader lock.
type ControllerLeaderConfiguration struct {
// Name is the name of the controller being migrated
// E.g. service-controller, route-controller, cloud-node-controller, etc
Name string `json:"name"`
// Component is the name of the component in which the controller should be running.
// E.g. kube-controller-manager, cloud-controller-manager, etc
// Or '*' meaning the controller can be run under any component that participates in the migration
Component string `json:"component"`
}

View File

@ -0,0 +1,72 @@
//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 deepcopy-gen. DO NOT EDIT.
package v1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration.
func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration {
if in == nil {
return nil
}
out := new(ControllerLeaderConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.ControllerLeaders != nil {
in, out := &in.ControllerLeaders, &out.ControllerLeaders
*out = make([]ControllerLeaderConfiguration, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration.
func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration {
if in == nil {
return nil
}
out := new(LeaderMigrationConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -25,6 +25,7 @@ import (
util "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
internal "k8s.io/controller-manager/config"
"k8s.io/controller-manager/config/v1"
"k8s.io/controller-manager/config/v1alpha1"
"k8s.io/controller-manager/config/v1beta1"
)
@ -48,6 +49,10 @@ func init() {
// v1beta1
util.Must(v1beta1.AddToScheme(cfgScheme))
util.Must(cfgScheme.SetVersionPriority(v1beta1.SchemeGroupVersion))
// v1
util.Must(v1.AddToScheme(cfgScheme))
util.Must(cfgScheme.SetVersionPriority(v1.SchemeGroupVersion))
}
// ReadLeaderMigrationConfiguration reads LeaderMigrationConfiguration from a YAML file at the given path.

View File

@ -23,6 +23,7 @@ import (
"testing"
"github.com/spf13/pflag"
"k8s.io/controller-manager/config"
migrationconfig "k8s.io/controller-manager/pkg/leadermigration/config"
)
@ -79,6 +80,106 @@ controllerLeaders: []
ControllerLeaders: []config.ControllerLeaderConfiguration{},
},
},
{
name: "enabled, with custom configuration file (version v1)",
flags: []string{"--enable-leader-migration"},
expectEnabled: true,
configContent: `
apiVersion: controllermanager.config.k8s.io/v1
kind: LeaderMigrationConfiguration
leaderName: test-leader-migration
controllerLeaders: []
`,
expectErr: false,
expectConfig: &config.LeaderMigrationConfiguration{
LeaderName: "test-leader-migration",
ResourceLock: "leases",
ControllerLeaders: []config.ControllerLeaderConfiguration{},
},
},
{
name: "enabled, with populated controllerLeaders (version v1)",
flags: []string{"--enable-leader-migration"},
expectEnabled: true,
configContent: `
apiVersion: controllermanager.config.k8s.io/v1
kind: LeaderMigrationConfiguration
leaderName: test-leader-migration
controllerLeaders:
- name: route
component: "*"
- name: service
component: "*"
- name: cloud-node-lifecycle
component: "*"
- name: nodeipam
component: "*"
`,
expectErr: false,
expectConfig: &config.LeaderMigrationConfiguration{
LeaderName: "test-leader-migration",
ResourceLock: "leases",
ControllerLeaders: []config.ControllerLeaderConfiguration{
{
Name: "route",
Component: "*",
},
{
Name: "service",
Component: "*",
},
{
Name: "cloud-node-lifecycle",
Component: "*",
},
{
Name: "nodeipam",
Component: "*",
},
},
},
}, {
name: "enabled, with non-wildcard controllerLeaders (version v1)",
flags: []string{"--enable-leader-migration"},
expectEnabled: true,
configContent: `
apiVersion: controllermanager.config.k8s.io/v1
kind: LeaderMigrationConfiguration
leaderName: test-leader-migration
controllerLeaders:
- name: route
component: "cloud-controller-manager"
- name: service
component: "cloud-controller-manager"
- name: cloud-node-lifecycle
component: "cloud-controller-manager"
- name: nodeipam
component: "kube-controller-manager"
`,
expectErr: false,
expectConfig: &config.LeaderMigrationConfiguration{
LeaderName: "test-leader-migration",
ResourceLock: "leases",
ControllerLeaders: []config.ControllerLeaderConfiguration{
{
Name: "route",
Component: "cloud-controller-manager",
},
{
Name: "service",
Component: "cloud-controller-manager",
},
{
Name: "cloud-node-lifecycle",
Component: "cloud-controller-manager",
},
{
Name: "nodeipam",
Component: "kube-controller-manager",
},
},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

1
vendor/modules.txt vendored
View File

@ -1983,6 +1983,7 @@ k8s.io/component-helpers/storage/volume
## explicit
k8s.io/controller-manager/app
k8s.io/controller-manager/config
k8s.io/controller-manager/config/v1
k8s.io/controller-manager/config/v1alpha1
k8s.io/controller-manager/config/v1beta1
k8s.io/controller-manager/controller