Skip to content

Commit

Permalink
Merge pull request kubernetes#22852 from miminar/no-admit-without-nam…
Browse files Browse the repository at this point in the history
…espace

Auto commit by PR queue bot
  • Loading branch information
k8s-merge-robot committed Mar 18, 2016
2 parents 6239907 + 2601ee5 commit e4dd8c1
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
10 changes: 10 additions & 0 deletions plugin/pkg/admission/resourcequota/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ func (q *quotaAdmission) Admit(a admission.Attributes) (err error) {
return nil
}

// Usage of some resources cannot be counted in isolation. For example when
// the resource represents a number of unique references to external
// resource. In such a case an evaluator needs to process other objects in
// the same namespace which needs to be known.
if om, err := api.ObjectMetaFor(inputObject); namespace != "" && err == nil {
if om.Namespace == "" {
om.Namespace = namespace
}
}

// there is at least one quota that definitely matches our object
// as a result, we need to measure the usage of this object for quota
// on updates, we need to subtract the previous measured usage
Expand Down
77 changes: 77 additions & 0 deletions plugin/pkg/admission/resourcequota/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ 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/client/cache"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
"k8s.io/kubernetes/pkg/quota"
"k8s.io/kubernetes/pkg/quota/evaluator/core"
"k8s.io/kubernetes/pkg/quota/generic"
"k8s.io/kubernetes/pkg/quota/install"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
)

Expand Down Expand Up @@ -566,3 +571,75 @@ func TestHasUsageStats(t *testing.T) {
}
}
}

// TestAdmissionSetsMissingNamespace verifies that if an object lacks a
// namespace, it will be set.
func TestAdmissionSetsMissingNamespace(t *testing.T) {
namespace := "test"
resourceQuota := &api.ResourceQuota{
ObjectMeta: api.ObjectMeta{Name: "quota", Namespace: namespace, ResourceVersion: "124"},
Status: api.ResourceQuotaStatus{
Hard: api.ResourceList{
api.ResourceCPU: resource.MustParse("3"),
},
Used: api.ResourceList{
api.ResourceCPU: resource.MustParse("1"),
},
},
}
kubeClient := fake.NewSimpleClientset(resourceQuota)
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc})

computeResources := []api.ResourceName{
api.ResourcePods,
api.ResourceCPU,
}

usageFunc := func(object runtime.Object) api.ResourceList {
pod, ok := object.(*api.Pod)
if !ok {
t.Fatalf("Expected pod, got %T", object)
}
if pod.Namespace != namespace {
t.Errorf("Expected pod with different namespace: %q != %q", pod.Namespace, namespace)
}
return core.PodUsageFunc(pod)
}

podEvaluator := &generic.GenericEvaluator{
Name: "Test-Evaluator.Pod",
InternalGroupKind: api.Kind("Pod"),
InternalOperationResources: map[admission.Operation][]api.ResourceName{
admission.Create: computeResources,
},
ConstraintsFunc: core.PodConstraintsFunc,
MatchedResourceNames: computeResources,
MatchesScopeFunc: core.PodMatchesScopeFunc,
UsageFunc: usageFunc,
}

registry := &generic.GenericRegistry{
InternalEvaluators: map[unversioned.GroupKind]quota.Evaluator{
podEvaluator.GroupKind(): podEvaluator,
},
}
handler := &quotaAdmission{
Handler: admission.NewHandler(admission.Create, admission.Update),
client: kubeClient,
indexer: indexer,
registry: registry,
}
handler.indexer.Add(resourceQuota)
newPod := validPod("pod-without-namespace", 1, getResourceRequirements(getResourceList("1", "2Gi"), getResourceList("", "")))

// unset the namespace
newPod.ObjectMeta.Namespace = ""

err := handler.Admit(admission.NewAttributesRecord(newPod, api.Kind("Pod"), namespace, newPod.Name, api.Resource("pods"), "", admission.Create, nil))
if err != nil {
t.Errorf("Got unexpected error: %v", err)
}
if newPod.Namespace != namespace {
t.Errorf("Got unexpected pod namespace: %q != %q", newPod.Namespace, namespace)
}
}

0 comments on commit e4dd8c1

Please sign in to comment.