From 09bac89aff5ab502a57d3a7d49fed5d767871903 Mon Sep 17 00:00:00 2001 From: derekwaynecarr Date: Thu, 7 Jul 2016 16:35:47 -0400 Subject: [PATCH] Add support to quota pvc storage requests --- pkg/api/helpers.go | 1 + pkg/api/types.go | 2 ++ pkg/api/v1/types.go | 2 ++ .../core/persistent_volume_claims.go | 19 +++++++++++++++++-- test/e2e/resource_quota.go | 4 ++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/api/helpers.go b/pkg/api/helpers.go index b188191423..6ba14937aa 100644 --- a/pkg/api/helpers.go +++ b/pkg/api/helpers.go @@ -134,6 +134,7 @@ var standardQuotaResources = sets.NewString( string(ResourceMemory), string(ResourceRequestsCPU), string(ResourceRequestsMemory), + string(ResourceRequestsStorage), string(ResourceLimitsCPU), string(ResourceLimitsMemory), string(ResourcePods), diff --git a/pkg/api/types.go b/pkg/api/types.go index 5ba2158c34..11549d42ff 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -2568,6 +2568,8 @@ const ( ResourceRequestsCPU ResourceName = "requests.cpu" // Memory request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) ResourceRequestsMemory ResourceName = "requests.memory" + // Storage request, in bytes + ResourceRequestsStorage ResourceName = "requests.storage" // CPU limit, in cores. (500m = .5 cores) ResourceLimitsCPU ResourceName = "limits.cpu" // Memory limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 54b6e8d6e9..9b690db3eb 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -3038,6 +3038,8 @@ const ( ResourceRequestsCPU ResourceName = "requests.cpu" // Memory request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) ResourceRequestsMemory ResourceName = "requests.memory" + // Storage request, in bytes + ResourceRequestsStorage ResourceName = "requests.storage" // CPU limit, in cores. (500m = .5 cores) ResourceLimitsCPU ResourceName = "limits.cpu" // Memory limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) diff --git a/pkg/quota/evaluator/core/persistent_volume_claims.go b/pkg/quota/evaluator/core/persistent_volume_claims.go index a00e44f100..230f196d3d 100644 --- a/pkg/quota/evaluator/core/persistent_volume_claims.go +++ b/pkg/quota/evaluator/core/persistent_volume_claims.go @@ -19,6 +19,7 @@ package core import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/resource" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" @@ -27,7 +28,7 @@ import ( // NewPersistentVolumeClaimEvaluator returns an evaluator that can evaluate persistent volume claims func NewPersistentVolumeClaimEvaluator(kubeClient clientset.Interface) quota.Evaluator { - allResources := []api.ResourceName{api.ResourcePersistentVolumeClaims} + allResources := []api.ResourceName{api.ResourcePersistentVolumeClaims, api.ResourceRequestsStorage} return &generic.GenericEvaluator{ Name: "Evaluator.PersistentVolumeClaim", InternalGroupKind: api.Kind("PersistentVolumeClaim"), @@ -37,9 +38,23 @@ func NewPersistentVolumeClaimEvaluator(kubeClient clientset.Interface) quota.Eva MatchedResourceNames: allResources, MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourcePersistentVolumeClaims), - UsageFunc: generic.ObjectCountUsageFunc(api.ResourcePersistentVolumeClaims), + UsageFunc: PersistentVolumeClaimUsageFunc, ListFuncByNamespace: func(namespace string, options api.ListOptions) (runtime.Object, error) { return kubeClient.Core().PersistentVolumeClaims(namespace).List(options) }, } } + +// PersistentVolumeClaimUsageFunc knows how to measure usage associated with persistent volume claims +func PersistentVolumeClaimUsageFunc(object runtime.Object) api.ResourceList { + pvc, ok := object.(*api.PersistentVolumeClaim) + if !ok { + return api.ResourceList{} + } + result := api.ResourceList{} + result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1") + if request, found := pvc.Spec.Resources.Requests[api.ResourceStorage]; found { + result[api.ResourceRequestsStorage] = request + } + return result +} diff --git a/test/e2e/resource_quota.go b/test/e2e/resource_quota.go index b383818345..5dd634b716 100644 --- a/test/e2e/resource_quota.go +++ b/test/e2e/resource_quota.go @@ -278,6 +278,7 @@ var _ = framework.KubeDescribe("ResourceQuota", func() { usedResources := api.ResourceList{} usedResources[api.ResourceQuotas] = resource.MustParse("1") usedResources[api.ResourcePersistentVolumeClaims] = resource.MustParse("0") + usedResources[api.ResourceRequestsStorage] = resource.MustParse("0") err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources) Expect(err).NotTo(HaveOccurred()) @@ -289,6 +290,7 @@ var _ = framework.KubeDescribe("ResourceQuota", func() { By("Ensuring resource quota status captures persistent volume claimcreation") usedResources = api.ResourceList{} usedResources[api.ResourcePersistentVolumeClaims] = resource.MustParse("1") + usedResources[api.ResourceRequestsStorage] = resource.MustParse("1Gi") err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources) Expect(err).NotTo(HaveOccurred()) @@ -298,6 +300,7 @@ var _ = framework.KubeDescribe("ResourceQuota", func() { By("Ensuring resource quota status released usage") usedResources[api.ResourcePersistentVolumeClaims] = resource.MustParse("0") + usedResources[api.ResourceRequestsStorage] = resource.MustParse("0") err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources) Expect(err).NotTo(HaveOccurred()) }) @@ -512,6 +515,7 @@ func newTestResourceQuota(name string) *api.ResourceQuota { hard[api.ResourceConfigMaps] = resource.MustParse("2") hard[api.ResourceSecrets] = resource.MustParse("10") hard[api.ResourcePersistentVolumeClaims] = resource.MustParse("10") + hard[api.ResourceRequestsStorage] = resource.MustParse("10Gi") return &api.ResourceQuota{ ObjectMeta: api.ObjectMeta{Name: name}, Spec: api.ResourceQuotaSpec{Hard: hard},