github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/meta.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 meta 18 19 import ( 20 "fmt" 21 "reflect" 22 23 "k8s.io/kubernetes/pkg/conversion" 24 "k8s.io/kubernetes/pkg/runtime" 25 "k8s.io/kubernetes/pkg/types" 26 ) 27 28 // Accessor takes an arbitrary object pointer and returns meta.Interface. 29 // obj must be a pointer to an API type. An error is returned if the minimum 30 // required fields are missing. Fields that are not required return the default 31 // value and are a no-op if set. 32 // TODO: add a fast path for *TypeMeta and *ObjectMeta for internal objects 33 func Accessor(obj interface{}) (Interface, error) { 34 v, err := conversion.EnforcePtr(obj) 35 if err != nil { 36 return nil, err 37 } 38 t := v.Type() 39 if v.Kind() != reflect.Struct { 40 return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface()) 41 } 42 43 typeMeta := v.FieldByName("TypeMeta") 44 if !typeMeta.IsValid() { 45 return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t) 46 } 47 48 a := &genericAccessor{} 49 if err := extractFromTypeMeta(typeMeta, a); err != nil { 50 return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err) 51 } 52 53 objectMeta := v.FieldByName("ObjectMeta") 54 if objectMeta.IsValid() { 55 // look for the ObjectMeta fields 56 if err := extractFromObjectMeta(objectMeta, a); err != nil { 57 return nil, fmt.Errorf("unable to find object fields on %#v: %v", objectMeta, err) 58 } 59 } else { 60 listMeta := v.FieldByName("ListMeta") 61 if listMeta.IsValid() { 62 // look for the ListMeta fields 63 if err := extractFromListMeta(listMeta, a); err != nil { 64 return nil, fmt.Errorf("unable to find list fields on %#v: %v", listMeta, err) 65 } 66 } else { 67 // look for the older TypeMeta with all metadata 68 if err := extractFromObjectMeta(typeMeta, a); err != nil { 69 return nil, fmt.Errorf("unable to find object fields on %#v: %v", typeMeta, err) 70 } 71 } 72 } 73 74 return a, nil 75 } 76 77 // TypeAccessor returns an interface that allows retrieving and modifying the APIVersion 78 // and Kind of an in-memory internal object. 79 // TODO: this interface is used to test code that does not have ObjectMeta or ListMeta 80 // in round tripping (objects which can use apiVersion/kind, but do not fit the Kube 81 // api conventions). 82 func TypeAccessor(obj interface{}) (TypeInterface, error) { 83 v, err := conversion.EnforcePtr(obj) 84 if err != nil { 85 return nil, err 86 } 87 t := v.Type() 88 if v.Kind() != reflect.Struct { 89 return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface()) 90 } 91 92 typeMeta := v.FieldByName("TypeMeta") 93 if !typeMeta.IsValid() { 94 return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t) 95 } 96 a := &genericAccessor{} 97 if err := extractFromTypeMeta(typeMeta, a); err != nil { 98 return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err) 99 } 100 return a, nil 101 } 102 103 // NewAccessor returns a MetadataAccessor that can retrieve 104 // or manipulate resource version on objects derived from core API 105 // metadata concepts. 106 func NewAccessor() MetadataAccessor { 107 return resourceAccessor{} 108 } 109 110 // resourceAccessor implements ResourceVersioner and SelfLinker. 111 type resourceAccessor struct{} 112 113 func (resourceAccessor) Kind(obj runtime.Object) (string, error) { 114 accessor, err := Accessor(obj) 115 if err != nil { 116 return "", err 117 } 118 return accessor.Kind(), nil 119 } 120 121 func (resourceAccessor) SetKind(obj runtime.Object, kind string) error { 122 accessor, err := Accessor(obj) 123 if err != nil { 124 return err 125 } 126 accessor.SetKind(kind) 127 return nil 128 } 129 130 func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) { 131 accessor, err := Accessor(obj) 132 if err != nil { 133 return "", err 134 } 135 return accessor.APIVersion(), nil 136 } 137 138 func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error { 139 accessor, err := Accessor(obj) 140 if err != nil { 141 return err 142 } 143 accessor.SetAPIVersion(version) 144 return nil 145 } 146 147 func (resourceAccessor) Namespace(obj runtime.Object) (string, error) { 148 accessor, err := Accessor(obj) 149 if err != nil { 150 return "", err 151 } 152 return accessor.Namespace(), nil 153 } 154 155 func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error { 156 accessor, err := Accessor(obj) 157 if err != nil { 158 return err 159 } 160 accessor.SetNamespace(namespace) 161 return nil 162 } 163 164 func (resourceAccessor) Name(obj runtime.Object) (string, error) { 165 accessor, err := Accessor(obj) 166 if err != nil { 167 return "", err 168 } 169 return accessor.Name(), nil 170 } 171 172 func (resourceAccessor) SetName(obj runtime.Object, name string) error { 173 accessor, err := Accessor(obj) 174 if err != nil { 175 return err 176 } 177 accessor.SetName(name) 178 return nil 179 } 180 181 func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) { 182 accessor, err := Accessor(obj) 183 if err != nil { 184 return "", err 185 } 186 return accessor.GenerateName(), nil 187 } 188 189 func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error { 190 accessor, err := Accessor(obj) 191 if err != nil { 192 return err 193 } 194 accessor.SetGenerateName(name) 195 return nil 196 } 197 198 func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) { 199 accessor, err := Accessor(obj) 200 if err != nil { 201 return "", err 202 } 203 return accessor.UID(), nil 204 } 205 206 func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error { 207 accessor, err := Accessor(obj) 208 if err != nil { 209 return err 210 } 211 accessor.SetUID(uid) 212 return nil 213 } 214 215 func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) { 216 accessor, err := Accessor(obj) 217 if err != nil { 218 return "", err 219 } 220 return accessor.SelfLink(), nil 221 } 222 223 func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { 224 accessor, err := Accessor(obj) 225 if err != nil { 226 return err 227 } 228 accessor.SetSelfLink(selfLink) 229 return nil 230 } 231 232 func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) { 233 accessor, err := Accessor(obj) 234 if err != nil { 235 return nil, err 236 } 237 return accessor.Labels(), nil 238 } 239 240 func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error { 241 accessor, err := Accessor(obj) 242 if err != nil { 243 return err 244 } 245 accessor.SetLabels(labels) 246 return nil 247 } 248 249 func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) { 250 accessor, err := Accessor(obj) 251 if err != nil { 252 return nil, err 253 } 254 return accessor.Annotations(), nil 255 } 256 257 func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error { 258 accessor, err := Accessor(obj) 259 if err != nil { 260 return err 261 } 262 accessor.SetAnnotations(annotations) 263 return nil 264 } 265 266 func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { 267 accessor, err := Accessor(obj) 268 if err != nil { 269 return "", err 270 } 271 return accessor.ResourceVersion(), nil 272 } 273 274 func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { 275 accessor, err := Accessor(obj) 276 if err != nil { 277 return err 278 } 279 accessor.SetResourceVersion(version) 280 return nil 281 } 282 283 // genericAccessor contains pointers to strings that can modify an arbitrary 284 // struct and implements the Accessor interface. 285 type genericAccessor struct { 286 namespace *string 287 name *string 288 generateName *string 289 uid *types.UID 290 apiVersion *string 291 kind *string 292 resourceVersion *string 293 selfLink *string 294 labels *map[string]string 295 annotations *map[string]string 296 } 297 298 func (a genericAccessor) Namespace() string { 299 if a.namespace == nil { 300 return "" 301 } 302 return *a.namespace 303 } 304 305 func (a genericAccessor) SetNamespace(namespace string) { 306 if a.namespace == nil { 307 return 308 } 309 *a.namespace = namespace 310 } 311 312 func (a genericAccessor) Name() string { 313 if a.name == nil { 314 return "" 315 } 316 return *a.name 317 } 318 319 func (a genericAccessor) SetName(name string) { 320 if a.name == nil { 321 return 322 } 323 *a.name = name 324 } 325 326 func (a genericAccessor) GenerateName() string { 327 if a.generateName == nil { 328 return "" 329 } 330 return *a.generateName 331 } 332 333 func (a genericAccessor) SetGenerateName(generateName string) { 334 if a.generateName == nil { 335 return 336 } 337 *a.generateName = generateName 338 } 339 340 func (a genericAccessor) UID() types.UID { 341 if a.uid == nil { 342 return "" 343 } 344 return *a.uid 345 } 346 347 func (a genericAccessor) SetUID(uid types.UID) { 348 if a.uid == nil { 349 return 350 } 351 *a.uid = uid 352 } 353 354 func (a genericAccessor) APIVersion() string { 355 return *a.apiVersion 356 } 357 358 func (a genericAccessor) SetAPIVersion(version string) { 359 *a.apiVersion = version 360 } 361 362 func (a genericAccessor) Kind() string { 363 return *a.kind 364 } 365 366 func (a genericAccessor) SetKind(kind string) { 367 *a.kind = kind 368 } 369 370 func (a genericAccessor) ResourceVersion() string { 371 return *a.resourceVersion 372 } 373 374 func (a genericAccessor) SetResourceVersion(version string) { 375 *a.resourceVersion = version 376 } 377 378 func (a genericAccessor) SelfLink() string { 379 return *a.selfLink 380 } 381 382 func (a genericAccessor) SetSelfLink(selfLink string) { 383 *a.selfLink = selfLink 384 } 385 386 func (a genericAccessor) Labels() map[string]string { 387 if a.labels == nil { 388 return nil 389 } 390 return *a.labels 391 } 392 393 func (a genericAccessor) SetLabels(labels map[string]string) { 394 *a.labels = labels 395 } 396 397 func (a genericAccessor) Annotations() map[string]string { 398 if a.annotations == nil { 399 return nil 400 } 401 return *a.annotations 402 } 403 404 func (a genericAccessor) SetAnnotations(annotations map[string]string) { 405 if a.annotations == nil { 406 emptyAnnotations := make(map[string]string) 407 a.annotations = &emptyAnnotations 408 } 409 *a.annotations = annotations 410 } 411 412 // extractFromTypeMeta extracts pointers to version and kind fields from an object 413 func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error { 414 if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil { 415 return err 416 } 417 if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil { 418 return err 419 } 420 return nil 421 } 422 423 // extractFromObjectMeta extracts pointers to metadata fields from an object 424 func extractFromObjectMeta(v reflect.Value, a *genericAccessor) error { 425 if err := runtime.FieldPtr(v, "Namespace", &a.namespace); err != nil { 426 return err 427 } 428 if err := runtime.FieldPtr(v, "Name", &a.name); err != nil { 429 return err 430 } 431 if err := runtime.FieldPtr(v, "GenerateName", &a.generateName); err != nil { 432 return err 433 } 434 if err := runtime.FieldPtr(v, "UID", &a.uid); err != nil { 435 return err 436 } 437 if err := runtime.FieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { 438 return err 439 } 440 if err := runtime.FieldPtr(v, "SelfLink", &a.selfLink); err != nil { 441 return err 442 } 443 if err := runtime.FieldPtr(v, "Labels", &a.labels); err != nil { 444 return err 445 } 446 if err := runtime.FieldPtr(v, "Annotations", &a.annotations); err != nil { 447 return err 448 } 449 return nil 450 } 451 452 // extractFromObjectMeta extracts pointers to metadata fields from a list object 453 func extractFromListMeta(v reflect.Value, a *genericAccessor) error { 454 if err := runtime.FieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { 455 return err 456 } 457 if err := runtime.FieldPtr(v, "SelfLink", &a.selfLink); err != nil { 458 return err 459 } 460 return nil 461 }