github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/api/meta/meta.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 "reflect" 22 23 metav1 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/v1" 24 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/conversion" 25 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime" 26 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema" 27 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/types" 28 "k8s.io/klog/v2" 29 ) 30 31 // errNotList is returned when an object implements the Object style interfaces but not the List style 32 // interfaces. 33 var errNotList = fmt.Errorf("object does not implement the List interfaces") 34 35 var errNotCommon = fmt.Errorf("object does not implement the common interface for accessing the SelfLink") 36 37 // CommonAccessor returns a Common interface for the provided object or an error if the object does 38 // not provide List. 39 func CommonAccessor(obj interface{}) (metav1.Common, error) { 40 switch t := obj.(type) { 41 case List: 42 return t, nil 43 case ListMetaAccessor: 44 if m := t.GetListMeta(); m != nil { 45 return m, nil 46 } 47 return nil, errNotCommon 48 case metav1.ListMetaAccessor: 49 if m := t.GetListMeta(); m != nil { 50 return m, nil 51 } 52 return nil, errNotCommon 53 case metav1.Object: 54 return t, nil 55 case metav1.ObjectMetaAccessor: 56 if m := t.GetObjectMeta(); m != nil { 57 return m, nil 58 } 59 return nil, errNotCommon 60 default: 61 return nil, errNotCommon 62 } 63 } 64 65 // ListAccessor returns a List interface for the provided object or an error if the object does 66 // not provide List. 67 // IMPORTANT: Objects are NOT a superset of lists. Do not use this check to determine whether an 68 // object *is* a List. 69 func ListAccessor(obj interface{}) (List, error) { 70 switch t := obj.(type) { 71 case List: 72 return t, nil 73 case ListMetaAccessor: 74 if m := t.GetListMeta(); m != nil { 75 return m, nil 76 } 77 return nil, errNotList 78 case metav1.ListMetaAccessor: 79 if m := t.GetListMeta(); m != nil { 80 return m, nil 81 } 82 return nil, errNotList 83 default: 84 return nil, errNotList 85 } 86 } 87 88 // errNotObject is returned when an object implements the List style interfaces but not the Object style 89 // interfaces. 90 var errNotObject = fmt.Errorf("object does not implement the Object interfaces") 91 92 // Accessor takes an arbitrary object pointer and returns meta.Interface. 93 // obj must be a pointer to an API type. An error is returned if the minimum 94 // required fields are missing. Fields that are not required return the default 95 // value and are a no-op if set. 96 func Accessor(obj interface{}) (metav1.Object, error) { 97 switch t := obj.(type) { 98 case metav1.Object: 99 return t, nil 100 case metav1.ObjectMetaAccessor: 101 if m := t.GetObjectMeta(); m != nil { 102 return m, nil 103 } 104 return nil, errNotObject 105 default: 106 return nil, errNotObject 107 } 108 } 109 110 // AsPartialObjectMetadata takes the metav1 interface and returns a partial object. 111 // TODO: consider making this solely a conversion action. 112 func AsPartialObjectMetadata(m metav1.Object) *metav1.PartialObjectMetadata { 113 switch t := m.(type) { 114 case *metav1.ObjectMeta: 115 return &metav1.PartialObjectMetadata{ObjectMeta: *t} 116 default: 117 return &metav1.PartialObjectMetadata{ 118 ObjectMeta: metav1.ObjectMeta{ 119 Name: m.GetName(), 120 GenerateName: m.GetGenerateName(), 121 Namespace: m.GetNamespace(), 122 SelfLink: m.GetSelfLink(), 123 UID: m.GetUID(), 124 ResourceVersion: m.GetResourceVersion(), 125 Generation: m.GetGeneration(), 126 CreationTimestamp: m.GetCreationTimestamp(), 127 DeletionTimestamp: m.GetDeletionTimestamp(), 128 DeletionGracePeriodSeconds: m.GetDeletionGracePeriodSeconds(), 129 Labels: m.GetLabels(), 130 Annotations: m.GetAnnotations(), 131 OwnerReferences: m.GetOwnerReferences(), 132 Finalizers: m.GetFinalizers(), 133 ManagedFields: m.GetManagedFields(), 134 }, 135 } 136 } 137 } 138 139 // TypeAccessor returns an interface that allows retrieving and modifying the APIVersion 140 // and Kind of an in-memory internal object. 141 // TODO: this interface is used to test code that does not have ObjectMeta or ListMeta 142 // in round tripping (objects which can use apiVersion/kind, but do not fit the Kube 143 // api conventions). 144 func TypeAccessor(obj interface{}) (Type, error) { 145 if typed, ok := obj.(runtime.Object); ok { 146 return objectAccessor{typed}, nil 147 } 148 v, err := conversion.EnforcePtr(obj) 149 if err != nil { 150 return nil, err 151 } 152 t := v.Type() 153 if v.Kind() != reflect.Struct { 154 return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface()) 155 } 156 157 typeMeta := v.FieldByName("TypeMeta") 158 if !typeMeta.IsValid() { 159 return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t) 160 } 161 a := &genericAccessor{} 162 if err := extractFromTypeMeta(typeMeta, a); err != nil { 163 return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err) 164 } 165 return a, nil 166 } 167 168 type objectAccessor struct { 169 runtime.Object 170 } 171 172 func (obj objectAccessor) GetKind() string { 173 return obj.GetObjectKind().GroupVersionKind().Kind 174 } 175 176 func (obj objectAccessor) SetKind(kind string) { 177 gvk := obj.GetObjectKind().GroupVersionKind() 178 gvk.Kind = kind 179 obj.GetObjectKind().SetGroupVersionKind(gvk) 180 } 181 182 func (obj objectAccessor) GetAPIVersion() string { 183 return obj.GetObjectKind().GroupVersionKind().GroupVersion().String() 184 } 185 186 func (obj objectAccessor) SetAPIVersion(version string) { 187 gvk := obj.GetObjectKind().GroupVersionKind() 188 gv, err := schema.ParseGroupVersion(version) 189 if err != nil { 190 gv = schema.GroupVersion{Version: version} 191 } 192 gvk.Group, gvk.Version = gv.Group, gv.Version 193 obj.GetObjectKind().SetGroupVersionKind(gvk) 194 } 195 196 // NewAccessor returns a MetadataAccessor that can retrieve 197 // or manipulate resource version on objects derived from core API 198 // metadata concepts. 199 func NewAccessor() MetadataAccessor { 200 return resourceAccessor{} 201 } 202 203 // resourceAccessor implements ResourceVersioner and SelfLinker. 204 type resourceAccessor struct{} 205 206 func (resourceAccessor) Kind(obj runtime.Object) (string, error) { 207 return objectAccessor{obj}.GetKind(), nil 208 } 209 210 func (resourceAccessor) SetKind(obj runtime.Object, kind string) error { 211 objectAccessor{obj}.SetKind(kind) 212 return nil 213 } 214 215 func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) { 216 return objectAccessor{obj}.GetAPIVersion(), nil 217 } 218 219 func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error { 220 objectAccessor{obj}.SetAPIVersion(version) 221 return nil 222 } 223 224 func (resourceAccessor) Namespace(obj runtime.Object) (string, error) { 225 accessor, err := Accessor(obj) 226 if err != nil { 227 return "", err 228 } 229 return accessor.GetNamespace(), nil 230 } 231 232 func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error { 233 accessor, err := Accessor(obj) 234 if err != nil { 235 return err 236 } 237 accessor.SetNamespace(namespace) 238 return nil 239 } 240 241 func (resourceAccessor) Name(obj runtime.Object) (string, error) { 242 accessor, err := Accessor(obj) 243 if err != nil { 244 return "", err 245 } 246 return accessor.GetName(), nil 247 } 248 249 func (resourceAccessor) SetName(obj runtime.Object, name string) error { 250 accessor, err := Accessor(obj) 251 if err != nil { 252 return err 253 } 254 accessor.SetName(name) 255 return nil 256 } 257 258 func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) { 259 accessor, err := Accessor(obj) 260 if err != nil { 261 return "", err 262 } 263 return accessor.GetGenerateName(), nil 264 } 265 266 func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error { 267 accessor, err := Accessor(obj) 268 if err != nil { 269 return err 270 } 271 accessor.SetGenerateName(name) 272 return nil 273 } 274 275 func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) { 276 accessor, err := Accessor(obj) 277 if err != nil { 278 return "", err 279 } 280 return accessor.GetUID(), nil 281 } 282 283 func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error { 284 accessor, err := Accessor(obj) 285 if err != nil { 286 return err 287 } 288 accessor.SetUID(uid) 289 return nil 290 } 291 292 func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) { 293 accessor, err := CommonAccessor(obj) 294 if err != nil { 295 return "", err 296 } 297 return accessor.GetSelfLink(), nil 298 } 299 300 func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { 301 accessor, err := CommonAccessor(obj) 302 if err != nil { 303 return err 304 } 305 accessor.SetSelfLink(selfLink) 306 return nil 307 } 308 309 func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) { 310 accessor, err := Accessor(obj) 311 if err != nil { 312 return nil, err 313 } 314 return accessor.GetLabels(), nil 315 } 316 317 func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error { 318 accessor, err := Accessor(obj) 319 if err != nil { 320 return err 321 } 322 accessor.SetLabels(labels) 323 return nil 324 } 325 326 func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) { 327 accessor, err := Accessor(obj) 328 if err != nil { 329 return nil, err 330 } 331 return accessor.GetAnnotations(), nil 332 } 333 334 func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error { 335 accessor, err := Accessor(obj) 336 if err != nil { 337 return err 338 } 339 accessor.SetAnnotations(annotations) 340 return nil 341 } 342 343 func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { 344 accessor, err := CommonAccessor(obj) 345 if err != nil { 346 return "", err 347 } 348 return accessor.GetResourceVersion(), nil 349 } 350 351 func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { 352 accessor, err := CommonAccessor(obj) 353 if err != nil { 354 return err 355 } 356 accessor.SetResourceVersion(version) 357 return nil 358 } 359 360 func (resourceAccessor) Continue(obj runtime.Object) (string, error) { 361 accessor, err := ListAccessor(obj) 362 if err != nil { 363 return "", err 364 } 365 return accessor.GetContinue(), nil 366 } 367 368 func (resourceAccessor) SetContinue(obj runtime.Object, version string) error { 369 accessor, err := ListAccessor(obj) 370 if err != nil { 371 return err 372 } 373 accessor.SetContinue(version) 374 return nil 375 } 376 377 // extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object. 378 func extractFromOwnerReference(v reflect.Value, o *metav1.OwnerReference) error { 379 if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil { 380 return err 381 } 382 if err := runtime.Field(v, "Kind", &o.Kind); err != nil { 383 return err 384 } 385 if err := runtime.Field(v, "Name", &o.Name); err != nil { 386 return err 387 } 388 if err := runtime.Field(v, "UID", &o.UID); err != nil { 389 return err 390 } 391 var controllerPtr *bool 392 if err := runtime.Field(v, "Controller", &controllerPtr); err != nil { 393 return err 394 } 395 if controllerPtr != nil { 396 controller := *controllerPtr 397 o.Controller = &controller 398 } 399 var blockOwnerDeletionPtr *bool 400 if err := runtime.Field(v, "BlockOwnerDeletion", &blockOwnerDeletionPtr); err != nil { 401 return err 402 } 403 if blockOwnerDeletionPtr != nil { 404 block := *blockOwnerDeletionPtr 405 o.BlockOwnerDeletion = &block 406 } 407 return nil 408 } 409 410 // setOwnerReference sets v to o. v is the OwnerReferences field of an object. 411 func setOwnerReference(v reflect.Value, o *metav1.OwnerReference) error { 412 if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil { 413 return err 414 } 415 if err := runtime.SetField(o.Kind, v, "Kind"); err != nil { 416 return err 417 } 418 if err := runtime.SetField(o.Name, v, "Name"); err != nil { 419 return err 420 } 421 if err := runtime.SetField(o.UID, v, "UID"); err != nil { 422 return err 423 } 424 if o.Controller != nil { 425 controller := *(o.Controller) 426 if err := runtime.SetField(&controller, v, "Controller"); err != nil { 427 return err 428 } 429 } 430 if o.BlockOwnerDeletion != nil { 431 block := *(o.BlockOwnerDeletion) 432 if err := runtime.SetField(&block, v, "BlockOwnerDeletion"); err != nil { 433 return err 434 } 435 } 436 return nil 437 } 438 439 // genericAccessor contains pointers to strings that can modify an arbitrary 440 // struct and implements the Accessor interface. 441 type genericAccessor struct { 442 namespace *string 443 name *string 444 generateName *string 445 uid *types.UID 446 apiVersion *string 447 kind *string 448 resourceVersion *string 449 selfLink *string 450 creationTimestamp *metav1.Time 451 deletionTimestamp **metav1.Time 452 labels *map[string]string 453 annotations *map[string]string 454 ownerReferences reflect.Value 455 finalizers *[]string 456 } 457 458 func (a genericAccessor) GetNamespace() string { 459 if a.namespace == nil { 460 return "" 461 } 462 return *a.namespace 463 } 464 465 func (a genericAccessor) SetNamespace(namespace string) { 466 if a.namespace == nil { 467 return 468 } 469 *a.namespace = namespace 470 } 471 472 func (a genericAccessor) GetName() string { 473 if a.name == nil { 474 return "" 475 } 476 return *a.name 477 } 478 479 func (a genericAccessor) SetName(name string) { 480 if a.name == nil { 481 return 482 } 483 *a.name = name 484 } 485 486 func (a genericAccessor) GetGenerateName() string { 487 if a.generateName == nil { 488 return "" 489 } 490 return *a.generateName 491 } 492 493 func (a genericAccessor) SetGenerateName(generateName string) { 494 if a.generateName == nil { 495 return 496 } 497 *a.generateName = generateName 498 } 499 500 func (a genericAccessor) GetUID() types.UID { 501 if a.uid == nil { 502 return "" 503 } 504 return *a.uid 505 } 506 507 func (a genericAccessor) SetUID(uid types.UID) { 508 if a.uid == nil { 509 return 510 } 511 *a.uid = uid 512 } 513 514 func (a genericAccessor) GetAPIVersion() string { 515 return *a.apiVersion 516 } 517 518 func (a genericAccessor) SetAPIVersion(version string) { 519 *a.apiVersion = version 520 } 521 522 func (a genericAccessor) GetKind() string { 523 return *a.kind 524 } 525 526 func (a genericAccessor) SetKind(kind string) { 527 *a.kind = kind 528 } 529 530 func (a genericAccessor) GetResourceVersion() string { 531 return *a.resourceVersion 532 } 533 534 func (a genericAccessor) SetResourceVersion(version string) { 535 *a.resourceVersion = version 536 } 537 538 func (a genericAccessor) GetSelfLink() string { 539 return *a.selfLink 540 } 541 542 func (a genericAccessor) SetSelfLink(selfLink string) { 543 *a.selfLink = selfLink 544 } 545 546 func (a genericAccessor) GetCreationTimestamp() metav1.Time { 547 return *a.creationTimestamp 548 } 549 550 func (a genericAccessor) SetCreationTimestamp(timestamp metav1.Time) { 551 *a.creationTimestamp = timestamp 552 } 553 554 func (a genericAccessor) GetDeletionTimestamp() *metav1.Time { 555 return *a.deletionTimestamp 556 } 557 558 func (a genericAccessor) SetDeletionTimestamp(timestamp *metav1.Time) { 559 *a.deletionTimestamp = timestamp 560 } 561 562 func (a genericAccessor) GetLabels() map[string]string { 563 if a.labels == nil { 564 return nil 565 } 566 return *a.labels 567 } 568 569 func (a genericAccessor) SetLabels(labels map[string]string) { 570 *a.labels = labels 571 } 572 573 func (a genericAccessor) GetAnnotations() map[string]string { 574 if a.annotations == nil { 575 return nil 576 } 577 return *a.annotations 578 } 579 580 func (a genericAccessor) SetAnnotations(annotations map[string]string) { 581 if a.annotations == nil { 582 emptyAnnotations := make(map[string]string) 583 a.annotations = &emptyAnnotations 584 } 585 *a.annotations = annotations 586 } 587 588 func (a genericAccessor) GetFinalizers() []string { 589 if a.finalizers == nil { 590 return nil 591 } 592 return *a.finalizers 593 } 594 595 func (a genericAccessor) SetFinalizers(finalizers []string) { 596 *a.finalizers = finalizers 597 } 598 599 func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { 600 var ret []metav1.OwnerReference 601 s := a.ownerReferences 602 if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { 603 klog.Errorf("expect %v to be a pointer to slice", s) 604 return ret 605 } 606 s = s.Elem() 607 // Set the capacity to one element greater to avoid copy if the caller later append an element. 608 ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1) 609 for i := 0; i < s.Len(); i++ { 610 if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil { 611 klog.Errorf("extractFromOwnerReference failed: %v", err) 612 return ret 613 } 614 } 615 return ret 616 } 617 618 func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) { 619 s := a.ownerReferences 620 if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { 621 klog.Errorf("expect %v to be a pointer to slice", s) 622 } 623 s = s.Elem() 624 newReferences := reflect.MakeSlice(s.Type(), len(references), len(references)) 625 for i := 0; i < len(references); i++ { 626 if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil { 627 klog.Errorf("setOwnerReference failed: %v", err) 628 return 629 } 630 } 631 s.Set(newReferences) 632 } 633 634 // extractFromTypeMeta extracts pointers to version and kind fields from an object 635 func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error { 636 if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil { 637 return err 638 } 639 if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil { 640 return err 641 } 642 return nil 643 }