// 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" // 2. It ensures the ServiceAccount referenced by the pod exists // 3. If LimitSecretReferences is true, it rejects the pod if the pod references Secret objects which the pod's ServiceAccount does not reference // 4. If the pod does not contain any ImagePullSecrets, the ImagePullSecrets of the service account are added. // 5. If MountServiceAccountToken is true, it adds a VolumeMount with the pod's ServiceAccount's api token secret to containers func NewServiceAccount(cl client.Interface) *serviceAccount { serviceAccountsIndexer, serviceAccountsReflector := cache.NewNamespaceKeyedIndexerAndReflector( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return cl.ServiceAccounts(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return cl.ServiceAccounts(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) }, }, &api.ServiceAccount{}, 0, ) tokenSelector := fields.SelectorFromSet(map[string]string{client.SecretType: string(api.SecretTypeServiceAccountToken)}) secretsIndexer, secretsReflector := cache.NewNamespaceKeyedIndexerAndReflector( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return cl.Secrets(api.NamespaceAll).List(labels.Everything(), tokenSelector) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return cl.Secrets(api.NamespaceAll).Watch(labels.Everything(), tokenSelector, resourceVersion) }, }, &api.Secret{}, 0, ) return &serviceAccount{ Handler: admission.NewHandler(admission.Create), // TODO: enable this once we've swept secret usage to account for adding secret references to service accounts LimitSecretReferences: false, // Auto mount service account API token secrets MountServiceAccountToken: true, client: cl, serviceAccounts: serviceAccountsIndexer, serviceAccountsReflector: serviceAccountsReflector, secrets: secretsIndexer, secretsReflector: secretsReflector, } }
// NewResourceQuota creates a new resource quota admission control handler func NewResourceQuota(client client.Interface) admission.Interface { lw := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return client.ResourceQuotas(api.NamespaceAll).List(labels.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return client.ResourceQuotas(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) }, } indexer, reflector := cache.NewNamespaceKeyedIndexerAndReflector(lw, &api.ResourceQuota{}, 0) reflector.Run() return createResourceQuota(client, indexer) }
// NewLimitRanger returns an object that enforces limits based on the supplied limit function func NewLimitRanger(client client.Interface, limitFunc LimitFunc) admission.Interface { lw := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return client.LimitRanges(api.NamespaceAll).List(labels.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return client.LimitRanges(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) }, } indexer, reflector := cache.NewNamespaceKeyedIndexerAndReflector(lw, &api.LimitRange{}, 0) reflector.Run() return &limitRanger{ Handler: admission.NewHandler(admission.Create, admission.Update), client: client, limitFunc: limitFunc, indexer: indexer, } }