mirror of https://github.com/k3s-io/k3s
Merge pull request #22852 from miminar/no-admit-without-namespace
Auto commit by PR queue botpull/6/head
commit
e4dd8c1e1f
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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 := "aAdmission{
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue