Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure strict encoding for RequestedToCapacityRatioArgs #91603

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions api/api-rules/violation_exceptions.list
Expand Up @@ -586,10 +586,6 @@ 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,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/v1beta1,ResourceSpec,Name
API rule violation: names_match,k8s.io/kube-scheduler/config/v1beta1,ResourceSpec,Weight
API rule violation: names_match,k8s.io/kube-scheduler/config/v1beta1,UtilizationShapePoint,Score
API rule violation: names_match,k8s.io/kube-scheduler/config/v1beta1,UtilizationShapePoint,Utilization
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
Expand Down
75 changes: 33 additions & 42 deletions pkg/scheduler/apis/config/scheme/scheme_test.go
Expand Up @@ -21,7 +21,7 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-scheduler/config/v1beta1"
Expand Down Expand Up @@ -108,8 +108,8 @@ profiles:
{
Name: "PodTopologySpread",
Args: &config.PodTopologySpreadArgs{
DefaultConstraints: []v1.TopologySpreadConstraint{
{MaxSkew: 1, TopologyKey: "zone", WhenUnsatisfiable: v1.ScheduleAnyway},
DefaultConstraints: []corev1.TopologySpreadConstraint{
{MaxSkew: 1, TopologyKey: "zone", WhenUnsatisfiable: corev1.ScheduleAnyway},
},
},
},
Expand Down Expand Up @@ -178,11 +178,25 @@ profiles:
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: InterPodAffinityArgs
`),
wantErr: "decoding .profiles[0].pluginConfig[0]: args for plugin NodeLabel were not of type NodeLabelArgs.kubescheduler.config.k8s.io, got InterPodAffinityArgs.kubescheduler.config.k8s.io",
wantErr: `decoding .profiles[0].pluginConfig[0]: args for plugin NodeLabel were not of type NodeLabelArgs.kubescheduler.config.k8s.io, got InterPodAffinityArgs.kubescheduler.config.k8s.io`,
liggitt marked this conversation as resolved.
Show resolved Hide resolved
},
{
// TODO: do not replicate this case for v1beta1.
name: "v1beta1 case insensitive RequestedToCapacityRatioArgs",
name: "v1beta1 RequestedToCapacityRatioArgs shape encoding is strict",
data: []byte(`
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
profiles:
- pluginConfig:
- name: RequestedToCapacityRatio
args:
shape:
- Utilization: 1
Score: 2
`),
wantErr: `decoding .profiles[0].pluginConfig[0]: decoding args for plugin RequestedToCapacityRatio: strict decoder error for {"shape":[{"Score":2,"Utilization":1}]}: v1beta1.RequestedToCapacityRatioArgs.Shape: []v1beta1.UtilizationShapePoint: v1beta1.UtilizationShapePoint.ReadObject: found unknown field: Score, error found in #10 byte of ...|:[{"Score":2,"Utiliz|..., bigger context ...|{"shape":[{"Score":2,"Utilization":1}]}|...`,
},
{
name: "v1beta1 RequestedToCapacityRatioArgs resources encoding is strict",
data: []byte(`
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
Expand All @@ -193,34 +207,11 @@ profiles:
shape:
- utilization: 1
score: 2
- Utilization: 3
Score: 4
resources:
- name: Upper
weight: 1
- Name: lower
weight: 2
- Name: 1
Weight: 2
`),
wantProfiles: []config.KubeSchedulerProfile{
{
SchedulerName: "default-scheduler",
PluginConfig: []config.PluginConfig{
{
Name: "RequestedToCapacityRatio",
Args: &config.RequestedToCapacityRatioArgs{
Shape: []config.UtilizationShapePoint{
{Utilization: 1, Score: 2},
{Utilization: 3, Score: 4},
},
Resources: []config.ResourceSpec{
{Name: "Upper", Weight: 1},
{Name: "lower", Weight: 2},
},
},
},
},
},
},
wantErr: `decoding .profiles[0].pluginConfig[0]: decoding args for plugin RequestedToCapacityRatio: strict decoder error for {"resources":[{"Name":1,"Weight":2}],"shape":[{"score":2,"utilization":1}]}: v1beta1.RequestedToCapacityRatioArgs.Shape: []v1beta1.UtilizationShapePoint: Resources: []v1beta1.ResourceSpec: v1beta1.ResourceSpec.ReadObject: found unknown field: Name, error found in #10 byte of ...|":[{"Name":1,"Weight|..., bigger context ...|{"resources":[{"Name":1,"Weight":2}],"shape":[{"score":2,"utilization":|...`,
},
{
name: "out-of-tree plugin args",
Expand Down Expand Up @@ -311,7 +302,7 @@ profiles:
obj, gvk, err := decoder.Decode(tt.data, nil, nil)
if err != nil {
if tt.wantErr != err.Error() {
t.Fatalf("got err %v, want %v", err.Error(), tt.wantErr)
t.Fatalf("\ngot err:\n\t%v\nwant:\n\t%s", err, tt.wantErr)
}
return
}
Expand Down Expand Up @@ -367,7 +358,7 @@ func TestCodecsEncodePluginConfig(t *testing.T) {
{Utilization: 1, Score: 2},
},
Resources: []v1beta1.ResourceSpec{
{Name: "lower", Weight: 2},
{Name: "cpu", Weight: 2},
},
},
},
Expand Down Expand Up @@ -424,18 +415,18 @@ profiles:
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: RequestedToCapacityRatioArgs
resources:
- Name: lower
Weight: 2
- name: cpu
weight: 2
shape:
- Score: 2
Utilization: 1
- score: 2
utilization: 1
name: RequestedToCapacityRatio
- args:
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: NodeResourcesLeastAllocatedArgs
resources:
- Name: mem
Weight: 2
- name: mem
weight: 2
name: NodeResourcesLeastAllocated
- args:
foo: bar
Expand Down Expand Up @@ -512,8 +503,8 @@ profiles:
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: NodeResourcesMostAllocatedArgs
resources:
- Name: cpu
Weight: 1
- name: cpu
weight: 1
name: NodeResourcesMostAllocated
- args:
apiVersion: kubescheduler.config.k8s.io/v1beta1
Expand Down
16 changes: 8 additions & 8 deletions pkg/scheduler/apis/config/v1beta1/defaults.go
Expand Up @@ -20,7 +20,7 @@ import (
"net"
"strconv"

v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/util/feature"
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
Expand All @@ -34,8 +34,8 @@ import (
)

var defaultResourceSpec = []v1beta1.ResourceSpec{
{Name: string(v1.ResourceCPU), Weight: 1},
{Name: string(v1.ResourceMemory), Weight: 1},
{Name: string(corev1.ResourceCPU), Weight: 1},
{Name: string(corev1.ResourceMemory), Weight: 1},
}

func addDefaultingFuncs(scheme *runtime.Scheme) error {
Expand Down Expand Up @@ -203,15 +203,15 @@ func SetDefaults_PodTopologySpreadArgs(obj *v1beta1.PodTopologySpreadArgs) {
return
}
if obj.DefaultConstraints == nil {
obj.DefaultConstraints = []v1.TopologySpreadConstraint{
obj.DefaultConstraints = []corev1.TopologySpreadConstraint{
{
TopologyKey: v1.LabelHostname,
WhenUnsatisfiable: v1.ScheduleAnyway,
TopologyKey: corev1.LabelHostname,
WhenUnsatisfiable: corev1.ScheduleAnyway,
MaxSkew: 3,
},
{
TopologyKey: v1.LabelZoneFailureDomainStable,
WhenUnsatisfiable: v1.ScheduleAnyway,
TopologyKey: corev1.LabelZoneFailureDomainStable,
WhenUnsatisfiable: corev1.ScheduleAnyway,
MaxSkew: 5,
},
}
Expand Down
Expand Up @@ -17,9 +17,7 @@ limitations under the License.
package v1beta1

import (
gojson "encoding/json"

v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -80,7 +78,7 @@ type PodTopologySpreadArgs struct {
// Empty by default.
// +optional
// +listType=atomic
DefaultConstraints []v1.TopologySpreadConstraint `json:"defaultConstraints"`
DefaultConstraints []corev1.TopologySpreadConstraint `json:"defaultConstraints"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down Expand Up @@ -123,39 +121,20 @@ type NodeResourcesMostAllocatedArgs struct {
Resources []ResourceSpec `json:"resources,omitempty"`
}

// TODO add JSON tags and remove custom unmarshalling in v1beta1.
pancernik marked this conversation as resolved.
Show resolved Hide resolved
// UtilizationShapePoint and ResourceSpec fields are not annotated with JSON tags in v1alpha2
// to maintain backward compatibility with the args shipped with v1.18.
// See https://github.com/kubernetes/kubernetes/pull/88585#discussion_r405021905

// UtilizationShapePoint represents single point of priority function shape.
type UtilizationShapePoint struct {
// Utilization (x axis). Valid values are 0 to 100. Fully utilized node maps to 100.
pancernik marked this conversation as resolved.
Show resolved Hide resolved
Utilization int32
Utilization int32 `json:"utilization"`
// Score assigned to given utilization (y axis). Valid values are 0 to 10.
Score int32
}

// UnmarshalJSON provides case insensitive unmarshalling for the type.
// TODO remove when copying to v1beta1.
func (t *UtilizationShapePoint) UnmarshalJSON(data []byte) error {
type internal *UtilizationShapePoint
return gojson.Unmarshal(data, internal(t))
Score int32 `json:"score"`
}

// ResourceSpec represents single resource and weight for bin packing of priority RequestedToCapacityRatioArguments.
type ResourceSpec struct {
// Name of the resource to be managed by RequestedToCapacityRatio function.
Name string
Name string `json:"name"`
// Weight of the resource.
Weight int64
}

// UnmarshalJSON provides case insensitive unmarshalling for the type.
// TODO remove when copying to v1beta1.
func (t *ResourceSpec) UnmarshalJSON(data []byte) error {
type internal *ResourceSpec
return gojson.Unmarshal(data, internal(t))
Weight int64 `json:"weight,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down