github.com/midokura/kubeedge@v1.2.0-mido.0/tests/stubs/cloud/controllerstub/podmanager.go (about) 1 /* 2 Copyright 2019 The KubeEdge 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 17 package controllerstub 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "io/ioutil" 23 "net/http" 24 "sync" 25 "time" 26 27 "k8s.io/klog" 28 29 "github.com/kubeedge/beehive/pkg/core/model" 30 "github.com/kubeedge/kubeedge/tests/stubs/common/constants" 31 "github.com/kubeedge/kubeedge/tests/stubs/common/types" 32 "github.com/kubeedge/kubeedge/tests/stubs/common/utils" 33 ) 34 35 // NewPodManager creates pod manger 36 func NewPodManager() (*PodManager, error) { 37 event := make(chan *model.Message, 1024) 38 pm := &PodManager{event: event} 39 return pm, nil 40 } 41 42 // PodManager is a manager watch pod change event 43 type PodManager struct { 44 // event 45 event chan *model.Message 46 // pods map 47 pods sync.Map 48 } 49 50 // GetEvent return a channel which receives event 51 func (pm *PodManager) GetEvent() chan *model.Message { 52 return pm.event 53 } 54 55 // AddPod adds pod in cache 56 func (pm *PodManager) AddPod(k string, v types.FakePod) { 57 pm.pods.Store(k, v) 58 } 59 60 // DeletePod deletes pod in cache 61 func (pm *PodManager) DeletePod(k string) { 62 pm.pods.Delete(k) 63 } 64 65 // UpdatePodStatus update pod status in cache 66 func (pm *PodManager) UpdatePodStatus(k string, s string) { 67 v, ok := pm.pods.Load(k) 68 if ok { 69 pod := v.(types.FakePod) 70 // Status becomes running in the first time 71 if pod.Status != s && s == constants.PodRunning { 72 pod.RunningTime = time.Now().UnixNano() 73 } 74 pod.Status = s 75 pm.pods.Store(k, pod) 76 } 77 } 78 79 // GetPod gets pod from cache 80 func (pm *PodManager) GetPod(key string) types.FakePod { 81 v, ok := pm.pods.Load(key) 82 if ok { 83 return v.(types.FakePod) 84 } else { 85 return types.FakePod{} 86 } 87 } 88 89 // ListPods lists all pods in cache 90 func (pm *PodManager) ListPods() []types.FakePod { 91 pods := make([]types.FakePod, 0) 92 pm.pods.Range(func(k, v interface{}) bool { 93 pods = append(pods, v.(types.FakePod)) 94 return true 95 }) 96 return pods 97 } 98 99 // PodHandlerFunc is used to receive and process message 100 func (pm *PodManager) PodHandlerFunc(w http.ResponseWriter, req *http.Request) { 101 switch req.Method { 102 case http.MethodGet: 103 // List Pod 104 klog.V(4).Infof("Receive list pod request") 105 pods := pm.ListPods() 106 klog.V(4).Infof("Current pods number: %v", len(pods)) 107 rspBodyBytes := new(bytes.Buffer) 108 json.NewEncoder(rspBodyBytes).Encode(pods) 109 w.Write(rspBodyBytes.Bytes()) 110 klog.V(4).Infof("Finish list pod request") 111 case http.MethodPost: 112 klog.V(4).Infof("Receive add pod request") 113 var p types.FakePod 114 // Get request body 115 if req.Body != nil { 116 body, err := ioutil.ReadAll(req.Body) 117 if err != nil { 118 klog.Errorf("Read body error %v", err) 119 w.Write([]byte("Read request body error")) 120 return 121 } 122 klog.V(4).Infof("Request body is %s", string(body)) 123 if err = json.Unmarshal(body, &p); err != nil { 124 klog.Errorf("Unmarshal request body error %v", err) 125 w.Write([]byte("Unmarshal request body error")) 126 return 127 } 128 } 129 // Add Pod 130 ns := constants.NamespaceDefault 131 if p.Namespace != "" { 132 ns = p.Namespace 133 } 134 135 // Build Add message 136 msg := model.NewMessage("") 137 resource, err := utils.BuildResource(p.NodeName, p.Namespace, model.ResourceTypePod, p.Name) 138 if err != nil { 139 klog.Errorf("Build message resource failed with error: %s", err) 140 w.Write([]byte("Build message resource failed with error")) 141 return 142 } 143 msg.Content = p 144 msg.BuildRouter(constants.ControllerStub, constants.GroupResource, resource, model.InsertOperation) 145 146 // Add pod in cache 147 p.CreateTime = time.Now().UnixNano() 148 pm.AddPod(ns+"/"+p.Name, p) 149 150 // Send msg 151 select { 152 case pm.event <- msg: 153 klog.V(4).Infof("Finish add pod request") 154 } 155 case http.MethodDelete: 156 // Delete Pod 157 klog.V(4).Infof("Receive delete pod request") 158 params := req.URL.Query() 159 ns := params.Get("namespace") 160 if ns == "" { 161 ns = constants.NamespaceDefault 162 } 163 nodename := params.Get("nodename") 164 name := params.Get("name") 165 klog.V(4).Infof("Pod Namespace: %s NodeName: %s Name: %s", ns, nodename, name) 166 167 // Build delete message 168 msg := model.NewMessage("") 169 resource, err := utils.BuildResource(nodename, ns, model.ResourceTypePod, name) 170 if err != nil { 171 klog.Errorf("Build message resource failed with error: %s", err) 172 w.Write([]byte("Build message resource failed with error")) 173 return 174 } 175 msg.Content = pm.GetPod(ns + "/" + name) 176 msg.BuildRouter(constants.ControllerStub, constants.GroupResource, resource, model.DeleteOperation) 177 178 // Delete pod in cache 179 pm.DeletePod(ns + "/" + name) 180 181 // Send msg 182 select { 183 case pm.event <- msg: 184 klog.V(4).Infof("Finish delete pod request") 185 } 186 187 default: 188 klog.Errorf("Http type: %s unsupported", req.Method) 189 } 190 }