Make node restriction admission pod lookups use an informer

This commit is contained in:
Jordan Liggitt 2018-05-09 12:23:46 -04:00
parent 1245601659
commit 8161033be4
No known key found for this signature in database
GPG Key ID: 39928704103C7229
4 changed files with 35 additions and 34 deletions

View File

@ -16,13 +16,12 @@ go_library(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/policy:go_default_library", "//pkg/apis/policy:go_default_library",
"//pkg/auth/nodeidentifier:go_default_library", "//pkg/auth/nodeidentifier:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
@ -38,14 +37,14 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/policy:go_default_library", "//pkg/apis/policy:go_default_library",
"//pkg/auth/nodeidentifier:go_default_library", "//pkg/auth/nodeidentifier:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library", "//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
], ],
) )

View File

@ -22,7 +22,6 @@ import (
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -31,8 +30,8 @@ import (
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/kubernetes/pkg/auth/nodeidentifier"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
coreinternalversion "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
) )
@ -62,18 +61,18 @@ func NewPlugin(nodeIdentifier nodeidentifier.NodeIdentifier) *nodePlugin {
type nodePlugin struct { type nodePlugin struct {
*admission.Handler *admission.Handler
nodeIdentifier nodeidentifier.NodeIdentifier nodeIdentifier nodeidentifier.NodeIdentifier
podsGetter coreinternalversion.PodsGetter podsGetter internalversion.PodLister
// allows overriding for testing // allows overriding for testing
features utilfeature.FeatureGate features utilfeature.FeatureGate
} }
var ( var (
_ = admission.Interface(&nodePlugin{}) _ = admission.Interface(&nodePlugin{})
_ = kubeapiserveradmission.WantsInternalKubeClientSet(&nodePlugin{}) _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&nodePlugin{})
) )
func (p *nodePlugin) SetInternalKubeClientSet(f internalclientset.Interface) { func (p *nodePlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
p.podsGetter = f.Core() p.podsGetter = f.Core().InternalVersion().Pods().Lister()
} }
func (p *nodePlugin) ValidateInitialization() error { func (p *nodePlugin) ValidateInitialization() error {
@ -183,14 +182,10 @@ func (c *nodePlugin) admitPod(nodeName string, a admission.Attributes) error {
return nil return nil
case admission.Delete: case admission.Delete:
// get the existing pod from the server cache // get the existing pod
existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(a.GetName(), v1.GetOptions{ResourceVersion: "0"}) existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(a.GetName())
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
// wasn't found in the server cache, do a live lookup before forbidding return err
existingPod, err = c.podsGetter.Pods(a.GetNamespace()).Get(a.GetName(), v1.GetOptions{})
if errors.IsNotFound(err) {
return err
}
} }
if err != nil { if err != nil {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
@ -241,14 +236,10 @@ func (c *nodePlugin) admitPodEviction(nodeName string, a admission.Attributes) e
} }
podName = eviction.Name podName = eviction.Name
} }
// get the existing pod from the server cache // get the existing pod
existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(podName, v1.GetOptions{ResourceVersion: "0"}) existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(podName)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
// wasn't found in the server cache, do a live lookup before forbidding return err
existingPod, err = c.podsGetter.Pods(a.GetNamespace()).Get(podName, v1.GetOptions{})
if errors.IsNotFound(err) {
return err
}
} }
if err != nil { if err != nil {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
@ -376,7 +367,7 @@ func (c *nodePlugin) admitServiceAccount(nodeName string, a admission.Attributes
if ref.UID == "" { if ref.UID == "" {
return admission.NewForbidden(a, fmt.Errorf("node requested token with a pod binding without a uid")) return admission.NewForbidden(a, fmt.Errorf("node requested token with a pod binding without a uid"))
} }
pod, err := c.podsGetter.Pods(a.GetNamespace()).Get(ref.Name, v1.GetOptions{}) pod, err := c.podsGetter.Pods(a.GetNamespace()).Get(ref.Name)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
return err return err
} }

View File

@ -25,12 +25,12 @@ import (
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/tools/cache"
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication" authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/kubernetes/pkg/auth/nodeidentifier"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
coreinternalversion "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
) )
@ -63,6 +63,7 @@ func makeTestPod(namespace, name, node string, mirror bool) *api.Pod {
func makeTestPodEviction(name string) *policy.Eviction { func makeTestPodEviction(name string) *policy.Eviction {
eviction := &policy.Eviction{} eviction := &policy.Eviction{}
eviction.Name = name eviction.Name = name
eviction.Namespace = "ns"
return eviction return eviction
} }
@ -135,10 +136,20 @@ func Test_nodePlugin_Admit(t *testing.T) {
svcacctResource = api.Resource("serviceaccounts").WithVersion("v1") svcacctResource = api.Resource("serviceaccounts").WithVersion("v1")
tokenrequestKind = api.Kind("TokenRequest").WithVersion("v1") tokenrequestKind = api.Kind("TokenRequest").WithVersion("v1")
noExistingPods = fake.NewSimpleClientset().Core() noExistingPodsIndex = cache.NewIndexer(cache.MetaNamespaceKeyFunc, nil)
existingPods = fake.NewSimpleClientset(mymirrorpod, othermirrorpod, unboundmirrorpod, mypod, otherpod, unboundpod).Core() noExistingPods = internalversion.NewPodLister(noExistingPodsIndex)
existingPodsIndex = cache.NewIndexer(cache.MetaNamespaceKeyFunc, nil)
existingPods = internalversion.NewPodLister(existingPodsIndex)
) )
existingPodsIndex.Add(mymirrorpod)
existingPodsIndex.Add(othermirrorpod)
existingPodsIndex.Add(unboundmirrorpod)
existingPodsIndex.Add(mypod)
existingPodsIndex.Add(otherpod)
existingPodsIndex.Add(unboundpod)
sapod := makeTestPod("ns", "mysapod", "mynode", true) sapod := makeTestPod("ns", "mysapod", "mynode", true)
sapod.Spec.ServiceAccountName = "foo" sapod.Spec.ServiceAccountName = "foo"
@ -153,7 +164,7 @@ func Test_nodePlugin_Admit(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
podsGetter coreinternalversion.PodsGetter podsGetter internalversion.PodLister
attributes admission.Attributes attributes admission.Attributes
features utilfeature.FeatureGate features utilfeature.FeatureGate
err string err string
@ -456,7 +467,7 @@ func Test_nodePlugin_Admit(t *testing.T) {
err: "forbidden: unexpected operation", err: "forbidden: unexpected operation",
}, },
{ {
name: "forbid create of eviction for normal pod bound to another", name: "forbid create of unnamed eviction for normal pod bound to another",
podsGetter: existingPods, podsGetter: existingPods,
attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, otherpod.Namespace, otherpod.Name, podResource, "eviction", admission.Create, mynode), attributes: admission.NewAttributesRecord(unnamedEviction, nil, evictionKind, otherpod.Namespace, otherpod.Name, podResource, "eviction", admission.Create, mynode),
err: "spec.nodeName set to itself", err: "spec.nodeName set to itself",

View File

@ -97,7 +97,7 @@ func TestNodeAuthorizer(t *testing.T) {
// Set up NodeRestriction admission // Set up NodeRestriction admission
nodeRestrictionAdmission := noderestriction.NewPlugin(nodeidentifier.NewDefaultNodeIdentifier()) nodeRestrictionAdmission := noderestriction.NewPlugin(nodeidentifier.NewDefaultNodeIdentifier())
nodeRestrictionAdmission.SetInternalKubeClientSet(superuserClient) nodeRestrictionAdmission.SetInternalKubeInformerFactory(informerFactory)
if err := nodeRestrictionAdmission.ValidateInitialization(); err != nil { if err := nodeRestrictionAdmission.ValidateInitialization(); err != nil {
t.Fatal(err) t.Fatal(err)
} }