From aa9efadec5919e010b7cdcd84ee97b395d196866 Mon Sep 17 00:00:00 2001 From: Salvatore Dario Minonne Date: Tue, 11 Oct 2016 16:14:14 +0200 Subject: [PATCH] To add Informer for ServiceAccount --- pkg/client/cache/serviceaccount.go | 64 +++++++++++++++++++ .../shared/serviceaccount_informers.go | 62 ++++++++++++++++++ pkg/controller/shared/shared_informer.go | 6 ++ 3 files changed, 132 insertions(+) create mode 100644 pkg/client/cache/serviceaccount.go create mode 100644 pkg/controller/shared/serviceaccount_informers.go diff --git a/pkg/client/cache/serviceaccount.go b/pkg/client/cache/serviceaccount.go new file mode 100644 index 000000000000..c426d62dc08d --- /dev/null +++ b/pkg/client/cache/serviceaccount.go @@ -0,0 +1,64 @@ +package cache + +import ( + kapi "k8s.io/kubernetes/pkg/api" + kapierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/labels" +) + +// StoreToServiceAccountLister gives a store List and Exists methods. The store must contain only ServiceAccounts. +type StoreToServiceAccountLister struct { + cache.Indexer +} + +func (s *StoreToServiceAccountLister) ServiceAccounts(namespace string) storeServiceAccountsNamespacer { + return storeServiceAccountsNamespacer{s.Indexer, namespace} +} + +// storeServiceAccountsNamespacer provides a way to get and list ServiceAccounts from a specific namespace. +type storeServiceAccountsNamespacer struct { + indexer cache.Indexer + namespace string +} + +// Get the ServiceAccount matching the name from the cache. +func (s storeServiceAccountsNamespacer) Get(name string) (*kapi.ServiceAccount, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, kapierrors.NewNotFound(kapi.Resource("serviceaccount"), name) + } + return obj.(*kapi.ServiceAccount), nil +} + +// List all the ServiceAccounts that match the provided selector using a namespace index. +// If the indexed list fails then we will fallback to listing from all namespaces and filter +// by the namespace we want. +func (s storeServiceAccountsNamespacer) List(selector labels.Selector) ([]*kapi.ServiceAccount, error) { + serviceAccounts := []*kapi.ServiceAccount{} + + if s.namespace == kapi.NamespaceAll { + for _, obj := range s.indexer.List() { + bc := obj.(*kapi.ServiceAccount) + if selector.Matches(labels.Set(bc.Labels)) { + serviceAccounts = append(serviceAccounts, bc) + } + } + return serviceAccounts, nil + } + + items, err := s.indexer.ByIndex(cache.NamespaceIndex, s.namespace) + if err != nil { + return nil, err + } + for _, obj := range items { + bc := obj.(*kapi.ServiceAccount) + if selector.Matches(labels.Set(bc.Labels)) { + serviceAccounts = append(serviceAccounts, bc) + } + } + return serviceAccounts, nil +} diff --git a/pkg/controller/shared/serviceaccount_informers.go b/pkg/controller/shared/serviceaccount_informers.go new file mode 100644 index 000000000000..209e20975a57 --- /dev/null +++ b/pkg/controller/shared/serviceaccount_informers.go @@ -0,0 +1,62 @@ +package shared + +import ( + "reflect" + + kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/controller/framework" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/watch" + + oscache "github.com/openshift/origin/pkg/client/cache" +) + +type ServiceAccountInformer interface { + Informer() framework.SharedIndexInformer + Indexer() cache.Indexer + Lister() oscache.StoreToServiceAccountLister +} + +type serviceAccountInformer struct { + *sharedInformerFactory +} + +func (s *serviceAccountInformer) Informer() framework.SharedIndexInformer { + s.lock.Lock() + defer s.lock.Unlock() + + informerObj := &kapi.ServiceAccount{} + informerType := reflect.TypeOf(informerObj) + informer, exists := s.informers[informerType] + if exists { + return informer + } + + informer = framework.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options kapi.ListOptions) (runtime.Object, error) { + return s.kubeClient.ServiceAccounts(kapi.NamespaceAll).List(options) + }, + WatchFunc: func(options kapi.ListOptions) (watch.Interface, error) { + return s.kubeClient.ServiceAccounts(kapi.NamespaceAll).Watch(options) + }, + }, + informerObj, + s.defaultResync, + cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, + ) + s.informers[informerType] = informer + + return informer +} + +func (s *serviceAccountInformer) Indexer() cache.Indexer { + informer := s.Informer() + return informer.GetIndexer() +} + +func (s *serviceAccountInformer) Lister() oscache.StoreToServiceAccountLister { + informer := s.Informer() + return oscache.StoreToServiceAccountLister{Indexer: informer.GetIndexer()} +} diff --git a/pkg/controller/shared/shared_informer.go b/pkg/controller/shared/shared_informer.go index 3259421054db..8cbe41484331 100644 --- a/pkg/controller/shared/shared_informer.go +++ b/pkg/controller/shared/shared_informer.go @@ -38,6 +38,7 @@ type InformerFactory interface { ImageStreams() ImageStreamInformer SecurityContextConstraints() SecurityContextConstraintsInformer ClusterResourceQuotas() ClusterResourceQuotaInformer + ServiceAccounts() ServiceAccountInformer KubernetesInformers() informers.SharedInformerFactory } @@ -175,6 +176,11 @@ func (f *sharedInformerFactory) KubernetesInformers() informers.SharedInformerFa return kubernetesSharedInformer{f} } +// TODO: it should use upstream informer as soon #34960 get merged +func (f *sharedInformerFactory) ServiceAccounts() ServiceAccountInformer { + return &serviceAccountInformer{sharedInformerFactory: f} +} + // kubernetesSharedInformer adapts this informer factory to the identical interface as kubernetes type kubernetesSharedInformer struct { f *sharedInformerFactory