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  }