diff --git a/pkg/webhook/pod/validating/cluster_colocation_profile.go b/pkg/webhook/pod/validating/cluster_colocation_profile.go index 53b6d0a09..5fae1a11f 100644 --- a/pkg/webhook/pod/validating/cluster_colocation_profile.go +++ b/pkg/webhook/pod/validating/cluster_colocation_profile.go @@ -57,6 +57,8 @@ func (h *PodValidatingHandler) clusterColocationProfileValidatingPod(ctx context allErrs = append(allErrs, validateRequiredQoSClass(newPod)...) allErrs = append(allErrs, forbidSpecialQoSClassAndPriorityClass(newPod, extension.QoSBE, extension.PriorityNone, extension.PriorityProd)...) allErrs = append(allErrs, forbidSpecialQoSClassAndPriorityClass(newPod, extension.QoSLSR, extension.PriorityNone, extension.PriorityMid, extension.PriorityBatch, extension.PriorityFree)...) + allErrs = append(allErrs, forbidSpecialQoSClassAndPriorityClass(newPod, extension.QoSLSE, extension.PriorityNone, extension.PriorityMid, extension.PriorityBatch, extension.PriorityFree)...) + allErrs = append(allErrs, forbidSpecialQoSClassAndPriorityClass(newPod, extension.QoSSystem, extension.PriorityMid, extension.PriorityBatch, extension.PriorityFree)...) allErrs = append(allErrs, validateResources(newPod)...) err := allErrs.ToAggregate() allowed := true diff --git a/pkg/webhook/pod/validating/cluster_colocation_profile_test.go b/pkg/webhook/pod/validating/cluster_colocation_profile_test.go index dc3221cdd..8d4a06888 100644 --- a/pkg/webhook/pod/validating/cluster_colocation_profile_test.go +++ b/pkg/webhook/pod/validating/cluster_colocation_profile_test.go @@ -383,6 +383,156 @@ func TestClusterColocationProfileValidatingPod(t *testing.T) { }, wantAllowed: true, }, + { + name: "forbidden QoS and priorityClass combination: LSE And batch", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSLSE), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityBatchValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=LSE and priorityClass=koord-batch cannot be used in combination`, + }, + { + name: "forbidden QoS and priorityClass combination: LSE And Mid", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSLSE), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityMidValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=LSE and priorityClass=koord-mid cannot be used in combination`, + }, + { + name: "forbidden QoS and priorityClass combination: LSE And free", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSLSE), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityFreeValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=LSE and priorityClass=koord-free cannot be used in combination`, + }, + { + name: "forbidden QoS and priorityClass combination: SYSTEM And batch", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSSystem), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityBatchValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=SYSTEM and priorityClass=koord-batch cannot be used in combination`, + }, + { + name: "forbidden QoS and priorityClass combination: SYSTEM And Mid", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSSystem), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityMidValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=SYSTEM and priorityClass=koord-mid cannot be used in combination`, + }, + { + name: "forbidden QoS and priorityClass combination: SYSTEM And free", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSSystem), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityFreeValueMax), + Containers: []corev1.Container{ + { + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + }, + }, + wantAllowed: false, + wantReason: `Pod: Forbidden: koordinator.sh/qosClass=SYSTEM and priorityClass=koord-free cannot be used in combination`, + }, { name: "forbidden resources - LSR And Prod: unset CPUs", operation: admissionv1.Create, @@ -443,6 +593,36 @@ func TestClusterColocationProfileValidatingPod(t *testing.T) { wantAllowed: false, wantReason: `pod.spec.containers[*].resources.requests: Invalid value: "100m": the requested CPUs of LSR Pod must be integer`, }, + { + name: "validate resources - LSE And Prod", + operation: admissionv1.Create, + newPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + extension.LabelPodQoS: string(extension.QoSLSE), + }, + }, + Spec: corev1.PodSpec{ + Priority: pointer.Int32(extension.PriorityProdValueMax), + Containers: []corev1.Container{ + { + Name: "test-container-skip", + Resources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1000m"), + corev1.ResourceMemory: resource.MustParse("4Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1000m"), + corev1.ResourceMemory: resource.MustParse("4Gi"), + }, + }, + }, + }, + }, + }, + wantAllowed: true, + }, } for _, tt := range tests {