From d7c84e11f544495c9162af3124807986e4bf47ad Mon Sep 17 00:00:00 2001 From: Rafal Wicha Date: Mon, 1 Jun 2020 11:12:00 +0100 Subject: [PATCH] Fix API encoding inconsistencies in KubeSchedulerConfig --- api/api-rules/violation_exceptions.list | 4 +- hack/.golint_failures | 1 + pkg/scheduler/apis/config/legacy_types.go | 83 ----- .../apis/config/testing/compatibility_test.go | 16 +- .../apis/config/testing/policy_test.go | 4 +- pkg/scheduler/apis/config/types.go | 81 +++++ pkg/scheduler/apis/config/v1/BUILD | 15 +- pkg/scheduler/apis/config/v1/conversion.go | 95 ++++++ .../apis/config/v1/conversion_test.go | 291 ++++++++++++++++++ .../apis/config/v1/zz_generated.conversion.go | 87 ++---- .../apis/config/v1beta1/conversion_test.go | 20 +- .../config/v1beta1/zz_generated.conversion.go | 98 ++++-- .../apis/config/zz_generated.deepcopy.go | 1 + pkg/scheduler/core/extender.go | 8 +- .../k8s.io/kube-scheduler/config/v1/types.go | 10 +- .../config/v1/zz_generated.deepcopy.go | 54 ++-- .../kube-scheduler/config/v1beta1/types.go | 47 ++- .../config/v1beta1/zz_generated.deepcopy.go | 29 +- 18 files changed, 722 insertions(+), 222 deletions(-) create mode 100644 pkg/scheduler/apis/config/v1/conversion.go create mode 100644 pkg/scheduler/apis/config/v1/conversion_test.go diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index 0600454d656..599e55546cb 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -375,11 +375,11 @@ API rule violation: list_type_missing,k8s.io/kube-controller-manager/config/v1al API rule violation: list_type_missing,k8s.io/kube-controller-manager/config/v1alpha1,GenericControllerManagerConfiguration,Controllers API rule violation: list_type_missing,k8s.io/kube-proxy/config/v1alpha1,KubeProxyConfiguration,NodePortAddresses API rule violation: list_type_missing,k8s.io/kube-proxy/config/v1alpha1,KubeProxyIPVSConfiguration,ExcludeCIDRs -API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,Extender,ManagedResources API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,ExtenderTLSConfig,CAData API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,ExtenderTLSConfig,CertData API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,ExtenderTLSConfig,KeyData API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,LabelsPresence,Labels +API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,LegacyExtender,ManagedResources API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,Policy,Extenders API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,Policy,Predicates API rule violation: list_type_missing,k8s.io/kube-scheduler/config/v1,Policy,Priorities @@ -585,7 +585,7 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,V API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,FlexVolumePluginDir API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,PersistentVolumeRecyclerConfiguration API rule violation: names_match,k8s.io/kube-proxy/config/v1alpha1,KubeProxyConfiguration,IPTables -API rule violation: names_match,k8s.io/kube-scheduler/config/v1,Extender,EnableHTTPS +API rule violation: names_match,k8s.io/kube-scheduler/config/v1,LegacyExtender,EnableHTTPS API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesDropBit API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesMasqueradeBit API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,ResolverConfig diff --git a/hack/.golint_failures b/hack/.golint_failures index b09e9d37fc9..ca1c26271ad 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -172,6 +172,7 @@ pkg/registry/scheduling/rest pkg/registry/settings/rest pkg/registry/storage/rest pkg/registry/storage/storageclass +pkg/scheduler/apis/config/v1 pkg/scheduler/apis/config/v1beta1 pkg/security/podsecuritypolicy pkg/security/podsecuritypolicy/group diff --git a/pkg/scheduler/apis/config/legacy_types.go b/pkg/scheduler/apis/config/legacy_types.go index b1ada2b22e5..80ff73671c5 100644 --- a/pkg/scheduler/apis/config/legacy_types.go +++ b/pkg/scheduler/apis/config/legacy_types.go @@ -17,8 +17,6 @@ limitations under the License. package config import ( - "time" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -135,84 +133,3 @@ type RequestedToCapacityRatioArguments struct { Shape []UtilizationShapePoint `json:"shape"` Resources []ResourceSpec `json:"resources,omitempty"` } - -// ExtenderManagedResource describes the arguments of extended resources -// managed by an extender. -type ExtenderManagedResource struct { - // Name is the extended resource name. - Name string - // IgnoredByScheduler indicates whether kube-scheduler should ignore this - // resource when applying predicates. - IgnoredByScheduler bool -} - -// ExtenderTLSConfig contains settings to enable TLS with extender -type ExtenderTLSConfig struct { - // Server should be accessed without verifying the TLS certificate. For testing only. - Insecure bool - // ServerName is passed to the server for SNI and is used in the client to check server - // certificates against. If ServerName is empty, the hostname used to contact the - // server is used. - ServerName string - - // Server requires TLS client certificate authentication - CertFile string - // Server requires TLS client certificate authentication - KeyFile string - // Trusted root certificates for server - CAFile string - - // CertData holds PEM-encoded bytes (typically read from a client certificate file). - // CertData takes precedence over CertFile - CertData []byte - // KeyData holds PEM-encoded bytes (typically read from a client certificate key file). - // KeyData takes precedence over KeyFile - KeyData []byte - // CAData holds PEM-encoded bytes (typically read from a root certificates bundle). - // CAData takes precedence over CAFile - CAData []byte -} - -// Extender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, -// it is assumed that the extender chose not to provide that extension. -type Extender struct { - // URLPrefix at which the extender is available - URLPrefix string - // Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender. - FilterVerb string - // Verb for the preempt call, empty if not supported. This verb is appended to the URLPrefix when issuing the preempt call to extender. - PreemptVerb string - // Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender. - PrioritizeVerb string - // The numeric multiplier for the node scores that the prioritize call generates. - // The weight should be a positive integer - Weight int64 - // Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender. - // If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver. Only one extender - // can implement this function. - BindVerb string - // EnableHTTPS specifies whether https should be used to communicate with the extender - EnableHTTPS bool - // TLSConfig specifies the transport layer security config - TLSConfig *ExtenderTLSConfig - // HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize - // timeout is ignored, k8s/other extenders priorities are used to select the node. - HTTPTimeout time.Duration - // NodeCacheCapable specifies that the extender is capable of caching node information, - // so the scheduler should only send minimal information about the eligible nodes - // assuming that the extender already cached full details of all nodes in the cluster - NodeCacheCapable bool - // ManagedResources is a list of extended resources that are managed by - // this extender. - // - A pod will be sent to the extender on the Filter, Prioritize and Bind - // (if the extender is the binder) phases iff the pod requests at least - // one of the extended resources in this list. If empty or unspecified, - // all pods will be sent to this extender. - // - If IgnoredByScheduler is set to true for a resource, kube-scheduler - // will skip checking the resource in predicates. - // +optional - ManagedResources []ExtenderManagedResource - // Ignorable specifies if the extender is ignorable, i.e. scheduling should not - // fail when the extender returns an error or is not reachable. - Ignorable bool -} diff --git a/pkg/scheduler/apis/config/testing/compatibility_test.go b/pkg/scheduler/apis/config/testing/compatibility_test.go index 4e42332a522..636fa8ea57a 100644 --- a/pkg/scheduler/apis/config/testing/compatibility_test.go +++ b/pkg/scheduler/apis/config/testing/compatibility_test.go @@ -513,7 +513,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.7 was missing json tags on the BindVerb field and required "BindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, }}, }, @@ -611,7 +611,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.8 became case-insensitive and tolerated "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, }}, }, @@ -716,7 +716,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.9 was case-insensitive and tolerated "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, }}, }, @@ -824,7 +824,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.10 was case-insensitive and tolerated "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, ManagedResources: []config.ExtenderManagedResource{{Name: "example.com/foo", IgnoredByScheduler: true}}, Ignorable: true, @@ -945,7 +945,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.11 restored case-sensitivity, but allowed either "BindVerb" or "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, ManagedResources: []config.ExtenderManagedResource{{Name: "example.com/foo", IgnoredByScheduler: true}}, Ignorable: true, @@ -1068,7 +1068,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.11 restored case-sensitivity, but allowed either "BindVerb" or "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, ManagedResources: []config.ExtenderManagedResource{{Name: "example.com/foo", IgnoredByScheduler: true}}, Ignorable: true, @@ -1191,7 +1191,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.11 restored case-sensitivity, but allowed either "BindVerb" or "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, ManagedResources: []config.ExtenderManagedResource{{Name: "example.com/foo", IgnoredByScheduler: true}}, Ignorable: true, @@ -1318,7 +1318,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { BindVerb: "bind", // 1.11 restored case-sensitivity, but allowed either "BindVerb" or "bindVerb" EnableHTTPS: true, TLSConfig: &config.ExtenderTLSConfig{Insecure: true}, - HTTPTimeout: 1, + HTTPTimeout: metav1.Duration{Duration: 1}, NodeCacheCapable: true, ManagedResources: []config.ExtenderManagedResource{{Name: "example.com/foo", IgnoredByScheduler: true}}, Ignorable: true, diff --git a/pkg/scheduler/apis/config/testing/policy_test.go b/pkg/scheduler/apis/config/testing/policy_test.go index 63e8123d3ae..5e3e1f29be7 100644 --- a/pkg/scheduler/apis/config/testing/policy_test.go +++ b/pkg/scheduler/apis/config/testing/policy_test.go @@ -36,7 +36,7 @@ extenders: filterVerb: filter prioritizeVerb: prioritize weight: 1 - enableHttps: false + enableHttps: true ` ) @@ -48,7 +48,7 @@ func TestSchedulerPolicy(t *testing.T) { FilterVerb: "filter", PrioritizeVerb: "prioritize", Weight: 1, - EnableHTTPS: false, + EnableHTTPS: true, }, }, } diff --git a/pkg/scheduler/apis/config/types.go b/pkg/scheduler/apis/config/types.go index 40f5279625f..af61a17170b 100644 --- a/pkg/scheduler/apis/config/types.go +++ b/pkg/scheduler/apis/config/types.go @@ -340,3 +340,84 @@ func mergePluginSets(defaultPluginSet, customPluginSet *PluginSet) *PluginSet { return &PluginSet{Enabled: enabledPlugins} } + +// Extender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, +// it is assumed that the extender chose not to provide that extension. +type Extender struct { + // URLPrefix at which the extender is available + URLPrefix string + // Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender. + FilterVerb string + // Verb for the preempt call, empty if not supported. This verb is appended to the URLPrefix when issuing the preempt call to extender. + PreemptVerb string + // Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender. + PrioritizeVerb string + // The numeric multiplier for the node scores that the prioritize call generates. + // The weight should be a positive integer + Weight int64 + // Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender. + // If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver. Only one extender + // can implement this function. + BindVerb string + // EnableHTTPS specifies whether https should be used to communicate with the extender + EnableHTTPS bool + // TLSConfig specifies the transport layer security config + TLSConfig *ExtenderTLSConfig + // HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize + // timeout is ignored, k8s/other extenders priorities are used to select the node. + HTTPTimeout metav1.Duration + // NodeCacheCapable specifies that the extender is capable of caching node information, + // so the scheduler should only send minimal information about the eligible nodes + // assuming that the extender already cached full details of all nodes in the cluster + NodeCacheCapable bool + // ManagedResources is a list of extended resources that are managed by + // this extender. + // - A pod will be sent to the extender on the Filter, Prioritize and Bind + // (if the extender is the binder) phases iff the pod requests at least + // one of the extended resources in this list. If empty or unspecified, + // all pods will be sent to this extender. + // - If IgnoredByScheduler is set to true for a resource, kube-scheduler + // will skip checking the resource in predicates. + // +optional + ManagedResources []ExtenderManagedResource + // Ignorable specifies if the extender is ignorable, i.e. scheduling should not + // fail when the extender returns an error or is not reachable. + Ignorable bool +} + +// ExtenderManagedResource describes the arguments of extended resources +// managed by an extender. +type ExtenderManagedResource struct { + // Name is the extended resource name. + Name string + // IgnoredByScheduler indicates whether kube-scheduler should ignore this + // resource when applying predicates. + IgnoredByScheduler bool +} + +// ExtenderTLSConfig contains settings to enable TLS with extender +type ExtenderTLSConfig struct { + // Server should be accessed without verifying the TLS certificate. For testing only. + Insecure bool + // ServerName is passed to the server for SNI and is used in the client to check server + // certificates against. If ServerName is empty, the hostname used to contact the + // server is used. + ServerName string + + // Server requires TLS client certificate authentication + CertFile string + // Server requires TLS client certificate authentication + KeyFile string + // Trusted root certificates for server + CAFile string + + // CertData holds PEM-encoded bytes (typically read from a client certificate file). + // CertData takes precedence over CertFile + CertData []byte + // KeyData holds PEM-encoded bytes (typically read from a client certificate key file). + // KeyData takes precedence over KeyFile + KeyData []byte + // CAData holds PEM-encoded bytes (typically read from a root certificates bundle). + // CAData takes precedence over CAFile + CAData []byte +} diff --git a/pkg/scheduler/apis/config/v1/BUILD b/pkg/scheduler/apis/config/v1/BUILD index 9a0724a1327..0adeafa6e3d 100644 --- a/pkg/scheduler/apis/config/v1/BUILD +++ b/pkg/scheduler/apis/config/v1/BUILD @@ -1,8 +1,9 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ + "conversion.go", "doc.go", "register.go", "zz_generated.conversion.go", @@ -33,3 +34,15 @@ filegroup( tags = ["automanaged"], visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = ["conversion_test.go"], + embed = [":go_default_library"], + deps = [ + "//pkg/scheduler/apis/config:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/kube-scheduler/config/v1:go_default_library", + "//vendor/github.com/google/go-cmp/cmp:go_default_library", + ], +) diff --git a/pkg/scheduler/apis/config/v1/conversion.go b/pkg/scheduler/apis/config/v1/conversion.go new file mode 100644 index 00000000000..06a6c7073f7 --- /dev/null +++ b/pkg/scheduler/apis/config/v1/conversion.go @@ -0,0 +1,95 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + v1 "k8s.io/kube-scheduler/config/v1" + "k8s.io/kubernetes/pkg/scheduler/apis/config" +) + +func Convert_v1_LegacyExtender_To_config_Extender(in *v1.LegacyExtender, out *config.Extender, s conversion.Scope) error { + out.URLPrefix = in.URLPrefix + out.FilterVerb = in.FilterVerb + out.PreemptVerb = in.PreemptVerb + out.PrioritizeVerb = in.PrioritizeVerb + out.Weight = in.Weight + out.BindVerb = in.BindVerb + out.EnableHTTPS = in.EnableHTTPS + out.HTTPTimeout.Duration = in.HTTPTimeout + out.NodeCacheCapable = in.NodeCacheCapable + out.Ignorable = in.Ignorable + + if in.TLSConfig != nil { + out.TLSConfig = &config.ExtenderTLSConfig{} + if err := Convert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig(in.TLSConfig, out.TLSConfig, s); err != nil { + return err + } + } else { + out.TLSConfig = nil + } + + if in.ManagedResources != nil { + out.ManagedResources = make([]config.ExtenderManagedResource, len(in.ManagedResources)) + for i, res := range in.ManagedResources { + err := Convert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(&res, &out.ManagedResources[i], s) + if err != nil { + return err + } + } + } else { + out.ManagedResources = nil + } + + return nil +} + +func Convert_config_Extender_To_v1_LegacyExtender(in *config.Extender, out *v1.LegacyExtender, s conversion.Scope) error { + out.URLPrefix = in.URLPrefix + out.FilterVerb = in.FilterVerb + out.PreemptVerb = in.PreemptVerb + out.PrioritizeVerb = in.PrioritizeVerb + out.Weight = in.Weight + out.BindVerb = in.BindVerb + out.EnableHTTPS = in.EnableHTTPS + out.HTTPTimeout = in.HTTPTimeout.Duration + out.NodeCacheCapable = in.NodeCacheCapable + out.Ignorable = in.Ignorable + + if in.TLSConfig != nil { + out.TLSConfig = &v1.ExtenderTLSConfig{} + if err := Convert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig(in.TLSConfig, out.TLSConfig, s); err != nil { + return err + } + } else { + out.TLSConfig = nil + } + + if in.ManagedResources != nil { + out.ManagedResources = make([]v1.ExtenderManagedResource, len(in.ManagedResources)) + for i, res := range in.ManagedResources { + err := Convert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource(&res, &out.ManagedResources[i], s) + if err != nil { + return err + } + } + } else { + out.ManagedResources = nil + } + + return nil +} diff --git a/pkg/scheduler/apis/config/v1/conversion_test.go b/pkg/scheduler/apis/config/v1/conversion_test.go new file mode 100644 index 00000000000..f8086efc515 --- /dev/null +++ b/pkg/scheduler/apis/config/v1/conversion_test.go @@ -0,0 +1,291 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/kube-scheduler/config/v1" + "k8s.io/kubernetes/pkg/scheduler/apis/config" +) + +func TestV1LegacyExtenderToConfigExtenderConversion(t *testing.T) { + cases := []struct { + name string + in v1.LegacyExtender + out config.Extender + want config.Extender + }{ + { + name: "empty extender conversion", + in: v1.LegacyExtender{}, + out: config.Extender{}, + want: config.Extender{}, + }, + { + name: "fully configured extender conversion", + in: v1.LegacyExtender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &v1.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: 10 * time.Second, + NodeCacheCapable: true, + ManagedResources: []v1.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + out: config.Extender{}, + want: config.Extender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &config.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: metav1.Duration{Duration: 10 * time.Second}, + NodeCacheCapable: true, + ManagedResources: []config.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + }, + { + name: "clears empty fields", + in: v1.LegacyExtender{}, + out: config.Extender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &config.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: metav1.Duration{Duration: 10 * time.Second}, + NodeCacheCapable: true, + ManagedResources: []config.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + want: config.Extender{}, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if err := Convert_v1_LegacyExtender_To_config_Extender(&tc.in, &tc.out, nil); err != nil { + t.Errorf("failed to convert: %+v", err) + } + if diff := cmp.Diff(tc.want, tc.out); diff != "" { + t.Errorf("unexpected conversion (-want, +got):\n%s", diff) + } + }) + } +} + +func TestConfigExtenderToV1LegacyExtenderConversion(t *testing.T) { + cases := []struct { + name string + in config.Extender + out v1.LegacyExtender + want v1.LegacyExtender + }{ + { + name: "empty extender conversion", + in: config.Extender{}, + out: v1.LegacyExtender{}, + want: v1.LegacyExtender{}, + }, + { + name: "fully configured extender conversion", + in: config.Extender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &config.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: metav1.Duration{Duration: 10 * time.Second}, + NodeCacheCapable: true, + ManagedResources: []config.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + out: v1.LegacyExtender{}, + want: v1.LegacyExtender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &v1.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: 10 * time.Second, + NodeCacheCapable: true, + ManagedResources: []v1.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + }, + { + name: "clears empty fields", + in: config.Extender{}, + out: v1.LegacyExtender{ + URLPrefix: "/prefix", + BindVerb: "bind", + FilterVerb: "filter", + PreemptVerb: "preempt", + PrioritizeVerb: "prioritize", + Weight: 5, + EnableHTTPS: true, + TLSConfig: &v1.ExtenderTLSConfig{ + Insecure: true, + ServerName: "server-name", + CertFile: "cert-file", + KeyFile: "key-file", + CAFile: "ca-file", + CertData: []byte("cert-data"), + KeyData: []byte("key-data"), + CAData: []byte("ca-data"), + }, + HTTPTimeout: 10 * time.Second, + NodeCacheCapable: true, + ManagedResources: []v1.ExtenderManagedResource{ + { + Name: "managed-resource", + IgnoredByScheduler: true, + }, + { + Name: "another-resource", + IgnoredByScheduler: false, + }, + }, + Ignorable: true, + }, + want: v1.LegacyExtender{}, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if err := Convert_config_Extender_To_v1_LegacyExtender(&tc.in, &tc.out, nil); err != nil { + t.Errorf("failed to convert: %+v", err) + } + if diff := cmp.Diff(tc.want, tc.out); diff != "" { + t.Errorf("unexpected conversion (-want, +got):\n%s", diff) + } + }) + } +} diff --git a/pkg/scheduler/apis/config/v1/zz_generated.conversion.go b/pkg/scheduler/apis/config/v1/zz_generated.conversion.go index c918b819fe9..79c3a50a8a2 100644 --- a/pkg/scheduler/apis/config/v1/zz_generated.conversion.go +++ b/pkg/scheduler/apis/config/v1/zz_generated.conversion.go @@ -21,7 +21,6 @@ limitations under the License. package v1 import ( - time "time" unsafe "unsafe" conversion "k8s.io/apimachinery/pkg/conversion" @@ -37,16 +36,6 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { - if err := s.AddGeneratedConversionFunc((*v1.Extender)(nil), (*config.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Extender_To_config_Extender(a.(*v1.Extender), b.(*config.Extender), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.Extender)(nil), (*v1.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_Extender_To_v1_Extender(a.(*config.Extender), b.(*v1.Extender), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1.ExtenderManagedResource)(nil), (*config.ExtenderManagedResource)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(a.(*v1.ExtenderManagedResource), b.(*config.ExtenderManagedResource), scope) }); err != nil { @@ -187,51 +176,19 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*config.Extender)(nil), (*v1.LegacyExtender)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_Extender_To_v1_LegacyExtender(a.(*config.Extender), b.(*v1.LegacyExtender), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1.LegacyExtender)(nil), (*config.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_LegacyExtender_To_config_Extender(a.(*v1.LegacyExtender), b.(*config.Extender), scope) + }); err != nil { + return err + } return nil } -func autoConvert_v1_Extender_To_config_Extender(in *v1.Extender, out *config.Extender, s conversion.Scope) error { - out.URLPrefix = in.URLPrefix - out.FilterVerb = in.FilterVerb - out.PreemptVerb = in.PreemptVerb - out.PrioritizeVerb = in.PrioritizeVerb - out.Weight = in.Weight - out.BindVerb = in.BindVerb - out.EnableHTTPS = in.EnableHTTPS - out.TLSConfig = (*config.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) - out.HTTPTimeout = time.Duration(in.HTTPTimeout) - out.NodeCacheCapable = in.NodeCacheCapable - out.ManagedResources = *(*[]config.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) - out.Ignorable = in.Ignorable - return nil -} - -// Convert_v1_Extender_To_config_Extender is an autogenerated conversion function. -func Convert_v1_Extender_To_config_Extender(in *v1.Extender, out *config.Extender, s conversion.Scope) error { - return autoConvert_v1_Extender_To_config_Extender(in, out, s) -} - -func autoConvert_config_Extender_To_v1_Extender(in *config.Extender, out *v1.Extender, s conversion.Scope) error { - out.URLPrefix = in.URLPrefix - out.FilterVerb = in.FilterVerb - out.PreemptVerb = in.PreemptVerb - out.PrioritizeVerb = in.PrioritizeVerb - out.Weight = in.Weight - out.BindVerb = in.BindVerb - out.EnableHTTPS = in.EnableHTTPS - out.TLSConfig = (*v1.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) - out.HTTPTimeout = time.Duration(in.HTTPTimeout) - out.NodeCacheCapable = in.NodeCacheCapable - out.ManagedResources = *(*[]v1.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) - out.Ignorable = in.Ignorable - return nil -} - -// Convert_config_Extender_To_v1_Extender is an autogenerated conversion function. -func Convert_config_Extender_To_v1_Extender(in *config.Extender, out *v1.Extender, s conversion.Scope) error { - return autoConvert_config_Extender_To_v1_Extender(in, out, s) -} - func autoConvert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(in *v1.ExtenderManagedResource, out *config.ExtenderManagedResource, s conversion.Scope) error { out.Name = in.Name out.IgnoredByScheduler = in.IgnoredByScheduler @@ -335,7 +292,17 @@ func Convert_config_LabelsPresence_To_v1_LabelsPresence(in *config.LabelsPresenc func autoConvert_v1_Policy_To_config_Policy(in *v1.Policy, out *config.Policy, s conversion.Scope) error { out.Predicates = *(*[]config.PredicatePolicy)(unsafe.Pointer(&in.Predicates)) out.Priorities = *(*[]config.PriorityPolicy)(unsafe.Pointer(&in.Priorities)) - out.Extenders = *(*[]config.Extender)(unsafe.Pointer(&in.Extenders)) + if in.Extenders != nil { + in, out := &in.Extenders, &out.Extenders + *out = make([]config.Extender, len(*in)) + for i := range *in { + if err := Convert_v1_LegacyExtender_To_config_Extender(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Extenders = nil + } out.HardPodAffinitySymmetricWeight = in.HardPodAffinitySymmetricWeight out.AlwaysCheckAllPredicates = in.AlwaysCheckAllPredicates return nil @@ -349,7 +316,17 @@ func Convert_v1_Policy_To_config_Policy(in *v1.Policy, out *config.Policy, s con func autoConvert_config_Policy_To_v1_Policy(in *config.Policy, out *v1.Policy, s conversion.Scope) error { out.Predicates = *(*[]v1.PredicatePolicy)(unsafe.Pointer(&in.Predicates)) out.Priorities = *(*[]v1.PriorityPolicy)(unsafe.Pointer(&in.Priorities)) - out.Extenders = *(*[]v1.Extender)(unsafe.Pointer(&in.Extenders)) + if in.Extenders != nil { + in, out := &in.Extenders, &out.Extenders + *out = make([]v1.LegacyExtender, len(*in)) + for i := range *in { + if err := Convert_config_Extender_To_v1_LegacyExtender(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Extenders = nil + } out.HardPodAffinitySymmetricWeight = in.HardPodAffinitySymmetricWeight out.AlwaysCheckAllPredicates = in.AlwaysCheckAllPredicates return nil diff --git a/pkg/scheduler/apis/config/v1beta1/conversion_test.go b/pkg/scheduler/apis/config/v1beta1/conversion_test.go index a2c03938e06..75ac0e93dec 100644 --- a/pkg/scheduler/apis/config/v1beta1/conversion_test.go +++ b/pkg/scheduler/apis/config/v1beta1/conversion_test.go @@ -20,7 +20,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/kube-scheduler/config/v1beta1" "k8s.io/kubernetes/pkg/scheduler/apis/config" @@ -29,14 +28,14 @@ import ( func TestV1beta1ToConfigKubeSchedulerConfigurationConversion(t *testing.T) { cases := []struct { - name string - config v1beta1.KubeSchedulerConfiguration - expected config.KubeSchedulerConfiguration + name string + config v1beta1.KubeSchedulerConfiguration + want config.KubeSchedulerConfiguration }{ { - name: "default conversion v1beta1 to config", - config: v1beta1.KubeSchedulerConfiguration{}, - expected: config.KubeSchedulerConfiguration{AlgorithmSource: config.SchedulerAlgorithmSource{Provider: pointer.StringPtr(v1beta1.SchedulerDefaultProviderName)}}, + name: "default conversion v1beta1 to config", + config: v1beta1.KubeSchedulerConfiguration{}, + want: config.KubeSchedulerConfiguration{AlgorithmSource: config.SchedulerAlgorithmSource{Provider: pointer.StringPtr(v1beta1.SchedulerDefaultProviderName)}}, }, } @@ -44,13 +43,14 @@ func TestV1beta1ToConfigKubeSchedulerConfigurationConversion(t *testing.T) { if err := AddToScheme(scheme); err != nil { t.Fatal(err) } + for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - var out config.KubeSchedulerConfiguration - if err := scheme.Convert(&tc.config, &out, nil); err != nil { + var got config.KubeSchedulerConfiguration + if err := scheme.Convert(&tc.config, &got, nil); err != nil { t.Errorf("failed to convert: %+v", err) } - if diff := cmp.Diff(tc.expected, out); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("unexpected conversion (-want, +got):\n%s", diff) } }) diff --git a/pkg/scheduler/apis/config/v1beta1/zz_generated.conversion.go b/pkg/scheduler/apis/config/v1beta1/zz_generated.conversion.go index 2ba5c02ed22..4fe750084f6 100644 --- a/pkg/scheduler/apis/config/v1beta1/zz_generated.conversion.go +++ b/pkg/scheduler/apis/config/v1beta1/zz_generated.conversion.go @@ -24,11 +24,11 @@ import ( unsafe "unsafe" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" v1alpha1 "k8s.io/component-base/config/v1alpha1" - configv1 "k8s.io/kube-scheduler/config/v1" + v1 "k8s.io/kube-scheduler/config/v1" v1beta1 "k8s.io/kube-scheduler/config/v1beta1" config "k8s.io/kubernetes/pkg/scheduler/apis/config" ) @@ -40,6 +40,16 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*v1beta1.Extender)(nil), (*config.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Extender_To_config_Extender(a.(*v1beta1.Extender), b.(*config.Extender), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.Extender)(nil), (*v1beta1.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_Extender_To_v1beta1_Extender(a.(*config.Extender), b.(*v1beta1.Extender), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1beta1.InterPodAffinityArgs)(nil), (*config.InterPodAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(a.(*v1beta1.InterPodAffinityArgs), b.(*config.InterPodAffinityArgs), scope) }); err != nil { @@ -213,8 +223,50 @@ func RegisterConversions(s *runtime.Scheme) error { return nil } +func autoConvert_v1beta1_Extender_To_config_Extender(in *v1beta1.Extender, out *config.Extender, s conversion.Scope) error { + out.URLPrefix = in.URLPrefix + out.FilterVerb = in.FilterVerb + out.PreemptVerb = in.PreemptVerb + out.PrioritizeVerb = in.PrioritizeVerb + out.Weight = in.Weight + out.BindVerb = in.BindVerb + out.EnableHTTPS = in.EnableHTTPS + out.TLSConfig = (*config.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) + out.HTTPTimeout = in.HTTPTimeout + out.NodeCacheCapable = in.NodeCacheCapable + out.ManagedResources = *(*[]config.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) + out.Ignorable = in.Ignorable + return nil +} + +// Convert_v1beta1_Extender_To_config_Extender is an autogenerated conversion function. +func Convert_v1beta1_Extender_To_config_Extender(in *v1beta1.Extender, out *config.Extender, s conversion.Scope) error { + return autoConvert_v1beta1_Extender_To_config_Extender(in, out, s) +} + +func autoConvert_config_Extender_To_v1beta1_Extender(in *config.Extender, out *v1beta1.Extender, s conversion.Scope) error { + out.URLPrefix = in.URLPrefix + out.FilterVerb = in.FilterVerb + out.PreemptVerb = in.PreemptVerb + out.PrioritizeVerb = in.PrioritizeVerb + out.Weight = in.Weight + out.BindVerb = in.BindVerb + out.EnableHTTPS = in.EnableHTTPS + out.TLSConfig = (*v1.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) + out.HTTPTimeout = in.HTTPTimeout + out.NodeCacheCapable = in.NodeCacheCapable + out.ManagedResources = *(*[]v1.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) + out.Ignorable = in.Ignorable + return nil +} + +// Convert_config_Extender_To_v1beta1_Extender is an autogenerated conversion function. +func Convert_config_Extender_To_v1beta1_Extender(in *config.Extender, out *v1beta1.Extender, s conversion.Scope) error { + return autoConvert_config_Extender_To_v1beta1_Extender(in, out, s) +} + func autoConvert_v1beta1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in *v1beta1.InterPodAffinityArgs, out *config.InterPodAffinityArgs, s conversion.Scope) error { - if err := v1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { + if err := metav1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { return err } return nil @@ -226,7 +278,7 @@ func Convert_v1beta1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in *v1b } func autoConvert_config_InterPodAffinityArgs_To_v1beta1_InterPodAffinityArgs(in *config.InterPodAffinityArgs, out *v1beta1.InterPodAffinityArgs, s conversion.Scope) error { - if err := v1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { + if err := metav1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { return err } return nil @@ -244,25 +296,25 @@ func autoConvert_v1beta1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfi if err := v1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { return err } - if err := v1.Convert_Pointer_string_To_string(&in.HealthzBindAddress, &out.HealthzBindAddress, s); err != nil { + if err := metav1.Convert_Pointer_string_To_string(&in.HealthzBindAddress, &out.HealthzBindAddress, s); err != nil { return err } - if err := v1.Convert_Pointer_string_To_string(&in.MetricsBindAddress, &out.MetricsBindAddress, s); err != nil { + if err := metav1.Convert_Pointer_string_To_string(&in.MetricsBindAddress, &out.MetricsBindAddress, s); err != nil { return err } if err := v1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil { return err } - if err := v1.Convert_Pointer_bool_To_bool(&in.DisablePreemption, &out.DisablePreemption, s); err != nil { + if err := metav1.Convert_Pointer_bool_To_bool(&in.DisablePreemption, &out.DisablePreemption, s); err != nil { return err } - if err := v1.Convert_Pointer_int32_To_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil { + if err := metav1.Convert_Pointer_int32_To_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil { return err } - if err := v1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { + if err := metav1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { return err } - if err := v1.Convert_Pointer_int64_To_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { + if err := metav1.Convert_Pointer_int64_To_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } if in.Profiles != nil { @@ -288,25 +340,25 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1beta1_KubeSchedulerConfi if err := v1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { return err } - if err := v1.Convert_string_To_Pointer_string(&in.HealthzBindAddress, &out.HealthzBindAddress, s); err != nil { + if err := metav1.Convert_string_To_Pointer_string(&in.HealthzBindAddress, &out.HealthzBindAddress, s); err != nil { return err } - if err := v1.Convert_string_To_Pointer_string(&in.MetricsBindAddress, &out.MetricsBindAddress, s); err != nil { + if err := metav1.Convert_string_To_Pointer_string(&in.MetricsBindAddress, &out.MetricsBindAddress, s); err != nil { return err } if err := v1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil { return err } - if err := v1.Convert_bool_To_Pointer_bool(&in.DisablePreemption, &out.DisablePreemption, s); err != nil { + if err := metav1.Convert_bool_To_Pointer_bool(&in.DisablePreemption, &out.DisablePreemption, s); err != nil { return err } - if err := v1.Convert_int32_To_Pointer_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil { + if err := metav1.Convert_int32_To_Pointer_int32(&in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore, s); err != nil { return err } - if err := v1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { + if err := metav1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { return err } - if err := v1.Convert_int64_To_Pointer_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { + if err := metav1.Convert_int64_To_Pointer_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { return err } if in.Profiles != nil { @@ -320,12 +372,12 @@ func autoConvert_config_KubeSchedulerConfiguration_To_v1beta1_KubeSchedulerConfi } else { out.Profiles = nil } - out.Extenders = *(*[]configv1.Extender)(unsafe.Pointer(&in.Extenders)) + out.Extenders = *(*[]v1beta1.Extender)(unsafe.Pointer(&in.Extenders)) return nil } func autoConvert_v1beta1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *v1beta1.KubeSchedulerProfile, out *config.KubeSchedulerProfile, s conversion.Scope) error { - if err := v1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { + if err := metav1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { return err } if in.Plugins != nil { @@ -357,7 +409,7 @@ func Convert_v1beta1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *v1b } func autoConvert_config_KubeSchedulerProfile_To_v1beta1_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *v1beta1.KubeSchedulerProfile, s conversion.Scope) error { - if err := v1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { + if err := metav1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { return err } if in.Plugins != nil { @@ -476,7 +528,7 @@ func Convert_config_NodeResourcesMostAllocatedArgs_To_v1beta1_NodeResourcesMostA func autoConvert_v1beta1_Plugin_To_config_Plugin(in *v1beta1.Plugin, out *config.Plugin, s conversion.Scope) error { out.Name = in.Name - if err := v1.Convert_Pointer_int32_To_int32(&in.Weight, &out.Weight, s); err != nil { + if err := metav1.Convert_Pointer_int32_To_int32(&in.Weight, &out.Weight, s); err != nil { return err } return nil @@ -489,7 +541,7 @@ func Convert_v1beta1_Plugin_To_config_Plugin(in *v1beta1.Plugin, out *config.Plu func autoConvert_config_Plugin_To_v1beta1_Plugin(in *config.Plugin, out *v1beta1.Plugin, s conversion.Scope) error { out.Name = in.Name - if err := v1.Convert_int32_To_Pointer_int32(&in.Weight, &out.Weight, s); err != nil { + if err := metav1.Convert_int32_To_Pointer_int32(&in.Weight, &out.Weight, s); err != nil { return err } return nil @@ -931,7 +983,7 @@ func Convert_config_UtilizationShapePoint_To_v1beta1_UtilizationShapePoint(in *c } func autoConvert_v1beta1_VolumeBindingArgs_To_config_VolumeBindingArgs(in *v1beta1.VolumeBindingArgs, out *config.VolumeBindingArgs, s conversion.Scope) error { - if err := v1.Convert_Pointer_int64_To_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { + if err := metav1.Convert_Pointer_int64_To_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { return err } return nil @@ -943,7 +995,7 @@ func Convert_v1beta1_VolumeBindingArgs_To_config_VolumeBindingArgs(in *v1beta1.V } func autoConvert_config_VolumeBindingArgs_To_v1beta1_VolumeBindingArgs(in *config.VolumeBindingArgs, out *v1beta1.VolumeBindingArgs, s conversion.Scope) error { - if err := v1.Convert_int64_To_Pointer_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { + if err := metav1.Convert_int64_To_Pointer_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { return err } return nil diff --git a/pkg/scheduler/apis/config/zz_generated.deepcopy.go b/pkg/scheduler/apis/config/zz_generated.deepcopy.go index 093f2db86a1..6eef7aa3757 100644 --- a/pkg/scheduler/apis/config/zz_generated.deepcopy.go +++ b/pkg/scheduler/apis/config/zz_generated.deepcopy.go @@ -33,6 +33,7 @@ func (in *Extender) DeepCopyInto(out *Extender) { *out = new(ExtenderTLSConfig) (*in).DeepCopyInto(*out) } + out.HTTPTimeout = in.HTTPTimeout if in.ManagedResources != nil { in, out := &in.ManagedResources, &out.ManagedResources *out = make([]ExtenderManagedResource, len(*in)) diff --git a/pkg/scheduler/core/extender.go b/pkg/scheduler/core/extender.go index b0fca92189c..b0e883f8d03 100644 --- a/pkg/scheduler/core/extender.go +++ b/pkg/scheduler/core/extender.go @@ -24,7 +24,7 @@ import ( "strings" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/sets" restclient "k8s.io/client-go/rest" @@ -84,8 +84,8 @@ func makeTransport(config *schedulerapi.Extender) (http.RoundTripper, error) { // NewHTTPExtender creates an HTTPExtender object. func NewHTTPExtender(config *schedulerapi.Extender) (framework.Extender, error) { - if config.HTTPTimeout.Nanoseconds() == 0 { - config.HTTPTimeout = time.Duration(DefaultExtenderTimeout) + if config.HTTPTimeout.Duration.Nanoseconds() == 0 { + config.HTTPTimeout.Duration = time.Duration(DefaultExtenderTimeout) } transport, err := makeTransport(config) @@ -94,7 +94,7 @@ func NewHTTPExtender(config *schedulerapi.Extender) (framework.Extender, error) } client := &http.Client{ Transport: transport, - Timeout: config.HTTPTimeout, + Timeout: config.HTTPTimeout.Duration, } managedResources := sets.NewString() for _, r := range config.ManagedResources { diff --git a/staging/src/k8s.io/kube-scheduler/config/v1/types.go b/staging/src/k8s.io/kube-scheduler/config/v1/types.go index a7dbdbb97f7..353bab4a384 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1/types.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1/types.go @@ -33,7 +33,7 @@ type Policy struct { // Holds the information to configure the priority functions Priorities []PriorityPolicy `json:"priorities"` // Holds the information to communicate with the extender(s) - Extenders []Extender `json:"extenders"` + Extenders []LegacyExtender `json:"extenders"` // RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule // corresponding to every RequiredDuringScheduling affinity rule. // HardPodAffinitySymmetricWeight represents the weight of implicit PreferredDuringScheduling affinity rule, in the range 1-100. @@ -185,9 +185,9 @@ type ExtenderTLSConfig struct { CAData []byte `json:"caData,omitempty"` } -// Extender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, +// LegacyExtender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, // it is assumed that the extender chose not to provide that extension. -type Extender struct { +type LegacyExtender struct { // URLPrefix at which the extender is available URLPrefix string `json:"urlPrefix"` // Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender. @@ -233,10 +233,10 @@ type Extender struct { // to preserve compatibility with incorrectly specified scheduler config fields: // * BindVerb, which originally did not specify a json tag, and required upper-case serialization in 1.7 // * TLSConfig, which uses a struct not intended for serialization, and does not include any json tags -type caseInsensitiveExtender *Extender +type caseInsensitiveExtender *LegacyExtender // UnmarshalJSON implements the json.Unmarshaller interface. // This preserves compatibility with incorrect case-insensitive configuration fields. -func (t *Extender) UnmarshalJSON(b []byte) error { +func (t *LegacyExtender) UnmarshalJSON(b []byte) error { return gojson.Unmarshal(b, caseInsensitiveExtender(t)) } diff --git a/staging/src/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go index 211db388ba2..652dd0c483c 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go @@ -24,32 +24,6 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Extender) DeepCopyInto(out *Extender) { - *out = *in - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(ExtenderTLSConfig) - (*in).DeepCopyInto(*out) - } - if in.ManagedResources != nil { - in, out := &in.ManagedResources, &out.ManagedResources - *out = make([]ExtenderManagedResource, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extender. -func (in *Extender) DeepCopy() *Extender { - if in == nil { - return nil - } - out := new(Extender) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtenderManagedResource) DeepCopyInto(out *ExtenderManagedResource) { *out = *in @@ -134,6 +108,32 @@ func (in *LabelsPresence) DeepCopy() *LabelsPresence { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LegacyExtender) DeepCopyInto(out *LegacyExtender) { + *out = *in + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(ExtenderTLSConfig) + (*in).DeepCopyInto(*out) + } + if in.ManagedResources != nil { + in, out := &in.ManagedResources, &out.ManagedResources + *out = make([]ExtenderManagedResource, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LegacyExtender. +func (in *LegacyExtender) DeepCopy() *LegacyExtender { + if in == nil { + return nil + } + out := new(LegacyExtender) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Policy) DeepCopyInto(out *Policy) { *out = *in @@ -154,7 +154,7 @@ func (in *Policy) DeepCopyInto(out *Policy) { } if in.Extenders != nil { in, out := &in.Extenders, &out.Extenders - *out = make([]Extender, len(*in)) + *out = make([]LegacyExtender, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/staging/src/k8s.io/kube-scheduler/config/v1beta1/types.go b/staging/src/k8s.io/kube-scheduler/config/v1beta1/types.go index 2a272c6629f..705732449fd 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1beta1/types.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1beta1/types.go @@ -95,7 +95,7 @@ type KubeSchedulerConfiguration struct { // Extenders are the list of scheduler extenders, each holding the values of how to communicate // with the extender. These extenders are shared by all scheduler profiles. // +listType=set - Extenders []v1.Extender `json:"extenders,omitempty"` + Extenders []Extender `json:"extenders,omitempty"` } // DecodeNestedObjects decodes plugin args for known types. @@ -264,3 +264,48 @@ func (c *PluginConfig) encodeNestedObjects(e runtime.Encoder) error { c.Args.Raw = json return nil } + +// Extender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, +// it is assumed that the extender chose not to provide that extension. +type Extender struct { + // URLPrefix at which the extender is available + URLPrefix string `json:"urlPrefix"` + // Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender. + FilterVerb string `json:"filterVerb,omitempty"` + // Verb for the preempt call, empty if not supported. This verb is appended to the URLPrefix when issuing the preempt call to extender. + PreemptVerb string `json:"preemptVerb,omitempty"` + // Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender. + PrioritizeVerb string `json:"prioritizeVerb,omitempty"` + // The numeric multiplier for the node scores that the prioritize call generates. + // The weight should be a positive integer + Weight int64 `json:"weight,omitempty"` + // Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender. + // If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver. Only one extender + // can implement this function. + BindVerb string `json:"bindVerb,omitempty"` + // EnableHTTPS specifies whether https should be used to communicate with the extender + EnableHTTPS bool `json:"enableHTTPS,omitempty"` + // TLSConfig specifies the transport layer security config + TLSConfig *v1.ExtenderTLSConfig `json:"tlsConfig,omitempty"` + // HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize + // timeout is ignored, k8s/other extenders priorities are used to select the node. + HTTPTimeout metav1.Duration `json:"httpTimeout,omitempty"` + // NodeCacheCapable specifies that the extender is capable of caching node information, + // so the scheduler should only send minimal information about the eligible nodes + // assuming that the extender already cached full details of all nodes in the cluster + NodeCacheCapable bool `json:"nodeCacheCapable,omitempty"` + // ManagedResources is a list of extended resources that are managed by + // this extender. + // - A pod will be sent to the extender on the Filter, Prioritize and Bind + // (if the extender is the binder) phases iff the pod requests at least + // one of the extended resources in this list. If empty or unspecified, + // all pods will be sent to this extender. + // - If IgnoredByScheduler is set to true for a resource, kube-scheduler + // will skip checking the resource in predicates. + // +optional + // +listType=atomic + ManagedResources []v1.ExtenderManagedResource `json:"managedResources,omitempty"` + // Ignorable specifies if the extender is ignorable, i.e. scheduling should not + // fail when the extender returns an error or is not reachable. + Ignorable bool `json:"ignorable,omitempty"` +} diff --git a/staging/src/k8s.io/kube-scheduler/config/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/kube-scheduler/config/v1beta1/zz_generated.deepcopy.go index 070a8ecd39f..082d8d8a581 100644 --- a/staging/src/k8s.io/kube-scheduler/config/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/kube-scheduler/config/v1beta1/zz_generated.deepcopy.go @@ -26,6 +26,33 @@ import ( v1 "k8s.io/kube-scheduler/config/v1" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Extender) DeepCopyInto(out *Extender) { + *out = *in + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(v1.ExtenderTLSConfig) + (*in).DeepCopyInto(*out) + } + out.HTTPTimeout = in.HTTPTimeout + if in.ManagedResources != nil { + in, out := &in.ManagedResources, &out.ManagedResources + *out = make([]v1.ExtenderManagedResource, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extender. +func (in *Extender) DeepCopy() *Extender { + if in == nil { + return nil + } + out := new(Extender) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InterPodAffinityArgs) DeepCopyInto(out *InterPodAffinityArgs) { *out = *in @@ -102,7 +129,7 @@ func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfigurati } if in.Extenders != nil { in, out := &in.Extenders, &out.Extenders - *out = make([]v1.Extender, len(*in)) + *out = make([]Extender, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) }