externalize serviceaacount admission controller

remove unused internal serviceaccount util
pull/8/head
yue9944882 2018-08-20 11:10:19 +08:00
parent 76e9fdaa72
commit 17306b540b
6 changed files with 109 additions and 127 deletions

View File

@ -20,7 +20,6 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount" apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
api "k8s.io/kubernetes/pkg/apis/core"
) )
// UserInfo returns a user.Info interface for the given namespace, service account name and UID // UserInfo returns a user.Info interface for the given namespace, service account name and UID
@ -51,24 +50,3 @@ func IsServiceAccountToken(secret *v1.Secret, sa *v1.ServiceAccount) bool {
return true return true
} }
// TODO: remove the duplicate code
// InternalIsServiceAccountToken returns true if the secret is a valid api token for the service account
func InternalIsServiceAccountToken(secret *api.Secret, sa *api.ServiceAccount) bool {
if secret.Type != api.SecretTypeServiceAccountToken {
return false
}
name := secret.Annotations[api.ServiceAccountNameKey]
uid := secret.Annotations[api.ServiceAccountUIDKey]
if name != sa.Name {
// Name must match
return false
}
if len(uid) > 0 && uid != string(sa.UID) {
// If UID is specified, it must match
return false
}
return true
}

View File

@ -16,19 +16,20 @@ go_library(
deps = [ deps = [
"//pkg/api/pod:go_default_library", "//pkg/api/pod:go_default_library",
"//pkg/apis/core:go_default_library", "//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/util:go_default_library", "//pkg/kubeapiserver/admission/util:go_default_library",
"//pkg/serviceaccount:go_default_library", "//pkg/serviceaccount: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/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema: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/admission/initializer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names: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",
], ],
) )
@ -38,16 +39,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/client/listers/core/internalversion:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types: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/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types: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/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1: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/stretchr/testify/assert:go_default_library",
], ],
) )

View File

@ -23,19 +23,20 @@ import (
"strconv" "strconv"
"time" "time"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
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/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
corev1listers "k8s.io/client-go/listers/core/v1"
podutil "k8s.io/kubernetes/pkg/api/pod" podutil "k8s.io/kubernetes/pkg/api/pod"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
"k8s.io/kubernetes/pkg/kubeapiserver/admission/util" "k8s.io/kubernetes/pkg/kubeapiserver/admission/util"
"k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount"
) )
@ -74,16 +75,16 @@ type serviceAccount struct {
// MountServiceAccountToken creates Volume and VolumeMounts for the first referenced ServiceAccountToken for the pod's service account // MountServiceAccountToken creates Volume and VolumeMounts for the first referenced ServiceAccountToken for the pod's service account
MountServiceAccountToken bool MountServiceAccountToken bool
client internalclientset.Interface client kubernetes.Interface
serviceAccountLister corelisters.ServiceAccountLister serviceAccountLister corev1listers.ServiceAccountLister
secretLister corelisters.SecretLister secretLister corev1listers.SecretLister
} }
var _ admission.MutationInterface = &serviceAccount{} var _ admission.MutationInterface = &serviceAccount{}
var _ admission.ValidationInterface = &serviceAccount{} var _ admission.ValidationInterface = &serviceAccount{}
var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&serviceAccount{}) var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&serviceAccount{})
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&serviceAccount{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAccount{})
// NewServiceAccount returns an admission.Interface implementation which limits admission of Pod CREATE requests based on the pod's ServiceAccount: // NewServiceAccount returns an admission.Interface implementation which limits admission of Pod CREATE requests based on the pod's ServiceAccount:
// 1. If the pod does not specify a ServiceAccount, it sets the pod's ServiceAccount to "default" // 1. If the pod does not specify a ServiceAccount, it sets the pod's ServiceAccount to "default"
@ -103,15 +104,15 @@ func NewServiceAccount() *serviceAccount {
} }
} }
func (a *serviceAccount) SetInternalKubeClientSet(cl internalclientset.Interface) { func (a *serviceAccount) SetExternalKubeClientSet(cl kubernetes.Interface) {
a.client = cl a.client = cl
} }
func (a *serviceAccount) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { func (a *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
serviceAccountInformer := f.Core().InternalVersion().ServiceAccounts() serviceAccountInformer := f.Core().V1().ServiceAccounts()
a.serviceAccountLister = serviceAccountInformer.Lister() a.serviceAccountLister = serviceAccountInformer.Lister()
secretInformer := f.Core().InternalVersion().Secrets() secretInformer := f.Core().V1().Secrets()
a.secretLister = secretInformer.Lister() a.secretLister = secretInformer.Lister()
a.SetReadyFunc(func() bool { a.SetReadyFunc(func() bool {
@ -174,7 +175,9 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) {
} }
if len(pod.Spec.ImagePullSecrets) == 0 { if len(pod.Spec.ImagePullSecrets) == 0 {
pod.Spec.ImagePullSecrets = make([]api.LocalObjectReference, len(serviceAccount.ImagePullSecrets)) pod.Spec.ImagePullSecrets = make([]api.LocalObjectReference, len(serviceAccount.ImagePullSecrets))
copy(pod.Spec.ImagePullSecrets, serviceAccount.ImagePullSecrets) for i := 0; i < len(serviceAccount.ImagePullSecrets); i++ {
pod.Spec.ImagePullSecrets[i].Name = serviceAccount.ImagePullSecrets[i].Name
}
} }
return s.Validate(a) return s.Validate(a)
@ -251,7 +254,7 @@ func shouldIgnore(a admission.Attributes) bool {
return false return false
} }
func shouldAutomount(sa *api.ServiceAccount, pod *api.Pod) bool { func shouldAutomount(sa *corev1.ServiceAccount, pod *api.Pod) bool {
// Pod's preference wins // Pod's preference wins
if pod.Spec.AutomountServiceAccountToken != nil { if pod.Spec.AutomountServiceAccountToken != nil {
return *pod.Spec.AutomountServiceAccountToken return *pod.Spec.AutomountServiceAccountToken
@ -266,7 +269,7 @@ func shouldAutomount(sa *api.ServiceAccount, pod *api.Pod) bool {
// enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account // enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account
// A global setting of true will override any flag set on the individual service account // A global setting of true will override any flag set on the individual service account
func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAccount) bool { func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceAccount) bool {
if s.LimitSecretReferences { if s.LimitSecretReferences {
return true return true
} }
@ -280,7 +283,7 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAcco
} }
// getServiceAccount returns the ServiceAccount for the given namespace and name if it exists // getServiceAccount returns the ServiceAccount for the given namespace and name if it exists
func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.ServiceAccount, error) { func (s *serviceAccount) getServiceAccount(namespace string, name string) (*corev1.ServiceAccount, error) {
serviceAccount, err := s.serviceAccountLister.ServiceAccounts(namespace).Get(name) serviceAccount, err := s.serviceAccountLister.ServiceAccounts(namespace).Get(name)
if err == nil { if err == nil {
return serviceAccount, nil return serviceAccount, nil
@ -313,7 +316,7 @@ func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.
} }
// getReferencedServiceAccountToken returns the name of the first referenced secret which is a ServiceAccountToken for the service account // getReferencedServiceAccountToken returns the name of the first referenced secret which is a ServiceAccountToken for the service account
func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *api.ServiceAccount) (string, error) { func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) {
if len(serviceAccount.Secrets) == 0 { if len(serviceAccount.Secrets) == 0 {
return "", nil return "", nil
} }
@ -338,27 +341,27 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *api.Se
} }
// getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount // getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount
func (s *serviceAccount) getServiceAccountTokens(serviceAccount *api.ServiceAccount) ([]*api.Secret, error) { func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceAccount) ([]*corev1.Secret, error) {
secrets, err := s.secretLister.Secrets(serviceAccount.Namespace).List(labels.Everything()) secrets, err := s.secretLister.Secrets(serviceAccount.Namespace).List(labels.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }
tokens := []*api.Secret{} tokens := []*corev1.Secret{}
for _, secret := range secrets { for _, secret := range secrets {
if secret.Type != api.SecretTypeServiceAccountToken { if secret.Type != corev1.SecretTypeServiceAccountToken {
continue continue
} }
if serviceaccount.InternalIsServiceAccountToken(secret, serviceAccount) { if serviceaccount.IsServiceAccountToken(secret, serviceAccount) {
tokens = append(tokens, secret) tokens = append(tokens, secret)
} }
} }
return tokens, nil return tokens, nil
} }
func (s *serviceAccount) limitSecretReferences(serviceAccount *api.ServiceAccount, pod *api.Pod) error { func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
// Ensure all secrets the pod references are allowed by the service account // Ensure all secrets the pod references are allowed by the service account
mountableSecrets := sets.NewString() mountableSecrets := sets.NewString()
for _, s := range serviceAccount.Secrets { for _, s := range serviceAccount.Secrets {
@ -408,7 +411,7 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *api.ServiceAccoun
return nil return nil
} }
func (s *serviceAccount) mountServiceAccountToken(serviceAccount *api.ServiceAccount, pod *api.Pod) error { func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
// Find the name of a referenced ServiceAccountToken secret we can mount // Find the name of a referenced ServiceAccountToken secret we can mount
serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount) serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount)
if err != nil { if err != nil {

View File

@ -21,15 +21,18 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
kubelet "k8s.io/kubernetes/pkg/kubelet/types" kubelet "k8s.io/kubernetes/pkg/kubelet/types"
) )
@ -168,12 +171,12 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.MountServiceAccountToken = true admit.MountServiceAccountToken = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns into the cache // Add the default service account for the ns into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -196,12 +199,12 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.MountServiceAccountToken = true admit.MountServiceAccountToken = true
admit.RequireAPIToken = true admit.RequireAPIToken = true
// Add the default service account for the ns into the cache // Add the default service account for the ns into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -220,7 +223,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
ns := "myns" ns := "myns"
// Build a test client that the admission plugin can use to look up the service account missing from its cache // Build a test client that the admission plugin can use to look up the service account missing from its cache
client := fake.NewSimpleClientset(&api.ServiceAccount{ client := fake.NewSimpleClientset(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -229,7 +232,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.client = client admit.client = client
admit.RequireAPIToken = false admit.RequireAPIToken = false
@ -251,9 +254,9 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
client := fake.NewSimpleClientset() client := fake.NewSimpleClientset()
admit := NewServiceAccount() admit := NewServiceAccount()
admit.SetInternalKubeClientSet(client) admit.SetExternalKubeClientSet(client)
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
@ -283,32 +286,32 @@ func TestAutomountsAPIToken(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.MountServiceAccountToken = true admit.MountServiceAccountToken = true
admit.RequireAPIToken = true admit.RequireAPIToken = true
// Add the default service account for the ns with a token into the cache // Add the default service account for the ns with a token into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName, Name: serviceAccountName,
Namespace: ns, Namespace: ns,
UID: types.UID(serviceAccountUID), UID: types.UID(serviceAccountUID),
}, },
Secrets: []api.ObjectReference{ Secrets: []corev1.ObjectReference{
{Name: tokenName}, {Name: tokenName},
}, },
}) })
// Add a token for the service account into the cache // Add a token for the service account into the cache
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{ informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: tokenName, Name: tokenName,
Namespace: ns, Namespace: ns,
Annotations: map[string]string{ Annotations: map[string]string{
api.ServiceAccountNameKey: serviceAccountName, corev1.ServiceAccountNameKey: serviceAccountName,
api.ServiceAccountUIDKey: serviceAccountUID, corev1.ServiceAccountUIDKey: serviceAccountUID,
}, },
}, },
Type: api.SecretTypeServiceAccountToken, Type: corev1.SecretTypeServiceAccountToken,
Data: map[string][]byte{ Data: map[string][]byte{
api.ServiceAccountTokenKey: []byte("token-data"), api.ServiceAccountTokenKey: []byte("token-data"),
}, },
@ -433,34 +436,34 @@ func TestRespectsExistingMount(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.MountServiceAccountToken = true admit.MountServiceAccountToken = true
admit.RequireAPIToken = true admit.RequireAPIToken = true
// Add the default service account for the ns with a token into the cache // Add the default service account for the ns with a token into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName, Name: serviceAccountName,
Namespace: ns, Namespace: ns,
UID: types.UID(serviceAccountUID), UID: types.UID(serviceAccountUID),
}, },
Secrets: []api.ObjectReference{ Secrets: []corev1.ObjectReference{
{Name: tokenName}, {Name: tokenName},
}, },
}) })
// Add a token for the service account into the cache // Add a token for the service account into the cache
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{ informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: tokenName, Name: tokenName,
Namespace: ns, Namespace: ns,
Annotations: map[string]string{ Annotations: map[string]string{
api.ServiceAccountNameKey: serviceAccountName, corev1.ServiceAccountNameKey: serviceAccountName,
api.ServiceAccountUIDKey: serviceAccountUID, corev1.ServiceAccountUIDKey: serviceAccountUID,
}, },
}, },
Type: api.SecretTypeServiceAccountToken, Type: corev1.SecretTypeServiceAccountToken,
Data: map[string][]byte{ Data: map[string][]byte{
api.ServiceAccountTokenKey: []byte("token-data"), corev1.ServiceAccountTokenKey: []byte("token-data"),
}, },
}) })
@ -531,17 +534,17 @@ func TestAllowsReferencedSecret(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns with a secret reference into the cache // Add the default service account for the ns with a secret reference into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
}, },
Secrets: []api.ObjectReference{ Secrets: []corev1.ObjectReference{
{Name: "foo"}, {Name: "foo"},
}, },
}) })
@ -612,12 +615,12 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns into the cache // Add the default service account for the ns into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -690,12 +693,12 @@ func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = false admit.LimitSecretReferences = false
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns into the cache // Add the default service account for the ns into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -722,17 +725,17 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns with a secret reference into the cache // Add the default service account for the ns with a secret reference into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
}, },
ImagePullSecrets: []api.LocalObjectReference{ ImagePullSecrets: []corev1.LocalObjectReference{
{Name: "foo"}, {Name: "foo"},
}, },
}) })
@ -754,12 +757,12 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns into the cache // Add the default service account for the ns into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -783,17 +786,17 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
// Add the default service account for the ns with a secret reference into the cache // Add the default service account for the ns with a secret reference into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{ informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
}, },
ImagePullSecrets: []api.LocalObjectReference{ ImagePullSecrets: []corev1.LocalObjectReference{
{Name: "foo"}, {Name: "foo"},
{Name: "bar"}, {Name: "bar"},
}, },
@ -820,22 +823,22 @@ func TestAddImagePullSecrets(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.LimitSecretReferences = true admit.LimitSecretReferences = true
admit.RequireAPIToken = false admit.RequireAPIToken = false
sa := &api.ServiceAccount{ sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
}, },
ImagePullSecrets: []api.LocalObjectReference{ ImagePullSecrets: []corev1.LocalObjectReference{
{Name: "foo"}, {Name: "foo"},
{Name: "bar"}, {Name: "bar"},
}, },
} }
// Add the default service account for the ns with a secret reference into the cache // Add the default service account for the ns with a secret reference into the cache
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa) informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
pod := &api.Pod{} pod := &api.Pod{}
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil) attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
@ -844,9 +847,7 @@ func TestAddImagePullSecrets(t *testing.T) {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
if len(pod.Spec.ImagePullSecrets) != 2 || !reflect.DeepEqual(sa.ImagePullSecrets, pod.Spec.ImagePullSecrets) { assert.EqualValues(t, sa.ImagePullSecrets, pod.Spec.ImagePullSecrets, "expected %v, got %v", sa.ImagePullSecrets, pod.Spec.ImagePullSecrets)
t.Errorf("expected %v, got %v", sa.ImagePullSecrets, pod.Spec.ImagePullSecrets)
}
pod.Spec.ImagePullSecrets[1] = api.LocalObjectReference{Name: "baz"} pod.Spec.ImagePullSecrets[1] = api.LocalObjectReference{Name: "baz"}
if reflect.DeepEqual(sa.ImagePullSecrets, pod.Spec.ImagePullSecrets) { if reflect.DeepEqual(sa.ImagePullSecrets, pod.Spec.ImagePullSecrets) {
@ -865,25 +866,25 @@ func TestMultipleReferencedSecrets(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
admit.SetInternalKubeInformerFactory(informerFactory) admit.SetExternalKubeInformerFactory(informerFactory)
admit.MountServiceAccountToken = true admit.MountServiceAccountToken = true
admit.RequireAPIToken = true admit.RequireAPIToken = true
sa := &api.ServiceAccount{ sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName, Name: serviceAccountName,
UID: types.UID(serviceAccountUID), UID: types.UID(serviceAccountUID),
Namespace: ns, Namespace: ns,
}, },
Secrets: []api.ObjectReference{ Secrets: []corev1.ObjectReference{
{Name: token1}, {Name: token1},
{Name: token2}, {Name: token2},
}, },
} }
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa) informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
// Add two tokens for the service account into the cache. // Add two tokens for the service account into the cache.
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{ informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: token2, Name: token2,
Namespace: ns, Namespace: ns,
@ -892,12 +893,12 @@ func TestMultipleReferencedSecrets(t *testing.T) {
api.ServiceAccountUIDKey: serviceAccountUID, api.ServiceAccountUIDKey: serviceAccountUID,
}, },
}, },
Type: api.SecretTypeServiceAccountToken, Type: corev1.SecretTypeServiceAccountToken,
Data: map[string][]byte{ Data: map[string][]byte{
api.ServiceAccountTokenKey: []byte("token-data"), api.ServiceAccountTokenKey: []byte("token-data"),
}, },
}) })
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{ informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: token1, Name: token1,
Namespace: ns, Namespace: ns,
@ -906,7 +907,7 @@ func TestMultipleReferencedSecrets(t *testing.T) {
api.ServiceAccountUIDKey: serviceAccountUID, api.ServiceAccountUIDKey: serviceAccountUID,
}, },
}, },
Type: api.SecretTypeServiceAccountToken, Type: corev1.SecretTypeServiceAccountToken,
Data: map[string][]byte{ Data: map[string][]byte{
api.ServiceAccountTokenKey: []byte("token-data"), api.ServiceAccountTokenKey: []byte("token-data"),
}, },
@ -934,14 +935,14 @@ func TestMultipleReferencedSecrets(t *testing.T) {
} }
} }
func newSecret(secretType api.SecretType, namespace, name, serviceAccountName, serviceAccountUID string) *api.Secret { func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName, serviceAccountUID string) *corev1.Secret {
return &api.Secret{ return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: namespace, Namespace: namespace,
Name: name, Name: name,
Annotations: map[string]string{ Annotations: map[string]string{
api.ServiceAccountNameKey: serviceAccountName, corev1.ServiceAccountNameKey: serviceAccountName,
api.ServiceAccountUIDKey: serviceAccountUID, corev1.ServiceAccountUIDKey: serviceAccountUID,
}, },
}, },
Type: secretType, Type: secretType,
@ -951,12 +952,12 @@ func newSecret(secretType api.SecretType, namespace, name, serviceAccountName, s
func TestGetServiceAccountTokens(t *testing.T) { func TestGetServiceAccountTokens(t *testing.T) {
admit := NewServiceAccount() admit := NewServiceAccount()
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
admit.secretLister = corelisters.NewSecretLister(indexer) admit.secretLister = corev1listers.NewSecretLister(indexer)
ns := "namespace" ns := "namespace"
serviceAccountUID := "12345" serviceAccountUID := "12345"
sa := &api.ServiceAccount{ sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: DefaultServiceAccountName, Name: DefaultServiceAccountName,
Namespace: ns, Namespace: ns,
@ -964,13 +965,13 @@ func TestGetServiceAccountTokens(t *testing.T) {
}, },
} }
nonSATokenSecret := newSecret(api.SecretTypeDockercfg, ns, "nonSATokenSecret", DefaultServiceAccountName, serviceAccountUID) nonSATokenSecret := newSecret(corev1.SecretTypeDockercfg, ns, "nonSATokenSecret", DefaultServiceAccountName, serviceAccountUID)
indexer.Add(nonSATokenSecret) indexer.Add(nonSATokenSecret)
differentSAToken := newSecret(api.SecretTypeServiceAccountToken, ns, "differentSAToken", "someOtherSA", "someOtherUID") differentSAToken := newSecret(corev1.SecretTypeServiceAccountToken, ns, "differentSAToken", "someOtherSA", "someOtherUID")
indexer.Add(differentSAToken) indexer.Add(differentSAToken)
matchingSAToken := newSecret(api.SecretTypeServiceAccountToken, ns, "matchingSAToken", DefaultServiceAccountName, serviceAccountUID) matchingSAToken := newSecret(corev1.SecretTypeServiceAccountToken, ns, "matchingSAToken", DefaultServiceAccountName, serviceAccountUID)
indexer.Add(matchingSAToken) indexer.Add(matchingSAToken)
tokens, err := admit.getServiceAccountTokens(sa) tokens, err := admit.getServiceAccountTokens(sa)

View File

@ -14,8 +14,6 @@ go_test(
], ],
tags = ["integration"], tags = ["integration"],
deps = [ deps = [
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/controller/serviceaccount:go_default_library", "//pkg/controller/serviceaccount:go_default_library",
"//pkg/serviceaccount:go_default_library", "//pkg/serviceaccount:go_default_library",

View File

@ -43,10 +43,9 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
internalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount" serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount"
@ -363,7 +362,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
// Root client // Root client
// TODO: remove rootClient after we refactor pkg/admission to use the clientset. // TODO: remove rootClient after we refactor pkg/admission to use the clientset.
rootClientset := clientset.NewForConfigOrDie(&restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}, BearerToken: rootToken}) rootClientset := clientset.NewForConfigOrDie(&restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}, BearerToken: rootToken})
internalRootClientset := internalclientset.NewForConfigOrDie(&restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}, BearerToken: rootToken}) externalRootClientset := kubernetes.NewForConfigOrDie(&restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}, BearerToken: rootToken})
// Set up two authenticators: // Set up two authenticators:
// 1. A token authenticator that maps the rootToken to the "root" user // 1. A token authenticator that maps the rootToken to the "root" user
// 2. A ServiceAccountToken authenticator that validates ServiceAccount tokens // 2. A ServiceAccountToken authenticator that validates ServiceAccount tokens
@ -418,9 +417,9 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
// Set up admission plugin to auto-assign serviceaccounts to pods // Set up admission plugin to auto-assign serviceaccounts to pods
serviceAccountAdmission := serviceaccountadmission.NewServiceAccount() serviceAccountAdmission := serviceaccountadmission.NewServiceAccount()
serviceAccountAdmission.SetInternalKubeClientSet(internalRootClientset) serviceAccountAdmission.SetExternalKubeClientSet(externalRootClientset)
internalInformers := internalinformers.NewSharedInformerFactory(internalRootClientset, controller.NoResyncPeriodFunc()) externalInformers := informers.NewSharedInformerFactory(externalRootClientset, controller.NoResyncPeriodFunc())
serviceAccountAdmission.SetInternalKubeInformerFactory(internalInformers) serviceAccountAdmission.SetExternalKubeInformerFactory(externalInformers)
informers := informers.NewSharedInformerFactory(rootClientset, controller.NoResyncPeriodFunc()) informers := informers.NewSharedInformerFactory(rootClientset, controller.NoResyncPeriodFunc())
masterConfig := framework.NewMasterConfig() masterConfig := framework.NewMasterConfig()
@ -460,7 +459,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
return rootClientset, clientConfig, stop, err return rootClientset, clientConfig, stop, err
} }
informers.Start(stopCh) informers.Start(stopCh)
internalInformers.Start(stopCh) externalInformers.Start(stopCh)
go serviceAccountController.Run(5, stopCh) go serviceAccountController.Run(5, stopCh)
return rootClientset, clientConfig, stop, nil return rootClientset, clientConfig, stop, nil