You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

upstream.go 2.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. Copyright 2021 The KubeEdge Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package controllers
  14. import (
  15. "fmt"
  16. "strings"
  17. "k8s.io/klog/v2"
  18. "github.com/kubeedge/sedna/pkg/globalmanager/messagelayer"
  19. "github.com/kubeedge/sedna/pkg/globalmanager/runtime"
  20. )
  21. // UpstreamController subscribes the updates from edge and syncs to k8s api server
  22. type UpstreamController struct {
  23. messageLayer messagelayer.MessageLayer
  24. updateHandlers map[string]runtime.UpstreamHandler
  25. }
  26. func (uc *UpstreamController) checkOperation(operation string) error {
  27. // current only support the 'status' operation
  28. if operation != "status" {
  29. return fmt.Errorf("unknown operation '%s'", operation)
  30. }
  31. return nil
  32. }
  33. // syncEdgeUpdate receives the updates from edge and syncs these to k8s.
  34. func (uc *UpstreamController) syncEdgeUpdate() {
  35. for {
  36. select {
  37. case <-uc.messageLayer.Done():
  38. klog.Info("Stop sedna upstream loop")
  39. return
  40. default:
  41. }
  42. update, err := uc.messageLayer.ReceiveResourceUpdate()
  43. if err == nil {
  44. err = uc.checkOperation(update.Operation)
  45. }
  46. if err != nil {
  47. klog.Warningf("Ignore update since this err: %+v", err)
  48. continue
  49. }
  50. kind := update.Kind
  51. namespace := update.Namespace
  52. name := update.Name
  53. operation := update.Operation
  54. handler, ok := uc.updateHandlers[kind]
  55. if ok {
  56. err := handler(name, namespace, operation, update.Content)
  57. if err != nil {
  58. klog.Errorf("Error to handle %s %s/%s operation(%s): %+v", kind, namespace, name, operation, err)
  59. }
  60. } else {
  61. klog.Warningf("No handler for resource kind %s", kind)
  62. }
  63. }
  64. }
  65. // Run starts the upstream controller
  66. func (uc *UpstreamController) Run(stopCh <-chan struct{}) {
  67. klog.Info("Start the sedna upstream controller")
  68. uc.syncEdgeUpdate()
  69. <-stopCh
  70. }
  71. func (uc *UpstreamController) Add(kind string, handler runtime.UpstreamHandler) error {
  72. kind = strings.ToLower(kind)
  73. if _, ok := uc.updateHandlers[kind]; ok {
  74. return fmt.Errorf("a upstream handler for kind %s already exists", kind)
  75. }
  76. uc.updateHandlers[kind] = handler
  77. return nil
  78. }
  79. // NewUpstreamController creates a new Upstream controller from config
  80. func NewUpstreamController(cc *runtime.ControllerContext) (*UpstreamController, error) {
  81. uc := &UpstreamController{
  82. messageLayer: messagelayer.NewContextMessageLayer(),
  83. updateHandlers: make(map[string]runtime.UpstreamHandler),
  84. }
  85. return uc, nil
  86. }