meta.go 16 KB

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