mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #22183 from pmorie/config-quota
Auto commit by PR queue bot
This commit is contained in:
commit
0e3469dce3
@ -237,6 +237,7 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig
|
||||
api.Kind("ReplicationController"),
|
||||
api.Kind("PersistentVolumeClaim"),
|
||||
api.Kind("Secret"),
|
||||
api.Kind("ConfigMap"),
|
||||
}
|
||||
resourceQuotaControllerOptions := &resourcequotacontroller.ResourceQuotaControllerOptions{
|
||||
KubeClient: resourceQuotaControllerClient,
|
||||
|
@ -140,6 +140,7 @@ var standardQuotaResources = sets.NewString(
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceConfigMaps),
|
||||
)
|
||||
|
||||
// IsStandardQuotaResourceName returns true if the resource is known to
|
||||
@ -160,6 +161,7 @@ var standardResources = sets.NewString(
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourceConfigMaps),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceStorage),
|
||||
)
|
||||
@ -175,6 +177,7 @@ var integerResources = sets.NewString(
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourceConfigMaps),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
)
|
||||
|
||||
|
@ -2187,6 +2187,8 @@ const (
|
||||
ResourceQuotas ResourceName = "resourcequotas"
|
||||
// ResourceSecrets, number
|
||||
ResourceSecrets ResourceName = "secrets"
|
||||
// ResourceConfigMaps, number
|
||||
ResourceConfigMaps ResourceName = "configmaps"
|
||||
// ResourcePersistentVolumeClaims, number
|
||||
ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims"
|
||||
// CPU request, in cores. (500m = .5 cores)
|
||||
|
@ -2644,6 +2644,8 @@ const (
|
||||
ResourceQuotas ResourceName = "resourcequotas"
|
||||
// ResourceSecrets, number
|
||||
ResourceSecrets ResourceName = "secrets"
|
||||
// ResourceConfigMaps, number
|
||||
ResourceConfigMaps ResourceName = "configmaps"
|
||||
// ResourcePersistentVolumeClaims, number
|
||||
ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims"
|
||||
// CPU request, in cores. (500m = .5 cores)
|
||||
|
@ -4082,6 +4082,8 @@ func TestValidateResourceQuota(t *testing.T) {
|
||||
api.ResourceServices: resource.MustParse("0"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("10"),
|
||||
api.ResourceQuotas: resource.MustParse("10"),
|
||||
api.ResourceConfigMaps: resource.MustParse("10"),
|
||||
api.ResourceSecrets: resource.MustParse("10"),
|
||||
},
|
||||
}
|
||||
|
||||
@ -4129,6 +4131,8 @@ func TestValidateResourceQuota(t *testing.T) {
|
||||
api.ResourceServices: resource.MustParse("-10"),
|
||||
api.ResourceReplicationControllers: resource.MustParse("-10"),
|
||||
api.ResourceQuotas: resource.MustParse("-10"),
|
||||
api.ResourceConfigMaps: resource.MustParse("-10"),
|
||||
api.ResourceSecrets: resource.MustParse("-10"),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,22 @@ func (r *replenishmentControllerFactory) NewController(options *ReplenishmentCon
|
||||
DeleteFunc: ObjectReplenishmentDeleteFunc(options),
|
||||
},
|
||||
)
|
||||
case api.Kind("ConfigMap"):
|
||||
_, result = framework.NewInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return r.kubeClient.Core().ConfigMaps(api.NamespaceAll).List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return r.kubeClient.Core().ConfigMaps(api.NamespaceAll).Watch(options)
|
||||
},
|
||||
},
|
||||
&api.ConfigMap{},
|
||||
options.ResyncPeriod(),
|
||||
framework.ResourceEventHandlerFuncs{
|
||||
DeleteFunc: ObjectReplenishmentDeleteFunc(options),
|
||||
},
|
||||
)
|
||||
default:
|
||||
return nil, fmt.Errorf("no replenishment controller available for %s", options.GroupKind)
|
||||
}
|
||||
|
45
pkg/quota/evaluator/core/configmap.go
Normal file
45
pkg/quota/evaluator/core/configmap.go
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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/quota"
|
||||
"k8s.io/kubernetes/pkg/quota/generic"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// NewConfigMapEvaluator returns an evaluator that can evaluate configMaps
|
||||
func NewConfigMapEvaluator(kubeClient clientset.Interface) quota.Evaluator {
|
||||
allResources := []api.ResourceName{api.ResourceConfigMaps}
|
||||
return &generic.GenericEvaluator{
|
||||
Name: "Evaluator.ConfigMap",
|
||||
InternalGroupKind: api.Kind("ConfigMap"),
|
||||
InternalOperationResources: map[admission.Operation][]api.ResourceName{
|
||||
admission.Create: allResources,
|
||||
},
|
||||
MatchedResourceNames: allResources,
|
||||
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)
|
||||
},
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ func NewRegistry(kubeClient clientset.Interface) quota.Registry {
|
||||
replicationController := NewReplicationControllerEvaluator(kubeClient)
|
||||
resourceQuota := NewResourceQuotaEvaluator(kubeClient)
|
||||
secret := NewSecretEvaluator(kubeClient)
|
||||
configMap := NewConfigMapEvaluator(kubeClient)
|
||||
persistentVolumeClaim := NewPersistentVolumeClaimEvaluator(kubeClient)
|
||||
return &generic.GenericRegistry{
|
||||
InternalEvaluators: map[unversioned.GroupKind]quota.Evaluator{
|
||||
@ -37,6 +38,7 @@ func NewRegistry(kubeClient clientset.Interface) quota.Registry {
|
||||
service.GroupKind(): service,
|
||||
replicationController.GroupKind(): replicationController,
|
||||
secret.GroupKind(): secret,
|
||||
configMap.GroupKind(): configMap,
|
||||
resourceQuota.GroupKind(): resourceQuota,
|
||||
persistentVolumeClaim.GroupKind(): persistentVolumeClaim,
|
||||
},
|
||||
|
@ -182,6 +182,41 @@ var _ = Describe("ResourceQuota", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should create a ResourceQuota and capture the life of a configMap.", 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 ConfigMap")
|
||||
configMap := newTestConfigMapForQuota("test-configmap")
|
||||
configMap, err = f.Client.ConfigMaps(f.Namespace.Name).Create(configMap)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Ensuring resource quota status captures configMap creation")
|
||||
usedResources = api.ResourceList{}
|
||||
usedResources[api.ResourceQuotas] = resource.MustParse("1")
|
||||
usedResources[api.ResourceConfigMaps] = resource.MustParse("1")
|
||||
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Deleting a ConfigMap")
|
||||
err = f.Client.ConfigMaps(f.Namespace.Name).Delete(configMap.Name)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Ensuring resource quota status released usage")
|
||||
usedResources[api.ResourceConfigMaps] = resource.MustParse("0")
|
||||
err = waitForResourceQuota(f.Client, f.Namespace.Name, quotaName, usedResources)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should verify ResourceQuota with terminating scopes.", func() {
|
||||
By("Creating a ResourceQuota with terminating scope")
|
||||
quotaTerminatingName := "quota-terminating"
|
||||
@ -387,6 +422,8 @@ func newTestResourceQuota(name string) *api.ResourceQuota {
|
||||
hard[api.ResourceQuotas] = resource.MustParse("1")
|
||||
hard[api.ResourceCPU] = resource.MustParse("1")
|
||||
hard[api.ResourceMemory] = resource.MustParse("500Mi")
|
||||
hard[api.ResourceConfigMaps] = resource.MustParse("2")
|
||||
hard[api.ResourceSecrets] = resource.MustParse("2")
|
||||
return &api.ResourceQuota{
|
||||
ObjectMeta: api.ObjectMeta{Name: name},
|
||||
Spec: api.ResourceQuotaSpec{Hard: hard},
|
||||
@ -429,6 +466,17 @@ func newTestServiceForQuota(name string) *api.Service {
|
||||
}
|
||||
}
|
||||
|
||||
func newTestConfigMapForQuota(name string) *api.ConfigMap {
|
||||
return &api.ConfigMap{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"a": "b",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestSecretForQuota(name string) *api.Secret {
|
||||
return &api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
|
Loading…
Reference in New Issue
Block a user