Adding loadbalancer services to quota

pull/6/head
Salvatore Dario Minonne 2016-04-14 10:55:52 +02:00
parent 590a5f3ad7
commit f4ed4998ff
6 changed files with 102 additions and 2 deletions

View File

@ -153,6 +153,7 @@ var standardQuotaResources = sets.NewString(
string(ResourcePersistentVolumeClaims),
string(ResourceConfigMaps),
string(ResourceServicesNodePorts),
string(ResourceServicesLoadBalancers),
)
// IsStandardQuotaResourceName returns true if the resource is known to
@ -192,6 +193,7 @@ var integerResources = sets.NewString(
string(ResourceConfigMaps),
string(ResourcePersistentVolumeClaims),
string(ResourceServicesNodePorts),
string(ResourceServicesLoadBalancers),
)
// IsIntegerResourceName returns true if the resource is measured in integer values

View File

@ -2212,6 +2212,8 @@ const (
ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims"
// ResourceServicesNodePorts, number
ResourceServicesNodePorts ResourceName = "services.nodeports"
// ResourceServicesLoadBalancers, number
ResourceServicesLoadBalancers ResourceName = "services.loadbalancers"
// CPU request, in cores. (500m = .5 cores)
ResourceRequestsCPU ResourceName = "requests.cpu"
// Memory request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)

View File

@ -2670,6 +2670,8 @@ const (
ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims"
// ResourceServicesNodePorts, number
ResourceServicesNodePorts ResourceName = "services.nodeports"
// ResourceServicesLoadBalancers, number
ResourceServicesLoadBalancers ResourceName = "services.loadbalancers"
// CPU request, in cores. (500m = .5 cores)
ResourceCPURequest ResourceName = "cpu.request"
// CPU limit, in cores. (500m = .5 cores)

View File

@ -215,7 +215,7 @@ func ServiceReplenishmentUpdateFunc(options *ReplenishmentControllerOptions) fun
return func(oldObj, newObj interface{}) {
oldService := oldObj.(*api.Service)
newService := newObj.(*api.Service)
if core.QuotaServiceType(oldService) && !core.QuotaServiceType(newService) {
if core.QuotaServiceType(oldService) || core.QuotaServiceType(newService) {
options.ReplenishmentFunc(options.GroupKind, newService.Namespace, newService)
}
}

View File

@ -31,6 +31,7 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator {
allResources := []api.ResourceName{
api.ResourceServices,
api.ResourceServicesNodePorts,
api.ResourceServicesLoadBalancers,
}
return &generic.GenericEvaluator{
Name: "Evaluator.Service",
@ -56,6 +57,8 @@ func ServiceUsageFunc(object runtime.Object) api.ResourceList {
switch service.Spec.Type {
case api.ServiceTypeNodePort:
result[api.ResourceServicesNodePorts] = resource.MustParse("1")
case api.ServiceTypeLoadBalancer:
result[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
}
}
return result
@ -64,7 +67,7 @@ func ServiceUsageFunc(object runtime.Object) api.ResourceList {
// QuotaServiceType returns true if the service type is eligible to track against a quota
func QuotaServiceType(service *api.Service) bool {
switch service.Spec.Type {
case api.ServiceTypeNodePort:
case api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer:
return true
}
return false

View File

@ -220,6 +220,96 @@ var _ = framework.KubeDescribe("ResourceQuota", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should create a ResourceQuota and capture the life of a loadBalancer service.", func() {
By("Creating a ResourceQuota")
quotaName := "test-quota"
resourceQuota := newTestResourceQuota(quotaName)
resourceQuota, err := createResourceQuota(f.Client, f.Namespace.Name, resourceQuota)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status is calculated")
usedResources := api.ResourceList{}
usedResources[api.ResourceQuotas] = resource.MustParse("1")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
By("Creating a loadBalancer type Service")
service := newTestServiceForQuota("test-service", api.ServiceTypeLoadBalancer)
service, err = f.Client.Services(f.Namespace.Name).Create(service)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status captures service creation")
usedResources = api.ResourceList{}
usedResources[api.ResourceQuotas] = resource.MustParse("1")
usedResources[api.ResourceServices] = resource.MustParse("1")
usedResources[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
By("Deleting a Service")
err = f.Client.Services(f.Namespace.Name).Delete(service.Name)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status released usage")
usedResources[api.ResourceServices] = resource.MustParse("0")
usedResources[api.ResourceServicesLoadBalancers] = resource.MustParse("0")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
})
It("should create a ResourceQuota and capture the life of a nodePort service updated to loadBalancer.", func() {
By("Creating a ResourceQuota")
quotaName := "test-quota"
resourceQuota := newTestResourceQuota(quotaName)
resourceQuota, err := createResourceQuota(f.Client, f.Namespace.Name, resourceQuota)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status is calculated")
usedResources := api.ResourceList{}
usedResources[api.ResourceQuotas] = resource.MustParse("1")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
By("Creating a nodePort type Service")
service := newTestServiceForQuota("test-service", api.ServiceTypeNodePort)
service, err = f.Client.Services(f.Namespace.Name).Create(service)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status captures service creation")
usedResources = api.ResourceList{}
usedResources[api.ResourceQuotas] = resource.MustParse("1")
usedResources[api.ResourceServices] = resource.MustParse("1")
usedResources[api.ResourceServicesLoadBalancers] = resource.MustParse("0")
usedResources[api.ResourceServicesNodePorts] = resource.MustParse("1")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
By("Updating the service type to loadBalancer")
service.Spec.Type = api.ServiceTypeLoadBalancer
service.Spec.Ports[0].NodePort = 0
_, err = f.Client.Services(f.Namespace.Name).Update(service)
Expect(err).NotTo(HaveOccurred())
By("Checking resource quota status capture service update")
usedResources = api.ResourceList{}
usedResources[api.ResourceQuotas] = resource.MustParse("1")
usedResources[api.ResourceServices] = resource.MustParse("1")
usedResources[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
usedResources[api.ResourceServicesNodePorts] = resource.MustParse("0")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
By("Deleting a Service")
err = f.Client.Services(f.Namespace.Name).Delete(service.Name)
Expect(err).NotTo(HaveOccurred())
By("Ensuring resource quota status released usage")
usedResources[api.ResourceServices] = resource.MustParse("0")
usedResources[api.ResourceServicesLoadBalancers] = resource.MustParse("0")
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
Expect(err).NotTo(HaveOccurred())
})
It("should create a ResourceQuota and capture the life of a pod.", func() {
By("Creating a ResourceQuota")
quotaName := "test-quota"
@ -578,6 +668,7 @@ func newTestResourceQuota(name string) *api.ResourceQuota {
hard[api.ResourcePods] = resource.MustParse("5")
hard[api.ResourceServices] = resource.MustParse("10")
hard[api.ResourceServicesNodePorts] = resource.MustParse("1")
hard[api.ResourceServicesLoadBalancers] = resource.MustParse("1")
hard[api.ResourceReplicationControllers] = resource.MustParse("10")
hard[api.ResourceQuotas] = resource.MustParse("1")
hard[api.ResourceCPU] = resource.MustParse("1")