k8s.io/kubernetes@v1.29.3/pkg/controller/replication/conversion.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // This file contains adapters that convert between RC and RS, 18 // as if ReplicationController were an older API version of ReplicaSet. 19 // It allows ReplicaSetController to directly replace the old ReplicationManager, 20 // which was previously a manually-maintained copy-paste of RSC. 21 22 package replication 23 24 import ( 25 "context" 26 "errors" 27 "fmt" 28 "time" 29 30 apps "k8s.io/api/apps/v1" 31 autoscalingv1 "k8s.io/api/autoscaling/v1" 32 v1 "k8s.io/api/core/v1" 33 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 34 "k8s.io/apimachinery/pkg/labels" 35 "k8s.io/apimachinery/pkg/runtime" 36 "k8s.io/apimachinery/pkg/types" 37 utilruntime "k8s.io/apimachinery/pkg/util/runtime" 38 "k8s.io/apimachinery/pkg/watch" 39 appsv1apply "k8s.io/client-go/applyconfigurations/apps/v1" 40 appsv1autoscaling "k8s.io/client-go/applyconfigurations/autoscaling/v1" 41 coreinformers "k8s.io/client-go/informers/core/v1" 42 clientset "k8s.io/client-go/kubernetes" 43 appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1" 44 v1client "k8s.io/client-go/kubernetes/typed/core/v1" 45 appslisters "k8s.io/client-go/listers/apps/v1" 46 v1listers "k8s.io/client-go/listers/core/v1" 47 "k8s.io/client-go/tools/cache" 48 appsinternal "k8s.io/kubernetes/pkg/apis/apps" 49 appsconversion "k8s.io/kubernetes/pkg/apis/apps/v1" 50 apiv1 "k8s.io/kubernetes/pkg/apis/core/v1" 51 "k8s.io/kubernetes/pkg/controller" 52 ) 53 54 // informerAdapter implements ReplicaSetInformer by wrapping ReplicationControllerInformer 55 // and converting objects. 56 type informerAdapter struct { 57 rcInformer coreinformers.ReplicationControllerInformer 58 } 59 60 func (i informerAdapter) Informer() cache.SharedIndexInformer { 61 return conversionInformer{i.rcInformer.Informer()} 62 } 63 64 func (i informerAdapter) Lister() appslisters.ReplicaSetLister { 65 return conversionLister{i.rcInformer.Lister()} 66 } 67 68 type conversionInformer struct { 69 cache.SharedIndexInformer 70 } 71 72 func (i conversionInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) { 73 return i.SharedIndexInformer.AddEventHandler(conversionEventHandler{handler}) 74 } 75 76 func (i conversionInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) (cache.ResourceEventHandlerRegistration, error) { 77 return i.SharedIndexInformer.AddEventHandlerWithResyncPeriod(conversionEventHandler{handler}, resyncPeriod) 78 } 79 80 type conversionLister struct { 81 rcLister v1listers.ReplicationControllerLister 82 } 83 84 func (l conversionLister) List(selector labels.Selector) ([]*apps.ReplicaSet, error) { 85 rcList, err := l.rcLister.List(selector) 86 if err != nil { 87 return nil, err 88 } 89 return convertSlice(rcList) 90 } 91 92 func (l conversionLister) ReplicaSets(namespace string) appslisters.ReplicaSetNamespaceLister { 93 return conversionNamespaceLister{l.rcLister.ReplicationControllers(namespace)} 94 } 95 96 func (l conversionLister) GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) { 97 rcList, err := l.rcLister.GetPodControllers(pod) 98 if err != nil { 99 return nil, err 100 } 101 return convertSlice(rcList) 102 } 103 104 type conversionNamespaceLister struct { 105 rcLister v1listers.ReplicationControllerNamespaceLister 106 } 107 108 func (l conversionNamespaceLister) List(selector labels.Selector) ([]*apps.ReplicaSet, error) { 109 rcList, err := l.rcLister.List(selector) 110 if err != nil { 111 return nil, err 112 } 113 return convertSlice(rcList) 114 } 115 116 func (l conversionNamespaceLister) Get(name string) (*apps.ReplicaSet, error) { 117 rc, err := l.rcLister.Get(name) 118 if err != nil { 119 return nil, err 120 } 121 return convertRCtoRS(rc, nil) 122 } 123 124 type conversionEventHandler struct { 125 handler cache.ResourceEventHandler 126 } 127 128 func (h conversionEventHandler) OnAdd(obj interface{}, isInInitialList bool) { 129 rs, err := convertRCtoRS(obj.(*v1.ReplicationController), nil) 130 if err != nil { 131 utilruntime.HandleError(fmt.Errorf("dropping RC OnAdd event: can't convert object %#v to RS: %v", obj, err)) 132 return 133 } 134 h.handler.OnAdd(rs, isInInitialList) 135 } 136 137 func (h conversionEventHandler) OnUpdate(oldObj, newObj interface{}) { 138 oldRS, err := convertRCtoRS(oldObj.(*v1.ReplicationController), nil) 139 if err != nil { 140 utilruntime.HandleError(fmt.Errorf("dropping RC OnUpdate event: can't convert old object %#v to RS: %v", oldObj, err)) 141 return 142 } 143 newRS, err := convertRCtoRS(newObj.(*v1.ReplicationController), nil) 144 if err != nil { 145 utilruntime.HandleError(fmt.Errorf("dropping RC OnUpdate event: can't convert new object %#v to RS: %v", newObj, err)) 146 return 147 } 148 h.handler.OnUpdate(oldRS, newRS) 149 } 150 151 func (h conversionEventHandler) OnDelete(obj interface{}) { 152 rc, ok := obj.(*v1.ReplicationController) 153 if !ok { 154 // Convert the Obj inside DeletedFinalStateUnknown. 155 tombstone, ok := obj.(cache.DeletedFinalStateUnknown) 156 if !ok { 157 utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: couldn't get object from tombstone %+v", obj)) 158 return 159 } 160 rc, ok = tombstone.Obj.(*v1.ReplicationController) 161 if !ok { 162 utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: tombstone contained object that is not a RC %#v", obj)) 163 return 164 } 165 rs, err := convertRCtoRS(rc, nil) 166 if err != nil { 167 utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: can't convert object %#v to RS: %v", obj, err)) 168 return 169 } 170 h.handler.OnDelete(cache.DeletedFinalStateUnknown{Key: tombstone.Key, Obj: rs}) 171 return 172 } 173 174 // It's a regular RC object. 175 rs, err := convertRCtoRS(rc, nil) 176 if err != nil { 177 utilruntime.HandleError(fmt.Errorf("dropping RC OnDelete event: can't convert object %#v to RS: %v", obj, err)) 178 return 179 } 180 h.handler.OnDelete(rs) 181 } 182 183 type clientsetAdapter struct { 184 clientset.Interface 185 } 186 187 func (c clientsetAdapter) AppsV1() appsv1client.AppsV1Interface { 188 return conversionAppsV1Client{c.Interface, c.Interface.AppsV1()} 189 } 190 191 func (c clientsetAdapter) Apps() appsv1client.AppsV1Interface { 192 return conversionAppsV1Client{c.Interface, c.Interface.AppsV1()} 193 } 194 195 type conversionAppsV1Client struct { 196 clientset clientset.Interface 197 appsv1client.AppsV1Interface 198 } 199 200 func (c conversionAppsV1Client) ReplicaSets(namespace string) appsv1client.ReplicaSetInterface { 201 return conversionClient{c.clientset.CoreV1().ReplicationControllers(namespace)} 202 } 203 204 type conversionClient struct { 205 v1client.ReplicationControllerInterface 206 } 207 208 func (c conversionClient) Create(ctx context.Context, rs *apps.ReplicaSet, opts metav1.CreateOptions) (*apps.ReplicaSet, error) { 209 return convertCall(func(rc *v1.ReplicationController) (*v1.ReplicationController, error) { 210 return c.ReplicationControllerInterface.Create(ctx, rc, opts) 211 }, rs) 212 } 213 214 func (c conversionClient) Update(ctx context.Context, rs *apps.ReplicaSet, opts metav1.UpdateOptions) (*apps.ReplicaSet, error) { 215 return convertCall(func(rc *v1.ReplicationController) (*v1.ReplicationController, error) { 216 return c.ReplicationControllerInterface.Update(ctx, rc, opts) 217 }, rs) 218 } 219 220 func (c conversionClient) UpdateStatus(ctx context.Context, rs *apps.ReplicaSet, opts metav1.UpdateOptions) (*apps.ReplicaSet, error) { 221 return convertCall(func(rc *v1.ReplicationController) (*v1.ReplicationController, error) { 222 return c.ReplicationControllerInterface.UpdateStatus(ctx, rc, opts) 223 }, rs) 224 } 225 226 func (c conversionClient) Get(ctx context.Context, name string, options metav1.GetOptions) (*apps.ReplicaSet, error) { 227 rc, err := c.ReplicationControllerInterface.Get(ctx, name, options) 228 if err != nil { 229 return nil, err 230 } 231 return convertRCtoRS(rc, nil) 232 } 233 234 func (c conversionClient) List(ctx context.Context, opts metav1.ListOptions) (*apps.ReplicaSetList, error) { 235 rcList, err := c.ReplicationControllerInterface.List(ctx, opts) 236 if err != nil { 237 return nil, err 238 } 239 return convertList(rcList) 240 } 241 242 func (c conversionClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { 243 // This is not used by RSC because we wrap the shared informer instead. 244 return nil, errors.New("Watch() is not implemented for conversionClient") 245 } 246 247 func (c conversionClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *apps.ReplicaSet, err error) { 248 // This is not used by RSC. 249 return nil, errors.New("Patch() is not implemented for conversionClient") 250 } 251 252 func (c conversionClient) Apply(ctx context.Context, rs *appsv1apply.ReplicaSetApplyConfiguration, opts metav1.ApplyOptions) (*apps.ReplicaSet, error) { 253 return nil, errors.New("Apply() is not implemented for conversionClient") 254 } 255 256 func (c conversionClient) ApplyStatus(ctx context.Context, rs *appsv1apply.ReplicaSetApplyConfiguration, opts metav1.ApplyOptions) (*apps.ReplicaSet, error) { 257 return nil, errors.New("ApplyStatus() is not implemented for conversionClient") 258 } 259 260 func (c conversionClient) GetScale(ctx context.Context, name string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { 261 // This is not used by RSC. 262 return nil, errors.New("GetScale() is not implemented for conversionClient") 263 } 264 265 func (c conversionClient) UpdateScale(ctx context.Context, name string, scale *autoscalingv1.Scale, opts metav1.UpdateOptions) (result *autoscalingv1.Scale, err error) { 266 // This is not used by RSC. 267 return nil, errors.New("UpdateScale() is not implemented for conversionClient") 268 } 269 270 func (c conversionClient) ApplyScale(ctx context.Context, name string, scale *appsv1autoscaling.ScaleApplyConfiguration, opts metav1.ApplyOptions) (*autoscalingv1.Scale, error) { 271 return nil, errors.New("ApplyScale() is not implemented for conversionClient") 272 } 273 274 func convertSlice(rcList []*v1.ReplicationController) ([]*apps.ReplicaSet, error) { 275 rsList := make([]*apps.ReplicaSet, 0, len(rcList)) 276 for _, rc := range rcList { 277 rs, err := convertRCtoRS(rc, nil) 278 if err != nil { 279 return nil, err 280 } 281 rsList = append(rsList, rs) 282 } 283 return rsList, nil 284 } 285 286 func convertList(rcList *v1.ReplicationControllerList) (*apps.ReplicaSetList, error) { 287 rsList := &apps.ReplicaSetList{Items: make([]apps.ReplicaSet, len(rcList.Items))} 288 for i := range rcList.Items { 289 rc := &rcList.Items[i] 290 _, err := convertRCtoRS(rc, &rsList.Items[i]) 291 if err != nil { 292 return nil, err 293 } 294 } 295 return rsList, nil 296 } 297 298 func convertCall(fn func(*v1.ReplicationController) (*v1.ReplicationController, error), rs *apps.ReplicaSet) (*apps.ReplicaSet, error) { 299 rc, err := convertRStoRC(rs) 300 if err != nil { 301 return nil, err 302 } 303 result, err := fn(rc) 304 if err != nil { 305 return nil, err 306 } 307 return convertRCtoRS(result, nil) 308 } 309 310 func convertRCtoRS(rc *v1.ReplicationController, out *apps.ReplicaSet) (*apps.ReplicaSet, error) { 311 var rsInternal appsinternal.ReplicaSet 312 if err := apiv1.Convert_v1_ReplicationController_To_apps_ReplicaSet(rc, &rsInternal, nil); err != nil { 313 return nil, fmt.Errorf("can't convert ReplicationController %v/%v to ReplicaSet: %v", rc.Namespace, rc.Name, err) 314 } 315 if out == nil { 316 out = new(apps.ReplicaSet) 317 } 318 if err := appsconversion.Convert_apps_ReplicaSet_To_v1_ReplicaSet(&rsInternal, out, nil); err != nil { 319 return nil, fmt.Errorf("can't convert ReplicaSet (converted from ReplicationController %v/%v) from internal to apps/v1: %v", rc.Namespace, rc.Name, err) 320 } 321 return out, nil 322 } 323 324 func convertRStoRC(rs *apps.ReplicaSet) (*v1.ReplicationController, error) { 325 var rsInternal appsinternal.ReplicaSet 326 if err := appsconversion.Convert_v1_ReplicaSet_To_apps_ReplicaSet(rs, &rsInternal, nil); err != nil { 327 return nil, fmt.Errorf("can't convert ReplicaSet (converting to ReplicationController %v/%v) from apps/v1 to internal: %v", rs.Namespace, rs.Name, err) 328 } 329 var rc v1.ReplicationController 330 if err := apiv1.Convert_apps_ReplicaSet_To_v1_ReplicationController(&rsInternal, &rc, nil); err != nil { 331 return nil, fmt.Errorf("can't convert ReplicaSet to ReplicationController %v/%v: %v", rs.Namespace, rs.Name, err) 332 } 333 return &rc, nil 334 } 335 336 type podControlAdapter struct { 337 controller.PodControlInterface 338 } 339 340 func (pc podControlAdapter) CreatePods(ctx context.Context, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error { 341 rc, err := convertRStoRC(object.(*apps.ReplicaSet)) 342 if err != nil { 343 return err 344 } 345 return pc.PodControlInterface.CreatePods(ctx, namespace, template, rc, controllerRef) 346 } 347 348 func (pc podControlAdapter) DeletePod(ctx context.Context, namespace string, podID string, object runtime.Object) error { 349 rc, err := convertRStoRC(object.(*apps.ReplicaSet)) 350 if err != nil { 351 return err 352 } 353 return pc.PodControlInterface.DeletePod(ctx, namespace, podID, rc) 354 }