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 }