Commit 17306b54 authored by yue9944882's avatar yue9944882

externalize serviceaacount admission controller

remove unused internal serviceaccount util
parent 76e9fdaa
...@@ -20,7 +20,6 @@ import ( ...@@ -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 { ...@@ -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
}
...@@ -16,19 +16,20 @@ go_library( ...@@ -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( ...@@ -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",
], ],
) )
......
...@@ -23,19 +23,20 @@ import ( ...@@ -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 { ...@@ -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 { ...@@ -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) { ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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. ...@@ -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 ...@@ -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 ...@@ -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 {
......
...@@ -14,8 +14,6 @@ go_test( ...@@ -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",
......
...@@ -43,10 +43,9 @@ import ( ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment