conversion.go 12 KB

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