mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
1697 lines
54 KiB
Go
1697 lines
54 KiB
Go
/*
|
|
Copyright 2018 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 options
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
apiserveroptions "k8s.io/apiserver/pkg/server/options"
|
|
componentbaseconfig "k8s.io/component-base/config"
|
|
"k8s.io/component-base/logs"
|
|
"k8s.io/klog/v2/ktesting"
|
|
v1 "k8s.io/kube-scheduler/config/v1"
|
|
"k8s.io/kube-scheduler/config/v1beta2"
|
|
"k8s.io/kube-scheduler/config/v1beta3"
|
|
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
|
"k8s.io/kubernetes/pkg/scheduler/apis/config/latest"
|
|
configtesting "k8s.io/kubernetes/pkg/scheduler/apis/config/testing"
|
|
"k8s.io/kubernetes/pkg/scheduler/apis/config/testing/defaults"
|
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
|
"k8s.io/utils/pointer"
|
|
)
|
|
|
|
func TestSchedulerOptions(t *testing.T) {
|
|
// temp dir
|
|
tmpDir, err := os.MkdirTemp("", "scheduler-options")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// record the username requests were made with
|
|
username := ""
|
|
// https server
|
|
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
username, _, _ = req.BasicAuth()
|
|
if username == "" {
|
|
username = "none, tls"
|
|
}
|
|
w.WriteHeader(200)
|
|
w.Write([]byte(`ok`))
|
|
}))
|
|
defer server.Close()
|
|
// http server
|
|
insecureserver := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
username, _, _ = req.BasicAuth()
|
|
if username == "" {
|
|
username = "none, http"
|
|
}
|
|
w.WriteHeader(200)
|
|
w.Write([]byte(`ok`))
|
|
}))
|
|
defer insecureserver.Close()
|
|
|
|
// config file and kubeconfig
|
|
configFile := filepath.Join(tmpDir, "scheduler.yaml")
|
|
configKubeconfig := filepath.Join(tmpDir, "config.kubeconfig")
|
|
if err := os.WriteFile(configFile, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(configKubeconfig, []byte(fmt.Sprintf(`
|
|
apiVersion: v1
|
|
kind: Config
|
|
clusters:
|
|
- cluster:
|
|
insecure-skip-tls-verify: true
|
|
server: %s
|
|
name: default
|
|
contexts:
|
|
- context:
|
|
cluster: default
|
|
user: default
|
|
name: default
|
|
current-context: default
|
|
users:
|
|
- name: default
|
|
user:
|
|
username: config
|
|
`, server.URL)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
oldConfigFile := filepath.Join(tmpDir, "scheduler_old.yaml")
|
|
if err := os.WriteFile(oldConfigFile, []byte(fmt.Sprintf(`
|
|
apiVersion: componentconfig/v1alpha1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
v1beta3VersionConfig := filepath.Join(tmpDir, "scheduler_v1beta3_api_version.yaml")
|
|
if err := os.WriteFile(v1beta3VersionConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
v1beta2VersionConfig := filepath.Join(tmpDir, "scheduler_v1beta2_api_version.yaml")
|
|
if err := os.WriteFile(v1beta2VersionConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
unknownVersionConfig := filepath.Join(tmpDir, "scheduler_invalid_wrong_api_version.yaml")
|
|
if err := os.WriteFile(unknownVersionConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/unknown
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
noVersionConfig := filepath.Join(tmpDir, "scheduler_invalid_no_version.yaml")
|
|
if err := os.WriteFile(noVersionConfig, []byte(fmt.Sprintf(`
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
unknownFieldConfig := filepath.Join(tmpDir, "scheduler_invalid_unknown_field.yaml")
|
|
if err := os.WriteFile(unknownFieldConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true
|
|
foo: bar`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
duplicateFieldConfig := filepath.Join(tmpDir, "scheduler_invalid_duplicate_fields.yaml")
|
|
if err := os.WriteFile(duplicateFieldConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
leaderElection:
|
|
leaderElect: true
|
|
leaderElect: false`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// flag-specified kubeconfig
|
|
flagKubeconfig := filepath.Join(tmpDir, "flag.kubeconfig")
|
|
if err := os.WriteFile(flagKubeconfig, []byte(fmt.Sprintf(`
|
|
apiVersion: v1
|
|
kind: Config
|
|
clusters:
|
|
- cluster:
|
|
insecure-skip-tls-verify: true
|
|
server: %s
|
|
name: default
|
|
contexts:
|
|
- context:
|
|
cluster: default
|
|
user: default
|
|
name: default
|
|
current-context: default
|
|
users:
|
|
- name: default
|
|
user:
|
|
username: flag
|
|
`, server.URL)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// plugin config
|
|
pluginConfigFile := filepath.Join(tmpDir, "plugin.yaml")
|
|
if err := os.WriteFile(pluginConfigFile, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- plugins:
|
|
preEnqueue:
|
|
enabled:
|
|
- name: foo
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: bar
|
|
disabled:
|
|
- name: VolumeBinding
|
|
preBind:
|
|
enabled:
|
|
- name: foo
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: InterPodAffinity
|
|
args:
|
|
hardPodAffinityWeight: 2
|
|
- name: foo
|
|
args:
|
|
bar: baz
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// v1beta3 plugin config
|
|
v1beta3PluginConfigFile := filepath.Join(tmpDir, "v1beta3_plugin.yaml")
|
|
if err := os.WriteFile(v1beta3PluginConfigFile, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- plugins:
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: bar
|
|
disabled:
|
|
- name: VolumeBinding
|
|
preBind:
|
|
enabled:
|
|
- name: foo
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: InterPodAffinity
|
|
args:
|
|
hardPodAffinityWeight: 2
|
|
- name: foo
|
|
args:
|
|
bar: baz
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// v1beta2 plugin config
|
|
v1beta2PluginConfigFile := filepath.Join(tmpDir, "v1beta2_plugin.yaml")
|
|
if err := os.WriteFile(v1beta2PluginConfigFile, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- plugins:
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: bar
|
|
disabled:
|
|
- name: VolumeBinding
|
|
preBind:
|
|
enabled:
|
|
- name: foo
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: InterPodAffinity
|
|
args:
|
|
hardPodAffinityWeight: 2
|
|
- name: foo
|
|
args:
|
|
bar: baz
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// multiple profiles config
|
|
multiProfilesConfig := filepath.Join(tmpDir, "multi-profiles.yaml")
|
|
if err := os.WriteFile(multiProfilesConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- schedulerName: "foo-profile"
|
|
plugins:
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: VolumeBinding
|
|
disabled:
|
|
- name: VolumeBinding
|
|
- schedulerName: "bar-profile"
|
|
plugins:
|
|
preBind:
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: foo
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// v1beta3 multiple profiles config
|
|
v1beta3MultiProfilesConfig := filepath.Join(tmpDir, "v1beta3_multi-profiles.yaml")
|
|
if err := os.WriteFile(v1beta3MultiProfilesConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- schedulerName: "foo-profile"
|
|
plugins:
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: VolumeBinding
|
|
disabled:
|
|
- name: VolumeBinding
|
|
- schedulerName: "bar-profile"
|
|
plugins:
|
|
preBind:
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: foo
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// multiple profiles config
|
|
v1beta2MultiProfilesConfig := filepath.Join(tmpDir, "v1beta2_multi-profiles.yaml")
|
|
if err := os.WriteFile(v1beta2MultiProfilesConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- schedulerName: "foo-profile"
|
|
plugins:
|
|
reserve:
|
|
enabled:
|
|
- name: foo
|
|
- name: VolumeBinding
|
|
disabled:
|
|
- name: VolumeBinding
|
|
- schedulerName: "bar-profile"
|
|
plugins:
|
|
preBind:
|
|
disabled:
|
|
- name: VolumeBinding
|
|
pluginConfig:
|
|
- name: foo
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// high throughput profile config
|
|
highThroughputProfileConfig := filepath.Join(tmpDir, "high-throughput.yaml")
|
|
if err := os.WriteFile(highThroughputProfileConfig, []byte(fmt.Sprintf(`
|
|
apiVersion: kubescheduler.config.k8s.io/v1
|
|
kind: KubeSchedulerConfiguration
|
|
clientConnection:
|
|
kubeconfig: '%s'
|
|
profiles:
|
|
- schedulerName: "high-throughput-profile"
|
|
plugins:
|
|
preScore:
|
|
enabled:
|
|
- name: InterPodAffinity
|
|
pluginConfig:
|
|
- name: InterPodAffinity
|
|
args:
|
|
ignorePreferredTermsOfExistingPods: true
|
|
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Insulate this test from picking up in-cluster config when run inside a pod
|
|
// We can't assume we have permissions to write to /var/run/secrets/... from a unit test to mock in-cluster config for testing
|
|
originalHost := os.Getenv("KUBERNETES_SERVICE_HOST")
|
|
if len(originalHost) > 0 {
|
|
os.Setenv("KUBERNETES_SERVICE_HOST", "")
|
|
defer os.Setenv("KUBERNETES_SERVICE_HOST", originalHost)
|
|
}
|
|
|
|
defaultPodInitialBackoffSeconds := int64(1)
|
|
defaultPodMaxBackoffSeconds := int64(10)
|
|
defaultPercentageOfNodesToScore := pointer.Int32(0)
|
|
|
|
testcases := []struct {
|
|
name string
|
|
options *Options
|
|
expectedUsername string
|
|
expectedError string
|
|
expectedConfig kubeschedulerconfig.KubeSchedulerConfiguration
|
|
checkErrFn func(err error) bool
|
|
}{
|
|
{
|
|
name: "v1 config file",
|
|
options: &Options{
|
|
ConfigFile: configFile,
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg := configtesting.V1ToInternalWithDefaults(t, v1.KubeSchedulerConfiguration{})
|
|
return cfg
|
|
}(),
|
|
SecureServing: (&apiserveroptions.SecureServingOptions{
|
|
ServerCert: apiserveroptions.GeneratableKeyCert{
|
|
CertDirectory: "/a/b/c",
|
|
PairName: "kube-scheduler",
|
|
},
|
|
HTTP2MaxStreamsPerConnection: 47,
|
|
}).WithLoopback(),
|
|
Authentication: &apiserveroptions.DelegatingAuthenticationOptions{
|
|
CacheTTL: 10 * time.Second,
|
|
ClientCert: apiserveroptions.ClientCertAuthenticationOptions{},
|
|
RequestHeader: apiserveroptions.RequestHeaderAuthenticationOptions{
|
|
UsernameHeaders: []string{"x-remote-user"},
|
|
GroupHeaders: []string{"x-remote-group"},
|
|
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
|
},
|
|
RemoteKubeConfigFileOptional: true,
|
|
},
|
|
Authorization: &apiserveroptions.DelegatingAuthorizationOptions{
|
|
AllowCacheTTL: 10 * time.Second,
|
|
DenyCacheTTL: 10 * time.Second,
|
|
RemoteKubeConfigFileOptional: true,
|
|
AlwaysAllowPaths: []string{"/healthz", "/readyz", "/livez"}, // note: this does not match /healthz/ or /healthz/*
|
|
AlwaysAllowGroups: []string{"system:masters"},
|
|
},
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: defaults.PluginsV1,
|
|
PluginConfig: defaults.PluginConfigsV1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta3 config file",
|
|
options: &Options{
|
|
ConfigFile: v1beta3VersionConfig,
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg := configtesting.V1beta3ToInternalWithDefaults(t, v1beta3.KubeSchedulerConfiguration{})
|
|
return cfg
|
|
}(),
|
|
SecureServing: (&apiserveroptions.SecureServingOptions{
|
|
ServerCert: apiserveroptions.GeneratableKeyCert{
|
|
CertDirectory: "/a/b/c",
|
|
PairName: "kube-scheduler",
|
|
},
|
|
HTTP2MaxStreamsPerConnection: 47,
|
|
}).WithLoopback(),
|
|
Authentication: &apiserveroptions.DelegatingAuthenticationOptions{
|
|
CacheTTL: 10 * time.Second,
|
|
ClientCert: apiserveroptions.ClientCertAuthenticationOptions{},
|
|
RequestHeader: apiserveroptions.RequestHeaderAuthenticationOptions{
|
|
UsernameHeaders: []string{"x-remote-user"},
|
|
GroupHeaders: []string{"x-remote-group"},
|
|
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
|
},
|
|
RemoteKubeConfigFileOptional: true,
|
|
},
|
|
Authorization: &apiserveroptions.DelegatingAuthorizationOptions{
|
|
AllowCacheTTL: 10 * time.Second,
|
|
DenyCacheTTL: 10 * time.Second,
|
|
RemoteKubeConfigFileOptional: true,
|
|
AlwaysAllowPaths: []string{"/healthz", "/readyz", "/livez"}, // note: this does not match /healthz/ or /healthz/*
|
|
AlwaysAllowGroups: []string{"system:masters"},
|
|
},
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta3.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: defaults.PluginsV1beta3,
|
|
PluginConfig: defaults.PluginConfigsV1beta3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta2 config file",
|
|
options: &Options{
|
|
ConfigFile: v1beta2VersionConfig,
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg := configtesting.V1beta2ToInternalWithDefaults(t, v1beta2.KubeSchedulerConfiguration{})
|
|
return cfg
|
|
}(),
|
|
SecureServing: (&apiserveroptions.SecureServingOptions{
|
|
ServerCert: apiserveroptions.GeneratableKeyCert{
|
|
CertDirectory: "/a/b/c",
|
|
PairName: "kube-scheduler",
|
|
},
|
|
HTTP2MaxStreamsPerConnection: 47,
|
|
}).WithLoopback(),
|
|
Authentication: &apiserveroptions.DelegatingAuthenticationOptions{
|
|
CacheTTL: 10 * time.Second,
|
|
ClientCert: apiserveroptions.ClientCertAuthenticationOptions{},
|
|
RequestHeader: apiserveroptions.RequestHeaderAuthenticationOptions{
|
|
UsernameHeaders: []string{"x-remote-user"},
|
|
GroupHeaders: []string{"x-remote-group"},
|
|
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
|
},
|
|
RemoteKubeConfigFileOptional: true,
|
|
},
|
|
Authorization: &apiserveroptions.DelegatingAuthorizationOptions{
|
|
AllowCacheTTL: 10 * time.Second,
|
|
DenyCacheTTL: 10 * time.Second,
|
|
RemoteKubeConfigFileOptional: true,
|
|
AlwaysAllowPaths: []string{"/healthz", "/readyz", "/livez"}, // note: this does not match /healthz/ or /healthz/*
|
|
AlwaysAllowGroups: []string{"system:masters"},
|
|
},
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta2.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: defaults.PluginsV1beta2,
|
|
PluginConfig: defaults.PluginConfigsV1beta2,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "config file in componentconfig/v1alpha1",
|
|
options: &Options{
|
|
ConfigFile: oldConfigFile,
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg, err := latest.Default()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return cfg
|
|
}(),
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"componentconfig/v1alpha1\"",
|
|
},
|
|
{
|
|
name: "unknown version kubescheduler.config.k8s.io/unknown",
|
|
options: &Options{
|
|
ConfigFile: unknownVersionConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"kubescheduler.config.k8s.io/unknown\"",
|
|
},
|
|
{
|
|
name: "config file with no version",
|
|
options: &Options{
|
|
ConfigFile: noVersionConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: "Object 'apiVersion' is missing",
|
|
},
|
|
{
|
|
name: "kubeconfig flag",
|
|
options: &Options{
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg, _ := latest.Default()
|
|
cfg.ClientConnection.Kubeconfig = flagKubeconfig
|
|
return cfg
|
|
}(),
|
|
SecureServing: (&apiserveroptions.SecureServingOptions{
|
|
ServerCert: apiserveroptions.GeneratableKeyCert{
|
|
CertDirectory: "/a/b/c",
|
|
PairName: "kube-scheduler",
|
|
},
|
|
HTTP2MaxStreamsPerConnection: 47,
|
|
}).WithLoopback(),
|
|
Authentication: &apiserveroptions.DelegatingAuthenticationOptions{
|
|
CacheTTL: 10 * time.Second,
|
|
ClientCert: apiserveroptions.ClientCertAuthenticationOptions{},
|
|
RequestHeader: apiserveroptions.RequestHeaderAuthenticationOptions{
|
|
UsernameHeaders: []string{"x-remote-user"},
|
|
GroupHeaders: []string{"x-remote-group"},
|
|
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
|
},
|
|
RemoteKubeConfigFileOptional: true,
|
|
},
|
|
Authorization: &apiserveroptions.DelegatingAuthorizationOptions{
|
|
AllowCacheTTL: 10 * time.Second,
|
|
DenyCacheTTL: 10 * time.Second,
|
|
RemoteKubeConfigFileOptional: true,
|
|
AlwaysAllowPaths: []string{"/healthz", "/readyz", "/livez"}, // note: this does not match /healthz/ or /healthz/*
|
|
AlwaysAllowGroups: []string{"system:masters"},
|
|
},
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "flag",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: flagKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: defaults.PluginsV1,
|
|
PluginConfig: defaults.PluginConfigsV1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "overridden master",
|
|
options: &Options{
|
|
ComponentConfig: func() *kubeschedulerconfig.KubeSchedulerConfiguration {
|
|
cfg, _ := latest.Default()
|
|
cfg.ClientConnection.Kubeconfig = flagKubeconfig
|
|
return cfg
|
|
}(),
|
|
Master: insecureserver.URL,
|
|
SecureServing: (&apiserveroptions.SecureServingOptions{
|
|
ServerCert: apiserveroptions.GeneratableKeyCert{
|
|
CertDirectory: "/a/b/c",
|
|
PairName: "kube-scheduler",
|
|
},
|
|
HTTP2MaxStreamsPerConnection: 47,
|
|
}).WithLoopback(),
|
|
Authentication: &apiserveroptions.DelegatingAuthenticationOptions{
|
|
CacheTTL: 10 * time.Second,
|
|
RequestHeader: apiserveroptions.RequestHeaderAuthenticationOptions{
|
|
UsernameHeaders: []string{"x-remote-user"},
|
|
GroupHeaders: []string{"x-remote-group"},
|
|
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
|
},
|
|
RemoteKubeConfigFileOptional: true,
|
|
},
|
|
Authorization: &apiserveroptions.DelegatingAuthorizationOptions{
|
|
AllowCacheTTL: 10 * time.Second,
|
|
DenyCacheTTL: 10 * time.Second,
|
|
RemoteKubeConfigFileOptional: true,
|
|
AlwaysAllowPaths: []string{"/healthz", "/readyz", "/livez"}, // note: this does not match /healthz/ or /healthz/*
|
|
AlwaysAllowGroups: []string{"system:masters"},
|
|
},
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: flagKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: defaults.PluginsV1,
|
|
PluginConfig: defaults.PluginConfigsV1,
|
|
},
|
|
},
|
|
},
|
|
expectedUsername: "none, http",
|
|
},
|
|
{
|
|
name: "plugin config",
|
|
options: &Options{
|
|
ConfigFile: pluginConfigFile,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
PreEnqueue: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
},
|
|
},
|
|
Reserve: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: "bar"},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
PreBind: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
MultiPoint: defaults.PluginsV1.MultiPoint,
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 2,
|
|
},
|
|
},
|
|
{
|
|
Name: "foo",
|
|
Args: &runtime.Unknown{
|
|
Raw: []byte(`{"bar":"baz"}`),
|
|
ContentType: "application/json",
|
|
},
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta3 plugin config",
|
|
options: &Options{
|
|
ConfigFile: v1beta3PluginConfigFile,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta3.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
PreEnqueue: defaults.PluginsV1beta3.PreEnqueue,
|
|
QueueSort: defaults.PluginsV1beta3.QueueSort,
|
|
PreFilter: defaults.PluginsV1beta3.PreFilter,
|
|
Filter: defaults.PluginsV1beta3.Filter,
|
|
PostFilter: defaults.PluginsV1beta3.PostFilter,
|
|
PreScore: defaults.PluginsV1beta3.PreScore,
|
|
Score: defaults.PluginsV1beta3.Score,
|
|
Reserve: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: "bar"},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "VolumeBinding"},
|
|
},
|
|
},
|
|
PreBind: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "VolumeBinding"},
|
|
},
|
|
},
|
|
Bind: defaults.PluginsV1beta3.Bind,
|
|
MultiPoint: defaults.PluginsV1beta3.MultiPoint,
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 2,
|
|
},
|
|
},
|
|
{
|
|
Name: "foo",
|
|
Args: &runtime.Unknown{
|
|
Raw: []byte(`{"bar":"baz"}`),
|
|
ContentType: "application/json",
|
|
},
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta2 plugin config",
|
|
options: &Options{
|
|
ConfigFile: v1beta2PluginConfigFile,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta2.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "default-scheduler",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
PreEnqueue: defaults.PluginsV1beta2.PreEnqueue,
|
|
QueueSort: defaults.PluginsV1beta2.QueueSort,
|
|
PreFilter: defaults.PluginsV1beta2.PreFilter,
|
|
Filter: defaults.PluginsV1beta2.Filter,
|
|
PostFilter: defaults.PluginsV1beta2.PostFilter,
|
|
PreScore: defaults.PluginsV1beta2.PreScore,
|
|
Score: defaults.PluginsV1beta2.Score,
|
|
Reserve: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: "bar"},
|
|
},
|
|
},
|
|
PreBind: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
},
|
|
},
|
|
Bind: defaults.PluginsV1beta2.Bind,
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 2,
|
|
},
|
|
},
|
|
{
|
|
Name: "foo",
|
|
Args: &runtime.Unknown{
|
|
Raw: []byte(`{"bar":"baz"}`),
|
|
ContentType: "application/json",
|
|
},
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple profiles",
|
|
options: &Options{
|
|
ConfigFile: multiProfilesConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "foo-profile",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
MultiPoint: defaults.PluginsV1.MultiPoint,
|
|
Reserve: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
},
|
|
PluginConfig: defaults.PluginConfigsV1,
|
|
},
|
|
{
|
|
SchedulerName: "bar-profile",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
MultiPoint: defaults.PluginsV1.MultiPoint,
|
|
PreBind: kubeschedulerconfig.PluginSet{
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "foo",
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta3 multiple profiles",
|
|
options: &Options{
|
|
ConfigFile: v1beta3MultiProfilesConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta3.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "foo-profile",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
MultiPoint: defaults.PluginsV1beta3.MultiPoint,
|
|
Reserve: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
},
|
|
PluginConfig: defaults.PluginConfigsV1beta3,
|
|
},
|
|
{
|
|
SchedulerName: "bar-profile",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
MultiPoint: defaults.PluginsV1beta3.MultiPoint,
|
|
PreBind: kubeschedulerconfig.PluginSet{
|
|
Disabled: []kubeschedulerconfig.Plugin{
|
|
{Name: names.VolumeBinding},
|
|
},
|
|
},
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "foo",
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "v1beta2 multiple profiles",
|
|
options: &Options{
|
|
ConfigFile: v1beta2MultiProfilesConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1beta2.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "foo-profile",
|
|
Plugins: func() *kubeschedulerconfig.Plugins {
|
|
plugins := defaults.PluginsV1beta2.DeepCopy()
|
|
plugins.Reserve.Enabled = []kubeschedulerconfig.Plugin{
|
|
{Name: "foo"},
|
|
{Name: names.VolumeBinding},
|
|
}
|
|
return plugins
|
|
}(),
|
|
PluginConfig: defaults.PluginConfigsV1beta2,
|
|
},
|
|
{
|
|
SchedulerName: "bar-profile",
|
|
Plugins: func() *kubeschedulerconfig.Plugins {
|
|
plugins := defaults.PluginsV1beta2.DeepCopy()
|
|
plugins.PreBind.Enabled = nil
|
|
return plugins
|
|
}(),
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "foo",
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no config",
|
|
options: &Options{
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: "no configuration has been provided",
|
|
},
|
|
{
|
|
name: "unknown field",
|
|
options: &Options{
|
|
ConfigFile: unknownFieldConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: `unknown field "foo"`,
|
|
checkErrFn: runtime.IsStrictDecodingError,
|
|
},
|
|
{
|
|
name: "duplicate fields",
|
|
options: &Options{
|
|
ConfigFile: duplicateFieldConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedError: `key "leaderElect" already set`,
|
|
checkErrFn: runtime.IsStrictDecodingError,
|
|
},
|
|
{
|
|
name: "high throughput profile",
|
|
options: &Options{
|
|
ConfigFile: highThroughputProfileConfig,
|
|
Logs: logs.NewOptions(),
|
|
},
|
|
expectedUsername: "config",
|
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1.SchemeGroupVersion.String(),
|
|
},
|
|
Parallelism: 16,
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: true,
|
|
EnableContentionProfiling: true,
|
|
},
|
|
LeaderElection: 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: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
Kubeconfig: configKubeconfig,
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
|
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
|
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
|
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: "high-throughput-profile",
|
|
Plugins: &kubeschedulerconfig.Plugins{
|
|
QueueSort: defaults.PluginsV1.QueueSort,
|
|
PreFilter: defaults.PluginsV1.PreFilter,
|
|
Filter: defaults.PluginsV1.Filter,
|
|
PostFilter: defaults.PluginsV1.PostFilter,
|
|
PreScore: kubeschedulerconfig.PluginSet{
|
|
Enabled: []kubeschedulerconfig.Plugin{
|
|
{Name: "InterPodAffinity"},
|
|
},
|
|
},
|
|
Score: defaults.PluginsV1.Score,
|
|
Bind: defaults.PluginsV1.Bind,
|
|
PreBind: defaults.PluginsV1.PreBind,
|
|
Reserve: defaults.PluginsV1.Reserve,
|
|
MultiPoint: defaults.PluginsV1.MultiPoint,
|
|
},
|
|
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: 1,
|
|
IgnorePreferredTermsOfExistingPods: true,
|
|
},
|
|
},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: 10,
|
|
MinCandidateNodesAbsolute: 100,
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
|
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
|
Type: kubeschedulerconfig.LeastAllocated,
|
|
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
|
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
|
BindTimeoutSeconds: 600,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if tc.options.ComponentConfig == nil {
|
|
if cfg, err := latest.Default(); err != nil {
|
|
t.Fatal(err)
|
|
} else {
|
|
tc.options.ComponentConfig = cfg
|
|
}
|
|
}
|
|
// create the config
|
|
_, ctx := ktesting.NewTestContext(t)
|
|
config, err := tc.options.Config(ctx)
|
|
|
|
// handle errors
|
|
if err != nil {
|
|
if tc.expectedError != "" || tc.checkErrFn != nil {
|
|
if tc.expectedError != "" {
|
|
assert.Contains(t, err.Error(), tc.expectedError)
|
|
}
|
|
if tc.checkErrFn != nil {
|
|
assert.True(t, tc.checkErrFn(err), "got error: %v", err)
|
|
}
|
|
return
|
|
}
|
|
t.Errorf("unexpected error creating config: %v", err)
|
|
return
|
|
}
|
|
|
|
if _, err := encodeConfig(&config.ComponentConfig); err != nil {
|
|
t.Errorf("unexpected error in encodeConfig: %v", err)
|
|
}
|
|
|
|
if diff := cmp.Diff(tc.expectedConfig, config.ComponentConfig); diff != "" {
|
|
t.Errorf("incorrect config (-want,+got):\n%s", diff)
|
|
}
|
|
|
|
// ensure we have a client
|
|
if config.Client == nil {
|
|
t.Error("unexpected nil client")
|
|
return
|
|
}
|
|
|
|
// test the client talks to the endpoint we expect with the credentials we expect
|
|
username = ""
|
|
_, err = config.Client.Discovery().RESTClient().Get().AbsPath("/").DoRaw(context.TODO())
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
if username != tc.expectedUsername {
|
|
t.Errorf("expected server call with user %q, got %q", tc.expectedUsername, username)
|
|
}
|
|
})
|
|
}
|
|
}
|