github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testapi/testapi.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors All rights reserved. 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 testapi provides a helper for retrieving the KUBE_TEST_API environment variable. 18 package testapi 19 20 import ( 21 "fmt" 22 "os" 23 "strings" 24 25 "k8s.io/kubernetes/pkg/api" 26 _ "k8s.io/kubernetes/pkg/api/install" 27 "k8s.io/kubernetes/pkg/api/unversioned" 28 _ "k8s.io/kubernetes/pkg/apis/extensions/install" 29 _ "k8s.io/kubernetes/pkg/apis/metrics/install" 30 31 "k8s.io/kubernetes/pkg/api/latest" 32 "k8s.io/kubernetes/pkg/api/meta" 33 apiutil "k8s.io/kubernetes/pkg/api/util" 34 "k8s.io/kubernetes/pkg/runtime" 35 ) 36 37 var ( 38 Groups = make(map[string]TestGroup) 39 Default TestGroup 40 Extensions TestGroup 41 ) 42 43 type TestGroup struct { 44 // Name of the group 45 Group string 46 // Version of the group Group under test 47 VersionUnderTest string 48 // Group and Version. In most cases equals to Group + "/" + VersionUnverTest 49 GroupVersionUnderTest string 50 } 51 52 func init() { 53 kubeTestAPI := os.Getenv("KUBE_TEST_API") 54 if kubeTestAPI != "" { 55 testGroupVersions := strings.Split(kubeTestAPI, ",") 56 for _, groupVersion := range testGroupVersions { 57 // TODO: caesarxuchao: the apiutil package is hacky, it will be replaced 58 // by a following PR. 59 Groups[apiutil.GetGroup(groupVersion)] = 60 TestGroup{apiutil.GetGroup(groupVersion), apiutil.GetVersion(groupVersion), groupVersion} 61 } 62 } 63 64 // TODO: caesarxuchao: we need a central place to store all available API 65 // groups and their metadata. 66 if _, ok := Groups[""]; !ok { 67 // TODO: The second latest.GroupOrDie("").Version will be latest.GroupVersion after we 68 // have multiple group support 69 Groups[""] = TestGroup{"", latest.GroupOrDie("").Version, latest.GroupOrDie("").GroupVersion} 70 } 71 if _, ok := Groups["extensions"]; !ok { 72 Groups["extensions"] = TestGroup{"extensions", latest.GroupOrDie("extensions").Version, latest.GroupOrDie("extensions").GroupVersion} 73 } 74 75 Default = Groups[""] 76 Extensions = Groups["extensions"] 77 } 78 79 // Version returns the API version to test against, as set by the KUBE_TEST_API env var. 80 func (g TestGroup) Version() string { 81 return g.VersionUnderTest 82 } 83 84 // GroupAndVersion returns the API version to test against for a group, as set 85 // by the KUBE_TEST_API env var. 86 // Return value is in the form of "group/version". 87 func (g TestGroup) GroupAndVersion() string { 88 return g.GroupVersionUnderTest 89 } 90 91 func (g TestGroup) GroupVersion() *unversioned.GroupVersion { 92 gv, err := unversioned.ParseGroupVersion(g.GroupVersionUnderTest) 93 if err != nil { 94 panic(err) 95 } 96 return &gv 97 } 98 99 // Codec returns the codec for the API version to test against, as set by the 100 // KUBE_TEST_API env var. 101 func (g TestGroup) Codec() runtime.Codec { 102 // TODO: caesarxuchao: Restructure the body once we have a central `latest`. 103 interfaces, err := latest.GroupOrDie(g.Group).InterfacesFor(g.GroupVersionUnderTest) 104 if err != nil { 105 panic(err) 106 } 107 return interfaces.Codec 108 } 109 110 // Converter returns the api.Scheme for the API version to test against, as set by the 111 // KUBE_TEST_API env var. 112 func (g TestGroup) Converter() runtime.ObjectConvertor { 113 // TODO: caesarxuchao: Restructure the body once we have a central `latest`. 114 if g.Group == "" { 115 interfaces, err := latest.GroupOrDie("").InterfacesFor(g.VersionUnderTest) 116 if err != nil { 117 panic(err) 118 } 119 return interfaces.ObjectConvertor 120 } 121 if g.Group == "extensions" { 122 interfaces, err := latest.GroupOrDie("extensions").InterfacesFor(g.VersionUnderTest) 123 if err != nil { 124 panic(err) 125 } 126 return interfaces.ObjectConvertor 127 } 128 panic(fmt.Errorf("cannot test group %s", g.Group)) 129 130 } 131 132 // MetadataAccessor returns the MetadataAccessor for the API version to test against, 133 // as set by the KUBE_TEST_API env var. 134 func (g TestGroup) MetadataAccessor() meta.MetadataAccessor { 135 // TODO: caesarxuchao: Restructure the body once we have a central `latest`. 136 if g.Group == "" { 137 interfaces, err := latest.GroupOrDie("").InterfacesFor(g.VersionUnderTest) 138 if err != nil { 139 panic(err) 140 } 141 return interfaces.MetadataAccessor 142 } 143 if g.Group == "extensions" { 144 interfaces, err := latest.GroupOrDie("extensions").InterfacesFor(g.VersionUnderTest) 145 if err != nil { 146 panic(err) 147 } 148 return interfaces.MetadataAccessor 149 } 150 panic(fmt.Errorf("cannot test group %s", g.Group)) 151 } 152 153 // SelfLink returns a self link that will appear to be for the version Version(). 154 // 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be 155 // empty for lists. 156 func (g TestGroup) SelfLink(resource, name string) string { 157 if g.Group == "" { 158 if name == "" { 159 return fmt.Sprintf("/api/%s/%s", g.Version(), resource) 160 } 161 return fmt.Sprintf("/api/%s/%s/%s", g.Version(), resource, name) 162 } else { 163 // TODO: will need a /apis prefix once we have proper multi-group 164 // support 165 if name == "" { 166 return fmt.Sprintf("/apis/%s/%s/%s", g.Group, g.Version(), resource) 167 } 168 return fmt.Sprintf("/apis/%s/%s/%s/%s", g.Group, g.Version(), resource, name) 169 } 170 } 171 172 // Returns the appropriate path for the given prefix (watch, proxy, redirect, etc), resource, namespace and name. 173 // For ex, this is of the form: 174 // /api/v1/watch/namespaces/foo/pods/pod0 for v1. 175 func (g TestGroup) ResourcePathWithPrefix(prefix, resource, namespace, name string) string { 176 var path string 177 if len(g.Group) == 0 { 178 path = "/api/" + g.Version() 179 } else { 180 // TODO: switch back once we have proper multiple group support 181 // path = "/apis/" + g.Group + "/" + Version(group...) 182 path = "/apis/" + g.Group + "/" + g.Version() 183 } 184 185 if prefix != "" { 186 path = path + "/" + prefix 187 } 188 if namespace != "" { 189 path = path + "/namespaces/" + namespace 190 } 191 // Resource names are lower case. 192 resource = strings.ToLower(resource) 193 if resource != "" { 194 path = path + "/" + resource 195 } 196 if name != "" { 197 path = path + "/" + name 198 } 199 return path 200 } 201 202 // Returns the appropriate path for the given resource, namespace and name. 203 // For example, this is of the form: 204 // /api/v1/namespaces/foo/pods/pod0 for v1. 205 func (g TestGroup) ResourcePath(resource, namespace, name string) string { 206 return g.ResourcePathWithPrefix("", resource, namespace, name) 207 } 208 209 func (g TestGroup) RESTMapper() meta.RESTMapper { 210 return latest.GroupOrDie(g.Group).RESTMapper 211 } 212 213 // Get codec based on runtime.Object 214 func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) { 215 _, kind, err := api.Scheme.ObjectVersionAndKind(obj) 216 if err != nil { 217 return nil, fmt.Errorf("unexpected encoding error: %v", err) 218 } 219 // TODO: caesarxuchao: we should detect which group an object belongs to 220 // by using the version returned by Schem.ObjectVersionAndKind() once we 221 // split the schemes for internal objects. 222 // TODO: caesarxuchao: we should add a map from kind to group in Scheme. 223 for _, group := range Groups { 224 if api.Scheme.Recognizes(group.GroupAndVersion(), kind) { 225 return group.Codec(), nil 226 } 227 } 228 // Codec used for unversioned types 229 if api.Scheme.Recognizes("", kind) { 230 return api.Codec, nil 231 } 232 return nil, fmt.Errorf("unexpected kind: %v", kind) 233 }