diff --git a/plugin/pkg/admission/resourcequota/admission_test.go b/plugin/pkg/admission/resourcequota/admission_test.go index 8e0600c75ae..8fdc8d3cff5 100644 --- a/plugin/pkg/admission/resourcequota/admission_test.go +++ b/plugin/pkg/admission/resourcequota/admission_test.go @@ -2182,3 +2182,93 @@ func TestAdmitLimitedScopeWithCoverQuota(t *testing.T) { } } + +// TestAdmitZeroDeltaUsageWithoutCoveringQuota verifies that resource quota is not required for zero delta requests. +func TestAdmitZeroDeltaUsageWithoutCoveringQuota(t *testing.T) { + + kubeClient := fake.NewSimpleClientset() + stopCh := make(chan struct{}) + defer close(stopCh) + + informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc()) + quotaAccessor, _ := newQuotaAccessor() + quotaAccessor.client = kubeClient + quotaAccessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister() + + // disable services unless there is a covering quota. + config := &resourcequotaapi.Configuration{ + LimitedResources: []resourcequotaapi.LimitedResource{ + { + Resource: "services", + MatchContains: []string{"services"}, + }, + }, + } + quotaConfiguration := install.NewQuotaConfigurationForAdmission() + evaluator := NewQuotaEvaluator(quotaAccessor, quotaConfiguration.IgnoredResources(), generic.NewRegistry(quotaConfiguration.Evaluators()), nil, config, 5, stopCh) + + handler := &QuotaAdmission{ + Handler: admission.NewHandler(admission.Create, admission.Update), + evaluator: evaluator, + } + + existingService := &api.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "service", Namespace: "test", ResourceVersion: "1"}, + Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer}, + } + newService := &api.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "service", Namespace: "test"}, + Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer}, + } + + err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) + if err != nil { + t.Errorf("unexpected error: %v", err) + } +} + +// TestAdmitRejectDeltaUsageWithoutCoveringQuota verifies that resource quota is required for non zero delta requests. +func TestAdmitRejectDeltaUsageWithoutCoveringQuota(t *testing.T) { + kubeClient := fake.NewSimpleClientset() + stopCh := make(chan struct{}) + defer close(stopCh) + + informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc()) + quotaAccessor, _ := newQuotaAccessor() + quotaAccessor.client = kubeClient + quotaAccessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister() + + // disable services unless there is a covering quota. + config := &resourcequotaapi.Configuration{ + LimitedResources: []resourcequotaapi.LimitedResource{ + { + Resource: "services", + MatchContains: []string{"services"}, + }, + }, + } + quotaConfiguration := install.NewQuotaConfigurationForAdmission() + evaluator := NewQuotaEvaluator(quotaAccessor, quotaConfiguration.IgnoredResources(), generic.NewRegistry(quotaConfiguration.Evaluators()), nil, config, 5, stopCh) + + handler := &QuotaAdmission{ + Handler: admission.NewHandler(admission.Create, admission.Update), + evaluator: evaluator, + } + + existingService := &api.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "service", Namespace: "test", ResourceVersion: "1"}, + Spec: api.ServiceSpec{Type: api.ServiceTypeLoadBalancer}, + } + newService := &api.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "service", Namespace: "test"}, + Spec: api.ServiceSpec{ + Type: api.ServiceTypeNodePort, + Ports: []api.ServicePort{{Port: 1234}}, + }, + } + + err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil) + if err == nil { + t.Errorf("Expected an error for consuming a limited resource without quota.") + } +}