github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/api/meta/multirestmapper.go (about) 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 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema" 24 utilerrors "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/errors" 25 ) 26 27 var ( 28 _ ResettableRESTMapper = MultiRESTMapper{} 29 ) 30 31 // MultiRESTMapper is a wrapper for multiple RESTMappers. 32 type MultiRESTMapper []RESTMapper 33 34 func (m MultiRESTMapper) String() string { 35 nested := make([]string, 0, len(m)) 36 for _, t := range m { 37 currString := fmt.Sprintf("%v", t) 38 splitStrings := strings.Split(currString, "\n") 39 nested = append(nested, strings.Join(splitStrings, "\n\t")) 40 } 41 42 return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t")) 43 } 44 45 // ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod) 46 // This implementation supports multiple REST schemas and return the first match. 47 func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { 48 for _, t := range m { 49 singular, err = t.ResourceSingularizer(resource) 50 if err == nil { 51 return 52 } 53 } 54 return 55 } 56 57 func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { 58 allGVRs := []schema.GroupVersionResource{} 59 for _, t := range m { 60 gvrs, err := t.ResourcesFor(resource) 61 // ignore "no match" errors, but any other error percolates back up 62 if IsNoMatchError(err) { 63 continue 64 } 65 if err != nil { 66 return nil, err 67 } 68 69 // walk the existing values to de-dup 70 for _, curr := range gvrs { 71 found := false 72 for _, existing := range allGVRs { 73 if curr == existing { 74 found = true 75 break 76 } 77 } 78 79 if !found { 80 allGVRs = append(allGVRs, curr) 81 } 82 } 83 } 84 85 if len(allGVRs) == 0 { 86 return nil, &NoResourceMatchError{PartialResource: resource} 87 } 88 89 return allGVRs, nil 90 } 91 92 func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { 93 allGVKs := []schema.GroupVersionKind{} 94 for _, t := range m { 95 gvks, err := t.KindsFor(resource) 96 // ignore "no match" errors, but any other error percolates back up 97 if IsNoMatchError(err) { 98 continue 99 } 100 if err != nil { 101 return nil, err 102 } 103 104 // walk the existing values to de-dup 105 for _, curr := range gvks { 106 found := false 107 for _, existing := range allGVKs { 108 if curr == existing { 109 found = true 110 break 111 } 112 } 113 114 if !found { 115 allGVKs = append(allGVKs, curr) 116 } 117 } 118 } 119 120 if len(allGVKs) == 0 { 121 return nil, &NoResourceMatchError{PartialResource: resource} 122 } 123 124 return allGVKs, nil 125 } 126 127 func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { 128 resources, err := m.ResourcesFor(resource) 129 if err != nil { 130 return schema.GroupVersionResource{}, err 131 } 132 if len(resources) == 1 { 133 return resources[0], nil 134 } 135 136 return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources} 137 } 138 139 func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { 140 kinds, err := m.KindsFor(resource) 141 if err != nil { 142 return schema.GroupVersionKind{}, err 143 } 144 if len(kinds) == 1 { 145 return kinds[0], nil 146 } 147 148 return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds} 149 } 150 151 // RESTMapping provides the REST mapping for the resource based on the 152 // kind and version. This implementation supports multiple REST schemas and 153 // return the first match. 154 func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) { 155 allMappings := []*RESTMapping{} 156 errors := []error{} 157 158 for _, t := range m { 159 currMapping, err := t.RESTMapping(gk, versions...) 160 // ignore "no match" errors, but any other error percolates back up 161 if IsNoMatchError(err) { 162 continue 163 } 164 if err != nil { 165 errors = append(errors, err) 166 continue 167 } 168 169 allMappings = append(allMappings, currMapping) 170 } 171 172 // if we got exactly one mapping, then use it even if other requested failed 173 if len(allMappings) == 1 { 174 return allMappings[0], nil 175 } 176 if len(allMappings) > 1 { 177 var kinds []schema.GroupVersionKind 178 for _, m := range allMappings { 179 kinds = append(kinds, m.GroupVersionKind) 180 } 181 return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds} 182 } 183 if len(errors) > 0 { 184 return nil, utilerrors.NewAggregate(errors) 185 } 186 return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions} 187 } 188 189 // RESTMappings returns all possible RESTMappings for the provided group kind, or an error 190 // if the type is not recognized. 191 func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { 192 var allMappings []*RESTMapping 193 var errors []error 194 195 for _, t := range m { 196 currMappings, err := t.RESTMappings(gk, versions...) 197 // ignore "no match" errors, but any other error percolates back up 198 if IsNoMatchError(err) { 199 continue 200 } 201 if err != nil { 202 errors = append(errors, err) 203 continue 204 } 205 allMappings = append(allMappings, currMappings...) 206 } 207 if len(errors) > 0 { 208 return nil, utilerrors.NewAggregate(errors) 209 } 210 if len(allMappings) == 0 { 211 return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions} 212 } 213 return allMappings, nil 214 } 215 216 func (m MultiRESTMapper) Reset() { 217 for _, t := range m { 218 MaybeResetRESTMapper(t) 219 } 220 }