conversion.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. Copyright 2017 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. // This file contains adapters that convert between RC and RS,
  14. // as if ReplicationController were an older API version of ReplicaSet.
  15. // It allows ReplicaSetController to directly replace the old ReplicationManager,
  16. // which was previously a manually-maintained copy-paste of RSC.
  17. package replication
  18. import (
  19. "errors"
  20. "fmt"
  21. "time"
  22. apps "k8s.io/api/apps/v1"
  23. autoscalingv1 "k8s.io/api/autoscaling/v1"
  24. "k8s.io/api/core/v1"
  25. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  26. "k8s.io/apimachinery/pkg/labels"
  27. "k8s.io/apimachinery/pkg/runtime"
  28. "k8s.io/apimachinery/pkg/types"
  29. utilruntime "k8s.io/apimachinery/pkg/util/runtime"
  30. "k8s.io/apimachinery/pkg/watch"
  31. coreinformers "k8s.io/client-go/informers/core/v1"
  32. clientset "k8s.io/client-go/kubernetes"
  33. appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1"
  34. v1client "k8s.io/client-go/kubernetes/typed/core/v1"
  35. appslisters "k8s.io/client-go/listers/apps/v1"
  36. v1listers "k8s.io/client-go/listers/core/v1"
  37. "k8s.io/client-go/tools/cache"
  38. appsinternal "k8s.io/kubernetes/pkg/apis/apps"
  39. appsconversion "k8s.io/kubernetes/pkg/apis/apps/v1"
  40. apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
  41. "k8s.io/kubernetes/pkg/controller"
  42. )
  43. // informerAdapter implements ReplicaSetInformer by wrapping ReplicationControllerInformer
  44. // and converting objects.
  45. type informerAdapter struct {
  46. rcInformer coreinformers.ReplicationControllerInformer
  47. }
  48. func (i informerAdapter) Informer() cache.SharedIndexInformer {
  49. return conversionInformer{i.rcInformer.Informer()}
  50. }
  51. func (i informerAdapter) Lister() appslisters.ReplicaSetLister {
  52. return conversionLister{i.rcInformer.Lister()}
  53. }
  54. type conversionInformer struct {
  55. cache.SharedIndexInformer
  56. }
  57. func (i conversionInformer) AddEventHandler(handler cache.ResourceEventHandler) {
  58. i.SharedIndexInformer.AddEventHandler(conversionEventHandler{handler})
  59. }
  60. func (i conversionInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) {
  61. i.SharedIndexInformer.AddEventHandlerWithResyncPeriod(conversionEventHandler{handler}, resyncPeriod)
  62. }
  63. type conversionLister struct {
  64. rcLister v1listers.ReplicationControllerLister
  65. }
  66. func (l conversionLister) List(selector labels.Selector) ([]*apps.ReplicaSet, error) {
  67. rcList, err := l.rcLister.List(selector)
  68. if err != nil {
  69. return nil, err
  70. }
  71. return convertSlice(rcList)
  72. }
  73. func (l conversionLister) ReplicaSets(namespace string) appslisters.ReplicaSetNamespaceLister {
  74. return conversionNamespaceLister{l.rcLister.ReplicationControllers(namespace)}
  75. }
  76. func (l conversionLister) GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) {
  77. rcList, err := l.rcLister.GetPodControllers(pod)
  78. if err != nil {
  79. return nil, err
  80. }
  81. return convertSlice(rcList)
  82. }
  83. type conversionNamespaceLister struct {
  84. rcLister v1listers.ReplicationControllerNamespaceLister
  85. }
  86. func (l conversionNamespaceLister) List(selector labels.Selector) ([]*apps.ReplicaSet, error) {
  87. rcList, err := l.rcLister.List(selector)
  88. if err != nil {
  89. return nil, err
  90. }
  91. return convertSlice(rcList)
  92. }
  93. func (l conversionNamespaceLister) Get(name string) (*apps.ReplicaSet, error) {
  94. rc, err := l.rcLister.Get(name)
  95. if err != nil {
  96. return nil, err
  97. }
  98. return convertRCtoRS(rc, nil)
  99. }
  100. type conversionEventHandler struct {
  101. handler cache.ResourceEventHandler
  102. }
  103. func (h conversionEventHandler) OnAdd(obj interface{}) {
  104. rs, err := convertRCtoRS(obj.(*v1.ReplicationController), nil)
  105. if err != nil {
  106. utilruntime.HandleError(fmt.Errorf("dropping RC OnAdd event: can't convert object %#v to RS: %v", obj, err))
  107. return
  108. }
  109. h.handler.OnAdd(rs)
  110. }
  111. func (h conversionEventHandler) OnUpdate(oldObj, newObj interface{}) {
  112. oldRS, err := convertRCtoRS(oldObj.(*v1.ReplicationController), nil)
  113. if err != nil {
  114. utilruntime.HandleError(fmt.Errorf("dropping RC OnUpdate event: can't convert old object %#v to RS: %v", oldObj, err))
  115. return
  116. }
  117. newRS, err := convertRCtoRS(newObj.(*v1.ReplicationController), nil)
  118. if err != nil {
  119. utilruntime.HandleError(fmt.Errorf("dropping RC OnUpdate event: can't convert new object %#v to RS: %v", newObj, err))
  120. return
  121. }
  122. h.handler.OnUpdate(oldRS, newRS)
  123. }
  124. func (h conversionEventHandler) OnDelete(obj interface{}) {
  125. rc, ok := obj.(*v1.ReplicationController)
  126. if !ok {
  127. // Convert the Obj inside DeletedFinalStateUnknown.
  128. tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
  129. if !ok {
  130. utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: couldn't get object from tombstone %+v", obj))
  131. return
  132. }
  133. rc, ok = tombstone.Obj.(*v1.ReplicationController)
  134. if !ok {
  135. utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: tombstone contained object that is not a RC %#v", obj))
  136. return
  137. }
  138. rs, err := convertRCtoRS(rc, nil)
  139. if err != nil {
  140. utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: can't convert object %#v to RS: %v", obj, err))
  141. return
  142. }
  143. h.handler.OnDelete(cache.DeletedFinalStateUnknown{Key: tombstone.Key, Obj: rs})
  144. return
  145. }
  146. // It's a regular RC object.
  147. rs, err := convertRCtoRS(rc, nil)
  148. if err != nil {
  149. utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: can't convert object %#v to RS: %v", obj, err))
  150. return
  151. }
  152. h.handler.OnDelete(rs)
  153. }
  154. type clientsetAdapter struct {
  155. clientset.Interface
  156. }
  157. func (c clientsetAdapter) AppsV1() appsv1client.AppsV1Interface {
  158. return conversionAppsV1Client{c.Interface, c.Interface.AppsV1()}
  159. }
  160. func (c clientsetAdapter) Apps() appsv1client.AppsV1Interface {
  161. return conversionAppsV1Client{c.Interface, c.Interface.AppsV1()}
  162. }
  163. type conversionAppsV1Client struct {
  164. clientset clientset.Interface
  165. appsv1client.AppsV1Interface
  166. }
  167. func (c conversionAppsV1Client) ReplicaSets(namespace string) appsv1client.ReplicaSetInterface {
  168. return conversionClient{c.clientset.CoreV1().ReplicationControllers(namespace)}
  169. }
  170. type conversionClient struct {
  171. v1client.ReplicationControllerInterface
  172. }
  173. func (c conversionClient) Create(rs *apps.ReplicaSet) (*apps.ReplicaSet, error) {
  174. return convertCall(c.ReplicationControllerInterface.Create, rs)
  175. }
  176. func (c conversionClient) Update(rs *apps.ReplicaSet) (*apps.ReplicaSet, error) {
  177. return convertCall(c.ReplicationControllerInterface.Update, rs)
  178. }
  179. func (c conversionClient) UpdateStatus(rs *apps.ReplicaSet) (*apps.ReplicaSet, error) {
  180. return convertCall(c.ReplicationControllerInterface.UpdateStatus, rs)
  181. }
  182. func (c conversionClient) Get(name string, options metav1.GetOptions) (*apps.ReplicaSet, error) {
  183. rc, err := c.ReplicationControllerInterface.Get(name, options)
  184. if err != nil {
  185. return nil, err
  186. }
  187. return convertRCtoRS(rc, nil)
  188. }
  189. func (c conversionClient) List(opts metav1.ListOptions) (*apps.ReplicaSetList, error) {
  190. rcList, err := c.ReplicationControllerInterface.List(opts)
  191. if err != nil {
  192. return nil, err
  193. }
  194. return convertList(rcList)
  195. }
  196. func (c conversionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
  197. // This is not used by RSC because we wrap the shared informer instead.
  198. return nil, errors.New("Watch() is not implemented for conversionClient")
  199. }
  200. func (c conversionClient) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apps.ReplicaSet, err error) {
  201. // This is not used by RSC.
  202. return nil, errors.New("Patch() is not implemented for conversionClient")
  203. }
  204. func (c conversionClient) GetScale(name string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) {
  205. // This is not used by RSC.
  206. return nil, errors.New("GetScale() is not implemented for conversionClient")
  207. }
  208. func (c conversionClient) UpdateScale(name string, scale *autoscalingv1.Scale) (result *autoscalingv1.Scale, err error) {
  209. // This is not used by RSC.
  210. return nil, errors.New("UpdateScale() is not implemented for conversionClient")
  211. }
  212. func convertSlice(rcList []*v1.ReplicationController) ([]*apps.ReplicaSet, error) {
  213. rsList := make([]*apps.ReplicaSet, 0, len(rcList))
  214. for _, rc := range rcList {
  215. rs, err := convertRCtoRS(rc, nil)
  216. if err != nil {
  217. return nil, err
  218. }
  219. rsList = append(rsList, rs)
  220. }
  221. return rsList, nil
  222. }
  223. func convertList(rcList *v1.ReplicationControllerList) (*apps.ReplicaSetList, error) {
  224. rsList := &apps.ReplicaSetList{Items: make([]apps.ReplicaSet, len(rcList.Items))}
  225. for i := range rcList.Items {
  226. rc := &rcList.Items[i]
  227. _, err := convertRCtoRS(rc, &rsList.Items[i])
  228. if err != nil {
  229. return nil, err
  230. }
  231. }
  232. return rsList, nil
  233. }
  234. func convertCall(fn func(*v1.ReplicationController) (*v1.ReplicationController, error), rs *apps.ReplicaSet) (*apps.ReplicaSet, error) {
  235. rc, err := convertRStoRC(rs)
  236. if err != nil {
  237. return nil, err
  238. }
  239. result, err := fn(rc)
  240. if err != nil {
  241. return nil, err
  242. }
  243. return convertRCtoRS(result, nil)
  244. }
  245. func convertRCtoRS(rc *v1.ReplicationController, out *apps.ReplicaSet) (*apps.ReplicaSet, error) {
  246. var rsInternal appsinternal.ReplicaSet
  247. if err := apiv1.Convert_v1_ReplicationController_To_apps_ReplicaSet(rc, &rsInternal, nil); err != nil {
  248. return nil, fmt.Errorf("can't convert ReplicationController %v/%v to ReplicaSet: %v", rc.Namespace, rc.Name, err)
  249. }
  250. if out == nil {
  251. out = new(apps.ReplicaSet)
  252. }
  253. if err := appsconversion.Convert_apps_ReplicaSet_To_v1_ReplicaSet(&rsInternal, out, nil); err != nil {
  254. return nil, fmt.Errorf("can't convert ReplicaSet (converted from ReplicationController %v/%v) from internal to apps/v1: %v", rc.Namespace, rc.Name, err)
  255. }
  256. return out, nil
  257. }
  258. func convertRStoRC(rs *apps.ReplicaSet) (*v1.ReplicationController, error) {
  259. var rsInternal appsinternal.ReplicaSet
  260. if err := appsconversion.Convert_v1_ReplicaSet_To_apps_ReplicaSet(rs, &rsInternal, nil); err != nil {
  261. return nil, fmt.Errorf("can't convert ReplicaSet (converting to ReplicationController %v/%v) from apps/v1 to internal: %v", rs.Namespace, rs.Name, err)
  262. }
  263. var rc v1.ReplicationController
  264. if err := apiv1.Convert_apps_ReplicaSet_To_v1_ReplicationController(&rsInternal, &rc, nil); err != nil {
  265. return nil, fmt.Errorf("can't convert ReplicaSet to ReplicationController %v/%v: %v", rs.Namespace, rs.Name, err)
  266. }
  267. return &rc, nil
  268. }
  269. type podControlAdapter struct {
  270. controller.PodControlInterface
  271. }
  272. func (pc podControlAdapter) CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
  273. // This is not used by RSC.
  274. return errors.New("CreatePods() is not implemented for podControlAdapter")
  275. }
  276. func (pc podControlAdapter) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
  277. // This is not used by RSC.
  278. return errors.New("CreatePodsOnNode() is not implemented for podControlAdapter")
  279. }
  280. func (pc podControlAdapter) CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
  281. rc, err := convertRStoRC(object.(*apps.ReplicaSet))
  282. if err != nil {
  283. return err
  284. }
  285. return pc.PodControlInterface.CreatePodsWithControllerRef(namespace, template, rc, controllerRef)
  286. }
  287. func (pc podControlAdapter) DeletePod(namespace string, podID string, object runtime.Object) error {
  288. rc, err := convertRStoRC(object.(*apps.ReplicaSet))
  289. if err != nil {
  290. return err
  291. }
  292. return pc.PodControlInterface.DeletePod(namespace, podID, rc)
  293. }