github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/cloud/pkg/synccontroller/objectsync.go (about)

     1  package synccontroller
     2  
     3  import (
     4  	"strconv"
     5  
     6  	v1 "k8s.io/api/core/v1"
     7  	apierrors "k8s.io/apimachinery/pkg/api/errors"
     8  	"k8s.io/apimachinery/pkg/api/meta"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/apimachinery/pkg/types"
    11  	"k8s.io/klog"
    12  
    13  	beehiveContext "github.com/kubeedge/beehive/pkg/core/context"
    14  	"github.com/kubeedge/beehive/pkg/core/model"
    15  	"github.com/kubeedge/kubeedge/cloud/pkg/apis/reliablesyncs/v1alpha1"
    16  	edgectrconst "github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/constants"
    17  	edgectrmessagelayer "github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/messagelayer"
    18  	commonconst "github.com/kubeedge/kubeedge/common/constants"
    19  )
    20  
    21  func (sctl *SyncController) managePod(sync *v1alpha1.ObjectSync) {
    22  	pod, err := sctl.podLister.Pods(sync.Namespace).Get(sync.Spec.ObjectName)
    23  
    24  	nodeName := getNodeName(sync.Name)
    25  
    26  	if err != nil {
    27  		if apierrors.IsNotFound(err) {
    28  			pod = &v1.Pod{
    29  				ObjectMeta: metav1.ObjectMeta{
    30  					Name:      sync.Spec.ObjectName,
    31  					Namespace: sync.Namespace,
    32  					UID:       types.UID(getObjectUID(sync.Name)),
    33  				},
    34  			}
    35  		} else {
    36  			klog.Errorf("Failed to manage pod sync of %s in namespace %s: %v", sync.Name, sync.Namespace, err)
    37  			return
    38  		}
    39  	}
    40  	sendEvents(err, nodeName, sync, model.ResourceTypePod, pod.ResourceVersion, pod)
    41  }
    42  
    43  func (sctl *SyncController) manageConfigMap(sync *v1alpha1.ObjectSync) {
    44  	configmap, err := sctl.configMapLister.ConfigMaps(sync.Namespace).Get(sync.Spec.ObjectName)
    45  
    46  	nodeName := getNodeName(sync.Name)
    47  
    48  	if err != nil {
    49  		if apierrors.IsNotFound(err) {
    50  			configmap = &v1.ConfigMap{
    51  				ObjectMeta: metav1.ObjectMeta{
    52  					Name:      sync.Spec.ObjectName,
    53  					Namespace: sync.Namespace,
    54  					UID:       types.UID(getObjectUID(sync.Name)),
    55  				},
    56  			}
    57  		} else {
    58  			klog.Errorf("Failed to manage configMap sync of %s in namespace %s: %v", sync.Name, sync.Namespace, err)
    59  			return
    60  		}
    61  	}
    62  	sendEvents(err, nodeName, sync, model.ResourceTypeConfigmap, configmap.ResourceVersion, configmap)
    63  }
    64  
    65  func (sctl *SyncController) manageSecret(sync *v1alpha1.ObjectSync) {
    66  	secret, err := sctl.secretLister.Secrets(sync.Namespace).Get(sync.Spec.ObjectName)
    67  
    68  	nodeName := getNodeName(sync.Name)
    69  
    70  	if err != nil {
    71  		if apierrors.IsNotFound(err) {
    72  			secret = &v1.Secret{
    73  				ObjectMeta: metav1.ObjectMeta{
    74  					Name:      sync.Spec.ObjectName,
    75  					Namespace: sync.Namespace,
    76  					UID:       types.UID(getObjectUID(sync.Name)),
    77  				},
    78  			}
    79  		} else {
    80  			klog.Errorf("Failed to manage secret sync of %s in namespace %s: %v", sync.Name, sync.Namespace, err)
    81  			return
    82  		}
    83  	}
    84  	sendEvents(err, nodeName, sync, model.ResourceTypeSecret, secret.ResourceVersion, secret)
    85  }
    86  
    87  func (sctl *SyncController) manageService(sync *v1alpha1.ObjectSync) {
    88  	service, err := sctl.serviceLister.Services(sync.Namespace).Get(sync.Spec.ObjectName)
    89  
    90  	nodeName := getNodeName(sync.Name)
    91  
    92  	if err != nil {
    93  		if apierrors.IsNotFound(err) {
    94  			service = &v1.Service{
    95  				ObjectMeta: metav1.ObjectMeta{
    96  					Name:      sync.Spec.ObjectName,
    97  					Namespace: sync.Namespace,
    98  					UID:       types.UID(getObjectUID(sync.Name)),
    99  				},
   100  			}
   101  		} else {
   102  			klog.Errorf("Failed to manage service sync of %s in namespace %s: %v", sync.Name, sync.Namespace, err)
   103  			return
   104  		}
   105  	}
   106  	sendEvents(err, nodeName, sync, commonconst.ResourceTypeService, service.ResourceVersion, service)
   107  }
   108  
   109  func (sctl *SyncController) manageEndpoint(sync *v1alpha1.ObjectSync) {
   110  	endpoint, err := sctl.endpointLister.Endpoints(sync.Namespace).Get(sync.Spec.ObjectName)
   111  
   112  	nodeName := getNodeName(sync.Name)
   113  
   114  	if err != nil {
   115  		if apierrors.IsNotFound(err) {
   116  			endpoint = &v1.Endpoints{
   117  				ObjectMeta: metav1.ObjectMeta{
   118  					Name:      sync.Spec.ObjectName,
   119  					Namespace: sync.Namespace,
   120  					UID:       types.UID(getObjectUID(sync.Name)),
   121  				},
   122  			}
   123  		} else {
   124  			klog.Errorf("Failed to manage endpoint sync of %s in namespace %s: %v", sync.Name, sync.Namespace, err)
   125  			return
   126  		}
   127  	}
   128  	sendEvents(err, nodeName, sync, commonconst.ResourceTypeEndpoints, endpoint.ResourceVersion, endpoint)
   129  }
   130  
   131  // todo: add events for devices
   132  func (sctl *SyncController) manageDevice(sync *v1alpha1.ObjectSync) {
   133  	//pod, err := sctl.deviceLister.Devices(sync.Namespace).Get(sync.Spec.ObjectName)
   134  
   135  	//
   136  	//if err != nil && apierrors.IsNotFound(err) {
   137  	//trigger the delete event
   138  	//}
   139  
   140  	//if pod.ResourceVersion > sync.Status.ObjectResourceVersion {
   141  	// trigger the update event
   142  	//}
   143  }
   144  
   145  func sendEvents(err error, nodeName string, sync *v1alpha1.ObjectSync, resourceType string,
   146  	objectResourceVersion string, obj interface{}) {
   147  
   148  	if err != nil && apierrors.IsNotFound(err) {
   149  		//trigger the delete event
   150  		klog.Infof("%s: %s has been deleted in K8s, send the delete event to edge", resourceType, sync.Spec.ObjectName)
   151  		msg := buildEdgeControllerMessage(nodeName, sync.Namespace, resourceType, sync.Spec.ObjectName, model.DeleteOperation, obj)
   152  		beehiveContext.Send(commonconst.DefaultContextSendModuleName, *msg)
   153  		return
   154  	}
   155  
   156  	if sync.Status.ObjectResourceVersion == "" {
   157  		klog.Errorf("The ObjectResourceVersion is empty in status of objectsync: %s", sync.Name)
   158  		return
   159  	}
   160  
   161  	if CompareResourceVersion(objectResourceVersion, sync.Status.ObjectResourceVersion) > 0 {
   162  		// trigger the update event
   163  		klog.Infof("The resourceVersion: %s of %s in K8s is greater than in edgenode: %s, send the update event", objectResourceVersion, resourceType, sync.Status.ObjectResourceVersion)
   164  		msg := buildEdgeControllerMessage(nodeName, sync.Namespace, resourceType, sync.Spec.ObjectName, model.UpdateOperation, obj)
   165  		beehiveContext.Send(commonconst.DefaultContextSendModuleName, *msg)
   166  	}
   167  }
   168  
   169  func buildEdgeControllerMessage(nodeName, namespace, resourceType, resourceName, operationType string, obj interface{}) *model.Message {
   170  	msg := model.NewMessage("")
   171  	resource, err := edgectrmessagelayer.BuildResource(nodeName, namespace, resourceType, resourceName)
   172  	if err != nil {
   173  		klog.Warningf("build message resource failed with error: %s", err)
   174  		return nil
   175  	}
   176  	msg.BuildRouter(edgectrconst.EdgeControllerModuleName, edgectrconst.GroupResource, resource, operationType)
   177  	msg.Content = obj
   178  
   179  	resourceVersion := GetObjectResourceVersion(obj)
   180  	msg.SetResourceVersion(resourceVersion)
   181  
   182  	return msg
   183  }
   184  
   185  // GetMessageUID returns the resourceVersion of the object in message
   186  func GetObjectResourceVersion(obj interface{}) string {
   187  	if obj == nil {
   188  		klog.Error("object is nil")
   189  		return ""
   190  	}
   191  
   192  	accessor, err := meta.Accessor(obj)
   193  	if err != nil {
   194  		klog.Errorf("Failed to get resourceVersion of the object: %v", obj)
   195  		return ""
   196  	}
   197  
   198  	return accessor.GetResourceVersion()
   199  }
   200  
   201  // CompareResourceVersion compares resourceversions, resource versions are actually
   202  // ints, so we can easily compare them.
   203  // If rva>rvb, return 1; rva=rvb, return 0; rva<rvb, return -1
   204  func CompareResourceVersion(rva, rvb string) int {
   205  	a, err := strconv.ParseUint(rva, 10, 64)
   206  	if err != nil {
   207  		// coder error
   208  		panic(err)
   209  	}
   210  	b, err := strconv.ParseUint(rvb, 10, 64)
   211  	if err != nil {
   212  		// coder error
   213  		panic(err)
   214  	}
   215  
   216  	if a > b {
   217  		return 1
   218  	}
   219  	if a == b {
   220  		return 0
   221  	}
   222  	return -1
   223  }