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

     1  /*
     2  Copyright 2014 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  @CHANGELOG
    17  KubeEdge Authors: To manage node/pod status for edge deployment scenarios,
    18  we grab some functions from `kubelet/status/status_manager.go and do some modifications, they are
    19  1. updatePodStatus
    20  2. updateNodeStatus
    21  3. normalizePodStatus
    22  4. isPodNotRunning
    23  */
    24  package controller
    25  
    26  import (
    27  	"encoding/json"
    28  	"sort"
    29  	"time"
    30  
    31  	v1 "k8s.io/api/core/v1"
    32  	"k8s.io/apimachinery/pkg/api/errors"
    33  	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    34  	"k8s.io/client-go/kubernetes"
    35  	"k8s.io/klog"
    36  
    37  	beehiveContext "github.com/kubeedge/beehive/pkg/core/context"
    38  	"github.com/kubeedge/beehive/pkg/core/model"
    39  	"github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/config"
    40  	"github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/constants"
    41  	"github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/messagelayer"
    42  	"github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/types"
    43  	"github.com/kubeedge/kubeedge/cloud/pkg/edgecontroller/utils"
    44  	common "github.com/kubeedge/kubeedge/common/constants"
    45  	edgeapi "github.com/kubeedge/kubeedge/common/types"
    46  )
    47  
    48  // SortedContainerStatuses define A type to help sort container statuses based on container names.
    49  type SortedContainerStatuses []v1.ContainerStatus
    50  
    51  func (s SortedContainerStatuses) Len() int      { return len(s) }
    52  func (s SortedContainerStatuses) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
    53  
    54  func (s SortedContainerStatuses) Less(i, j int) bool {
    55  	return s[i].Name < s[j].Name
    56  }
    57  
    58  // SortInitContainerStatuses ensures that statuses are in the order that their
    59  // init container appears in the pod spec
    60  func SortInitContainerStatuses(p *v1.Pod, statuses []v1.ContainerStatus) {
    61  	containers := p.Spec.InitContainers
    62  	current := 0
    63  	for _, container := range containers {
    64  		for j := current; j < len(statuses); j++ {
    65  			if container.Name == statuses[j].Name {
    66  				statuses[current], statuses[j] = statuses[j], statuses[current]
    67  				current++
    68  				break
    69  			}
    70  		}
    71  	}
    72  }
    73  
    74  // UpstreamController subscribe messages from edge and sync to k8s api server
    75  type UpstreamController struct {
    76  	kubeClient   *kubernetes.Clientset
    77  	messageLayer messagelayer.MessageLayer
    78  
    79  	// message channel
    80  	nodeStatusChan            chan model.Message
    81  	podStatusChan             chan model.Message
    82  	secretChan                chan model.Message
    83  	configMapChan             chan model.Message
    84  	serviceChan               chan model.Message
    85  	endpointsChan             chan model.Message
    86  	persistentVolumeChan      chan model.Message
    87  	persistentVolumeClaimChan chan model.Message
    88  	volumeAttachmentChan      chan model.Message
    89  	queryNodeChan             chan model.Message
    90  	updateNodeChan            chan model.Message
    91  }
    92  
    93  // Start UpstreamController
    94  func (uc *UpstreamController) Start() error {
    95  	klog.Info("start upstream controller")
    96  
    97  	uc.nodeStatusChan = make(chan model.Message, config.Config.Buffer.UpdateNodeStatus)
    98  	uc.podStatusChan = make(chan model.Message, config.Config.Buffer.UpdatePodStatus)
    99  	uc.configMapChan = make(chan model.Message, config.Config.Buffer.QueryConfigmap)
   100  	uc.secretChan = make(chan model.Message, config.Config.Buffer.QuerySecret)
   101  	uc.serviceChan = make(chan model.Message, config.Config.Buffer.QueryService)
   102  	uc.endpointsChan = make(chan model.Message, config.Config.Buffer.QueryEndpoints)
   103  	uc.persistentVolumeChan = make(chan model.Message, config.Config.Buffer.QueryPersistentVolume)
   104  	uc.persistentVolumeClaimChan = make(chan model.Message, config.Config.Buffer.QueryPersistentVolumeClaim)
   105  	uc.volumeAttachmentChan = make(chan model.Message, config.Config.Buffer.QueryVolumeAttachment)
   106  	uc.queryNodeChan = make(chan model.Message, config.Config.Buffer.QueryNode)
   107  	uc.updateNodeChan = make(chan model.Message, config.Config.Buffer.UpdateNode)
   108  
   109  	go uc.dispatchMessage()
   110  
   111  	for i := 0; i < int(config.Config.Load.UpdateNodeStatusWorkers); i++ {
   112  		go uc.updateNodeStatus()
   113  	}
   114  	for i := 0; i < int(config.Config.Load.UpdatePodStatusWorkers); i++ {
   115  		go uc.updatePodStatus()
   116  	}
   117  	for i := 0; i < int(config.Config.Load.QueryConfigmapWorkers); i++ {
   118  		go uc.queryConfigMap()
   119  	}
   120  	for i := 0; i < int(config.Config.Load.QuerySecretWorkers); i++ {
   121  		go uc.querySecret()
   122  	}
   123  	for i := 0; i < int(config.Config.Load.QueryServiceWorkers); i++ {
   124  		go uc.queryService()
   125  	}
   126  	for i := 0; i < int(config.Config.Load.QueryEndpointsWorkers); i++ {
   127  		go uc.queryEndpoints()
   128  	}
   129  	for i := 0; i < int(config.Config.Load.QueryPersistentVolumeWorkers); i++ {
   130  		go uc.queryPersistentVolume()
   131  	}
   132  	for i := 0; i < int(config.Config.Load.QueryPersistentVolumeClaimWorkers); i++ {
   133  		go uc.queryPersistentVolumeClaim()
   134  	}
   135  	for i := 0; i < int(config.Config.Load.QueryVolumeAttachmentWorkers); i++ {
   136  		go uc.queryVolumeAttachment()
   137  	}
   138  	for i := 0; i < int(config.Config.Load.QueryNodeWorkers); i++ {
   139  		go uc.queryNode()
   140  	}
   141  	for i := 0; i < int(config.Config.Load.UpdateNodeWorkers); i++ {
   142  		go uc.updateNode()
   143  	}
   144  	return nil
   145  }
   146  
   147  func (uc *UpstreamController) dispatchMessage() {
   148  	for {
   149  		select {
   150  		case <-beehiveContext.Done():
   151  			klog.Info("stop dispatchMessage")
   152  			return
   153  		default:
   154  		}
   155  		msg, err := uc.messageLayer.Receive()
   156  		if err != nil {
   157  			klog.Warningf("receive message failed, %s", err)
   158  			continue
   159  		}
   160  
   161  		klog.Infof("dispatch message ID: %s", msg.GetID())
   162  		klog.V(5).Infof("dispatch message content: %++v", msg)
   163  
   164  		resourceType, err := messagelayer.GetResourceType(msg)
   165  		if err != nil {
   166  			klog.Warningf("parse message: %s resource type with error: %s", msg.GetID(), err)
   167  			continue
   168  		}
   169  		klog.Infof("message: %s, resource type is: %s", msg.GetID(), resourceType)
   170  		operationType := msg.GetOperation()
   171  		klog.Infof("message: %s, operation type is: %s", msg.GetID(), operationType)
   172  
   173  		switch resourceType {
   174  		case model.ResourceTypeNodeStatus:
   175  			uc.nodeStatusChan <- msg
   176  		case model.ResourceTypePodStatus:
   177  			uc.podStatusChan <- msg
   178  		case model.ResourceTypeConfigmap:
   179  			uc.configMapChan <- msg
   180  		case model.ResourceTypeSecret:
   181  			uc.secretChan <- msg
   182  		case common.ResourceTypeService:
   183  			uc.serviceChan <- msg
   184  		case common.ResourceTypeEndpoints:
   185  			uc.endpointsChan <- msg
   186  		case common.ResourceTypePersistentVolume:
   187  			uc.persistentVolumeChan <- msg
   188  		case common.ResourceTypePersistentVolumeClaim:
   189  			uc.persistentVolumeClaimChan <- msg
   190  		case common.ResourceTypeVolumeAttachment:
   191  			uc.volumeAttachmentChan <- msg
   192  		case model.ResourceTypeNode:
   193  			switch operationType {
   194  			case model.QueryOperation:
   195  				uc.queryNodeChan <- msg
   196  			case model.UpdateOperation:
   197  				uc.updateNodeChan <- msg
   198  			default:
   199  				klog.Errorf("message: %s, operation type: %s unsupported", msg.GetID(), operationType)
   200  			}
   201  		default:
   202  			klog.Errorf("message: %s, resource type: %s unsupported", msg.GetID(), resourceType)
   203  		}
   204  	}
   205  }
   206  
   207  func (uc *UpstreamController) updatePodStatus() {
   208  	for {
   209  		select {
   210  		case <-beehiveContext.Done():
   211  			klog.Warning("stop updatePodStatus")
   212  			return
   213  		case msg := <-uc.podStatusChan:
   214  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   215  
   216  			namespace, podStatuses := uc.unmarshalPodStatusMessage(msg)
   217  			switch msg.GetOperation() {
   218  			case model.UpdateOperation:
   219  				for _, podStatus := range podStatuses {
   220  					getPod, err := uc.kubeClient.CoreV1().Pods(namespace).Get(podStatus.Name, metaV1.GetOptions{})
   221  					if errors.IsNotFound(err) {
   222  						klog.Warningf("message: %s, pod not found, namespace: %s, name: %s", msg.GetID(), namespace, podStatus.Name)
   223  
   224  						// Send request to delete this pod on edge side
   225  						delMsg := model.NewMessage("")
   226  						nodeID, err := messagelayer.GetNodeID(msg)
   227  						if err != nil {
   228  							klog.Warningf("Get node ID failed with error: %s", err)
   229  							continue
   230  						}
   231  						resource, err := messagelayer.BuildResource(nodeID, namespace, model.ResourceTypePod, podStatus.Name)
   232  						if err != nil {
   233  							klog.Warningf("Built message resource failed with error: %s", err)
   234  							continue
   235  						}
   236  						pod := &v1.Pod{}
   237  						pod.Namespace, pod.Name = namespace, podStatus.Name
   238  						delMsg.Content = pod
   239  						delMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.DeleteOperation)
   240  						if err := uc.messageLayer.Send(*delMsg); err != nil {
   241  							klog.Warningf("Send message failed with error: %s, operation: %s, resource: %s", err, delMsg.GetOperation(), delMsg.GetResource())
   242  						} else {
   243  							klog.Infof("Send message successfully, operation: %s, resource: %s", delMsg.GetOperation(), delMsg.GetResource())
   244  						}
   245  
   246  						continue
   247  					}
   248  					if err != nil {
   249  						klog.Warningf("message: %s, pod is nil, namespace: %s, name: %s, error: %s", msg.GetID(), namespace, podStatus.Name, err)
   250  						continue
   251  					}
   252  					status := podStatus.Status
   253  					oldStatus := getPod.Status
   254  					// Set ReadyCondition.LastTransitionTime
   255  					if _, readyCondition := uc.getPodCondition(&status, v1.PodReady); readyCondition != nil {
   256  						// Need to set LastTransitionTime.
   257  						lastTransitionTime := metaV1.Now()
   258  						_, oldReadyCondition := uc.getPodCondition(&oldStatus, v1.PodReady)
   259  						if oldReadyCondition != nil && readyCondition.Status == oldReadyCondition.Status {
   260  							lastTransitionTime = oldReadyCondition.LastTransitionTime
   261  						}
   262  						readyCondition.LastTransitionTime = lastTransitionTime
   263  					}
   264  
   265  					// Set InitializedCondition.LastTransitionTime.
   266  					if _, initCondition := uc.getPodCondition(&status, v1.PodInitialized); initCondition != nil {
   267  						// Need to set LastTransitionTime.
   268  						lastTransitionTime := metaV1.Now()
   269  						_, oldInitCondition := uc.getPodCondition(&oldStatus, v1.PodInitialized)
   270  						if oldInitCondition != nil && initCondition.Status == oldInitCondition.Status {
   271  							lastTransitionTime = oldInitCondition.LastTransitionTime
   272  						}
   273  						initCondition.LastTransitionTime = lastTransitionTime
   274  					}
   275  
   276  					// ensure that the start time does not change across updates.
   277  					if oldStatus.StartTime != nil && !oldStatus.StartTime.IsZero() {
   278  						status.StartTime = oldStatus.StartTime
   279  					} else if status.StartTime.IsZero() {
   280  						// if the status has no start time, we need to set an initial time
   281  						now := metaV1.Now()
   282  						status.StartTime = &now
   283  					}
   284  
   285  					uc.normalizePodStatus(getPod, &status)
   286  					getPod.Status = status
   287  
   288  					if updatedPod, err := uc.kubeClient.CoreV1().Pods(getPod.Namespace).UpdateStatus(getPod); err != nil {
   289  						klog.Warningf("message: %s, update pod status failed with error: %s, namespace: %s, name: %s", msg.GetID(), err, getPod.Namespace, getPod.Name)
   290  					} else {
   291  						klog.Infof("message: %s, update pod status successfully, namespace: %s, name: %s", msg.GetID(), updatedPod.Namespace, updatedPod.Name)
   292  						if updatedPod.DeletionTimestamp != nil && (status.Phase == v1.PodSucceeded || status.Phase == v1.PodFailed) {
   293  							if uc.isPodNotRunning(status.ContainerStatuses) {
   294  								if err := uc.kubeClient.CoreV1().Pods(updatedPod.Namespace).Delete(updatedPod.Name, metaV1.NewDeleteOptions(0)); err != nil {
   295  									klog.Warningf("message: %s, graceful delete pod failed with error: %s, namespace: %s, name: %s", msg.GetID(), err, updatedPod.Namespace, updatedPod.Name)
   296  								}
   297  								klog.Infof("message: %s, pod delete successfully, namespace: %s, name: %s", msg.GetID(), updatedPod.Namespace, updatedPod.Name)
   298  							}
   299  						}
   300  					}
   301  				}
   302  
   303  			default:
   304  				klog.Warningf("pod status operation: %s unsupported", msg.GetOperation())
   305  			}
   306  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   307  		}
   308  	}
   309  }
   310  
   311  // createNode create new edge node to kubernetes
   312  func (uc *UpstreamController) createNode(name string, node *v1.Node) (*v1.Node, error) {
   313  	node.Name = name
   314  
   315  	//add default labels
   316  	if node.Labels == nil {
   317  		node.Labels = make(map[string]string)
   318  	}
   319  	node.Labels["name"] = name
   320  	node.Labels["node-role.kubernetes.io/edge"] = ""
   321  
   322  	return uc.kubeClient.CoreV1().Nodes().Create(node)
   323  }
   324  
   325  func (uc *UpstreamController) updateNodeStatus() {
   326  	for {
   327  		select {
   328  		case <-beehiveContext.Done():
   329  			klog.Warning("stop updateNodeStatus")
   330  			return
   331  		case msg := <-uc.nodeStatusChan:
   332  			klog.Infof("message: %s, operation is: %s, and resource is %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   333  
   334  			var data []byte
   335  			switch msg.Content.(type) {
   336  			case []byte:
   337  				data = msg.GetContent().([]byte)
   338  			default:
   339  				var err error
   340  				data, err = json.Marshal(msg.GetContent())
   341  				if err != nil {
   342  					klog.Warningf("message: %s process failure, marshal message content with error: %s", msg.GetID(), err)
   343  					continue
   344  				}
   345  			}
   346  
   347  			namespace, err := messagelayer.GetNamespace(msg)
   348  			if err != nil {
   349  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   350  				continue
   351  			}
   352  			name, err := messagelayer.GetResourceName(msg)
   353  			if err != nil {
   354  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   355  				continue
   356  			}
   357  
   358  			switch msg.GetOperation() {
   359  			case model.InsertOperation:
   360  				_, err := uc.kubeClient.CoreV1().Nodes().Get(name, metaV1.GetOptions{})
   361  				if err == nil {
   362  					klog.Infof("node: %s already exists, do nothing", name)
   363  					uc.nodeMsgResponse(name, namespace, "OK", msg)
   364  					continue
   365  				}
   366  
   367  				if !errors.IsNotFound(err) {
   368  					klog.Errorf("get node %s info error: %v , register node failed", name, err)
   369  					uc.nodeMsgResponse(name, namespace, "", msg)
   370  					continue
   371  				}
   372  
   373  				node := &v1.Node{}
   374  				err = json.Unmarshal(data, node)
   375  				if err != nil {
   376  					klog.Errorf("message: %s process failure, unmarshal marshaled message content with error: %s", msg.GetID(), err)
   377  					uc.nodeMsgResponse(name, namespace, "", msg)
   378  					continue
   379  				}
   380  
   381  				if _, err = uc.createNode(name, node); err != nil {
   382  					klog.Errorf("create node %s error: %v , register node failed", name, err)
   383  					uc.nodeMsgResponse(name, namespace, "", msg)
   384  					continue
   385  				}
   386  
   387  				uc.nodeMsgResponse(name, namespace, "OK", msg)
   388  
   389  			case model.UpdateOperation:
   390  				nodeStatusRequest := &edgeapi.NodeStatusRequest{}
   391  				err := json.Unmarshal(data, nodeStatusRequest)
   392  				if err != nil {
   393  					klog.Warningf("message: %s process failure, unmarshal marshaled message content with error: %s", msg.GetID(), err)
   394  					continue
   395  				}
   396  
   397  				getNode, err := uc.kubeClient.CoreV1().Nodes().Get(name, metaV1.GetOptions{})
   398  				if errors.IsNotFound(err) {
   399  					klog.Warningf("message: %s process failure, node %s not found", msg.GetID(), name)
   400  					continue
   401  				}
   402  
   403  				if err != nil {
   404  					klog.Warningf("message: %s process failure with error: %s, namespaces: %s name: %s", msg.GetID(), err, namespace, name)
   405  					continue
   406  				}
   407  
   408  				// TODO: comment below for test failure. Needs to decide whether to keep post troubleshoot
   409  				// In case the status stored at metadata service is outdated, update the heartbeat automatically
   410  				if !config.Config.EdgeSiteEnable {
   411  					for i := range nodeStatusRequest.Status.Conditions {
   412  						if time.Now().Sub(nodeStatusRequest.Status.Conditions[i].LastHeartbeatTime.Time) > time.Duration(config.Config.NodeUpdateFrequency)*time.Second {
   413  							nodeStatusRequest.Status.Conditions[i].LastHeartbeatTime = metaV1.NewTime(time.Now())
   414  						}
   415  
   416  						if time.Now().Sub(nodeStatusRequest.Status.Conditions[i].LastTransitionTime.Time) > time.Duration(config.Config.NodeUpdateFrequency)*time.Second {
   417  							nodeStatusRequest.Status.Conditions[i].LastTransitionTime = metaV1.NewTime(time.Now())
   418  						}
   419  					}
   420  				}
   421  
   422  				if getNode.Annotations == nil {
   423  					klog.Warningf("node annotations is nil map, new a map for it. namespace: %s, name: %s", getNode.Namespace, getNode.Name)
   424  					getNode.Annotations = make(map[string]string)
   425  				}
   426  				for name, v := range nodeStatusRequest.ExtendResources {
   427  					if name == constants.NvidiaGPUScalarResourceName {
   428  						var gpuStatus []types.NvidiaGPUStatus
   429  						for _, er := range v {
   430  							gpuStatus = append(gpuStatus, types.NvidiaGPUStatus{ID: er.Name, Healthy: true})
   431  						}
   432  						if len(gpuStatus) > 0 {
   433  							data, _ := json.Marshal(gpuStatus)
   434  							getNode.Annotations[constants.NvidiaGPUStatusAnnotationKey] = string(data)
   435  						}
   436  					}
   437  					data, err := json.Marshal(v)
   438  					if err != nil {
   439  						klog.Warningf("message: %s process failure, extend resource list marshal with error: %s", msg.GetID(), err)
   440  						continue
   441  					}
   442  					getNode.Annotations[string(name)] = string(data)
   443  				}
   444  
   445  				// Keep the same "VolumesAttached" attribute with upstream,
   446  				// since this value is maintained by kube-controller-manager.
   447  				nodeStatusRequest.Status.VolumesAttached = getNode.Status.VolumesAttached
   448  
   449  				getNode.Status = nodeStatusRequest.Status
   450  				node, err := uc.kubeClient.CoreV1().Nodes().UpdateStatus(getNode)
   451  				if err != nil {
   452  					klog.Warningf("message: %s process failure, update node failed with error: %s, namespace: %s, name: %s", msg.GetID(), err, getNode.Namespace, getNode.Name)
   453  					continue
   454  				}
   455  
   456  				resMsg := model.NewMessage(msg.GetID())
   457  				resMsg.SetResourceVersion(node.ResourceVersion)
   458  				resMsg.Content = "OK"
   459  				nodeID, err := messagelayer.GetNodeID(msg)
   460  				if err != nil {
   461  					klog.Warningf("Message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   462  					continue
   463  				}
   464  				resource, err := messagelayer.BuildResource(nodeID, namespace, model.ResourceTypeNode, name)
   465  				if err != nil {
   466  					klog.Warningf("Message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   467  					continue
   468  				}
   469  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   470  				if err = uc.messageLayer.Response(*resMsg); err != nil {
   471  					klog.Warningf("Message: %s process failure, response failed with error: %s", msg.GetID(), err)
   472  					continue
   473  				}
   474  
   475  				klog.V(4).Infof("message: %s, update node status successfully, namespace: %s, name: %s", msg.GetID(), getNode.Namespace, getNode.Name)
   476  
   477  			default:
   478  				klog.Warningf("message: %s process failure, node status operation: %s unsupported", msg.GetID(), msg.GetOperation())
   479  			}
   480  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   481  		}
   482  	}
   483  }
   484  
   485  func (uc *UpstreamController) queryConfigMap() {
   486  	for {
   487  		select {
   488  		case <-beehiveContext.Done():
   489  			klog.Warning("stop queryConfigMap")
   490  			return
   491  		case msg := <-uc.configMapChan:
   492  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   493  			namespace, err := messagelayer.GetNamespace(msg)
   494  			if err != nil {
   495  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   496  				continue
   497  			}
   498  			name, err := messagelayer.GetResourceName(msg)
   499  			if err != nil {
   500  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   501  				continue
   502  			}
   503  
   504  			switch msg.GetOperation() {
   505  			case model.QueryOperation:
   506  				configMap, err := uc.kubeClient.CoreV1().ConfigMaps(namespace).Get(name, metaV1.GetOptions{})
   507  				if errors.IsNotFound(err) {
   508  					klog.Warningf("message: %s process failure, configMap not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   509  					continue
   510  				}
   511  				if err != nil {
   512  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   513  					continue
   514  				}
   515  				resMsg := model.NewMessage(msg.GetID())
   516  				resMsg.SetResourceVersion(configMap.ResourceVersion)
   517  				resMsg.Content = configMap
   518  				nodeID, err := messagelayer.GetNodeID(msg)
   519  				if err != nil {
   520  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   521  				}
   522  				resource, err := messagelayer.BuildResource(nodeID, configMap.Namespace, model.ResourceTypeConfigmap, configMap.Name)
   523  				if err != nil {
   524  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   525  				}
   526  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   527  				err = uc.messageLayer.Response(*resMsg)
   528  				if err != nil {
   529  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   530  					continue
   531  				}
   532  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   533  			default:
   534  				klog.Warningf("message: %s process failure, configMap operation: %s unsupported", msg.GetID(), msg.GetOperation())
   535  			}
   536  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   537  		}
   538  	}
   539  }
   540  
   541  func (uc *UpstreamController) querySecret() {
   542  	for {
   543  		select {
   544  		case <-beehiveContext.Done():
   545  			klog.Warning("stop querySecret")
   546  			return
   547  		case msg := <-uc.secretChan:
   548  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   549  			namespace, err := messagelayer.GetNamespace(msg)
   550  			if err != nil {
   551  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   552  				continue
   553  			}
   554  			name, err := messagelayer.GetResourceName(msg)
   555  			if err != nil {
   556  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   557  				continue
   558  			}
   559  
   560  			switch msg.GetOperation() {
   561  			case model.QueryOperation:
   562  				secret, err := uc.kubeClient.CoreV1().Secrets(namespace).Get(name, metaV1.GetOptions{})
   563  				if errors.IsNotFound(err) {
   564  					klog.Warningf("message: %s process failure, secret not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   565  					continue
   566  				}
   567  				if err != nil {
   568  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   569  					continue
   570  				}
   571  				resMsg := model.NewMessage(msg.GetID())
   572  				resMsg.SetResourceVersion(secret.ResourceVersion)
   573  				resMsg.Content = secret
   574  				nodeID, err := messagelayer.GetNodeID(msg)
   575  				if err != nil {
   576  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   577  					continue
   578  				}
   579  				resource, err := messagelayer.BuildResource(nodeID, secret.Namespace, model.ResourceTypeSecret, secret.Name)
   580  				if err != nil {
   581  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   582  					continue
   583  				}
   584  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   585  				err = uc.messageLayer.Response(*resMsg)
   586  				if err != nil {
   587  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   588  					continue
   589  				}
   590  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   591  			default:
   592  				klog.Warningf("message: %s process failure, secret operation: %s unsupported", msg.GetID(), msg.GetOperation())
   593  			}
   594  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   595  		}
   596  	}
   597  }
   598  
   599  func (uc *UpstreamController) queryService() {
   600  	for {
   601  		select {
   602  		case <-beehiveContext.Done():
   603  			klog.Warning("stop queryService")
   604  			return
   605  		case msg := <-uc.serviceChan:
   606  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   607  			namespace, err := messagelayer.GetNamespace(msg)
   608  			if err != nil {
   609  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   610  				continue
   611  			}
   612  			name, err := messagelayer.GetResourceName(msg)
   613  			if err != nil {
   614  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   615  				continue
   616  			}
   617  
   618  			switch msg.GetOperation() {
   619  			case model.QueryOperation:
   620  				svc, err := uc.kubeClient.CoreV1().Services(namespace).Get(name, metaV1.GetOptions{})
   621  				if errors.IsNotFound(err) {
   622  					klog.Warningf("message: %s process failure, service not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   623  					continue
   624  				}
   625  				if err != nil {
   626  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   627  					continue
   628  				}
   629  				resMsg := model.NewMessage(msg.GetID())
   630  				resMsg.SetResourceVersion(svc.ResourceVersion)
   631  				resMsg.Content = svc
   632  				nodeID, err := messagelayer.GetNodeID(msg)
   633  				if err != nil {
   634  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   635  				}
   636  				resource, err := messagelayer.BuildResource(nodeID, svc.Namespace, common.ResourceTypeService, svc.Name)
   637  				if err != nil {
   638  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   639  				}
   640  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   641  				err = uc.messageLayer.Response(*resMsg)
   642  				if err != nil {
   643  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   644  					continue
   645  				}
   646  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   647  			default:
   648  				klog.Warningf("message: %s process failure, service operation: %s unsupported", msg.GetID(), msg.GetOperation())
   649  			}
   650  		}
   651  	}
   652  }
   653  
   654  func (uc *UpstreamController) queryEndpoints() {
   655  	for {
   656  		select {
   657  		case <-beehiveContext.Done():
   658  			klog.Warning("stop queryEndpoints")
   659  			return
   660  		case msg := <-uc.endpointsChan:
   661  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   662  			namespace, err := messagelayer.GetNamespace(msg)
   663  			if err != nil {
   664  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   665  				continue
   666  			}
   667  			name, err := messagelayer.GetResourceName(msg)
   668  			if err != nil {
   669  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   670  				continue
   671  			}
   672  
   673  			switch msg.GetOperation() {
   674  			case model.QueryOperation:
   675  				eps, err := uc.kubeClient.CoreV1().Endpoints(namespace).Get(name, metaV1.GetOptions{})
   676  				if errors.IsNotFound(err) {
   677  					klog.Warningf("message: %s process failure, endpoints not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   678  					continue
   679  				}
   680  				if err != nil {
   681  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   682  					continue
   683  				}
   684  				resMsg := model.NewMessage(msg.GetID())
   685  				resMsg.SetResourceVersion(eps.ResourceVersion)
   686  				resMsg.Content = eps
   687  				nodeID, err := messagelayer.GetNodeID(msg)
   688  				if err != nil {
   689  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   690  					continue
   691  				}
   692  				resource, err := messagelayer.BuildResource(nodeID, eps.Namespace, common.ResourceTypeEndpoints, eps.Name)
   693  				if err != nil {
   694  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   695  					continue
   696  				}
   697  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   698  				err = uc.messageLayer.Response(*resMsg)
   699  				if err != nil {
   700  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   701  					continue
   702  				}
   703  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   704  			default:
   705  				klog.Warningf("message: %s process failure, endpoints operation: %s unsupported", msg.GetID(), msg.GetOperation())
   706  			}
   707  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   708  		}
   709  	}
   710  }
   711  
   712  func (uc *UpstreamController) queryPersistentVolume() {
   713  	for {
   714  		select {
   715  		case <-beehiveContext.Done():
   716  			klog.Warning("stop queryPersistentVolume")
   717  			return
   718  		case msg := <-uc.persistentVolumeChan:
   719  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   720  			namespace, err := messagelayer.GetNamespace(msg)
   721  			if err != nil {
   722  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   723  				continue
   724  			}
   725  			name, err := messagelayer.GetResourceName(msg)
   726  			if err != nil {
   727  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   728  				continue
   729  			}
   730  
   731  			switch msg.GetOperation() {
   732  			case model.QueryOperation:
   733  				pv, err := uc.kubeClient.CoreV1().PersistentVolumes().Get(name, metaV1.GetOptions{})
   734  				if errors.IsNotFound(err) {
   735  					klog.Warningf("message: %s process failure, persistentvolume not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   736  					continue
   737  				}
   738  				if err != nil {
   739  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   740  					continue
   741  				}
   742  				resMsg := model.NewMessage(msg.GetID())
   743  				resMsg.SetResourceVersion(pv.ResourceVersion)
   744  				resMsg.Content = pv
   745  				nodeID, err := messagelayer.GetNodeID(msg)
   746  				if err != nil {
   747  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   748  					continue
   749  				}
   750  				resource, err := messagelayer.BuildResource(nodeID, namespace, "persistentvolume", pv.Name)
   751  				if err != nil {
   752  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   753  					continue
   754  				}
   755  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   756  				err = uc.messageLayer.Response(*resMsg)
   757  				if err != nil {
   758  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   759  					continue
   760  				}
   761  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   762  			default:
   763  				klog.Warningf("message: %s process failure, persistentvolume operation: %s unsupported", msg.GetID(), msg.GetOperation())
   764  			}
   765  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   766  		}
   767  	}
   768  }
   769  
   770  func (uc *UpstreamController) queryPersistentVolumeClaim() {
   771  	for {
   772  		select {
   773  		case <-beehiveContext.Done():
   774  			klog.Warning("stop queryPersistentVolumeClaim")
   775  			return
   776  		case msg := <-uc.persistentVolumeClaimChan:
   777  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   778  			namespace, err := messagelayer.GetNamespace(msg)
   779  			if err != nil {
   780  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   781  				continue
   782  			}
   783  			name, err := messagelayer.GetResourceName(msg)
   784  			if err != nil {
   785  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   786  				continue
   787  			}
   788  
   789  			switch msg.GetOperation() {
   790  			case model.QueryOperation:
   791  				pvc, err := uc.kubeClient.CoreV1().PersistentVolumeClaims(namespace).Get(name, metaV1.GetOptions{})
   792  				if errors.IsNotFound(err) {
   793  					klog.Warningf("message: %s process failure, persistentvolumeclaim not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   794  					continue
   795  				}
   796  				if err != nil {
   797  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   798  					continue
   799  				}
   800  				resMsg := model.NewMessage(msg.GetID())
   801  				resMsg.SetResourceVersion(pvc.ResourceVersion)
   802  				resMsg.Content = pvc
   803  				nodeID, err := messagelayer.GetNodeID(msg)
   804  				if err != nil {
   805  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   806  					continue
   807  				}
   808  				resource, err := messagelayer.BuildResource(nodeID, pvc.Namespace, "persistentvolumeclaim", pvc.Name)
   809  				if err != nil {
   810  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   811  					continue
   812  				}
   813  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   814  				err = uc.messageLayer.Response(*resMsg)
   815  				if err != nil {
   816  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   817  					continue
   818  				}
   819  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   820  			default:
   821  				klog.Warningf("message: %s process failure, persistentvolumeclaim operation: %s unsupported", msg.GetID(), msg.GetOperation())
   822  			}
   823  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   824  		}
   825  	}
   826  }
   827  
   828  func (uc *UpstreamController) queryVolumeAttachment() {
   829  	for {
   830  		select {
   831  		case <-beehiveContext.Done():
   832  			klog.Warning("stop queryVolumeAttachment")
   833  			return
   834  		case msg := <-uc.volumeAttachmentChan:
   835  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   836  			namespace, err := messagelayer.GetNamespace(msg)
   837  			if err != nil {
   838  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   839  				continue
   840  			}
   841  			name, err := messagelayer.GetResourceName(msg)
   842  			if err != nil {
   843  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   844  				continue
   845  			}
   846  
   847  			switch msg.GetOperation() {
   848  			case model.QueryOperation:
   849  				va, err := uc.kubeClient.StorageV1().VolumeAttachments().Get(name, metaV1.GetOptions{})
   850  				if errors.IsNotFound(err) {
   851  					klog.Warningf("message: %s process failure, volumeattachment not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
   852  					continue
   853  				}
   854  				if err != nil {
   855  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
   856  					continue
   857  				}
   858  				resMsg := model.NewMessage(msg.GetID())
   859  				resMsg.SetResourceVersion(va.ResourceVersion)
   860  				resMsg.Content = va
   861  				nodeID, err := messagelayer.GetNodeID(msg)
   862  				if err != nil {
   863  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   864  					continue
   865  				}
   866  				resource, err := messagelayer.BuildResource(nodeID, namespace, "volumeattachment", va.Name)
   867  				if err != nil {
   868  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   869  					continue
   870  				}
   871  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   872  				err = uc.messageLayer.Response(*resMsg)
   873  				if err != nil {
   874  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
   875  					continue
   876  				}
   877  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
   878  			default:
   879  				klog.Warningf("message: %s process failure, volumeattachment operation: %s unsupported", msg.GetID(), msg.GetOperation())
   880  			}
   881  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   882  		}
   883  	}
   884  }
   885  
   886  func (uc *UpstreamController) updateNode() {
   887  	for {
   888  		select {
   889  		case <-beehiveContext.Done():
   890  			klog.Warning("stop updateNode")
   891  			return
   892  		case msg := <-uc.updateNodeChan:
   893  			klog.Infof("message: %s, operation is: %s, and resource is %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   894  			noderequest := &v1.Node{}
   895  
   896  			var data []byte
   897  			switch msg.Content.(type) {
   898  			case []byte:
   899  				data = msg.GetContent().([]byte)
   900  			default:
   901  				var err error
   902  				data, err = json.Marshal(msg.GetContent())
   903  				if err != nil {
   904  					klog.Warningf("message: %s process failure, marshal message content with error: %s", msg.GetID(), err)
   905  					continue
   906  				}
   907  			}
   908  
   909  			err := json.Unmarshal(data, noderequest)
   910  			if err != nil {
   911  				klog.Warningf("message: %s process failure, unmarshal marshaled message content with error: %s", msg.GetID(), err)
   912  				continue
   913  			}
   914  
   915  			namespace, err := messagelayer.GetNamespace(msg)
   916  			if err != nil {
   917  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   918  				continue
   919  			}
   920  			name, err := messagelayer.GetResourceName(msg)
   921  			if err != nil {
   922  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   923  				continue
   924  			}
   925  
   926  			switch msg.GetOperation() {
   927  			case model.UpdateOperation:
   928  				getNode, err := uc.kubeClient.CoreV1().Nodes().Get(name, metaV1.GetOptions{})
   929  				if errors.IsNotFound(err) {
   930  					klog.Warningf("message: %s process failure, node %s not found", msg.GetID(), name)
   931  					continue
   932  				}
   933  				if err != nil {
   934  					klog.Warningf("message: %s process failure with error: %s, name: %s", msg.GetID(), err, name)
   935  					continue
   936  				}
   937  
   938  				if getNode.Annotations == nil {
   939  					klog.Warningf("node annotations is nil map, new a map for it. namespace: %s, name: %s", getNode.Namespace, getNode.Name)
   940  					getNode.Annotations = make(map[string]string)
   941  				}
   942  				for k, v := range noderequest.Annotations {
   943  					getNode.Annotations[k] = v
   944  				}
   945  				node, err := uc.kubeClient.CoreV1().Nodes().Update(getNode)
   946  				if err != nil {
   947  					klog.Warningf("message: %s process failure, update node failed with error: %s, namespace: %s, name: %s", msg.GetID(), err, getNode.Namespace, getNode.Name)
   948  					continue
   949  				}
   950  
   951  				resMsg := model.NewMessage(msg.GetID())
   952  				resMsg.SetResourceVersion(node.ResourceVersion)
   953  				resMsg.Content = "OK"
   954  				nodeID, err := messagelayer.GetNodeID(msg)
   955  				if err != nil {
   956  					klog.Warningf("Message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
   957  					continue
   958  				}
   959  				resource, err := messagelayer.BuildResource(nodeID, namespace, model.ResourceTypeNode, name)
   960  				if err != nil {
   961  					klog.Warningf("Message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
   962  					continue
   963  				}
   964  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
   965  				if err = uc.messageLayer.Response(*resMsg); err != nil {
   966  					klog.Warningf("Message: %s process failure, response failed with error: %s", msg.GetID(), err)
   967  					continue
   968  				}
   969  
   970  				klog.V(4).Infof("message: %s, update node successfully, namespace: %s, name: %s", msg.GetID(), getNode.Namespace, getNode.Name)
   971  			default:
   972  				klog.Warningf("message: %s process failure, node operation: %s unsupported", msg.GetID(), msg.GetOperation())
   973  			}
   974  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
   975  		}
   976  	}
   977  }
   978  
   979  func (uc *UpstreamController) queryNode() {
   980  	for {
   981  		select {
   982  		case <-beehiveContext.Done():
   983  			klog.Warning("stop queryNode")
   984  			return
   985  		case msg := <-uc.queryNodeChan:
   986  			klog.Infof("message: %s, operation is: %s, and resource is: %s", msg.GetID(), msg.GetOperation(), msg.GetResource())
   987  			namespace, err := messagelayer.GetNamespace(msg)
   988  			if err != nil {
   989  				klog.Warningf("message: %s process failure, get namespace failed with error: %s", msg.GetID(), err)
   990  				continue
   991  			}
   992  			name, err := messagelayer.GetResourceName(msg)
   993  			if err != nil {
   994  				klog.Warningf("message: %s process failure, get resource name failed with error: %s", msg.GetID(), err)
   995  				continue
   996  			}
   997  
   998  			switch msg.GetOperation() {
   999  			case model.QueryOperation:
  1000  				node, err := uc.kubeClient.CoreV1().Nodes().Get(name, metaV1.GetOptions{})
  1001  				if errors.IsNotFound(err) {
  1002  					klog.Warningf("message: %s process failure, node not found, namespace: %s, name: %s", msg.GetID(), namespace, name)
  1003  					continue
  1004  				}
  1005  				if err != nil {
  1006  					klog.Warningf("message: %s process failure with error: %s, namespace: %s, name: %s", msg.GetID(), err, namespace, name)
  1007  					continue
  1008  				}
  1009  				resMsg := model.NewMessage(msg.GetID())
  1010  				resMsg.SetResourceVersion(node.ResourceVersion)
  1011  				resMsg.Content = node
  1012  				nodeID, err := messagelayer.GetNodeID(msg)
  1013  				if err != nil {
  1014  					klog.Warningf("message: %s process failure, get node id failed with error: %s", msg.GetID(), err)
  1015  				}
  1016  				resource, err := messagelayer.BuildResource(nodeID, namespace, model.ResourceTypeNode, node.Name)
  1017  				if err != nil {
  1018  					klog.Warningf("message: %s process failure, build message resource failed with error: %s", msg.GetID(), err)
  1019  				}
  1020  				resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
  1021  				err = uc.messageLayer.Response(*resMsg)
  1022  				if err != nil {
  1023  					klog.Warningf("message: %s process failure, response failed with error: %s", msg.GetID(), err)
  1024  					continue
  1025  				}
  1026  				klog.V(4).Infof("message: %s process successfully", msg.GetID())
  1027  			default:
  1028  				klog.Warningf("message: %s process failure, query node operation: %s unsupported", msg.GetID(), msg.GetOperation())
  1029  			}
  1030  			klog.V(4).Infof("message: %s process successfully", msg.GetID())
  1031  		}
  1032  	}
  1033  }
  1034  
  1035  func (uc *UpstreamController) unmarshalPodStatusMessage(msg model.Message) (ns string, podStatuses []edgeapi.PodStatusRequest) {
  1036  	ns, err := messagelayer.GetNamespace(msg)
  1037  	if err != nil {
  1038  		klog.Warningf("message: %s process failure, get namespace with error: %s", msg.GetID(), err)
  1039  		return
  1040  	}
  1041  	name, _ := messagelayer.GetResourceName(msg)
  1042  
  1043  	var data []byte
  1044  	switch msg.Content.(type) {
  1045  	case []byte:
  1046  		data = msg.GetContent().([]byte)
  1047  	default:
  1048  		var err error
  1049  		data, err = json.Marshal(msg.GetContent())
  1050  		if err != nil {
  1051  			klog.Warningf("message: %s process failure, marshal content failed with error: %s", msg.GetID(), err)
  1052  			return
  1053  		}
  1054  	}
  1055  
  1056  	if name == "" {
  1057  		// multi pod status in one message
  1058  		err = json.Unmarshal(data, &podStatuses)
  1059  		if err != nil {
  1060  			return
  1061  		}
  1062  	} else {
  1063  		// one pod status per message
  1064  		var status edgeapi.PodStatusRequest
  1065  		if err := json.Unmarshal(data, &status); err != nil {
  1066  			return
  1067  		}
  1068  		podStatuses = append(podStatuses, status)
  1069  	}
  1070  	return
  1071  }
  1072  
  1073  // GetPodCondition extracts the provided condition from the given status and returns that.
  1074  // Returns nil and -1 if the condition is not present, and the index of the located condition.
  1075  func (uc *UpstreamController) getPodCondition(status *v1.PodStatus, conditionType v1.PodConditionType) (int, *v1.PodCondition) {
  1076  	if status == nil {
  1077  		return -1, nil
  1078  	}
  1079  	for i := range status.Conditions {
  1080  		if status.Conditions[i].Type == conditionType {
  1081  			return i, &status.Conditions[i]
  1082  		}
  1083  	}
  1084  	return -1, nil
  1085  }
  1086  
  1087  func (uc *UpstreamController) isPodNotRunning(statuses []v1.ContainerStatus) bool {
  1088  	for _, status := range statuses {
  1089  		if status.State.Terminated == nil && status.State.Waiting == nil {
  1090  			return false
  1091  		}
  1092  	}
  1093  	return true
  1094  }
  1095  
  1096  // We add this function, because apiserver only supports *RFC3339* now, which means that the timestamp returned by
  1097  // apiserver has no nanosecond information. However, the timestamp returned by unversioned.Now() contains nanosecond,
  1098  // so when we do comparison between status from apiserver and cached status, isStatusEqual() will always return false.
  1099  // There is related issue #15262 and PR #15263 about this.
  1100  func (uc *UpstreamController) normalizePodStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus {
  1101  	normalizeTimeStamp := func(t *metaV1.Time) {
  1102  		*t = t.Rfc3339Copy()
  1103  	}
  1104  	normalizeContainerState := func(c *v1.ContainerState) {
  1105  		if c.Running != nil {
  1106  			normalizeTimeStamp(&c.Running.StartedAt)
  1107  		}
  1108  		if c.Terminated != nil {
  1109  			normalizeTimeStamp(&c.Terminated.StartedAt)
  1110  			normalizeTimeStamp(&c.Terminated.FinishedAt)
  1111  		}
  1112  	}
  1113  
  1114  	if status.StartTime != nil {
  1115  		normalizeTimeStamp(status.StartTime)
  1116  	}
  1117  	for i := range status.Conditions {
  1118  		condition := &status.Conditions[i]
  1119  		normalizeTimeStamp(&condition.LastProbeTime)
  1120  		normalizeTimeStamp(&condition.LastTransitionTime)
  1121  	}
  1122  
  1123  	// update container statuses
  1124  	for i := range status.ContainerStatuses {
  1125  		cstatus := &status.ContainerStatuses[i]
  1126  		normalizeContainerState(&cstatus.State)
  1127  		normalizeContainerState(&cstatus.LastTerminationState)
  1128  	}
  1129  	// Sort the container statuses, so that the order won't affect the result of comparison
  1130  	sort.Sort(SortedContainerStatuses(status.ContainerStatuses))
  1131  
  1132  	// update init container statuses
  1133  	for i := range status.InitContainerStatuses {
  1134  		cstatus := &status.InitContainerStatuses[i]
  1135  		normalizeContainerState(&cstatus.State)
  1136  		normalizeContainerState(&cstatus.LastTerminationState)
  1137  	}
  1138  	// Sort the container statuses, so that the order won't affect the result of comparison
  1139  	SortInitContainerStatuses(pod, status.InitContainerStatuses)
  1140  	return status
  1141  }
  1142  
  1143  // nodeMsgResponse response message of ResourceTypeNode
  1144  func (uc *UpstreamController) nodeMsgResponse(nodeName, namespace, content string, msg model.Message) {
  1145  	resMsg := model.NewMessage(msg.GetID())
  1146  	resMsg.Content = content
  1147  	nodeID, err := messagelayer.GetNodeID(msg)
  1148  	if err != nil {
  1149  		klog.Warningf("Response message: %s failed, get node: %s id failed with error: %s", msg.GetID(), nodeName, err)
  1150  		return
  1151  	}
  1152  
  1153  	resource, err := messagelayer.BuildResource(nodeID, namespace, model.ResourceTypeNode, nodeName)
  1154  	if err != nil {
  1155  		klog.Warningf("Response message: %s failed, build message resource failed with error: %s", msg.GetID(), err)
  1156  		return
  1157  	}
  1158  
  1159  	resMsg.BuildRouter(constants.EdgeControllerModuleName, constants.GroupResource, resource, model.ResponseOperation)
  1160  	if err = uc.messageLayer.Response(*resMsg); err != nil {
  1161  		klog.Warningf("Response message: %s failed, response failed with error: %s", msg.GetID(), err)
  1162  		return
  1163  	}
  1164  
  1165  	return
  1166  }
  1167  
  1168  // NewUpstreamController create UpstreamController from config
  1169  func NewUpstreamController() (*UpstreamController, error) {
  1170  	cli, err := utils.KubeClient()
  1171  	if err != nil {
  1172  		klog.Warningf("create kube client failed with error: %s", err)
  1173  		return nil, err
  1174  	}
  1175  	uc := &UpstreamController{
  1176  		kubeClient:   cli,
  1177  		messageLayer: messagelayer.NewContextMessageLayer(),
  1178  	}
  1179  	return uc, nil
  1180  }