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  }