Commit b86e8f76 authored by yue9944882's avatar yue9944882

externalize quota admission controller

parent 444373b4
...@@ -17,19 +17,16 @@ go_library( ...@@ -17,19 +17,16 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/plugin/pkg/admission/resourcequota", importpath = "k8s.io/kubernetes/plugin/pkg/admission/resourcequota",
deps = [ deps = [
"//pkg/apis/core:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission:go_default_library",
"//pkg/quota:go_default_library", "//pkg/quota/v1:go_default_library",
"//pkg/quota/generic:go_default_library", "//pkg/quota/v1/generic:go_default_library",
"//pkg/util/reflector/prometheus:go_default_library", "//pkg/util/reflector/prometheus:go_default_library",
"//pkg/util/workqueue/prometheus:go_default_library", "//pkg/util/workqueue/prometheus:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota/install:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota/install:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota/validation:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota/validation:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
...@@ -41,7 +38,11 @@ go_library( ...@@ -41,7 +38,11 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/etcd:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/etcd:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library", "//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/hashicorp/golang-lru:go_default_library", "//vendor/github.com/hashicorp/golang-lru:go_default_library",
...@@ -54,17 +55,18 @@ go_test( ...@@ -54,17 +55,18 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/quota/generic:go_default_library", "//pkg/quota/v1/generic:go_default_library",
"//pkg/quota/install:go_default_library", "//pkg/quota/v1/install:go_default_library",
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library", "//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/github.com/hashicorp/golang-lru:go_default_library", "//vendor/github.com/hashicorp/golang-lru:go_default_library",
......
...@@ -21,13 +21,14 @@ import ( ...@@ -21,13 +21,14 @@ import (
"io" "io"
"time" "time"
corev1 "k8s.io/api/core/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
api "k8s.io/kubernetes/pkg/apis/core" genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/client-go/informers"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" "k8s.io/client-go/kubernetes"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
"k8s.io/kubernetes/pkg/quota" quota "k8s.io/kubernetes/pkg/quota/v1"
"k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/quota/v1/generic"
resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota" resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota"
"k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation" "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation"
) )
...@@ -65,12 +66,13 @@ type QuotaAdmission struct { ...@@ -65,12 +66,13 @@ type QuotaAdmission struct {
} }
var _ admission.ValidationInterface = &QuotaAdmission{} var _ admission.ValidationInterface = &QuotaAdmission{}
var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&QuotaAdmission{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&QuotaAdmission{})
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&QuotaAdmission{})
var _ = kubeapiserveradmission.WantsQuotaConfiguration(&QuotaAdmission{}) var _ = kubeapiserveradmission.WantsQuotaConfiguration(&QuotaAdmission{})
type liveLookupEntry struct { type liveLookupEntry struct {
expiry time.Time expiry time.Time
items []*api.ResourceQuota items []*corev1.ResourceQuota
} }
// NewResourceQuota configures an admission controller that can enforce quota constraints // NewResourceQuota configures an admission controller that can enforce quota constraints
...@@ -91,12 +93,12 @@ func NewResourceQuota(config *resourcequotaapi.Configuration, numEvaluators int, ...@@ -91,12 +93,12 @@ func NewResourceQuota(config *resourcequotaapi.Configuration, numEvaluators int,
}, nil }, nil
} }
func (a *QuotaAdmission) SetInternalKubeClientSet(client internalclientset.Interface) { func (a *QuotaAdmission) SetExternalKubeClientSet(client kubernetes.Interface) {
a.quotaAccessor.client = client a.quotaAccessor.client = client
} }
func (a *QuotaAdmission) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { func (a *QuotaAdmission) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
a.quotaAccessor.lister = f.Core().InternalVersion().ResourceQuotas().Lister() a.quotaAccessor.lister = f.Core().V1().ResourceQuotas().Lister()
} }
func (a *QuotaAdmission) SetQuotaConfiguration(c quota.Configuration) { func (a *QuotaAdmission) SetQuotaConfiguration(c quota.Configuration) {
......
...@@ -20,14 +20,14 @@ import ( ...@@ -20,14 +20,14 @@ import (
"fmt" "fmt"
"time" "time"
lru "github.com/hashicorp/golang-lru" "github.com/hashicorp/golang-lru"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apiserver/pkg/storage/etcd" "k8s.io/apiserver/pkg/storage/etcd"
api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/client-go/kubernetes"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" corev1listers "k8s.io/client-go/listers/core/v1"
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
) )
// QuotaAccessor abstracts the get/set logic from the rest of the Evaluator. This could be a test stub, a straight passthrough, // QuotaAccessor abstracts the get/set logic from the rest of the Evaluator. This could be a test stub, a straight passthrough,
...@@ -35,17 +35,17 @@ import ( ...@@ -35,17 +35,17 @@ import (
type QuotaAccessor interface { type QuotaAccessor interface {
// UpdateQuotaStatus is called to persist final status. This method should write to persistent storage. // UpdateQuotaStatus is called to persist final status. This method should write to persistent storage.
// An error indicates that write didn't complete successfully. // An error indicates that write didn't complete successfully.
UpdateQuotaStatus(newQuota *api.ResourceQuota) error UpdateQuotaStatus(newQuota *corev1.ResourceQuota) error
// GetQuotas gets all possible quotas for a given namespace // GetQuotas gets all possible quotas for a given namespace
GetQuotas(namespace string) ([]api.ResourceQuota, error) GetQuotas(namespace string) ([]corev1.ResourceQuota, error)
} }
type quotaAccessor struct { type quotaAccessor struct {
client clientset.Interface client kubernetes.Interface
// lister can list/get quota objects from a shared informer's cache // lister can list/get quota objects from a shared informer's cache
lister corelisters.ResourceQuotaLister lister corev1listers.ResourceQuotaLister
// liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures. // liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures.
// This lets us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results. // This lets us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results.
...@@ -77,8 +77,8 @@ func newQuotaAccessor() (*quotaAccessor, error) { ...@@ -77,8 +77,8 @@ func newQuotaAccessor() (*quotaAccessor, error) {
}, nil }, nil
} }
func (e *quotaAccessor) UpdateQuotaStatus(newQuota *api.ResourceQuota) error { func (e *quotaAccessor) UpdateQuotaStatus(newQuota *corev1.ResourceQuota) error {
updatedQuota, err := e.client.Core().ResourceQuotas(newQuota.Namespace).UpdateStatus(newQuota) updatedQuota, err := e.client.CoreV1().ResourceQuotas(newQuota.Namespace).UpdateStatus(newQuota)
if err != nil { if err != nil {
return err return err
} }
...@@ -93,13 +93,13 @@ var etcdVersioner = etcd.APIObjectVersioner{} ...@@ -93,13 +93,13 @@ var etcdVersioner = etcd.APIObjectVersioner{}
// checkCache compares the passed quota against the value in the look-aside cache and returns the newer // checkCache compares the passed quota against the value in the look-aside cache and returns the newer
// if the cache is out of date, it deletes the stale entry. This only works because of etcd resourceVersions // if the cache is out of date, it deletes the stale entry. This only works because of etcd resourceVersions
// being monotonically increasing integers // being monotonically increasing integers
func (e *quotaAccessor) checkCache(quota *api.ResourceQuota) *api.ResourceQuota { func (e *quotaAccessor) checkCache(quota *corev1.ResourceQuota) *corev1.ResourceQuota {
key := quota.Namespace + "/" + quota.Name key := quota.Namespace + "/" + quota.Name
uncastCachedQuota, ok := e.updatedQuotas.Get(key) uncastCachedQuota, ok := e.updatedQuotas.Get(key)
if !ok { if !ok {
return quota return quota
} }
cachedQuota := uncastCachedQuota.(*api.ResourceQuota) cachedQuota := uncastCachedQuota.(*corev1.ResourceQuota)
if etcdVersioner.CompareResourceVersion(quota, cachedQuota) >= 0 { if etcdVersioner.CompareResourceVersion(quota, cachedQuota) >= 0 {
e.updatedQuotas.Remove(key) e.updatedQuotas.Remove(key)
...@@ -108,7 +108,7 @@ func (e *quotaAccessor) checkCache(quota *api.ResourceQuota) *api.ResourceQuota ...@@ -108,7 +108,7 @@ func (e *quotaAccessor) checkCache(quota *api.ResourceQuota) *api.ResourceQuota
return cachedQuota return cachedQuota
} }
func (e *quotaAccessor) GetQuotas(namespace string) ([]api.ResourceQuota, error) { func (e *quotaAccessor) GetQuotas(namespace string) ([]corev1.ResourceQuota, error) {
// determine if there are any quotas in this namespace // determine if there are any quotas in this namespace
// if there are no quotas, we don't need to do anything // if there are no quotas, we don't need to do anything
items, err := e.lister.ResourceQuotas(namespace).List(labels.Everything()) items, err := e.lister.ResourceQuotas(namespace).List(labels.Everything())
...@@ -142,7 +142,7 @@ func (e *quotaAccessor) GetQuotas(namespace string) ([]api.ResourceQuota, error) ...@@ -142,7 +142,7 @@ func (e *quotaAccessor) GetQuotas(namespace string) ([]api.ResourceQuota, error)
} }
} }
resourceQuotas := []api.ResourceQuota{} resourceQuotas := []corev1.ResourceQuota{}
for i := range items { for i := range items {
quota := items[i] quota := items[i]
quota = e.checkCache(quota) quota = e.checkCache(quota)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment