meta.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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. ClusterName: m.GetClusterName(),
  121. ManagedFields: m.GetManagedFields(),
  122. },
  123. }
  124. }
  125. }
  126. // TypeAccessor returns an interface that allows retrieving and modifying the APIVersion
  127. // and Kind of an in-memory internal object.
  128. // TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
  129. // in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
  130. // api conventions).
  131. func TypeAccessor(obj interface{}) (Type, error) {
  132. if typed, ok := obj.(runtime.Object); ok {
  133. return objectAccessor{typed}, nil
  134. }
  135. v, err := conversion.EnforcePtr(obj)
  136. if err != nil {
  137. return nil, err
  138. }
  139. t := v.Type()
  140. if v.Kind() != reflect.Struct {
  141. return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface())
  142. }
  143. typeMeta := v.FieldByName("TypeMeta")
  144. if !typeMeta.IsValid() {
  145. return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t)
  146. }
  147. a := &genericAccessor{}
  148. if err := extractFromTypeMeta(typeMeta, a); err != nil {
  149. return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err)
  150. }
  151. return a, nil
  152. }
  153. type objectAccessor struct {
  154. runtime.Object
  155. }
  156. func (obj objectAccessor) GetKind() string {
  157. return obj.GetObjectKind().GroupVersionKind().Kind
  158. }
  159. func (obj objectAccessor) SetKind(kind string) {
  160. gvk := obj.GetObjectKind().GroupVersionKind()
  161. gvk.Kind = kind
  162. obj.GetObjectKind().SetGroupVersionKind(gvk)
  163. }
  164. func (obj objectAccessor) GetAPIVersion() string {
  165. return obj.GetObjectKind().GroupVersionKind().GroupVersion().String()
  166. }
  167. func (obj objectAccessor) SetAPIVersion(version string) {
  168. gvk := obj.GetObjectKind().GroupVersionKind()
  169. gv, err := schema.ParseGroupVersion(version)
  170. if err != nil {
  171. gv = schema.GroupVersion{Version: version}
  172. }
  173. gvk.Group, gvk.Version = gv.Group, gv.Version
  174. obj.GetObjectKind().SetGroupVersionKind(gvk)
  175. }
  176. // NewAccessor returns a MetadataAccessor that can retrieve
  177. // or manipulate resource version on objects derived from core API
  178. // metadata concepts.
  179. func NewAccessor() MetadataAccessor {
  180. return resourceAccessor{}
  181. }
  182. // resourceAccessor implements ResourceVersioner and SelfLinker.
  183. type resourceAccessor struct{}
  184. func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
  185. return objectAccessor{obj}.GetKind(), nil
  186. }
  187. func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
  188. objectAccessor{obj}.SetKind(kind)
  189. return nil
  190. }
  191. func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
  192. return objectAccessor{obj}.GetAPIVersion(), nil
  193. }
  194. func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
  195. objectAccessor{obj}.SetAPIVersion(version)
  196. return nil
  197. }
  198. func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
  199. accessor, err := Accessor(obj)
  200. if err != nil {
  201. return "", err
  202. }
  203. return accessor.GetNamespace(), nil
  204. }
  205. func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
  206. accessor, err := Accessor(obj)
  207. if err != nil {
  208. return err
  209. }
  210. accessor.SetNamespace(namespace)
  211. return nil
  212. }
  213. func (resourceAccessor) Name(obj runtime.Object) (string, error) {
  214. accessor, err := Accessor(obj)
  215. if err != nil {
  216. return "", err
  217. }
  218. return accessor.GetName(), nil
  219. }
  220. func (resourceAccessor) SetName(obj runtime.Object, name string) error {
  221. accessor, err := Accessor(obj)
  222. if err != nil {
  223. return err
  224. }
  225. accessor.SetName(name)
  226. return nil
  227. }
  228. func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
  229. accessor, err := Accessor(obj)
  230. if err != nil {
  231. return "", err
  232. }
  233. return accessor.GetGenerateName(), nil
  234. }
  235. func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
  236. accessor, err := Accessor(obj)
  237. if err != nil {
  238. return err
  239. }
  240. accessor.SetGenerateName(name)
  241. return nil
  242. }
  243. func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
  244. accessor, err := Accessor(obj)
  245. if err != nil {
  246. return "", err
  247. }
  248. return accessor.GetUID(), nil
  249. }
  250. func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
  251. accessor, err := Accessor(obj)
  252. if err != nil {
  253. return err
  254. }
  255. accessor.SetUID(uid)
  256. return nil
  257. }
  258. func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
  259. accessor, err := CommonAccessor(obj)
  260. if err != nil {
  261. return "", err
  262. }
  263. return accessor.GetSelfLink(), nil
  264. }
  265. func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
  266. accessor, err := CommonAccessor(obj)
  267. if err != nil {
  268. return err
  269. }
  270. accessor.SetSelfLink(selfLink)
  271. return nil
  272. }
  273. func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
  274. accessor, err := Accessor(obj)
  275. if err != nil {
  276. return nil, err
  277. }
  278. return accessor.GetLabels(), nil
  279. }
  280. func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
  281. accessor, err := Accessor(obj)
  282. if err != nil {
  283. return err
  284. }
  285. accessor.SetLabels(labels)
  286. return nil
  287. }
  288. func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) {
  289. accessor, err := Accessor(obj)
  290. if err != nil {
  291. return nil, err
  292. }
  293. return accessor.GetAnnotations(), nil
  294. }
  295. func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
  296. accessor, err := Accessor(obj)
  297. if err != nil {
  298. return err
  299. }
  300. accessor.SetAnnotations(annotations)
  301. return nil
  302. }
  303. func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
  304. accessor, err := CommonAccessor(obj)
  305. if err != nil {
  306. return "", err
  307. }
  308. return accessor.GetResourceVersion(), nil
  309. }
  310. func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
  311. accessor, err := CommonAccessor(obj)
  312. if err != nil {
  313. return err
  314. }
  315. accessor.SetResourceVersion(version)
  316. return nil
  317. }
  318. func (resourceAccessor) Continue(obj runtime.Object) (string, error) {
  319. accessor, err := ListAccessor(obj)
  320. if err != nil {
  321. return "", err
  322. }
  323. return accessor.GetContinue(), nil
  324. }
  325. func (resourceAccessor) SetContinue(obj runtime.Object, version string) error {
  326. accessor, err := ListAccessor(obj)
  327. if err != nil {
  328. return err
  329. }
  330. accessor.SetContinue(version)
  331. return nil
  332. }
  333. // extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object.
  334. func extractFromOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
  335. if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil {
  336. return err
  337. }
  338. if err := runtime.Field(v, "Kind", &o.Kind); err != nil {
  339. return err
  340. }
  341. if err := runtime.Field(v, "Name", &o.Name); err != nil {
  342. return err
  343. }
  344. if err := runtime.Field(v, "UID", &o.UID); err != nil {
  345. return err
  346. }
  347. var controllerPtr *bool
  348. if err := runtime.Field(v, "Controller", &controllerPtr); err != nil {
  349. return err
  350. }
  351. if controllerPtr != nil {
  352. controller := *controllerPtr
  353. o.Controller = &controller
  354. }
  355. var blockOwnerDeletionPtr *bool
  356. if err := runtime.Field(v, "BlockOwnerDeletion", &blockOwnerDeletionPtr); err != nil {
  357. return err
  358. }
  359. if blockOwnerDeletionPtr != nil {
  360. block := *blockOwnerDeletionPtr
  361. o.BlockOwnerDeletion = &block
  362. }
  363. return nil
  364. }
  365. // setOwnerReference sets v to o. v is the OwnerReferences field of an object.
  366. func setOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
  367. if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil {
  368. return err
  369. }
  370. if err := runtime.SetField(o.Kind, v, "Kind"); err != nil {
  371. return err
  372. }
  373. if err := runtime.SetField(o.Name, v, "Name"); err != nil {
  374. return err
  375. }
  376. if err := runtime.SetField(o.UID, v, "UID"); err != nil {
  377. return err
  378. }
  379. if o.Controller != nil {
  380. controller := *(o.Controller)
  381. if err := runtime.SetField(&controller, v, "Controller"); err != nil {
  382. return err
  383. }
  384. }
  385. if o.BlockOwnerDeletion != nil {
  386. block := *(o.BlockOwnerDeletion)
  387. if err := runtime.SetField(&block, v, "BlockOwnerDeletion"); err != nil {
  388. return err
  389. }
  390. }
  391. return nil
  392. }
  393. // genericAccessor contains pointers to strings that can modify an arbitrary
  394. // struct and implements the Accessor interface.
  395. type genericAccessor struct {
  396. namespace *string
  397. name *string
  398. generateName *string
  399. uid *types.UID
  400. apiVersion *string
  401. kind *string
  402. resourceVersion *string
  403. selfLink *string
  404. creationTimestamp *metav1.Time
  405. deletionTimestamp **metav1.Time
  406. labels *map[string]string
  407. annotations *map[string]string
  408. ownerReferences reflect.Value
  409. finalizers *[]string
  410. }
  411. func (a genericAccessor) GetNamespace() string {
  412. if a.namespace == nil {
  413. return ""
  414. }
  415. return *a.namespace
  416. }
  417. func (a genericAccessor) SetNamespace(namespace string) {
  418. if a.namespace == nil {
  419. return
  420. }
  421. *a.namespace = namespace
  422. }
  423. func (a genericAccessor) GetName() string {
  424. if a.name == nil {
  425. return ""
  426. }
  427. return *a.name
  428. }
  429. func (a genericAccessor) SetName(name string) {
  430. if a.name == nil {
  431. return
  432. }
  433. *a.name = name
  434. }
  435. func (a genericAccessor) GetGenerateName() string {
  436. if a.generateName == nil {
  437. return ""
  438. }
  439. return *a.generateName
  440. }
  441. func (a genericAccessor) SetGenerateName(generateName string) {
  442. if a.generateName == nil {
  443. return
  444. }
  445. *a.generateName = generateName
  446. }
  447. func (a genericAccessor) GetUID() types.UID {
  448. if a.uid == nil {
  449. return ""
  450. }
  451. return *a.uid
  452. }
  453. func (a genericAccessor) SetUID(uid types.UID) {
  454. if a.uid == nil {
  455. return
  456. }
  457. *a.uid = uid
  458. }
  459. func (a genericAccessor) GetAPIVersion() string {
  460. return *a.apiVersion
  461. }
  462. func (a genericAccessor) SetAPIVersion(version string) {
  463. *a.apiVersion = version
  464. }
  465. func (a genericAccessor) GetKind() string {
  466. return *a.kind
  467. }
  468. func (a genericAccessor) SetKind(kind string) {
  469. *a.kind = kind
  470. }
  471. func (a genericAccessor) GetResourceVersion() string {
  472. return *a.resourceVersion
  473. }
  474. func (a genericAccessor) SetResourceVersion(version string) {
  475. *a.resourceVersion = version
  476. }
  477. func (a genericAccessor) GetSelfLink() string {
  478. return *a.selfLink
  479. }
  480. func (a genericAccessor) SetSelfLink(selfLink string) {
  481. *a.selfLink = selfLink
  482. }
  483. func (a genericAccessor) GetCreationTimestamp() metav1.Time {
  484. return *a.creationTimestamp
  485. }
  486. func (a genericAccessor) SetCreationTimestamp(timestamp metav1.Time) {
  487. *a.creationTimestamp = timestamp
  488. }
  489. func (a genericAccessor) GetDeletionTimestamp() *metav1.Time {
  490. return *a.deletionTimestamp
  491. }
  492. func (a genericAccessor) SetDeletionTimestamp(timestamp *metav1.Time) {
  493. *a.deletionTimestamp = timestamp
  494. }
  495. func (a genericAccessor) GetLabels() map[string]string {
  496. if a.labels == nil {
  497. return nil
  498. }
  499. return *a.labels
  500. }
  501. func (a genericAccessor) SetLabels(labels map[string]string) {
  502. *a.labels = labels
  503. }
  504. func (a genericAccessor) GetAnnotations() map[string]string {
  505. if a.annotations == nil {
  506. return nil
  507. }
  508. return *a.annotations
  509. }
  510. func (a genericAccessor) SetAnnotations(annotations map[string]string) {
  511. if a.annotations == nil {
  512. emptyAnnotations := make(map[string]string)
  513. a.annotations = &emptyAnnotations
  514. }
  515. *a.annotations = annotations
  516. }
  517. func (a genericAccessor) GetFinalizers() []string {
  518. if a.finalizers == nil {
  519. return nil
  520. }
  521. return *a.finalizers
  522. }
  523. func (a genericAccessor) SetFinalizers(finalizers []string) {
  524. *a.finalizers = finalizers
  525. }
  526. func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
  527. var ret []metav1.OwnerReference
  528. s := a.ownerReferences
  529. if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
  530. klog.Errorf("expect %v to be a pointer to slice", s)
  531. return ret
  532. }
  533. s = s.Elem()
  534. // Set the capacity to one element greater to avoid copy if the caller later append an element.
  535. ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1)
  536. for i := 0; i < s.Len(); i++ {
  537. if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
  538. klog.Errorf("extractFromOwnerReference failed: %v", err)
  539. return ret
  540. }
  541. }
  542. return ret
  543. }
  544. func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) {
  545. s := a.ownerReferences
  546. if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
  547. klog.Errorf("expect %v to be a pointer to slice", s)
  548. }
  549. s = s.Elem()
  550. newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
  551. for i := 0; i < len(references); i++ {
  552. if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
  553. klog.Errorf("setOwnerReference failed: %v", err)
  554. return
  555. }
  556. }
  557. s.Set(newReferences)
  558. }
  559. // extractFromTypeMeta extracts pointers to version and kind fields from an object
  560. func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error {
  561. if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil {
  562. return err
  563. }
  564. if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil {
  565. return err
  566. }
  567. return nil
  568. }