diff --git a/pkg/scheduler/apis/config/validation/validation.go b/pkg/scheduler/apis/config/validation/validation.go index 1dcfc699e80..e284101607f 100644 --- a/pkg/scheduler/apis/config/validation/validation.go +++ b/pkg/scheduler/apis/config/validation/validation.go @@ -42,6 +42,14 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) u var errs []error errs = append(errs, componentbasevalidation.ValidateClientConnectionConfiguration(&cc.ClientConnection, field.NewPath("clientConnection")).ToAggregate()) errs = append(errs, componentbasevalidation.ValidateLeaderElectionConfiguration(&cc.LeaderElection, field.NewPath("leaderElection")).ToAggregate()) + + // TODO: This can be removed when ResourceLock is not available + // Only ResourceLock values with leases are allowed + if cc.LeaderElection.LeaderElect && cc.LeaderElection.ResourceLock != "leases" { + leaderElectionPath := field.NewPath("leaderElection") + errs = append(errs, field.Invalid(leaderElectionPath.Child("resourceLock"), cc.LeaderElection.ResourceLock, `resourceLock value must be "leases"`)) + } + profilesPath := field.NewPath("profiles") if cc.Parallelism <= 0 { errs = append(errs, field.Invalid(field.NewPath("parallelism"), cc.Parallelism, "should be an integer value greater than zero")) diff --git a/pkg/scheduler/apis/config/validation/validation_test.go b/pkg/scheduler/apis/config/validation/validation_test.go index 6dce867b3c6..ddb9a9ccc91 100644 --- a/pkg/scheduler/apis/config/validation/validation_test.go +++ b/pkg/scheduler/apis/config/validation/validation_test.go @@ -46,7 +46,7 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) { Burst: 10, }, LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ - ResourceLock: "configmap", + ResourceLock: "leases", LeaderElect: true, LeaseDuration: metav1.Duration{Duration: 30 * time.Second}, RenewDeadline: metav1.Duration{Duration: 15 * time.Second}, @@ -104,6 +104,9 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) { resourceNamespaceNotSet := validConfig.DeepCopy() resourceNamespaceNotSet.LeaderElection.ResourceNamespace = "" + resourceLockNotLeases := validConfig.DeepCopy() + resourceLockNotLeases.LeaderElection.ResourceLock = "configmap" + enableContentProfilingSetWithoutEnableProfiling := validConfig.DeepCopy() enableContentProfilingSetWithoutEnableProfiling.EnableProfiling = false enableContentProfilingSetWithoutEnableProfiling.EnableContentionProfiling = true @@ -248,6 +251,15 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) { }, }, }, + "bad-resource-lock-not-leases": { + config: resourceLockNotLeases, + wantErrs: field.ErrorList{ + &field.Error{ + Type: field.ErrorTypeInvalid, + Field: "leaderElection.resourceLock", + }, + }, + }, "non-empty-metrics-bind-addr": { config: metricsBindAddrInvalid, wantErrs: field.ErrorList{ @@ -432,7 +444,7 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) { Burst: 10, }, LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ - ResourceLock: "configmap", + ResourceLock: "leases", LeaderElect: true, LeaseDuration: metav1.Duration{Duration: 30 * time.Second}, RenewDeadline: metav1.Duration{Duration: 15 * time.Second}, @@ -487,6 +499,9 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) { resourceNameNotSet := validConfig.DeepCopy() resourceNameNotSet.LeaderElection.ResourceName = "" + resourceLockNotLeases := validConfig.DeepCopy() + resourceLockNotLeases.LeaderElection.ResourceLock = "configmap" + resourceNamespaceNotSet := validConfig.DeepCopy() resourceNamespaceNotSet.LeaderElection.ResourceNamespace = "" @@ -631,6 +646,15 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) { }, }, }, + "bad-resource-lock-not-leases": { + config: resourceLockNotLeases, + wantErrs: field.ErrorList{ + &field.Error{ + Type: field.ErrorTypeInvalid, + Field: "leaderElection.resourceLock", + }, + }, + }, "bad-resource-namespace-not-set": { config: resourceNamespaceNotSet, wantErrs: field.ErrorList{ @@ -824,7 +848,7 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) { Burst: 10, }, LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ - ResourceLock: "configmap", + ResourceLock: "leases", LeaderElect: true, LeaseDuration: metav1.Duration{Duration: 30 * time.Second}, RenewDeadline: metav1.Duration{Duration: 15 * time.Second}, @@ -883,6 +907,9 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) { resourceNamespaceNotSet := validConfig.DeepCopy() resourceNamespaceNotSet.LeaderElection.ResourceNamespace = "" + resourceLockNotLeases := validConfig.DeepCopy() + resourceLockNotLeases.LeaderElection.ResourceLock = "configmap" + enableContentProfilingSetWithoutEnableProfiling := validConfig.DeepCopy() enableContentProfilingSetWithoutEnableProfiling.EnableProfiling = false enableContentProfilingSetWithoutEnableProfiling.EnableContentionProfiling = true @@ -1030,6 +1057,15 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) { }, }, }, + "bad-resource-lock-not-leases": { + config: resourceLockNotLeases, + wantErrs: field.ErrorList{ + &field.Error{ + Type: field.ErrorTypeInvalid, + Field: "leaderElection.resourceLock", + }, + }, + }, "non-empty-metrics-bind-addr": { config: metricsBindAddrInvalid, wantErrs: field.ErrorList{ diff --git a/staging/src/k8s.io/controller-manager/options/generic.go b/staging/src/k8s.io/controller-manager/options/generic.go index bb7e8c7d411..45c086b11f2 100644 --- a/staging/src/k8s.io/controller-manager/options/generic.go +++ b/staging/src/k8s.io/controller-manager/options/generic.go @@ -102,6 +102,12 @@ func (o *GenericControllerManagerConfigurationOptions) Validate(allControllers [ errs := []error{} errs = append(errs, o.Debugging.Validate()...) + // TODO: This can be removed when ResourceLock is not available + // Lock the ResourceLock using leases + if o.LeaderElection.LeaderElect && o.LeaderElection.ResourceLock != "leases" { + errs = append(errs, fmt.Errorf(`resourceLock value must be "leases"`)) + } + allControllersSet := sets.NewString(allControllers...) for _, controller := range o.Controllers { if controller == "*" {