mirror of https://github.com/k3s-io/k3s
quota controller uses informers if available for pod calculation
parent
35bdb1ee46
commit
1bcb057636
|
@ -323,7 +323,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl
|
|||
}
|
||||
|
||||
resourceQuotaControllerClient := client("resourcequota-controller")
|
||||
resourceQuotaRegistry := quotainstall.NewRegistry(resourceQuotaControllerClient)
|
||||
resourceQuotaRegistry := quotainstall.NewRegistry(resourceQuotaControllerClient, sharedInformers)
|
||||
groupKindsToReplenish := []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("Service"),
|
||||
|
@ -336,7 +336,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl
|
|||
KubeClient: resourceQuotaControllerClient,
|
||||
ResyncPeriod: controller.StaticResyncPeriodFunc(s.ResourceQuotaSyncPeriod.Duration),
|
||||
Registry: resourceQuotaRegistry,
|
||||
ControllerFactory: resourcequotacontroller.NewReplenishmentControllerFactory(sharedInformers.Pods().Informer(), resourceQuotaControllerClient),
|
||||
ControllerFactory: resourcequotacontroller.NewReplenishmentControllerFactory(sharedInformers, resourceQuotaControllerClient),
|
||||
ReplenishmentResyncPeriod: ResyncPeriod(s),
|
||||
GroupKindsToReplenish: groupKindsToReplenish,
|
||||
}
|
||||
|
|
|
@ -94,19 +94,21 @@ type ReplenishmentControllerFactory interface {
|
|||
|
||||
// replenishmentControllerFactory implements ReplenishmentControllerFactory
|
||||
type replenishmentControllerFactory struct {
|
||||
kubeClient clientset.Interface
|
||||
podInformer cache.SharedInformer
|
||||
kubeClient clientset.Interface
|
||||
sharedInformerFactory informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
// NewReplenishmentControllerFactory returns a factory that knows how to build controllers
|
||||
// to replenish resources when updated or deleted
|
||||
func NewReplenishmentControllerFactory(podInformer cache.SharedInformer, kubeClient clientset.Interface) ReplenishmentControllerFactory {
|
||||
func NewReplenishmentControllerFactory(f informers.SharedInformerFactory, kubeClient clientset.Interface) ReplenishmentControllerFactory {
|
||||
return &replenishmentControllerFactory{
|
||||
kubeClient: kubeClient,
|
||||
podInformer: podInformer,
|
||||
kubeClient: kubeClient,
|
||||
sharedInformerFactory: f,
|
||||
}
|
||||
}
|
||||
|
||||
// NewReplenishmentControllerFactoryFromClient returns a factory that knows how to build controllers to replenish resources
|
||||
// when updated or deleted using the specified client.
|
||||
func NewReplenishmentControllerFactoryFromClient(kubeClient clientset.Interface) ReplenishmentControllerFactory {
|
||||
return NewReplenishmentControllerFactory(nil, kubeClient)
|
||||
}
|
||||
|
@ -119,18 +121,16 @@ func (r *replenishmentControllerFactory) NewController(options *ReplenishmentCon
|
|||
|
||||
switch options.GroupKind {
|
||||
case api.Kind("Pod"):
|
||||
if r.podInformer != nil {
|
||||
r.podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
if r.sharedInformerFactory != nil {
|
||||
podInformer := r.sharedInformerFactory.Pods().Informer()
|
||||
podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
UpdateFunc: PodReplenishmentUpdateFunc(options),
|
||||
DeleteFunc: ObjectReplenishmentDeleteFunc(options),
|
||||
})
|
||||
result = r.podInformer.GetController()
|
||||
result = podInformer.GetController()
|
||||
break
|
||||
}
|
||||
|
||||
r.podInformer = informers.NewPodInformer(r.kubeClient, options.ResyncPeriod())
|
||||
result = r.podInformer
|
||||
|
||||
result = informers.NewPodInformer(r.kubeClient, options.ResyncPeriod())
|
||||
case api.Kind("Service"):
|
||||
_, result = cache.NewInformer(
|
||||
&cache.ListWatch{
|
||||
|
|
|
@ -107,7 +107,7 @@ func TestSyncResourceQuota(t *testing.T) {
|
|||
resourceQuotaControllerOptions := &ResourceQuotaControllerOptions{
|
||||
KubeClient: kubeClient,
|
||||
ResyncPeriod: controller.NoResyncPeriodFunc,
|
||||
Registry: install.NewRegistry(kubeClient),
|
||||
Registry: install.NewRegistry(kubeClient, nil),
|
||||
GroupKindsToReplenish: []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("Service"),
|
||||
|
@ -192,7 +192,7 @@ func TestSyncResourceQuotaSpecChange(t *testing.T) {
|
|||
resourceQuotaControllerOptions := &ResourceQuotaControllerOptions{
|
||||
KubeClient: kubeClient,
|
||||
ResyncPeriod: controller.NoResyncPeriodFunc,
|
||||
Registry: install.NewRegistry(kubeClient),
|
||||
Registry: install.NewRegistry(kubeClient, nil),
|
||||
GroupKindsToReplenish: []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("Service"),
|
||||
|
@ -280,7 +280,7 @@ func TestSyncResourceQuotaSpecHardChange(t *testing.T) {
|
|||
resourceQuotaControllerOptions := &ResourceQuotaControllerOptions{
|
||||
KubeClient: kubeClient,
|
||||
ResyncPeriod: controller.NoResyncPeriodFunc,
|
||||
Registry: install.NewRegistry(kubeClient),
|
||||
Registry: install.NewRegistry(kubeClient, nil),
|
||||
GroupKindsToReplenish: []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("Service"),
|
||||
|
@ -368,7 +368,7 @@ func TestSyncResourceQuotaNoChange(t *testing.T) {
|
|||
resourceQuotaControllerOptions := &ResourceQuotaControllerOptions{
|
||||
KubeClient: kubeClient,
|
||||
ResyncPeriod: controller.NoResyncPeriodFunc,
|
||||
Registry: install.NewRegistry(kubeClient),
|
||||
Registry: install.NewRegistry(kubeClient, nil),
|
||||
GroupKindsToReplenish: []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("Service"),
|
||||
|
@ -400,7 +400,7 @@ func TestAddQuota(t *testing.T) {
|
|||
resourceQuotaControllerOptions := &ResourceQuotaControllerOptions{
|
||||
KubeClient: kubeClient,
|
||||
ResyncPeriod: controller.NoResyncPeriodFunc,
|
||||
Registry: install.NewRegistry(kubeClient),
|
||||
Registry: install.NewRegistry(kubeClient, nil),
|
||||
GroupKindsToReplenish: []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
api.Kind("ReplicationController"),
|
||||
|
|
|
@ -31,6 +31,7 @@ go_library(
|
|||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset: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",
|
||||
|
|
|
@ -38,8 +38,16 @@ 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) {
|
||||
return kubeClient.Core().ConfigMaps(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().ConfigMaps(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,16 @@ func NewPersistentVolumeClaimEvaluator(kubeClient clientset.Interface) quota.Eva
|
|||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||
ConstraintsFunc: PersistentVolumeClaimConstraintsFunc,
|
||||
UsageFunc: PersistentVolumeClaimUsageFunc,
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) (runtime.Object, error) {
|
||||
return kubeClient.Core().PersistentVolumeClaims(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().PersistentVolumeClaims(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,10 @@ import (
|
|||
"k8s.io/kubernetes/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/quota/generic"
|
||||
|
@ -33,8 +35,27 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// listPodsByNamespaceFuncUsingClient returns a pod listing function based on the provided client.
|
||||
func listPodsByNamespaceFuncUsingClient(kubeClient clientset.Interface) generic.ListFuncByNamespace {
|
||||
// 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) {
|
||||
itemList, err := kubeClient.Core().Pods(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewPodEvaluator returns an evaluator that can evaluate pods
|
||||
func NewPodEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
||||
// if the specified shared informer factory is not nil, evaluator may use it to support listing functions.
|
||||
func NewPodEvaluator(kubeClient clientset.Interface, f informers.SharedInformerFactory) quota.Evaluator {
|
||||
computeResources := []api.ResourceName{
|
||||
api.ResourceCPU,
|
||||
api.ResourceMemory,
|
||||
|
@ -44,6 +65,10 @@ func NewPodEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||
api.ResourceLimitsMemory,
|
||||
}
|
||||
allResources := append(computeResources, api.ResourcePods)
|
||||
listFuncByNamespace := listPodsByNamespaceFuncUsingClient(kubeClient)
|
||||
if f != nil {
|
||||
listFuncByNamespace = generic.ListResourceUsingInformerFunc(f, unversioned.GroupResource{Resource: "pods"})
|
||||
}
|
||||
return &generic.GenericEvaluator{
|
||||
Name: "Evaluator.Pod",
|
||||
InternalGroupKind: api.Kind("Pod"),
|
||||
|
@ -59,9 +84,7 @@ func NewPodEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||
MatchedResourceNames: allResources,
|
||||
MatchesScopeFunc: PodMatchesScopeFunc,
|
||||
UsageFunc: PodUsageFunc,
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) (runtime.Object, error) {
|
||||
return kubeClient.Core().Pods(namespace).List(options)
|
||||
},
|
||||
ListFuncByNamespace: listFuncByNamespace,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ func TestPodConstraintsFunc(t *testing.T) {
|
|||
|
||||
func TestPodEvaluatorUsage(t *testing.T) {
|
||||
kubeClient := fake.NewSimpleClientset()
|
||||
evaluator := NewPodEvaluator(kubeClient)
|
||||
evaluator := NewPodEvaluator(kubeClient, nil)
|
||||
testCases := map[string]struct {
|
||||
pod *api.Pod
|
||||
usage api.ResourceList
|
||||
|
|
|
@ -19,13 +19,15 @@ package core
|
|||
import (
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/quota/generic"
|
||||
)
|
||||
|
||||
// NewRegistry returns a registry that knows how to deal with core kubernetes resources
|
||||
func NewRegistry(kubeClient clientset.Interface) quota.Registry {
|
||||
pod := NewPodEvaluator(kubeClient)
|
||||
// If an informer factory is provided, evaluators will use them.
|
||||
func NewRegistry(kubeClient clientset.Interface, f informers.SharedInformerFactory) quota.Registry {
|
||||
pod := NewPodEvaluator(kubeClient, f)
|
||||
service := NewServiceEvaluator(kubeClient)
|
||||
replicationController := NewReplicationControllerEvaluator(kubeClient)
|
||||
resourceQuota := NewResourceQuotaEvaluator(kubeClient)
|
||||
|
|
|
@ -38,8 +38,16 @@ 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) {
|
||||
return kubeClient.Core().ReplicationControllers(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().ReplicationControllers(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,16 @@ 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) {
|
||||
return kubeClient.Core().ResourceQuotas(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().ResourceQuotas(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,16 @@ 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) {
|
||||
return kubeClient.Core().Secrets(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().Secrets(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,16 @@ func NewServiceEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
|||
MatchesScopeFunc: generic.MatchesNoScopeFunc,
|
||||
ConstraintsFunc: ServiceConstraintsFunc,
|
||||
UsageFunc: ServiceUsageFunc,
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) (runtime.Object, error) {
|
||||
return kubeClient.Core().Services(namespace).List(options)
|
||||
ListFuncByNamespace: func(namespace string, options api.ListOptions) ([]runtime.Object, error) {
|
||||
itemList, err := kubeClient.Core().Services(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := make([]runtime.Object, 0, len(itemList.Items))
|
||||
for i := range itemList.Items {
|
||||
results = append(results, &itemList.Items[i])
|
||||
}
|
||||
return results, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,10 @@ go_library(
|
|||
deps = [
|
||||
"//pkg/admission:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/quota:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
],
|
||||
|
|
|
@ -21,13 +21,25 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
informer, err := f.ForResource(groupResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return informer.Lister().ByNamespace(namespace).List(options.LabelSelector)
|
||||
}
|
||||
}
|
||||
|
||||
// ConstraintsFunc takes a list of required resources that must match on the input item
|
||||
type ConstraintsFunc func(required []api.ResourceName, item runtime.Object) error
|
||||
|
||||
|
@ -35,7 +47,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 api.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
|
||||
|
@ -171,18 +183,12 @@ func (g *GenericEvaluator) UsageStats(options quota.UsageStatsOptions) (quota.Us
|
|||
for _, resourceName := range g.MatchedResourceNames {
|
||||
result.Used[resourceName] = resource.MustParse("0")
|
||||
}
|
||||
list, err := g.ListFuncByNamespace(options.Namespace, api.ListOptions{})
|
||||
items, err := g.ListFuncByNamespace(options.Namespace, api.ListOptions{
|
||||
LabelSelector: labels.Everything(),
|
||||
})
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("%s: Failed to list %v: %v", g.Name, g.GroupKind(), err)
|
||||
}
|
||||
_, err = meta.ListAccessor(list)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("%s: Unable to understand list result, does not appear to be a list %#v", g.Name, list)
|
||||
}
|
||||
items, err := meta.ExtractList(list)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("%s: Unable to understand list result %#v (%v)", g.Name, list, err)
|
||||
}
|
||||
for _, item := range items {
|
||||
// need to verify that the item matches the set of scopes
|
||||
matchesScopes := true
|
||||
|
|
|
@ -16,6 +16,7 @@ go_library(
|
|||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/controller/informers:go_default_library",
|
||||
"//pkg/quota:go_default_library",
|
||||
"//pkg/quota/evaluator/core:go_default_library",
|
||||
],
|
||||
|
|
|
@ -18,13 +18,14 @@ package install
|
|||
|
||||
import (
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
"k8s.io/kubernetes/pkg/quota/evaluator/core"
|
||||
)
|
||||
|
||||
// NewRegistry returns a registry that knows how to deal kubernetes resources
|
||||
// across API groups
|
||||
func NewRegistry(kubeClient clientset.Interface) quota.Registry {
|
||||
// NewRegistry returns a registry of quota evaluators.
|
||||
// If a shared informer factory is provided, it is used by evaluators rather than performing direct queries.
|
||||
func NewRegistry(kubeClient clientset.Interface, f informers.SharedInformerFactory) quota.Registry {
|
||||
// TODO: when quota supports resources in other api groups, we will need to merge
|
||||
return core.NewRegistry(kubeClient)
|
||||
return core.NewRegistry(kubeClient, f)
|
||||
}
|
||||
|
|
|
@ -31,8 +31,9 @@ import (
|
|||
func init() {
|
||||
admission.RegisterPlugin("ResourceQuota",
|
||||
func(client clientset.Interface, config io.Reader) (admission.Interface, error) {
|
||||
registry := install.NewRegistry(client)
|
||||
// TODO: expose a stop channel in admission factory
|
||||
// NOTE: we do not provide informers to the registry because admission level decisions
|
||||
// does not require us to open watches for all items tracked by quota.
|
||||
registry := install.NewRegistry(client, nil)
|
||||
return NewResourceQuota(client, registry, 5, make(chan struct{}))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
|
|||
kubeClient := fake.NewSimpleClientset()
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
handler, err := NewResourceQuota(kubeClient, install.NewRegistry(kubeClient), 5, stopCh)
|
||||
handler, err := NewResourceQuota(kubeClient, install.NewRegistry(kubeClient, nil), 5, stopCh)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ func TestAdmissionIgnoresSubresources(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -201,7 +201,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -283,7 +283,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -379,7 +379,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -472,7 +472,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -515,7 +515,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -568,7 +568,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) {
|
|||
quotaAccessor.indexer = indexer
|
||||
quotaAccessor.liveLookupCache = liveLookupCache
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -633,7 +633,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -737,7 +737,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -828,7 +828,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -945,7 +945,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
evaluator.(*quotaEvaluator).registry = registry
|
||||
|
||||
handler := "aAdmission{
|
||||
|
@ -990,7 +990,7 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
@ -1035,7 +1035,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
|
|||
quotaAccessor, _ := newQuotaAccessor(kubeClient)
|
||||
quotaAccessor.indexer = indexer
|
||||
go quotaAccessor.Run(stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient), nil, 5, stopCh)
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, install.NewRegistry(kubeClient, nil), nil, 5, stopCh)
|
||||
|
||||
handler := "aAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
|
|
|
@ -64,7 +64,7 @@ func TestQuota(t *testing.T) {
|
|||
|
||||
admissionCh := make(chan struct{})
|
||||
clientset := clientset.NewForConfigOrDie(&restclient.Config{QPS: -1, Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion}})
|
||||
admission, err := resourcequota.NewResourceQuota(clientset, quotainstall.NewRegistry(clientset), 5, admissionCh)
|
||||
admission, err := resourcequota.NewResourceQuota(clientset, quotainstall.NewRegistry(clientset, nil), 5, admissionCh)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func TestQuota(t *testing.T) {
|
|||
go replicationcontroller.NewReplicationManagerFromClientForIntegration(clientset, controller.NoResyncPeriodFunc, replicationcontroller.BurstReplicas, 4096).
|
||||
Run(3, controllerCh)
|
||||
|
||||
resourceQuotaRegistry := quotainstall.NewRegistry(clientset)
|
||||
resourceQuotaRegistry := quotainstall.NewRegistry(clientset, nil)
|
||||
groupKindsToReplenish := []unversioned.GroupKind{
|
||||
api.Kind("Pod"),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue