meta.go 17 KB

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