Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / apimachinery / pkg / api / meta / multirestmapper.go
1 /*
2 Copyright 2014 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package meta
18
19 import (
20         "fmt"
21         "strings"
22
23         "k8s.io/apimachinery/pkg/runtime/schema"
24         utilerrors "k8s.io/apimachinery/pkg/util/errors"
25 )
26
27 // MultiRESTMapper is a wrapper for multiple RESTMappers.
28 type MultiRESTMapper []RESTMapper
29
30 func (m MultiRESTMapper) String() string {
31         nested := []string{}
32         for _, t := range m {
33                 currString := fmt.Sprintf("%v", t)
34                 splitStrings := strings.Split(currString, "\n")
35                 nested = append(nested, strings.Join(splitStrings, "\n\t"))
36         }
37
38         return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t"))
39 }
40
41 // ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod)
42 // This implementation supports multiple REST schemas and return the first match.
43 func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
44         for _, t := range m {
45                 singular, err = t.ResourceSingularizer(resource)
46                 if err == nil {
47                         return
48                 }
49         }
50         return
51 }
52
53 func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
54         allGVRs := []schema.GroupVersionResource{}
55         for _, t := range m {
56                 gvrs, err := t.ResourcesFor(resource)
57                 // ignore "no match" errors, but any other error percolates back up
58                 if IsNoMatchError(err) {
59                         continue
60                 }
61                 if err != nil {
62                         return nil, err
63                 }
64
65                 // walk the existing values to de-dup
66                 for _, curr := range gvrs {
67                         found := false
68                         for _, existing := range allGVRs {
69                                 if curr == existing {
70                                         found = true
71                                         break
72                                 }
73                         }
74
75                         if !found {
76                                 allGVRs = append(allGVRs, curr)
77                         }
78                 }
79         }
80
81         if len(allGVRs) == 0 {
82                 return nil, &NoResourceMatchError{PartialResource: resource}
83         }
84
85         return allGVRs, nil
86 }
87
88 func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
89         allGVKs := []schema.GroupVersionKind{}
90         for _, t := range m {
91                 gvks, err := t.KindsFor(resource)
92                 // ignore "no match" errors, but any other error percolates back up
93                 if IsNoMatchError(err) {
94                         continue
95                 }
96                 if err != nil {
97                         return nil, err
98                 }
99
100                 // walk the existing values to de-dup
101                 for _, curr := range gvks {
102                         found := false
103                         for _, existing := range allGVKs {
104                                 if curr == existing {
105                                         found = true
106                                         break
107                                 }
108                         }
109
110                         if !found {
111                                 allGVKs = append(allGVKs, curr)
112                         }
113                 }
114         }
115
116         if len(allGVKs) == 0 {
117                 return nil, &NoResourceMatchError{PartialResource: resource}
118         }
119
120         return allGVKs, nil
121 }
122
123 func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
124         resources, err := m.ResourcesFor(resource)
125         if err != nil {
126                 return schema.GroupVersionResource{}, err
127         }
128         if len(resources) == 1 {
129                 return resources[0], nil
130         }
131
132         return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
133 }
134
135 func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
136         kinds, err := m.KindsFor(resource)
137         if err != nil {
138                 return schema.GroupVersionKind{}, err
139         }
140         if len(kinds) == 1 {
141                 return kinds[0], nil
142         }
143
144         return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
145 }
146
147 // RESTMapping provides the REST mapping for the resource based on the
148 // kind and version. This implementation supports multiple REST schemas and
149 // return the first match.
150 func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
151         allMappings := []*RESTMapping{}
152         errors := []error{}
153
154         for _, t := range m {
155                 currMapping, err := t.RESTMapping(gk, versions...)
156                 // ignore "no match" errors, but any other error percolates back up
157                 if IsNoMatchError(err) {
158                         continue
159                 }
160                 if err != nil {
161                         errors = append(errors, err)
162                         continue
163                 }
164
165                 allMappings = append(allMappings, currMapping)
166         }
167
168         // if we got exactly one mapping, then use it even if other requested failed
169         if len(allMappings) == 1 {
170                 return allMappings[0], nil
171         }
172         if len(allMappings) > 1 {
173                 var kinds []schema.GroupVersionKind
174                 for _, m := range allMappings {
175                         kinds = append(kinds, m.GroupVersionKind)
176                 }
177                 return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
178         }
179         if len(errors) > 0 {
180                 return nil, utilerrors.NewAggregate(errors)
181         }
182         return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
183 }
184
185 // RESTMappings returns all possible RESTMappings for the provided group kind, or an error
186 // if the type is not recognized.
187 func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) {
188         var allMappings []*RESTMapping
189         var errors []error
190
191         for _, t := range m {
192                 currMappings, err := t.RESTMappings(gk, versions...)
193                 // ignore "no match" errors, but any other error percolates back up
194                 if IsNoMatchError(err) {
195                         continue
196                 }
197                 if err != nil {
198                         errors = append(errors, err)
199                         continue
200                 }
201                 allMappings = append(allMappings, currMappings...)
202         }
203         if len(errors) > 0 {
204                 return nil, utilerrors.NewAggregate(errors)
205         }
206         if len(allMappings) == 0 {
207                 return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
208         }
209         return allMappings, nil
210 }