Merge pull request #80681 from ricky1993/customize_resource_name_and_namespace

add options for name and namespace of leaderelection object
This commit is contained in:
Kubernetes Prow Robot 2019-08-07 01:36:51 -07:00 committed by GitHub
commit aa6a077cfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 421 additions and 105 deletions

View File

@ -186,8 +186,8 @@ func Run(c *cloudcontrollerconfig.CompletedConfig, stopCh <-chan struct{}) error
// Lock required for leader election
rl, err := resourcelock.New(c.ComponentConfig.Generic.LeaderElection.ResourceLock,
"kube-system",
"cloud-controller-manager",
c.ComponentConfig.Generic.LeaderElection.ResourceNamespace,
c.ComponentConfig.Generic.LeaderElection.ResourceName,
c.LeaderElectionClient.CoreV1(),
c.LeaderElectionClient.CoordinationV1(),
resourcelock.ResourceLockConfig{

View File

@ -107,6 +107,9 @@ func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error)
s.SecureServing.ServerCert.PairName = "cloud-controller-manager"
s.SecureServing.BindPort = ports.CloudControllerManagerPort
s.Generic.LeaderElection.ResourceName = "cloud-controller-manager"
s.Generic.LeaderElection.ResourceNamespace = "kube-system"
return &s, nil
}

View File

@ -49,11 +49,13 @@ func TestDefaultFlags(t *testing.T) {
},
ControllerStartInterval: metav1.Duration{Duration: 0},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
ResourceLock: "endpoints",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceName: "cloud-controller-manager",
ResourceNamespace: "kube-system",
},
Controllers: []string{"*"},
},
@ -178,11 +180,13 @@ func TestAddFlags(t *testing.T) {
},
ControllerStartInterval: metav1.Duration{Duration: 2 * time.Minute},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
ResourceLock: "configmap",
LeaderElect: false,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceLock: "configmap",
LeaderElect: false,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceName: "cloud-controller-manager",
ResourceNamespace: "kube-system",
},
Controllers: []string{"foo", "bar"},
},

View File

@ -257,9 +257,10 @@ func Run(c *config.CompletedConfig, stopCh <-chan struct{}) error {
// add a uniquifier so that two processes on the same host don't accidentally both become active
id = id + "_" + string(uuid.NewUUID())
rl, err := resourcelock.New(c.ComponentConfig.Generic.LeaderElection.ResourceLock,
"kube-system",
"kube-controller-manager",
c.ComponentConfig.Generic.LeaderElection.ResourceNamespace,
c.ComponentConfig.Generic.LeaderElection.ResourceName,
c.LeaderElectionClient.CoreV1(),
c.LeaderElectionClient.CoordinationV1(),
resourcelock.ResourceLockConfig{

View File

@ -188,6 +188,8 @@ func NewKubeControllerManagerOptions() (*KubeControllerManagerOptions, error) {
}
s.GarbageCollectorController.GCIgnoredResources = gcIgnoredResources
s.Generic.LeaderElection.ResourceName = "kube-controller-manager"
s.Generic.LeaderElection.ResourceNamespace = "kube-system"
return &s, nil
}

View File

@ -156,11 +156,13 @@ func TestAddFlags(t *testing.T) {
},
ControllerStartInterval: metav1.Duration{Duration: 2 * time.Minute},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
ResourceLock: "configmap",
LeaderElect: false,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceLock: "configmap",
LeaderElect: false,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceName: "kube-controller-manager",
ResourceNamespace: "kube-system",
},
Controllers: []string{"foo", "bar"},
},

View File

@ -18,6 +18,7 @@ package options
import (
"fmt"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/validation/field"
@ -58,8 +59,8 @@ func (o *DeprecatedOptions) AddFlags(fs *pflag.FlagSet, cfg *kubeschedulerconfig
fs.Float32Var(&cfg.ClientConnection.QPS, "kube-api-qps", cfg.ClientConnection.QPS, "DEPRECATED: QPS to use while talking with kubernetes apiserver")
fs.Int32Var(&cfg.ClientConnection.Burst, "kube-api-burst", cfg.ClientConnection.Burst, "DEPRECATED: burst to use while talking with kubernetes apiserver")
fs.StringVar(&cfg.SchedulerName, "scheduler-name", cfg.SchedulerName, "DEPRECATED: name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.schedulerName\".")
fs.StringVar(&cfg.LeaderElection.LockObjectNamespace, "lock-object-namespace", cfg.LeaderElection.LockObjectNamespace, "DEPRECATED: define the namespace of the lock object.")
fs.StringVar(&cfg.LeaderElection.LockObjectName, "lock-object-name", cfg.LeaderElection.LockObjectName, "DEPRECATED: define the name of the lock object.")
fs.StringVar(&cfg.LeaderElection.ResourceNamespace, "lock-object-namespace", cfg.LeaderElection.ResourceNamespace, "DEPRECATED: define the namespace of the lock object. Will be removed in favor of leader-elect-resource-namespace.")
fs.StringVar(&cfg.LeaderElection.ResourceName, "lock-object-name", cfg.LeaderElection.ResourceName, "DEPRECATED: define the name of the lock object. Will be removed in favor of leader-elect-resource-name")
fs.Int32Var(&cfg.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", cfg.HardPodAffinitySymmetricWeight,
"RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+

View File

@ -275,8 +275,8 @@ func makeLeaderElectionConfig(config kubeschedulerconfig.KubeSchedulerLeaderElec
id := hostname + "_" + string(uuid.NewUUID())
rl, err := resourcelock.New(config.ResourceLock,
config.LockObjectNamespace,
config.LockObjectName,
config.ResourceNamespace,
config.ResourceName,
client.CoreV1(),
client.CoordinationV1(),
resourcelock.ResourceLockConfig{

View File

@ -234,14 +234,14 @@ pluginConfig:
MetricsBindAddress: "0.0.0.0:10251",
LeaderElection: kubeschedulerconfig.KubeSchedulerLeaderElectionConfiguration{
LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
LockObjectNamespace: "kube-system",
LockObjectName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
Kubeconfig: configKubeconfig,
@ -314,14 +314,14 @@ pluginConfig:
MetricsBindAddress: "", // defaults empty when not running from config file
LeaderElection: kubeschedulerconfig.KubeSchedulerLeaderElectionConfiguration{
LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
LockObjectNamespace: "kube-system",
LockObjectName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
Kubeconfig: flagKubeconfig,
@ -375,14 +375,14 @@ pluginConfig:
MetricsBindAddress: "0.0.0.0:10251",
LeaderElection: kubeschedulerconfig.KubeSchedulerLeaderElectionConfiguration{
LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "endpoints",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
LockObjectNamespace: "kube-system",
LockObjectName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
Kubeconfig: configKubeconfig,

View File

@ -43,4 +43,10 @@ func BindFlags(l *componentbaseconfig.LeaderElectionConfiguration, fs *pflag.Fla
fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+
"The type of resource object that is used for locking during "+
"leader election. Supported options are `endpoints` (default) and `configmaps`.")
fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+
"The name of resource object that is used for locking during "+
"leader election.")
fs.StringVar(&l.ResourceNamespace, "leader-elect-resource-namespace", l.ResourceNamespace, ""+
"The namespace of resource object that is used for locking during "+
"leader election.")
}

View File

@ -138,10 +138,6 @@ type SchedulerPolicyConfigMapSource struct {
// to include scheduler specific configuration.
type KubeSchedulerLeaderElectionConfiguration struct {
componentbaseconfig.LeaderElectionConfiguration
// LockObjectNamespace defines the namespace of the lock object
LockObjectNamespace string
// LockObjectName defines the lock object name
LockObjectName string
}
// Plugins include multiple extension points. When specified, the list of plugins for

View File

@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"conversion.go",
"defaults.go",
"doc.go",
"register.go",
@ -27,12 +28,19 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["defaults_test.go"],
srcs = [
"conversion_test.go",
"defaults_test.go",
],
embed = [":go_default_library"],
deps = [
"//pkg/scheduler/apis/config:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/component-base/config:go_default_library",
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
"//staging/src/k8s.io/kube-scheduler/config/v1alpha1:go_default_library",
],
)

View File

@ -0,0 +1,68 @@
/*
Copyright 2019 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 (
"fmt"
conversion "k8s.io/apimachinery/pkg/conversion"
v1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
config "k8s.io/kubernetes/pkg/scheduler/apis/config"
)
// Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in *v1alpha1.KubeSchedulerLeaderElectionConfiguration, out *config.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
if err := autoConvert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in, out, s); err != nil {
return err
}
if len(in.ResourceNamespace) > 0 && len(in.LockObjectNamespace) == 0 {
out.ResourceNamespace = in.ResourceNamespace
} else if len(in.ResourceNamespace) == 0 && len(in.LockObjectNamespace) > 0 {
out.ResourceNamespace = in.LockObjectNamespace
} else if len(in.ResourceNamespace) > 0 && len(in.LockObjectNamespace) > 0 {
if in.ResourceNamespace == in.LockObjectNamespace {
out.ResourceNamespace = in.ResourceNamespace
} else {
return fmt.Errorf("ResourceNamespace and LockObjectNamespace are both set and do not match, ResourceNamespace: %s, LockObjectNamespace: %s", in.ResourceNamespace, in.LockObjectNamespace)
}
}
if len(in.ResourceName) > 0 && len(in.LockObjectName) == 0 {
out.ResourceName = in.ResourceName
} else if len(in.ResourceName) == 0 && len(in.LockObjectName) > 0 {
out.ResourceName = in.LockObjectName
} else if len(in.ResourceName) > 0 && len(in.LockObjectName) > 0 {
if in.ResourceName == in.LockObjectName {
out.ResourceName = in.ResourceName
} else {
return fmt.Errorf("ResourceName and LockObjectName are both set and do not match, ResourceName: %s, LockObjectName: %s", in.ResourceName, in.LockObjectName)
}
}
return nil
}
// Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration is an autogenerated conversion function.
func Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(in *config.KubeSchedulerLeaderElectionConfiguration, out *v1alpha1.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
if err := autoConvert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(in, out, s); err != nil {
return err
}
out.ResourceNamespace = in.ResourceNamespace
out.LockObjectNamespace = in.ResourceNamespace
out.ResourceName = in.ResourceName
out.LockObjectName = in.ResourceName
return nil
}

View File

@ -0,0 +1,193 @@
/*
Copyright 2019 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 (
"testing"
conversion "k8s.io/apimachinery/pkg/conversion"
componentbaseconfig "k8s.io/component-base/config"
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
v1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
config "k8s.io/kubernetes/pkg/scheduler/apis/config"
)
func TestV1alpha1ToConfigKubeSchedulerLeaderElectionConfiguration(t *testing.T) {
configuration := &v1alpha1.KubeSchedulerLeaderElectionConfiguration{
LockObjectName: "name",
LockObjectNamespace: "namespace",
LeaderElectionConfiguration: componentbaseconfigv1alpha1.LeaderElectionConfiguration{
ResourceName: "name",
ResourceNamespace: "namespace",
},
}
emptyLockObjectNameConfig := configuration.DeepCopy()
emptyLockObjectNameConfig.LockObjectName = ""
emptyLockObjectNamespaceConfig := configuration.DeepCopy()
emptyLockObjectNamespaceConfig.LockObjectNamespace = ""
emptyResourceNameConfig := configuration.DeepCopy()
emptyResourceNameConfig.ResourceName = ""
emptyResourceNamespaceConfig := configuration.DeepCopy()
emptyResourceNamespaceConfig.ResourceNamespace = ""
differentNameConfig := configuration.DeepCopy()
differentNameConfig.LockObjectName = "name1"
differentNamespaceConfig := configuration.DeepCopy()
differentNamespaceConfig.LockObjectNamespace = "namespace1"
emptyconfig := &v1alpha1.KubeSchedulerLeaderElectionConfiguration{}
scenarios := map[string]struct {
expectedResourceNamespace string
expectedResourceName string
expectedToFailed bool
config *v1alpha1.KubeSchedulerLeaderElectionConfiguration
}{
"both-set-same-name-and-namespace": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedToFailed: false,
config: configuration,
},
"not-set-lock-object-name": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedToFailed: false,
config: emptyLockObjectNameConfig,
},
"not-set-lock-object-namespace": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedToFailed: false,
config: emptyLockObjectNamespaceConfig,
},
"not-set-resource-name": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedToFailed: false,
config: emptyResourceNameConfig,
},
"not-set-resource-namespace": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedToFailed: false,
config: emptyResourceNamespaceConfig,
},
"set-different-name": {
expectedResourceNamespace: "",
expectedResourceName: "",
expectedToFailed: true,
config: differentNameConfig,
},
"set-different-namespace": {
expectedResourceNamespace: "",
expectedResourceName: "",
expectedToFailed: true,
config: differentNamespaceConfig,
},
"set-empty-name-and-namespace": {
expectedResourceNamespace: "",
expectedResourceName: "",
expectedToFailed: false,
config: emptyconfig,
},
}
for name, scenario := range scenarios {
out := &config.KubeSchedulerLeaderElectionConfiguration{}
s := conversion.Scope(nil)
err := Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(scenario.config, out, s)
if err == nil && scenario.expectedToFailed {
t.Errorf("Unexpected success for scenario: %s", name)
}
if err == nil && !scenario.expectedToFailed {
if out.ResourceName != scenario.expectedResourceName {
t.Errorf("Unexpected success for scenario: %s, out.ResourceName: %s, expectedResourceName: %s", name, out.ResourceName, scenario.expectedResourceName)
}
if out.ResourceNamespace != scenario.expectedResourceNamespace {
t.Errorf("Unexpected success for scenario: %s, out.ResourceNamespace: %s, expectedResourceNamespace: %s", name, out.ResourceNamespace, scenario.expectedResourceNamespace)
}
}
if err != nil && !scenario.expectedToFailed {
t.Errorf("Unexpected failure for scenario: %s - %+v", name, err)
}
}
}
func TestConfigToV1alpha1KubeSchedulerLeaderElectionConfiguration(t *testing.T) {
configuration := &config.KubeSchedulerLeaderElectionConfiguration{
LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{
ResourceName: "name",
ResourceNamespace: "namespace",
},
}
emptyconfig := &config.KubeSchedulerLeaderElectionConfiguration{}
scenarios := map[string]struct {
expectedResourceNamespace string
expectedResourceName string
expectedLockObjectNamespace string
expectedLockObjectName string
expectedToFailed bool
config *config.KubeSchedulerLeaderElectionConfiguration
}{
"both-set-name-and-namespace": {
expectedResourceNamespace: "namespace",
expectedResourceName: "name",
expectedLockObjectNamespace: "namespace",
expectedLockObjectName: "name",
expectedToFailed: false,
config: configuration,
},
"set-empty-name-and-namespace": {
expectedResourceNamespace: "",
expectedResourceName: "",
expectedLockObjectNamespace: "",
expectedLockObjectName: "",
expectedToFailed: false,
config: emptyconfig,
},
}
for name, scenario := range scenarios {
out := &v1alpha1.KubeSchedulerLeaderElectionConfiguration{}
s := conversion.Scope(nil)
err := Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(scenario.config, out, s)
if err == nil && scenario.expectedToFailed {
t.Errorf("Unexpected success for scenario: %s", name)
}
if err == nil && !scenario.expectedToFailed {
if out.ResourceName != scenario.expectedResourceName {
t.Errorf("Unexpected success for scenario: %s, out.ResourceName: %s, expectedResourceName: %s", name, out.ResourceName, scenario.expectedResourceName)
}
if out.LockObjectName != scenario.expectedLockObjectName {
t.Errorf("Unexpected success for scenario: %s, out.LockObjectName: %s, expectedLockObjectName: %s", name, out.LockObjectName, scenario.expectedLockObjectName)
}
if out.ResourceNamespace != scenario.expectedResourceNamespace {
t.Errorf("Unexpected success for scenario: %s, out.ResourceNamespace: %s, expectedResourceNamespace: %s", name, out.ResourceNamespace, scenario.expectedResourceNamespace)
}
if out.LockObjectNamespace != scenario.expectedLockObjectNamespace {
t.Errorf("Unexpected success for scenario: %s, out.LockObjectNamespace: %s, expectedLockObjectNamespace: %s", name, out.LockObjectNamespace, scenario.expectedLockObjectNamespace)
}
}
if err != nil && !scenario.expectedToFailed {
t.Errorf("Unexpected failure for scenario: %s - %+v", name, err)
}
}
}

View File

@ -23,7 +23,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
kubescedulerconfigv1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
kubeschedulerconfigv1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
// this package shouldn't really depend on other k8s.io/kubernetes code
api "k8s.io/kubernetes/pkg/apis/core"
@ -39,7 +39,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
}
// SetDefaults_KubeSchedulerConfiguration sets additional defaults
func SetDefaults_KubeSchedulerConfiguration(obj *kubescedulerconfigv1alpha1.KubeSchedulerConfiguration) {
func SetDefaults_KubeSchedulerConfiguration(obj *kubeschedulerconfigv1alpha1.KubeSchedulerConfiguration) {
if len(obj.SchedulerName) == 0 {
obj.SchedulerName = api.DefaultSchedulerName
}
@ -50,7 +50,7 @@ func SetDefaults_KubeSchedulerConfiguration(obj *kubescedulerconfigv1alpha1.Kube
if obj.AlgorithmSource.Policy == nil &&
(obj.AlgorithmSource.Provider == nil || len(*obj.AlgorithmSource.Provider) == 0) {
val := kubescedulerconfigv1alpha1.SchedulerDefaultProviderName
val := kubeschedulerconfigv1alpha1.SchedulerDefaultProviderName
obj.AlgorithmSource.Provider = &val
}
@ -78,11 +78,11 @@ func SetDefaults_KubeSchedulerConfiguration(obj *kubescedulerconfigv1alpha1.Kube
obj.MetricsBindAddress = net.JoinHostPort("0.0.0.0", strconv.Itoa(ports.InsecureSchedulerPort))
}
if len(obj.LeaderElection.LockObjectNamespace) == 0 {
obj.LeaderElection.LockObjectNamespace = kubescedulerconfigv1alpha1.SchedulerDefaultLockObjectNamespace
if len(obj.LeaderElection.LockObjectNamespace) == 0 && len(obj.LeaderElection.ResourceNamespace) == 0 {
obj.LeaderElection.LockObjectNamespace = kubeschedulerconfigv1alpha1.SchedulerDefaultLockObjectNamespace
}
if len(obj.LeaderElection.LockObjectName) == 0 {
obj.LeaderElection.LockObjectName = kubescedulerconfigv1alpha1.SchedulerDefaultLockObjectName
if len(obj.LeaderElection.LockObjectName) == 0 && len(obj.LeaderElection.ResourceName) == 0 {
obj.LeaderElection.LockObjectName = kubeschedulerconfigv1alpha1.SchedulerDefaultLockObjectName
}
if len(obj.ClientConnection.ContentType) == 0 {

View File

@ -25,7 +25,7 @@ import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
configv1alpha1 "k8s.io/component-base/config/v1alpha1"
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
v1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
config "k8s.io/kubernetes/pkg/scheduler/apis/config"
)
@ -137,6 +137,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddConversionFunc((*config.KubeSchedulerLeaderElectionConfiguration)(nil), (*v1alpha1.KubeSchedulerLeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(a.(*config.KubeSchedulerLeaderElectionConfiguration), b.(*v1alpha1.KubeSchedulerLeaderElectionConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*v1alpha1.KubeSchedulerLeaderElectionConfiguration)(nil), (*config.KubeSchedulerLeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(a.(*v1alpha1.KubeSchedulerLeaderElectionConfiguration), b.(*config.KubeSchedulerLeaderElectionConfiguration), scope)
}); err != nil {
return err
}
return nil
}
@ -149,12 +159,12 @@ func autoConvert_v1alpha1_KubeSchedulerConfiguration_To_config_KubeSchedulerConf
if err := Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil {
return err
}
if err := configv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {
return err
}
out.HealthzBindAddress = in.HealthzBindAddress
out.MetricsBindAddress = in.MetricsBindAddress
if err := configv1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
return err
}
out.DisablePreemption = in.DisablePreemption
@ -179,12 +189,12 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConf
if err := Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil {
return err
}
if err := configv1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {
return err
}
out.HealthzBindAddress = in.HealthzBindAddress
out.MetricsBindAddress = in.MetricsBindAddress
if err := configv1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil {
return err
}
out.DisablePreemption = in.DisablePreemption
@ -201,33 +211,21 @@ func Convert_config_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfigur
}
func autoConvert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in *v1alpha1.KubeSchedulerLeaderElectionConfiguration, out *config.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
if err := configv1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElectionConfiguration, &out.LeaderElectionConfiguration, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElectionConfiguration, &out.LeaderElectionConfiguration, s); err != nil {
return err
}
out.LockObjectNamespace = in.LockObjectNamespace
out.LockObjectName = in.LockObjectName
// WARNING: in.LockObjectNamespace requires manual conversion: does not exist in peer-type
// WARNING: in.LockObjectName requires manual conversion: does not exist in peer-type
return nil
}
// Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in *v1alpha1.KubeSchedulerLeaderElectionConfiguration, out *config.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha1_KubeSchedulerLeaderElectionConfiguration_To_config_KubeSchedulerLeaderElectionConfiguration(in, out, s)
}
func autoConvert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(in *config.KubeSchedulerLeaderElectionConfiguration, out *v1alpha1.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
if err := configv1alpha1.Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(&in.LeaderElectionConfiguration, &out.LeaderElectionConfiguration, s); err != nil {
if err := componentbaseconfigv1alpha1.Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(&in.LeaderElectionConfiguration, &out.LeaderElectionConfiguration, s); err != nil {
return err
}
out.LockObjectNamespace = in.LockObjectNamespace
out.LockObjectName = in.LockObjectName
return nil
}
// Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration is an autogenerated conversion function.
func Convert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(in *config.KubeSchedulerLeaderElectionConfiguration, out *v1alpha1.KubeSchedulerLeaderElectionConfiguration, s conversion.Scope) error {
return autoConvert_config_KubeSchedulerLeaderElectionConfiguration_To_v1alpha1_KubeSchedulerLeaderElectionConfiguration(in, out, s)
}
func autoConvert_v1alpha1_Plugin_To_config_Plugin(in *v1alpha1.Plugin, out *config.Plugin, s conversion.Scope) error {
out.Name = in.Name
out.Weight = in.Weight

View File

@ -57,11 +57,5 @@ func ValidateKubeSchedulerLeaderElectionConfiguration(cc *config.KubeSchedulerLe
return allErrs
}
allErrs = append(allErrs, componentbasevalidation.ValidateLeaderElectionConfiguration(&cc.LeaderElectionConfiguration, field.NewPath("leaderElectionConfiguration"))...)
if len(cc.LockObjectNamespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("lockObjectNamespace"), ""))
}
if len(cc.LockObjectName) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("lockObjectName"), ""))
}
return allErrs
}

View File

@ -47,14 +47,14 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
},
},
LeaderElection: config.KubeSchedulerLeaderElectionConfiguration{
LockObjectNamespace: "name",
LockObjectName: "name",
LeaderElectionConfiguration: componentbaseconfig.LeaderElectionConfiguration{
ResourceLock: "configmap",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceLock: "configmap",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceNamespace: "name",
ResourceName: "name",
},
},
BindTimeoutSeconds: &testTimeout,
@ -67,11 +67,11 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
HardPodAffinitySymmetricWeightLt0 := validConfig.DeepCopy()
HardPodAffinitySymmetricWeightLt0.HardPodAffinitySymmetricWeight = -1
lockObjectNameNotSet := validConfig.DeepCopy()
lockObjectNameNotSet.LeaderElection.LockObjectName = ""
resourceNameNotSet := validConfig.DeepCopy()
resourceNameNotSet.LeaderElection.ResourceName = ""
lockObjectNamespaceNotSet := validConfig.DeepCopy()
lockObjectNamespaceNotSet.LeaderElection.LockObjectNamespace = ""
resourceNamespaceNotSet := validConfig.DeepCopy()
resourceNamespaceNotSet.LeaderElection.ResourceNamespace = ""
metricsBindAddrHostInvalid := validConfig.DeepCopy()
metricsBindAddrHostInvalid.MetricsBindAddress = "0.0.0.0.0:9090"
@ -103,13 +103,13 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
expectedToFail: false,
config: validConfig,
},
"bad-lock-object-names-not-set": {
"bad-resource-name-not-set": {
expectedToFail: true,
config: lockObjectNameNotSet,
config: resourceNameNotSet,
},
"bad-lock-object-namespace-not-set": {
"bad-resource-namespace-not-set": {
expectedToFail: true,
config: lockObjectNamespaceNotSet,
config: resourceNamespaceNotSet,
},
"bad-healthz-port-invalid": {
expectedToFail: true,

View File

@ -62,6 +62,12 @@ type LeaderElectionConfiguration struct {
// resourceLock indicates the resource object type that will be used to lock
// during leader election cycles.
ResourceLock string
// resourceName indicates the name of resource object that will be used to lock
// during leader election cycles.
ResourceName string
// resourceName indicates the namespace of resource object that will be used to lock
// during leader election cycles.
ResourceNamespace string
}
// DebuggingConfiguration holds configuration for Debugging related features.

View File

@ -48,6 +48,12 @@ type LeaderElectionConfiguration struct {
// resourceLock indicates the resource object type that will be used to lock
// during leader election cycles.
ResourceLock string `json:"resourceLock"`
// resourceName indicates the name of resource object that will be used to lock
// during leader election cycles.
ResourceName string `json:"resourceName"`
// resourceName indicates the namespace of resource object that will be used to lock
// during leader election cycles.
ResourceNamespace string `json:"resourceNamespace"`
}
// DebuggingConfiguration holds configuration for Debugging related features.

View File

@ -135,6 +135,8 @@ func autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionCo
out.RenewDeadline = in.RenewDeadline
out.RetryPeriod = in.RetryPeriod
out.ResourceLock = in.ResourceLock
out.ResourceName = in.ResourceName
out.ResourceNamespace = in.ResourceNamespace
return nil
}
@ -146,5 +148,7 @@ func autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionCo
out.RenewDeadline = in.RenewDeadline
out.RetryPeriod = in.RetryPeriod
out.ResourceLock = in.ResourceLock
out.ResourceName = in.ResourceName
out.ResourceNamespace = in.ResourceNamespace
return nil
}

View File

@ -40,7 +40,7 @@ func ValidateLeaderElectionConfiguration(cc *config.LeaderElectionConfiguration,
allErrs = append(allErrs, field.Invalid(fldPath.Child("leaseDuration"), cc.LeaseDuration, "must be greater than zero"))
}
if cc.RenewDeadline.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("renewDeadline"), cc.LeaseDuration, "must be greater than zero"))
allErrs = append(allErrs, field.Invalid(fldPath.Child("renewDeadline"), cc.RenewDeadline, "must be greater than zero"))
}
if cc.RetryPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("retryPeriod"), cc.RetryPeriod, "must be greater than zero"))
@ -49,7 +49,13 @@ func ValidateLeaderElectionConfiguration(cc *config.LeaderElectionConfiguration,
allErrs = append(allErrs, field.Invalid(fldPath.Child("leaseDuration"), cc.RenewDeadline, "LeaseDuration must be greater than RenewDeadline"))
}
if len(cc.ResourceLock) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceLock"), cc.RenewDeadline, "resourceLock is required"))
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceLock"), cc.ResourceLock, "resourceLock is required"))
}
if len(cc.ResourceNamespace) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceNamespace"), cc.ResourceNamespace, "resourceNamespace is required"))
}
if len(cc.ResourceName) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceName"), cc.ResourceName, "resourceName is required"))
}
return allErrs
}

View File

@ -70,11 +70,13 @@ func TestValidateClientConnectionConfiguration(t *testing.T) {
func TestValidateLeaderElectionConfiguration(t *testing.T) {
validConfig := &config.LeaderElectionConfiguration{
ResourceLock: "configmap",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceLock: "configmap",
LeaderElect: true,
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
ResourceNamespace: "namespace",
ResourceName: "name",
}
renewDeadlineExceedsLeaseDuration := validConfig.DeepCopy()
@ -102,6 +104,12 @@ func TestValidateLeaderElectionConfiguration(t *testing.T) {
resourceLockNotDefined := validConfig.DeepCopy()
resourceLockNotDefined.ResourceLock = ""
resourceNameNotDefined := validConfig.DeepCopy()
resourceNameNotDefined.ResourceName = ""
resourceNamespaceNotDefined := validConfig.DeepCopy()
resourceNamespaceNotDefined.ResourceNamespace = ""
scenarios := map[string]struct {
expectedToFail bool
config *config.LeaderElectionConfiguration
@ -142,6 +150,14 @@ func TestValidateLeaderElectionConfiguration(t *testing.T) {
expectedToFail: true,
config: resourceLockNotDefined,
},
"bad-resource-name-not-defined": {
expectedToFail: true,
config: resourceNameNotDefined,
},
"bad-resource-namespace-not-defined": {
expectedToFail: true,
config: resourceNamespaceNotDefined,
},
}
for name, scenario := range scenarios {

View File

@ -135,8 +135,10 @@ type SchedulerPolicyConfigMapSource struct {
type KubeSchedulerLeaderElectionConfiguration struct {
componentbaseconfigv1alpha1.LeaderElectionConfiguration `json:",inline"`
// LockObjectNamespace defines the namespace of the lock object
// DEPRECATED: will be removed in favor of resourceNamespace
LockObjectNamespace string `json:"lockObjectNamespace"`
// LockObjectName defines the lock object name
// DEPRECATED: will be removed in favor of resourceName
LockObjectName string `json:"lockObjectName"`
}