blob: 27d51a6b38797f9a70ea205249fcf848c6ddd0cc [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001/*
2Copyright 2014 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package cache
18
19import (
20 "github.com/golang/glog"
21
22 "k8s.io/apimachinery/pkg/api/errors"
23 "k8s.io/apimachinery/pkg/api/meta"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/apimachinery/pkg/labels"
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/runtime/schema"
28)
29
30// AppendFunc is used to add a matching item to whatever list the caller is using
31type AppendFunc func(interface{})
32
33func ListAll(store Store, selector labels.Selector, appendFn AppendFunc) error {
34 for _, m := range store.List() {
35 metadata, err := meta.Accessor(m)
36 if err != nil {
37 return err
38 }
39 if selector.Matches(labels.Set(metadata.GetLabels())) {
40 appendFn(m)
41 }
42 }
43 return nil
44}
45
46func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selector, appendFn AppendFunc) error {
47 if namespace == metav1.NamespaceAll {
48 for _, m := range indexer.List() {
49 metadata, err := meta.Accessor(m)
50 if err != nil {
51 return err
52 }
53 if selector.Matches(labels.Set(metadata.GetLabels())) {
54 appendFn(m)
55 }
56 }
57 return nil
58 }
59
60 items, err := indexer.Index(NamespaceIndex, &metav1.ObjectMeta{Namespace: namespace})
61 if err != nil {
62 // Ignore error; do slow search without index.
63 glog.Warningf("can not retrieve list of objects using index : %v", err)
64 for _, m := range indexer.List() {
65 metadata, err := meta.Accessor(m)
66 if err != nil {
67 return err
68 }
69 if metadata.GetNamespace() == namespace && selector.Matches(labels.Set(metadata.GetLabels())) {
70 appendFn(m)
71 }
72
73 }
74 return nil
75 }
76 for _, m := range items {
77 metadata, err := meta.Accessor(m)
78 if err != nil {
79 return err
80 }
81 if selector.Matches(labels.Set(metadata.GetLabels())) {
82 appendFn(m)
83 }
84 }
85
86 return nil
87}
88
89// GenericLister is a lister skin on a generic Indexer
90type GenericLister interface {
91 // List will return all objects across namespaces
92 List(selector labels.Selector) (ret []runtime.Object, err error)
93 // Get will attempt to retrieve assuming that name==key
94 Get(name string) (runtime.Object, error)
95 // ByNamespace will give you a GenericNamespaceLister for one namespace
96 ByNamespace(namespace string) GenericNamespaceLister
97}
98
99// GenericNamespaceLister is a lister skin on a generic Indexer
100type GenericNamespaceLister interface {
101 // List will return all objects in this namespace
102 List(selector labels.Selector) (ret []runtime.Object, err error)
103 // Get will attempt to retrieve by namespace and name
104 Get(name string) (runtime.Object, error)
105}
106
107func NewGenericLister(indexer Indexer, resource schema.GroupResource) GenericLister {
108 return &genericLister{indexer: indexer, resource: resource}
109}
110
111type genericLister struct {
112 indexer Indexer
113 resource schema.GroupResource
114}
115
116func (s *genericLister) List(selector labels.Selector) (ret []runtime.Object, err error) {
117 err = ListAll(s.indexer, selector, func(m interface{}) {
118 ret = append(ret, m.(runtime.Object))
119 })
120 return ret, err
121}
122
123func (s *genericLister) ByNamespace(namespace string) GenericNamespaceLister {
124 return &genericNamespaceLister{indexer: s.indexer, namespace: namespace, resource: s.resource}
125}
126
127func (s *genericLister) Get(name string) (runtime.Object, error) {
128 obj, exists, err := s.indexer.GetByKey(name)
129 if err != nil {
130 return nil, err
131 }
132 if !exists {
133 return nil, errors.NewNotFound(s.resource, name)
134 }
135 return obj.(runtime.Object), nil
136}
137
138type genericNamespaceLister struct {
139 indexer Indexer
140 namespace string
141 resource schema.GroupResource
142}
143
144func (s *genericNamespaceLister) List(selector labels.Selector) (ret []runtime.Object, err error) {
145 err = ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
146 ret = append(ret, m.(runtime.Object))
147 })
148 return ret, err
149}
150
151func (s *genericNamespaceLister) Get(name string) (runtime.Object, error) {
152 obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
153 if err != nil {
154 return nil, err
155 }
156 if !exists {
157 return nil, errors.NewNotFound(s.resource, name)
158 }
159 return obj.(runtime.Object), nil
160}