diff --git a/staging/src/k8s.io/controller-manager/config/v1/conversion.go b/staging/src/k8s.io/controller-manager/config/v1/conversion.go new file mode 100644 index 00000000000..4ba5bd8a8c4 --- /dev/null +++ b/staging/src/k8s.io/controller-manager/config/v1/conversion.go @@ -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 +} diff --git a/staging/src/k8s.io/controller-manager/config/v1/doc.go b/staging/src/k8s.io/controller-manager/config/v1/doc.go new file mode 100644 index 00000000000..037cfb78563 --- /dev/null +++ b/staging/src/k8s.io/controller-manager/config/v1/doc.go @@ -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" diff --git a/staging/src/k8s.io/controller-manager/config/v1/register.go b/staging/src/k8s.io/controller-manager/config/v1/register.go new file mode 100644 index 00000000000..e48f90a7c8c --- /dev/null +++ b/staging/src/k8s.io/controller-manager/config/v1/register.go @@ -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 +} diff --git a/staging/src/k8s.io/controller-manager/config/v1/types.go b/staging/src/k8s.io/controller-manager/config/v1/types.go new file mode 100644 index 00000000000..e2027868625 --- /dev/null +++ b/staging/src/k8s.io/controller-manager/config/v1/types.go @@ -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"` +} diff --git a/staging/src/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..d5b54b0b23c --- /dev/null +++ b/staging/src/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go @@ -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 +} diff --git a/staging/src/k8s.io/controller-manager/pkg/leadermigration/config/config.go b/staging/src/k8s.io/controller-manager/pkg/leadermigration/config/config.go index 9cecdbafff2..460c4ec9d91 100644 --- a/staging/src/k8s.io/controller-manager/pkg/leadermigration/config/config.go +++ b/staging/src/k8s.io/controller-manager/pkg/leadermigration/config/config.go @@ -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. diff --git a/staging/src/k8s.io/controller-manager/pkg/leadermigration/options/options_test.go b/staging/src/k8s.io/controller-manager/pkg/leadermigration/options/options_test.go index b6db3686e51..05c58e98c53 100644 --- a/staging/src/k8s.io/controller-manager/pkg/leadermigration/options/options_test.go +++ b/staging/src/k8s.io/controller-manager/pkg/leadermigration/options/options_test.go @@ -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) { diff --git a/vendor/modules.txt b/vendor/modules.txt index 99241fffcca..a430282e77a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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