github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.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 install installs the v1 monolithic api, making it available as an 18 // option to all of the API encoding/decoding machinery. 19 package install 20 21 import ( 22 "fmt" 23 24 "github.com/golang/glog" 25 26 "k8s.io/kubernetes/pkg/api" 27 "k8s.io/kubernetes/pkg/api/meta" 28 "k8s.io/kubernetes/pkg/api/unversioned" 29 "k8s.io/kubernetes/pkg/api/v1" 30 "k8s.io/kubernetes/pkg/apimachinery" 31 "k8s.io/kubernetes/pkg/apimachinery/registered" 32 "k8s.io/kubernetes/pkg/conversion" 33 "k8s.io/kubernetes/pkg/runtime" 34 "k8s.io/kubernetes/pkg/util/sets" 35 ) 36 37 const importPrefix = "k8s.io/kubernetes/pkg/api" 38 39 var accessor = meta.NewAccessor() 40 41 // availableVersions lists all known external versions for this group from most preferred to least preferred 42 var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion} 43 44 func init() { 45 registered.RegisterVersions(availableVersions) 46 externalVersions := []unversioned.GroupVersion{} 47 for _, v := range availableVersions { 48 if registered.IsAllowedVersion(v) { 49 externalVersions = append(externalVersions, v) 50 } 51 } 52 if len(externalVersions) == 0 { 53 glog.V(4).Infof("No version is registered for group %v", api.GroupName) 54 return 55 } 56 57 if err := registered.EnableVersions(externalVersions...); err != nil { 58 glog.V(4).Infof("%v", err) 59 return 60 } 61 if err := enableVersions(externalVersions); err != nil { 62 glog.V(4).Infof("%v", err) 63 return 64 } 65 } 66 67 // TODO: enableVersions should be centralized rather than spread in each API 68 // group. 69 // We can combine registered.RegisterVersions, registered.EnableVersions and 70 // registered.RegisterGroup once we have moved enableVersions there. 71 func enableVersions(externalVersions []unversioned.GroupVersion) error { 72 addVersionsToScheme(externalVersions...) 73 preferredExternalVersion := externalVersions[0] 74 75 groupMeta := apimachinery.GroupMeta{ 76 GroupVersion: preferredExternalVersion, 77 GroupVersions: externalVersions, 78 RESTMapper: newRESTMapper(externalVersions), 79 SelfLinker: runtime.SelfLinker(accessor), 80 InterfacesFor: interfacesFor, 81 } 82 83 if err := registered.RegisterGroup(groupMeta); err != nil { 84 return err 85 } 86 api.RegisterRESTMapper(groupMeta.RESTMapper) 87 return nil 88 } 89 90 // userResources is a group of resources mostly used by a kubectl user 91 var userResources = []string{"rc", "svc", "pods", "pvc"} 92 93 func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { 94 // the list of kinds that are scoped at the root of the api hierarchy 95 // if a kind is not enumerated here, it is assumed to have a namespace scope 96 rootScoped := sets.NewString( 97 "Node", 98 "Namespace", 99 "PersistentVolume", 100 "ComponentStatus", 101 ) 102 103 // these kinds should be excluded from the list of resources 104 ignoredKinds := sets.NewString( 105 "ListOptions", 106 "DeleteOptions", 107 "Status", 108 "PodLogOptions", 109 "PodExecOptions", 110 "PodAttachOptions", 111 "PodProxyOptions", 112 "NodeProxyOptions", 113 "ServiceProxyOptions", 114 "ThirdPartyResource", 115 "ThirdPartyResourceData", 116 "ThirdPartyResourceList") 117 118 mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) 119 // setup aliases for groups of resources 120 mapper.AddResourceAlias("all", userResources...) 121 122 return mapper 123 } 124 125 // InterfacesFor returns the default Codec and ResourceVersioner for a given version 126 // string, or an error if the version is not known. 127 func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { 128 switch version { 129 case v1.SchemeGroupVersion: 130 return &meta.VersionInterfaces{ 131 ObjectConvertor: api.Scheme, 132 MetadataAccessor: accessor, 133 }, nil 134 default: 135 g, _ := registered.Group(api.GroupName) 136 return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) 137 } 138 } 139 140 func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) { 141 // add the internal version to Scheme 142 api.AddToScheme(api.Scheme) 143 // add the enabled external versions to Scheme 144 for _, v := range externalVersions { 145 if !registered.IsEnabledVersion(v) { 146 glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v) 147 continue 148 } 149 switch v { 150 case v1.SchemeGroupVersion: 151 v1.AddToScheme(api.Scheme) 152 } 153 } 154 155 // This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are 156 // converted the most in the cluster. 157 // TODO: generate one of these for every external API group - this is to prove the impact 158 api.Scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) { 159 switch a := objA.(type) { 160 case *v1.Pod: 161 switch b := objB.(type) { 162 case *api.Pod: 163 return true, v1.Convert_v1_Pod_To_api_Pod(a, b, s) 164 } 165 case *api.Pod: 166 switch b := objB.(type) { 167 case *v1.Pod: 168 return true, v1.Convert_api_Pod_To_v1_Pod(a, b, s) 169 } 170 171 case *v1.Event: 172 switch b := objB.(type) { 173 case *api.Event: 174 return true, v1.Convert_v1_Event_To_api_Event(a, b, s) 175 } 176 case *api.Event: 177 switch b := objB.(type) { 178 case *v1.Event: 179 return true, v1.Convert_api_Event_To_v1_Event(a, b, s) 180 } 181 182 case *v1.ReplicationController: 183 switch b := objB.(type) { 184 case *api.ReplicationController: 185 return true, v1.Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s) 186 } 187 case *api.ReplicationController: 188 switch b := objB.(type) { 189 case *v1.ReplicationController: 190 return true, v1.Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s) 191 } 192 193 case *v1.Node: 194 switch b := objB.(type) { 195 case *api.Node: 196 return true, v1.Convert_v1_Node_To_api_Node(a, b, s) 197 } 198 case *api.Node: 199 switch b := objB.(type) { 200 case *v1.Node: 201 return true, v1.Convert_api_Node_To_v1_Node(a, b, s) 202 } 203 204 case *v1.Namespace: 205 switch b := objB.(type) { 206 case *api.Namespace: 207 return true, v1.Convert_v1_Namespace_To_api_Namespace(a, b, s) 208 } 209 case *api.Namespace: 210 switch b := objB.(type) { 211 case *v1.Namespace: 212 return true, v1.Convert_api_Namespace_To_v1_Namespace(a, b, s) 213 } 214 215 case *v1.Service: 216 switch b := objB.(type) { 217 case *api.Service: 218 return true, v1.Convert_v1_Service_To_api_Service(a, b, s) 219 } 220 case *api.Service: 221 switch b := objB.(type) { 222 case *v1.Service: 223 return true, v1.Convert_api_Service_To_v1_Service(a, b, s) 224 } 225 226 case *v1.Endpoints: 227 switch b := objB.(type) { 228 case *api.Endpoints: 229 return true, v1.Convert_v1_Endpoints_To_api_Endpoints(a, b, s) 230 } 231 case *api.Endpoints: 232 switch b := objB.(type) { 233 case *v1.Endpoints: 234 return true, v1.Convert_api_Endpoints_To_v1_Endpoints(a, b, s) 235 } 236 } 237 return false, nil 238 }) 239 }