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 }