Skip to content

Commit 2ffb13e

Browse files
Do lenient decoding only for kubescheduler config v1alpha1
Signed-off-by: Aldo Culquicondor <[email protected]>
1 parent a71586f commit 2ffb13e

File tree

5 files changed

+95
-40
lines changed

5 files changed

+95
-40
lines changed

cmd/kube-scheduler/app/options/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ go_library(
4040
"//staging/src/k8s.io/component-base/cli/flag:go_default_library",
4141
"//staging/src/k8s.io/component-base/codec:go_default_library",
4242
"//staging/src/k8s.io/component-base/config:go_default_library",
43-
"//staging/src/k8s.io/kube-scheduler/config/v1alpha1:go_default_library",
43+
"//staging/src/k8s.io/kube-scheduler/config/v1alpha2:go_default_library",
4444
"//vendor/github.com/spf13/pflag:go_default_library",
4545
"//vendor/k8s.io/klog:go_default_library",
4646
],
@@ -73,10 +73,10 @@ go_test(
7373
"//pkg/scheduler/apis/config:go_default_library",
7474
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
7575
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
76-
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
7776
"//staging/src/k8s.io/apimachinery/pkg/util/rand:go_default_library",
7877
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
7978
"//staging/src/k8s.io/component-base/config:go_default_library",
79+
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
8080
"//vendor/github.com/stretchr/testify/assert:go_default_library",
8181
],
8282
)

cmd/kube-scheduler/app/options/configfile.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ func loadConfigFromFile(file string) (*kubeschedulerconfig.KubeSchedulerConfigur
4141
}
4242

4343
func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
44-
configObj := &kubeschedulerconfig.KubeSchedulerConfiguration{}
4544
// The UniversalDecoder runs defaulting and returns the internal type by default.
46-
err := runtime.DecodeInto(kubeschedulerscheme.Codecs.UniversalDecoder(), data, configObj)
45+
obj, gvk, err := kubeschedulerscheme.Codecs.UniversalDecoder().Decode(data, nil, nil)
4746
if err != nil {
4847
// Try strict decoding first. If that fails decode with a lenient
4948
// decoder, which has only v1alpha1 registered, and log a warning.
@@ -56,18 +55,20 @@ func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, e
5655
_, lenientCodecs, lenientErr := codec.NewLenientSchemeAndCodecs(
5756
kubeschedulerconfig.AddToScheme,
5857
kubeschedulerconfigv1alpha1.AddToScheme,
59-
kubeschedulerconfigv1alpha2.AddToScheme,
6058
)
6159
if lenientErr != nil {
6260
return nil, lenientErr
6361
}
64-
if lenientErr = runtime.DecodeInto(lenientCodecs.UniversalDecoder(), data, configObj); lenientErr != nil {
65-
return nil, fmt.Errorf("failed lenient decoding: %v", err)
62+
obj, gvk, lenientErr = lenientCodecs.UniversalDecoder().Decode(data, nil, nil)
63+
if lenientErr != nil {
64+
return nil, err
6665
}
6766
klog.Warningf("using lenient decoding as strict decoding failed: %v", err)
6867
}
69-
70-
return configObj, nil
68+
if cfgObj, ok := obj.(*kubeschedulerconfig.KubeSchedulerConfiguration); ok {
69+
return cfgObj, nil
70+
}
71+
return nil, fmt.Errorf("couldn't decode as KubeSchedulerConfiguration, got %s: ", gvk)
7172
}
7273

7374
// WriteConfigFile writes the config into the given file name as YAML.

cmd/kube-scheduler/app/options/options.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import (
4040
cliflag "k8s.io/component-base/cli/flag"
4141
componentbaseconfig "k8s.io/component-base/config"
4242
"k8s.io/klog"
43-
kubeschedulerconfigv1alpha1 "k8s.io/kube-scheduler/config/v1alpha1"
43+
kubeschedulerconfigv1alpha2 "k8s.io/kube-scheduler/config/v1alpha2"
4444
schedulerappconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
4545
"k8s.io/kubernetes/pkg/client/leaderelectionconfig"
4646
"k8s.io/kubernetes/pkg/master/ports"
@@ -129,10 +129,10 @@ func splitHostIntPort(s string) (string, int, error) {
129129
}
130130

131131
func newDefaultComponentConfig() (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
132-
cfgv1alpha1 := kubeschedulerconfigv1alpha1.KubeSchedulerConfiguration{}
133-
kubeschedulerscheme.Scheme.Default(&cfgv1alpha1)
132+
versionedCfg := kubeschedulerconfigv1alpha2.KubeSchedulerConfiguration{}
133+
kubeschedulerscheme.Scheme.Default(&versionedCfg)
134134
cfg := kubeschedulerconfig.KubeSchedulerConfiguration{}
135-
if err := kubeschedulerscheme.Scheme.Convert(&cfgv1alpha1, &cfg, nil); err != nil {
135+
if err := kubeschedulerscheme.Scheme.Convert(&versionedCfg, &cfg, nil); err != nil {
136136
return nil, err
137137
}
138138
return &cfg, nil

cmd/kube-scheduler/app/options/options_test.go

Lines changed: 76 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@ import (
2424
"net/http/httptest"
2525
"os"
2626
"path/filepath"
27-
"reflect"
2827
"testing"
2928
"time"
3029

30+
"github.com/google/go-cmp/cmp"
3131
"github.com/stretchr/testify/assert"
3232

3333
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3434
"k8s.io/apimachinery/pkg/runtime"
35-
"k8s.io/apimachinery/pkg/util/diff"
3635
apiserveroptions "k8s.io/apiserver/pkg/server/options"
3736
componentbaseconfig "k8s.io/component-base/config"
3837
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
@@ -73,7 +72,7 @@ func TestSchedulerOptions(t *testing.T) {
7372
configFile := filepath.Join(tmpDir, "scheduler.yaml")
7473
configKubeconfig := filepath.Join(tmpDir, "config.kubeconfig")
7574
if err := ioutil.WriteFile(configFile, []byte(fmt.Sprintf(`
76-
apiVersion: kubescheduler.config.k8s.io/v1alpha1
75+
apiVersion: kubescheduler.config.k8s.io/v1alpha2
7776
kind: KubeSchedulerConfiguration
7877
clientConnection:
7978
kubeconfig: "%s"
@@ -103,8 +102,8 @@ users:
103102
t.Fatal(err)
104103
}
105104

106-
oldconfigFile := filepath.Join(tmpDir, "scheduler_old.yaml")
107-
if err := ioutil.WriteFile(oldconfigFile, []byte(fmt.Sprintf(`
105+
oldConfigFile := filepath.Join(tmpDir, "scheduler_old.yaml")
106+
if err := ioutil.WriteFile(oldConfigFile, []byte(fmt.Sprintf(`
108107
apiVersion: componentconfig/v1alpha1
109108
kind: KubeSchedulerConfiguration
110109
clientConnection:
@@ -114,9 +113,9 @@ leaderElection:
114113
t.Fatal(err)
115114
}
116115

117-
invalidconfigFile := filepath.Join(tmpDir, "scheduler_invalid_wrong_api_version.yaml")
118-
if err := ioutil.WriteFile(invalidconfigFile, []byte(fmt.Sprintf(`
119-
apiVersion: componentconfig/v1alpha2
116+
unknownVersionConfig := filepath.Join(tmpDir, "scheduler_invalid_wrong_api_version.yaml")
117+
if err := ioutil.WriteFile(unknownVersionConfig, []byte(fmt.Sprintf(`
118+
apiVersion: kubescheduler.config.k8s.io/unknown
120119
kind: KubeSchedulerConfiguration
121120
clientConnection:
122121
kubeconfig: "%s"
@@ -125,9 +124,31 @@ leaderElection:
125124
t.Fatal(err)
126125
}
127126

127+
noVersionConfig := filepath.Join(tmpDir, "scheduler_invalid_no_version.yaml")
128+
if err := ioutil.WriteFile(noVersionConfig, []byte(fmt.Sprintf(`
129+
kind: KubeSchedulerConfiguration
130+
clientConnection:
131+
kubeconfig: "%s"
132+
leaderElection:
133+
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
134+
t.Fatal(err)
135+
}
136+
137+
unknownFieldConfigLenient := filepath.Join(tmpDir, "scheduler_invalid_unknown_field_lenient.yaml")
138+
if err := ioutil.WriteFile(unknownFieldConfigLenient, []byte(fmt.Sprintf(`
139+
apiVersion: kubescheduler.config.k8s.io/v1alpha1
140+
kind: KubeSchedulerConfiguration
141+
clientConnection:
142+
kubeconfig: "%s"
143+
leaderElection:
144+
leaderElect: true
145+
foo: bar`, configKubeconfig)), os.FileMode(0600)); err != nil {
146+
t.Fatal(err)
147+
}
148+
128149
unknownFieldConfig := filepath.Join(tmpDir, "scheduler_invalid_unknown_field.yaml")
129150
if err := ioutil.WriteFile(unknownFieldConfig, []byte(fmt.Sprintf(`
130-
apiVersion: kubescheduler.config.k8s.io/v1alpha1
151+
apiVersion: kubescheduler.config.k8s.io/v1alpha2
131152
kind: KubeSchedulerConfiguration
132153
clientConnection:
133154
kubeconfig: "%s"
@@ -137,9 +158,21 @@ foo: bar`, configKubeconfig)), os.FileMode(0600)); err != nil {
137158
t.Fatal(err)
138159
}
139160

161+
duplicateFieldConfigLenient := filepath.Join(tmpDir, "scheduler_invalid_duplicate_fields_lenient.yaml")
162+
if err := ioutil.WriteFile(duplicateFieldConfigLenient, []byte(fmt.Sprintf(`
163+
apiVersion: kubescheduler.config.k8s.io/v1alpha1
164+
kind: KubeSchedulerConfiguration
165+
clientConnection:
166+
kubeconfig: "%s"
167+
leaderElection:
168+
leaderElect: true
169+
leaderElect: false`, configKubeconfig)), os.FileMode(0600)); err != nil {
170+
t.Fatal(err)
171+
}
172+
140173
duplicateFieldConfig := filepath.Join(tmpDir, "scheduler_invalid_duplicate_fields.yaml")
141174
if err := ioutil.WriteFile(duplicateFieldConfig, []byte(fmt.Sprintf(`
142-
apiVersion: kubescheduler.config.k8s.io/v1alpha1
175+
apiVersion: kubescheduler.config.k8s.io/v1alpha2
143176
kind: KubeSchedulerConfiguration
144177
clientConnection:
145178
kubeconfig: "%s"
@@ -176,7 +209,7 @@ users:
176209
// plugin config
177210
pluginconfigFile := filepath.Join(tmpDir, "plugin.yaml")
178211
if err := ioutil.WriteFile(pluginconfigFile, []byte(fmt.Sprintf(`
179-
apiVersion: kubescheduler.config.k8s.io/v1alpha1
212+
apiVersion: kubescheduler.config.k8s.io/v1alpha2
180213
kind: KubeSchedulerConfiguration
181214
clientConnection:
182215
kubeconfig: "%s"
@@ -293,7 +326,7 @@ pluginConfig:
293326
{
294327
name: "config file in componentconfig/v1alpha1",
295328
options: &Options{
296-
ConfigFile: oldconfigFile,
329+
ConfigFile: oldConfigFile,
297330
ComponentConfig: func() kubeschedulerconfig.KubeSchedulerConfiguration {
298331
cfg, err := newDefaultComponentConfig()
299332
if err != nil {
@@ -306,9 +339,14 @@ pluginConfig:
306339
},
307340

308341
{
309-
name: "invalid config file in componentconfig/v1alpha2",
310-
options: &Options{ConfigFile: invalidconfigFile},
311-
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"componentconfig/v1alpha2\"",
342+
name: "unknown version kubescheduler.config.k8s.io/unknown",
343+
options: &Options{ConfigFile: unknownVersionConfig},
344+
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"kubescheduler.config.k8s.io/unknown\"",
345+
},
346+
{
347+
name: "config file with no version",
348+
options: &Options{ConfigFile: noVersionConfig},
349+
expectedError: "Object 'apiVersion' is missing",
312350
},
313351
{
314352
name: "kubeconfig flag",
@@ -522,9 +560,9 @@ pluginConfig:
522560
expectedError: "no configuration has been provided",
523561
},
524562
{
525-
name: "unknown field",
563+
name: "unknown field lenient (v1alpha1)",
526564
options: &Options{
527-
ConfigFile: unknownFieldConfig,
565+
ConfigFile: unknownFieldConfigLenient,
528566
},
529567
// TODO (obitech): Remove this comment and add a new test for v1alpha2, when it's available, as this should fail then.
530568
// expectedError: "found unknown field: foo",
@@ -565,9 +603,17 @@ pluginConfig:
565603
},
566604
},
567605
{
568-
name: "duplicate fields",
606+
name: "unknown field",
569607
options: &Options{
570-
ConfigFile: duplicateFieldConfig,
608+
ConfigFile: unknownFieldConfig,
609+
},
610+
expectedError: "found unknown field: foo",
611+
checkErrFn: runtime.IsStrictDecodingError,
612+
},
613+
{
614+
name: "duplicate fields lenient (v1alpha1)",
615+
options: &Options{
616+
ConfigFile: duplicateFieldConfigLenient,
571617
},
572618
// TODO (obitech): Remove this comment and add a new test for v1alpha2, when it's available, as this should fail then.
573619
// expectedError: `key "leaderElect" already set`,
@@ -607,6 +653,14 @@ pluginConfig:
607653
Plugins: nil,
608654
},
609655
},
656+
{
657+
name: "duplicate fields",
658+
options: &Options{
659+
ConfigFile: duplicateFieldConfig,
660+
},
661+
expectedError: `key "leaderElect" already set`,
662+
checkErrFn: runtime.IsStrictDecodingError,
663+
},
610664
}
611665

612666
for _, tc := range testcases {
@@ -618,7 +672,7 @@ pluginConfig:
618672
if err != nil {
619673
if tc.expectedError != "" || tc.checkErrFn != nil {
620674
if tc.expectedError != "" {
621-
assert.Contains(t, err.Error(), tc.expectedError, tc.name)
675+
assert.Contains(t, err.Error(), tc.expectedError)
622676
}
623677
if tc.checkErrFn != nil {
624678
assert.True(t, tc.checkErrFn(err), "got error: %v", err)
@@ -629,8 +683,8 @@ pluginConfig:
629683
return
630684
}
631685

632-
if !reflect.DeepEqual(config.ComponentConfig, tc.expectedConfig) {
633-
t.Errorf("config.diff:\n%s", diff.ObjectReflectDiff(tc.expectedConfig, config.ComponentConfig))
686+
if diff := cmp.Diff(tc.expectedConfig, config.ComponentConfig); diff != "" {
687+
t.Errorf("incorrect config (-want, +got):\n%s", diff)
634688
}
635689

636690
// ensure we have a client

pkg/scheduler/apis/config/scheme/scheme.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ func init() {
4040

4141
// AddToScheme builds the kubescheduler scheme using all known versions of the kubescheduler api.
4242
func AddToScheme(scheme *runtime.Scheme) {
43-
utilruntime.Must(kubeschedulerconfig.AddToScheme(Scheme))
44-
utilruntime.Must(kubeschedulerconfigv1.AddToScheme(Scheme))
45-
utilruntime.Must(kubeschedulerconfigv1alpha1.AddToScheme(Scheme))
46-
utilruntime.Must(kubeschedulerconfigv1alpha2.AddToScheme(Scheme))
47-
utilruntime.Must(scheme.SetVersionPriority(kubeschedulerconfigv1alpha1.SchemeGroupVersion))
43+
utilruntime.Must(kubeschedulerconfig.AddToScheme(scheme))
44+
utilruntime.Must(kubeschedulerconfigv1.AddToScheme(scheme))
45+
utilruntime.Must(kubeschedulerconfigv1alpha1.AddToScheme(scheme))
46+
utilruntime.Must(kubeschedulerconfigv1alpha2.AddToScheme(scheme))
47+
utilruntime.Must(scheme.SetVersionPriority(kubeschedulerconfigv1alpha2.SchemeGroupVersion, kubeschedulerconfigv1alpha1.SchemeGroupVersion))
4848
}

0 commit comments

Comments
 (0)