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