From f8b36bdd40dfac6b75dad6d21bfd3813d706c965 Mon Sep 17 00:00:00 2001 From: Chao Xu Date: Fri, 18 Nov 2016 13:23:02 -0800 Subject: [PATCH] TRICKY: dependencies: pkg/quota --- pkg/quota/evaluator/core/BUILD | 10 +-- pkg/quota/evaluator/core/configmap.go | 5 +- .../core/persistent_volume_claims.go | 23 ++++--- .../core/persistent_volume_claims_test.go | 2 +- pkg/quota/evaluator/core/pods.go | 47 ++++++++------ pkg/quota/evaluator/core/pods_test.go | 2 +- pkg/quota/evaluator/core/registry.go | 2 +- .../evaluator/core/replication_controllers.go | 5 +- pkg/quota/evaluator/core/resource_quotas.go | 5 +- pkg/quota/evaluator/core/secrets.go | 5 +- pkg/quota/evaluator/core/services.go | 61 +++++++++++-------- pkg/quota/evaluator/core/services_test.go | 2 +- pkg/quota/generic/BUILD | 2 +- pkg/quota/generic/evaluator.go | 15 +++-- pkg/quota/install/BUILD | 6 +- pkg/quota/install/registry.go | 2 +- pkg/quota/resources.go | 24 ++++++++ 17 files changed, 142 insertions(+), 76 deletions(-) diff --git a/pkg/quota/evaluator/core/BUILD b/pkg/quota/evaluator/core/BUILD index 26cd8d9ade..4a8d147d21 100644 --- a/pkg/quota/evaluator/core/BUILD +++ b/pkg/quota/evaluator/core/BUILD @@ -30,11 +30,11 @@ go_library( "//pkg/api/resource:go_default_library", "//pkg/api/unversioned:go_default_library", "//pkg/api/validation:go_default_library", - "//pkg/client/clientset_generated/internalclientset:go_default_library", + "//pkg/client/clientset_generated/release_1_5:go_default_library", "//pkg/controller/informers:go_default_library", "//pkg/kubelet/qos:go_default_library", - "//pkg/quota:go_default_library", - "//pkg/quota/generic:go_default_library", + "//pkg/quotainternal:go_default_library", + "//pkg/quotainternal/generic:go_default_library", "//pkg/runtime:go_default_library", "//pkg/util/sets:go_default_library", "//pkg/util/validation/field:go_default_library", @@ -54,7 +54,7 @@ go_test( "//pkg/api:go_default_library", "//pkg/api/resource:go_default_library", "//pkg/api/unversioned:go_default_library", - "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", - "//pkg/quota:go_default_library", + "//pkg/client/clientset_generated/release_1_5/fake:go_default_library", + "//pkg/quotainternal:go_default_library", ], ) diff --git a/pkg/quota/evaluator/core/configmap.go b/pkg/quota/evaluator/core/configmap.go index 3358df60f3..476537f95d 100644 --- a/pkg/quota/evaluator/core/configmap.go +++ b/pkg/quota/evaluator/core/configmap.go @@ -19,7 +19,8 @@ package core import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" @@ -38,7 +39,7 @@ func NewConfigMapEvaluator(kubeClient clientset.Interface) quota.Evaluator { MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceConfigMaps), UsageFunc: generic.ObjectCountUsageFunc(api.ResourceConfigMaps), - ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().ConfigMaps(namespace).List(options) if err != nil { return nil, err diff --git a/pkg/quota/evaluator/core/persistent_volume_claims.go b/pkg/quota/evaluator/core/persistent_volume_claims.go index fc1fc6ab20..e3c1e033e8 100644 --- a/pkg/quota/evaluator/core/persistent_volume_claims.go +++ b/pkg/quota/evaluator/core/persistent_volume_claims.go @@ -24,7 +24,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" @@ -37,7 +38,7 @@ func listPersistentVolumeClaimsByNamespaceFuncUsingClient(kubeClient clientset.I // TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this. // unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require // structured objects. - return func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().PersistentVolumeClaims(namespace).List(options) if err != nil { return nil, err @@ -75,13 +76,21 @@ func NewPersistentVolumeClaimEvaluator(kubeClient clientset.Interface, f informe // 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{} + var found bool + var request resource.Quantity + + switch t := object.(type) { + case *v1.PersistentVolumeClaim: + request, found = t.Spec.Resources.Requests[v1.ResourceStorage] + case *api.PersistentVolumeClaim: + request, found = t.Spec.Resources.Requests[api.ResourceStorage] + default: + panic(fmt.Sprintf("expect *api.PersistenVolumeClaim or *v1.PersistentVolumeClaim, got %v", t)) + } + result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1") - if request, found := pvc.Spec.Resources.Requests[api.ResourceStorage]; found { + if found { result[api.ResourceRequestsStorage] = request } return result diff --git a/pkg/quota/evaluator/core/persistent_volume_claims_test.go b/pkg/quota/evaluator/core/persistent_volume_claims_test.go index 775e3df4fb..7d24ba38dd 100644 --- a/pkg/quota/evaluator/core/persistent_volume_claims_test.go +++ b/pkg/quota/evaluator/core/persistent_volume_claims_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake" "k8s.io/kubernetes/pkg/quota" ) diff --git a/pkg/quota/evaluator/core/pods.go b/pkg/quota/evaluator/core/pods.go index 4d5d8ea75d..c270211128 100644 --- a/pkg/quota/evaluator/core/pods.go +++ b/pkg/quota/evaluator/core/pods.go @@ -24,8 +24,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/validation" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/quota" @@ -40,7 +41,7 @@ func listPodsByNamespaceFuncUsingClient(kubeClient clientset.Interface) generic. // TODO: ideally, we could pass dynamic client pool down into this code, and have one way of doing this. // unfortunately, dynamic client works with Unstructured objects, and when we calculate Usage, we require // structured objects. - return func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().Pods(namespace).List(options) if err != nil { return nil, err @@ -163,23 +164,32 @@ func podUsageHelper(requests api.ResourceList, limits api.ResourceList) api.Reso return result } -// PodUsageFunc knows how to measure usage associated with pods -func PodUsageFunc(object runtime.Object) api.ResourceList { - pod, ok := object.(*api.Pod) - if !ok { - return api.ResourceList{} +func toInternalPodOrDie(obj runtime.Object) *api.Pod { + pod := &api.Pod{} + switch t := obj.(type) { + case *v1.Pod: + if err := v1.Convert_v1_Pod_To_api_Pod(t, pod, nil); err != nil { + panic(err) + } + case *api.Pod: + pod = t + default: + panic(fmt.Sprintf("expect *api.Pod or *v1.Pod, got %v", t)) } + return pod +} +// PodUsageFunc knows how to measure usage associated with pods +func PodUsageFunc(obj runtime.Object) api.ResourceList { + pod := toInternalPodOrDie(obj) // by convention, we do not quota pods that have reached an end-of-life state if !QuotaPod(pod) { return api.ResourceList{} } - - // TODO: fix this when we have pod level cgroups - // when we have pod level cgroups, we can just read pod level requests/limits requests := api.ResourceList{} limits := api.ResourceList{} - + // TODO: fix this when we have pod level cgroups + // when we have pod level cgroups, we can just read pod level requests/limits for i := range pod.Spec.Containers { requests = quota.Add(requests, pod.Spec.Containers[i].Resources.Requests) limits = quota.Add(limits, pod.Spec.Containers[i].Resources.Limits) @@ -197,10 +207,7 @@ func PodUsageFunc(object runtime.Object) api.ResourceList { // PodMatchesScopeFunc is a function that knows how to evaluate if a pod matches a scope func PodMatchesScopeFunc(scope api.ResourceQuotaScope, object runtime.Object) bool { - pod, ok := object.(*api.Pod) - if !ok { - return false - } + pod := toInternalPodOrDie(object) switch scope { case api.ResourceQuotaScopeTerminating: return isTerminating(pod) @@ -215,7 +222,7 @@ func PodMatchesScopeFunc(scope api.ResourceQuotaScope, object runtime.Object) bo } func isBestEffort(pod *api.Pod) bool { - return qos.GetPodQOS(pod) == qos.BestEffort + return qos.InternalGetPodQOS(pod) == qos.BestEffort } func isTerminating(pod *api.Pod) bool { @@ -228,7 +235,11 @@ func isTerminating(pod *api.Pod) bool { // QuotaPod returns true if the pod is eligible to track against a quota // if it's not in a terminal state according to its phase. func QuotaPod(pod *api.Pod) bool { - // see GetPhase in kubelet.go for details on how it covers all restart policy conditions - // https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kubelet.go#L3001 return !(api.PodFailed == pod.Status.Phase || api.PodSucceeded == pod.Status.Phase) } + +// QuotaV1Pod returns true if the pod is eligible to track against a quota +// if it's not in a terminal state according to its phase. +func QuotaV1Pod(pod *v1.Pod) bool { + return !(v1.PodFailed == pod.Status.Phase || v1.PodSucceeded == pod.Status.Phase) +} diff --git a/pkg/quota/evaluator/core/pods_test.go b/pkg/quota/evaluator/core/pods_test.go index 32c454fb4d..79ed8783e1 100644 --- a/pkg/quota/evaluator/core/pods_test.go +++ b/pkg/quota/evaluator/core/pods_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake" "k8s.io/kubernetes/pkg/quota" ) diff --git a/pkg/quota/evaluator/core/registry.go b/pkg/quota/evaluator/core/registry.go index 7768848abd..093a61798d 100644 --- a/pkg/quota/evaluator/core/registry.go +++ b/pkg/quota/evaluator/core/registry.go @@ -18,7 +18,7 @@ package core import ( "k8s.io/kubernetes/pkg/api/unversioned" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" diff --git a/pkg/quota/evaluator/core/replication_controllers.go b/pkg/quota/evaluator/core/replication_controllers.go index c95da8c34d..bf1c63e971 100644 --- a/pkg/quota/evaluator/core/replication_controllers.go +++ b/pkg/quota/evaluator/core/replication_controllers.go @@ -19,7 +19,8 @@ package core import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" @@ -38,7 +39,7 @@ func NewReplicationControllerEvaluator(kubeClient clientset.Interface) quota.Eva MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceReplicationControllers), UsageFunc: generic.ObjectCountUsageFunc(api.ResourceReplicationControllers), - ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().ReplicationControllers(namespace).List(options) if err != nil { return nil, err diff --git a/pkg/quota/evaluator/core/resource_quotas.go b/pkg/quota/evaluator/core/resource_quotas.go index 5652ea5b54..6ea1fc28f4 100644 --- a/pkg/quota/evaluator/core/resource_quotas.go +++ b/pkg/quota/evaluator/core/resource_quotas.go @@ -19,7 +19,8 @@ package core import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" @@ -38,7 +39,7 @@ func NewResourceQuotaEvaluator(kubeClient clientset.Interface) quota.Evaluator { MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceQuotas), UsageFunc: generic.ObjectCountUsageFunc(api.ResourceQuotas), - ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().ResourceQuotas(namespace).List(options) if err != nil { return nil, err diff --git a/pkg/quota/evaluator/core/secrets.go b/pkg/quota/evaluator/core/secrets.go index 48676f35ab..d664480ea3 100644 --- a/pkg/quota/evaluator/core/secrets.go +++ b/pkg/quota/evaluator/core/secrets.go @@ -19,7 +19,8 @@ package core import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" @@ -38,7 +39,7 @@ func NewSecretEvaluator(kubeClient clientset.Interface) quota.Evaluator { MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: generic.ObjectCountConstraintsFunc(api.ResourceSecrets), UsageFunc: generic.ObjectCountUsageFunc(api.ResourceSecrets), - ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().Secrets(namespace).List(options) if err != nil { return nil, err diff --git a/pkg/quota/evaluator/core/services.go b/pkg/quota/evaluator/core/services.go index 3d07335f9f..d6a6378c9d 100644 --- a/pkg/quota/evaluator/core/services.go +++ b/pkg/quota/evaluator/core/services.go @@ -23,7 +23,8 @@ 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/api/v1" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" @@ -48,7 +49,7 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator { MatchesScopeFunc: generic.MatchesNoScopeFunc, ConstraintsFunc: ServiceConstraintsFunc, UsageFunc: ServiceUsageFunc, - ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + ListFuncByNamespace: func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { itemList, err := kubeClient.Core().Services(namespace).List(options) if err != nil { return nil, err @@ -65,42 +66,54 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator { // ServiceUsageFunc knows how to measure usage associated with services func ServiceUsageFunc(object runtime.Object) api.ResourceList { result := api.ResourceList{} - if service, ok := object.(*api.Service); ok { - // default service usage - result[api.ResourceServices] = resource.MustParse("1") - result[api.ResourceServicesLoadBalancers] = resource.MustParse("0") - result[api.ResourceServicesNodePorts] = resource.MustParse("0") - switch service.Spec.Type { - case api.ServiceTypeNodePort: - // node port services need to count node ports - value := resource.NewQuantity(int64(len(service.Spec.Ports)), resource.DecimalSI) - result[api.ResourceServicesNodePorts] = *value - case api.ServiceTypeLoadBalancer: - // load balancer services need to count load balancers - result[api.ResourceServicesLoadBalancers] = resource.MustParse("1") - } + var serviceType api.ServiceType + var ports int + + switch t := object.(type) { + case *v1.Service: + serviceType = api.ServiceType(t.Spec.Type) + ports = len(t.Spec.Ports) + case *api.Service: + serviceType = t.Spec.Type + ports = len(t.Spec.Ports) + default: + panic(fmt.Sprintf("expect *api.Service or *v1.Service, got %v", t)) + } + + // default service usage + result[api.ResourceServices] = resource.MustParse("1") + result[api.ResourceServicesLoadBalancers] = resource.MustParse("0") + result[api.ResourceServicesNodePorts] = resource.MustParse("0") + switch serviceType { + case api.ServiceTypeNodePort: + // node port services need to count node ports + value := resource.NewQuantity(int64(ports), resource.DecimalSI) + result[api.ResourceServicesNodePorts] = *value + case api.ServiceTypeLoadBalancer: + // load balancer services need to count load balancers + result[api.ResourceServicesLoadBalancers] = resource.MustParse("1") } return result } // QuotaServiceType returns true if the service type is eligible to track against a quota -func QuotaServiceType(service *api.Service) bool { +func QuotaServiceType(service *v1.Service) bool { switch service.Spec.Type { - case api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer: + case v1.ServiceTypeNodePort, v1.ServiceTypeLoadBalancer: return true } return false } //GetQuotaServiceType returns ServiceType if the service type is eligible to track against a quota, nor return "" -func GetQuotaServiceType(service *api.Service) api.ServiceType { +func GetQuotaServiceType(service *v1.Service) v1.ServiceType { switch service.Spec.Type { - case api.ServiceTypeNodePort: - return api.ServiceTypeNodePort - case api.ServiceTypeLoadBalancer: - return api.ServiceTypeLoadBalancer + case v1.ServiceTypeNodePort: + return v1.ServiceTypeNodePort + case v1.ServiceTypeLoadBalancer: + return v1.ServiceTypeLoadBalancer } - return api.ServiceType("") + return v1.ServiceType("") } // ServiceConstraintsFunc verifies that all required resources are captured in service usage. diff --git a/pkg/quota/evaluator/core/services_test.go b/pkg/quota/evaluator/core/services_test.go index fc0c5a5bec..d5f17955fd 100644 --- a/pkg/quota/evaluator/core/services_test.go +++ b/pkg/quota/evaluator/core/services_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake" "k8s.io/kubernetes/pkg/quota" ) diff --git a/pkg/quota/generic/BUILD b/pkg/quota/generic/BUILD index 7bad635e23..a33fd80eb4 100644 --- a/pkg/quota/generic/BUILD +++ b/pkg/quota/generic/BUILD @@ -24,7 +24,7 @@ go_library( "//pkg/api/unversioned:go_default_library", "//pkg/controller/informers:go_default_library", "//pkg/labels:go_default_library", - "//pkg/quota:go_default_library", + "//pkg/quotainternal:go_default_library", "//pkg/runtime:go_default_library", ], ) diff --git a/pkg/quota/generic/evaluator.go b/pkg/quota/generic/evaluator.go index 9c8bda66d3..554756f35e 100644 --- a/pkg/quota/generic/evaluator.go +++ b/pkg/quota/generic/evaluator.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/quota" @@ -31,12 +32,16 @@ import ( // ListResourceUsingInformerFunc returns a listing function based on the shared informer factory for the specified resource. func ListResourceUsingInformerFunc(f informers.SharedInformerFactory, groupResource unversioned.GroupResource) ListFuncByNamespace { - return func(namespace string, options api.ListOptions) ([]runtime.Object, error) { + return func(namespace string, options v1.ListOptions) ([]runtime.Object, error) { + labelSelector, err := labels.Parse(options.LabelSelector) + if err != nil { + return nil, err + } informer, err := f.ForResource(groupResource) if err != nil { return nil, err } - return informer.Lister().ByNamespace(namespace).List(options.LabelSelector) + return informer.Lister().ByNamespace(namespace).List(labelSelector) } } @@ -47,7 +52,7 @@ type ConstraintsFunc func(required []api.ResourceName, item runtime.Object) erro type GetFuncByNamespace func(namespace, name string) (runtime.Object, error) // ListFuncByNamespace knows how to list resources in a namespace -type ListFuncByNamespace func(namespace string, options api.ListOptions) ([]runtime.Object, error) +type ListFuncByNamespace func(namespace string, options v1.ListOptions) ([]runtime.Object, error) // MatchesScopeFunc knows how to evaluate if an object matches a scope type MatchesScopeFunc func(scope api.ResourceQuotaScope, object runtime.Object) bool @@ -183,8 +188,8 @@ func (g *GenericEvaluator) UsageStats(options quota.UsageStatsOptions) (quota.Us for _, resourceName := range g.MatchedResourceNames { result.Used[resourceName] = resource.MustParse("0") } - items, err := g.ListFuncByNamespace(options.Namespace, api.ListOptions{ - LabelSelector: labels.Everything(), + items, err := g.ListFuncByNamespace(options.Namespace, v1.ListOptions{ + LabelSelector: labels.Everything().String(), }) if err != nil { return result, fmt.Errorf("%s: Failed to list %v: %v", g.Name, g.GroupKind(), err) diff --git a/pkg/quota/install/BUILD b/pkg/quota/install/BUILD index 8055b14fa0..bf3f6c03e4 100644 --- a/pkg/quota/install/BUILD +++ b/pkg/quota/install/BUILD @@ -15,9 +15,9 @@ go_library( srcs = ["registry.go"], tags = ["automanaged"], deps = [ - "//pkg/client/clientset_generated/internalclientset:go_default_library", + "//pkg/client/clientset_generated/release_1_5:go_default_library", "//pkg/controller/informers:go_default_library", - "//pkg/quota:go_default_library", - "//pkg/quota/evaluator/core:go_default_library", + "//pkg/quotainternal:go_default_library", + "//pkg/quotainternal/evaluator/core:go_default_library", ], ) diff --git a/pkg/quota/install/registry.go b/pkg/quota/install/registry.go index 563702b441..0e910d42fe 100644 --- a/pkg/quota/install/registry.go +++ b/pkg/quota/install/registry.go @@ -17,7 +17,7 @@ limitations under the License. package install import ( - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/evaluator/core" diff --git a/pkg/quota/resources.go b/pkg/quota/resources.go index 94e0f6b3c9..4629faec5a 100644 --- a/pkg/quota/resources.go +++ b/pkg/quota/resources.go @@ -19,6 +19,7 @@ package quota import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/util/sets" ) @@ -45,6 +46,29 @@ func Equals(a api.ResourceList, b api.ResourceList) bool { return true } +// V1Equals returns true if the two lists are equivalent +func V1Equals(a v1.ResourceList, b v1.ResourceList) bool { + for key, value1 := range a { + value2, found := b[key] + if !found { + return false + } + if value1.Cmp(value2) != 0 { + return false + } + } + for key, value1 := range b { + value2, found := a[key] + if !found { + return false + } + if value1.Cmp(value2) != 0 { + return false + } + } + return true +} + // LessThanOrEqual returns true if a < b for each key in b // If false, it returns the keys in a that exceeded b func LessThanOrEqual(a api.ResourceList, b api.ResourceList) (bool, []api.ResourceName) {