From 069745c1a857e7a1b99f5078732e38e4bd924f3b Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 16 Sep 2021 11:48:27 +0200 Subject: [PATCH] =?UTF-8?q?Use=20an=20Informer=20to=20list=20LimitRanges?= =?UTF-8?q?=20=F0=9F=A5=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a LimitRange lister here instead, so this doesn't end up hitting the real API server on each call. Taking into account a review : https://github.com/tektoncd/pipeline/pull/4176#issuecomment-920366660. Signed-off-by: Vincent Demeester --- pkg/internal/limitrange/limitrange.go | 21 ++-- .../core/v1/limitrange/limitrange.go | 106 ++++++++++++++++++ vendor/modules.txt | 1 + 3 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange/limitrange.go diff --git a/pkg/internal/limitrange/limitrange.go b/pkg/internal/limitrange/limitrange.go index af3c905fdeb..473d14289cc 100644 --- a/pkg/internal/limitrange/limitrange.go +++ b/pkg/internal/limitrange/limitrange.go @@ -20,23 +20,25 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" + limitrangeinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange" ) func getVirtualLimitRange(ctx context.Context, namespace string, c kubernetes.Interface) (*corev1.LimitRange, error) { - limitRanges, err := c.CoreV1().LimitRanges(namespace).List(ctx, metav1.ListOptions{}) + limitrangeInformer := limitrangeinformer.Get(ctx) + limitRanges, err := limitrangeInformer.Lister().LimitRanges(namespace).List(labels.Everything()) if err != nil { return nil, err } - var limitRange corev1.LimitRange + var limitRange *corev1.LimitRange switch { - case len(limitRanges.Items) == 0: + case len(limitRanges) == 0: // No LimitRange defined break - case len(limitRanges.Items) == 1: + case len(limitRanges) == 1: // One LimitRange defined - limitRange = limitRanges.Items[0] + limitRange = limitRanges[0] default: // Several LimitRange defined // Create a virtual LimitRange with @@ -45,8 +47,9 @@ func getVirtualLimitRange(ctx context.Context, namespace string, c kubernetes.In // - Default that "fits" into min/max taken above // - Default request that "fits" into min/max taken above // - Smallest ratio (aka the most restrictive one) + limitRange = &corev1.LimitRange{} m := map[corev1.LimitType]corev1.LimitRangeItem{} - for _, lr := range limitRanges.Items { + for _, lr := range limitRanges { for _, item := range lr.Spec.Limits { _, exists := m[item.Type] if !exists { @@ -74,7 +77,7 @@ func getVirtualLimitRange(ctx context.Context, namespace string, c kubernetes.In } } // Handle Default and DefaultRequest - for _, lr := range limitRanges.Items { + for _, lr := range limitRanges { for _, item := range lr.Spec.Limits { // Default m[item.Type].Default[corev1.ResourceCPU] = minOfBetween(m[item.Type].Default[corev1.ResourceCPU], item.Default[corev1.ResourceCPU], m[item.Type].Min[corev1.ResourceCPU], m[item.Type].Max[corev1.ResourceCPU]) @@ -90,7 +93,7 @@ func getVirtualLimitRange(ctx context.Context, namespace string, c kubernetes.In limitRange.Spec.Limits = append(limitRange.Spec.Limits, v) } } - return &limitRange, nil + return limitRange, nil } func maxOf(a, b resource.Quantity) resource.Quantity { diff --git a/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange/limitrange.go b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange/limitrange.go new file mode 100644 index 00000000000..d86077f7db7 --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange/limitrange.go @@ -0,0 +1,106 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package limitrange + +import ( + context "context" + + apicorev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/client-go/informers/core/v1" + kubernetes "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" + client "knative.dev/pkg/client/injection/kube/client" + factory "knative.dev/pkg/client/injection/kube/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) + injection.Dynamic.RegisterDynamicInformer(withDynamicInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Core().V1().LimitRanges() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +func withDynamicInformer(ctx context.Context) context.Context { + inf := &wrapper{client: client.Get(ctx)} + return context.WithValue(ctx, Key{}, inf) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1.LimitRangeInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch k8s.io/client-go/informers/core/v1.LimitRangeInformer from context.") + } + return untyped.(v1.LimitRangeInformer) +} + +type wrapper struct { + client kubernetes.Interface + + namespace string +} + +var _ v1.LimitRangeInformer = (*wrapper)(nil) +var _ corev1.LimitRangeLister = (*wrapper)(nil) + +func (w *wrapper) Informer() cache.SharedIndexInformer { + return cache.NewSharedIndexInformer(nil, &apicorev1.LimitRange{}, 0, nil) +} + +func (w *wrapper) Lister() corev1.LimitRangeLister { + return w +} + +func (w *wrapper) LimitRanges(namespace string) corev1.LimitRangeNamespaceLister { + return &wrapper{client: w.client, namespace: namespace} +} + +func (w *wrapper) List(selector labels.Selector) (ret []*apicorev1.LimitRange, err error) { + lo, err := w.client.CoreV1().LimitRanges(w.namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: selector.String(), + // TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria. + }) + if err != nil { + return nil, err + } + for idx := range lo.Items { + ret = append(ret, &lo.Items[idx]) + } + return ret, nil +} + +func (w *wrapper) Get(name string) (*apicorev1.LimitRange, error) { + return w.client.CoreV1().LimitRanges(w.namespace).Get(context.TODO(), name, metav1.GetOptions{ + // TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria. + }) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8bffb17a773..ddc609915ad 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -937,6 +937,7 @@ knative.dev/pkg/client/injection/kube/informers/admissionregistration/v1/mutatin knative.dev/pkg/client/injection/kube/informers/admissionregistration/v1/validatingwebhookconfiguration knative.dev/pkg/client/injection/kube/informers/core/v1/configmap knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/fake +knative.dev/pkg/client/injection/kube/informers/core/v1/limitrange knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered/fake knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount