| /* |
| Copyright 2014 The Kubernetes Authors. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package cache |
| |
| import ( |
| "k8s.io/klog" |
| |
| "k8s.io/apimachinery/pkg/api/errors" |
| "k8s.io/apimachinery/pkg/api/meta" |
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| "k8s.io/apimachinery/pkg/labels" |
| "k8s.io/apimachinery/pkg/runtime" |
| "k8s.io/apimachinery/pkg/runtime/schema" |
| ) |
| |
| // AppendFunc is used to add a matching item to whatever list the caller is using |
| type AppendFunc func(interface{}) |
| |
| func ListAll(store Store, selector labels.Selector, appendFn AppendFunc) error { |
| for _, m := range store.List() { |
| metadata, err := meta.Accessor(m) |
| if err != nil { |
| return err |
| } |
| if selector.Matches(labels.Set(metadata.GetLabels())) { |
| appendFn(m) |
| } |
| } |
| return nil |
| } |
| |
| func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selector, appendFn AppendFunc) error { |
| if namespace == metav1.NamespaceAll { |
| for _, m := range indexer.List() { |
| metadata, err := meta.Accessor(m) |
| if err != nil { |
| return err |
| } |
| if selector.Matches(labels.Set(metadata.GetLabels())) { |
| appendFn(m) |
| } |
| } |
| return nil |
| } |
| |
| items, err := indexer.Index(NamespaceIndex, &metav1.ObjectMeta{Namespace: namespace}) |
| if err != nil { |
| // Ignore error; do slow search without index. |
| klog.Warningf("can not retrieve list of objects using index : %v", err) |
| for _, m := range indexer.List() { |
| metadata, err := meta.Accessor(m) |
| if err != nil { |
| return err |
| } |
| if metadata.GetNamespace() == namespace && selector.Matches(labels.Set(metadata.GetLabels())) { |
| appendFn(m) |
| } |
| |
| } |
| return nil |
| } |
| for _, m := range items { |
| metadata, err := meta.Accessor(m) |
| if err != nil { |
| return err |
| } |
| if selector.Matches(labels.Set(metadata.GetLabels())) { |
| appendFn(m) |
| } |
| } |
| |
| return nil |
| } |
| |
| // GenericLister is a lister skin on a generic Indexer |
| type GenericLister interface { |
| // List will return all objects across namespaces |
| List(selector labels.Selector) (ret []runtime.Object, err error) |
| // Get will attempt to retrieve assuming that name==key |
| Get(name string) (runtime.Object, error) |
| // ByNamespace will give you a GenericNamespaceLister for one namespace |
| ByNamespace(namespace string) GenericNamespaceLister |
| } |
| |
| // GenericNamespaceLister is a lister skin on a generic Indexer |
| type GenericNamespaceLister interface { |
| // List will return all objects in this namespace |
| List(selector labels.Selector) (ret []runtime.Object, err error) |
| // Get will attempt to retrieve by namespace and name |
| Get(name string) (runtime.Object, error) |
| } |
| |
| func NewGenericLister(indexer Indexer, resource schema.GroupResource) GenericLister { |
| return &genericLister{indexer: indexer, resource: resource} |
| } |
| |
| type genericLister struct { |
| indexer Indexer |
| resource schema.GroupResource |
| } |
| |
| func (s *genericLister) List(selector labels.Selector) (ret []runtime.Object, err error) { |
| err = ListAll(s.indexer, selector, func(m interface{}) { |
| ret = append(ret, m.(runtime.Object)) |
| }) |
| return ret, err |
| } |
| |
| func (s *genericLister) ByNamespace(namespace string) GenericNamespaceLister { |
| return &genericNamespaceLister{indexer: s.indexer, namespace: namespace, resource: s.resource} |
| } |
| |
| func (s *genericLister) Get(name string) (runtime.Object, error) { |
| obj, exists, err := s.indexer.GetByKey(name) |
| if err != nil { |
| return nil, err |
| } |
| if !exists { |
| return nil, errors.NewNotFound(s.resource, name) |
| } |
| return obj.(runtime.Object), nil |
| } |
| |
| type genericNamespaceLister struct { |
| indexer Indexer |
| namespace string |
| resource schema.GroupResource |
| } |
| |
| func (s *genericNamespaceLister) List(selector labels.Selector) (ret []runtime.Object, err error) { |
| err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { |
| ret = append(ret, m.(runtime.Object)) |
| }) |
| return ret, err |
| } |
| |
| func (s *genericNamespaceLister) Get(name string) (runtime.Object, error) { |
| obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) |
| if err != nil { |
| return nil, err |
| } |
| if !exists { |
| return nil, errors.NewNotFound(s.resource, name) |
| } |
| return obj.(runtime.Object), nil |
| } |