github.com/polarismesh/polaris@v1.17.8/plugin/cmdb/memory/mock/mock_server.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package mock
    19  
    20  import (
    21  	"encoding/binary"
    22  	"encoding/json"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"log"
    26  	"math/rand"
    27  	"net"
    28  	"net/http"
    29  	"time"
    30  )
    31  
    32  // IPType ip type
    33  type IPType string
    34  
    35  const (
    36  	Host    IPType = "host"
    37  	Mask    IPType = "mask"
    38  	Backoff IPType = "backoff"
    39  )
    40  
    41  // Request request cmdb data
    42  type Request struct {
    43  	RequestID string `json:"request_id"`
    44  	PageNo    int64  `json:"page_no"`
    45  	PageSize  int64  `json:"page_size"`
    46  }
    47  
    48  // Response response cmdb data
    49  type Response struct {
    50  	Total    int      `json:"total"`
    51  	Size     int      `json:"size"`
    52  	Code     int      `json:"code"`
    53  	Info     string   `json:"info"`
    54  	Priority string   `json:"priority"`
    55  	Data     []IPInfo `json:"data"`
    56  }
    57  
    58  // IPInfo ip info
    59  type IPInfo struct {
    60  	IP     string       `json:"ip"`
    61  	Type   IPType       `json:"type"`
    62  	Region LocationInfo `json:"region"`
    63  	Zone   LocationInfo `json:"zone"`
    64  	Campus LocationInfo `json:"campus"`
    65  }
    66  
    67  // LocationInfo
    68  type LocationInfo struct {
    69  	Name     string                 `json:"name"`
    70  	Metadata map[string]interface{} `json:"metadata"`
    71  }
    72  
    73  func RunMockCMDBServer(cnt int) (int, net.Listener) {
    74  	initData(cnt)
    75  	ln, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", 0))
    76  	if err != nil {
    77  		log.Fatalf("[ERROR]fail to listen tcp, err is %v", err)
    78  	}
    79  
    80  	port := ln.Addr().(*net.TCPAddr).Port
    81  	log.Printf("listen port : %d", port)
    82  
    83  	mux := http.NewServeMux()
    84  	mux.HandleFunc("/", handle)
    85  	go func() {
    86  		_ = http.Serve(ln, mux)
    87  	}()
    88  	return port, ln
    89  }
    90  
    91  var (
    92  	IPInfos []IPInfo
    93  )
    94  
    95  func initData(cnt int) {
    96  	IPInfos = []IPInfo{}
    97  	for i := 0; i < cnt; i++ {
    98  		ipv4 := IPv4Int(RandomIpv4Int())
    99  
   100  		IPInfos = append(IPInfos, IPInfo{
   101  			IP:   ipv4.ip().String(),
   102  			Type: Host,
   103  			Region: LocationInfo{
   104  				Name: "ap-gz",
   105  			},
   106  			Zone: LocationInfo{
   107  				Name: fmt.Sprintf("ap-gz-%d", i),
   108  				Metadata: map[string]interface{}{
   109  					"id": i,
   110  				},
   111  			},
   112  		})
   113  	}
   114  }
   115  
   116  func handle(w http.ResponseWriter, r *http.Request) {
   117  	defer r.Body.Close()
   118  	data, err := ioutil.ReadAll(r.Body)
   119  	if err != nil {
   120  		resp := Response{
   121  			Code: 500001,
   122  			Info: err.Error(),
   123  		}
   124  
   125  		if ret, err := json.Marshal(resp); err != nil {
   126  			log.Printf("json marshal %+v", err)
   127  			w.WriteHeader(http.StatusInternalServerError)
   128  		} else {
   129  			_, _ = w.Write(ret)
   130  		}
   131  		return
   132  	}
   133  
   134  	req := Request{}
   135  	if err := json.Unmarshal(data, &req); err != nil {
   136  		resp := Response{
   137  			Code: 500001,
   138  			Info: err.Error(),
   139  		}
   140  
   141  		if ret, err := json.Marshal(resp); err != nil {
   142  			log.Printf("json marshal %+v", err)
   143  			w.WriteHeader(http.StatusInternalServerError)
   144  		} else {
   145  			_, _ = w.Write(ret)
   146  		}
   147  		return
   148  	}
   149  
   150  	pageNo := req.PageNo
   151  	pageSize := req.PageSize
   152  
   153  	offset := (pageNo - 1) * pageSize
   154  	end := offset + pageSize
   155  	if int(offset) > len(IPInfos) {
   156  		resp := Response{
   157  			Code:  200000,
   158  			Total: len(IPInfos),
   159  			Size:  0,
   160  			Data:  []IPInfo{},
   161  		}
   162  
   163  		if ret, err := json.Marshal(resp); err != nil {
   164  			log.Printf("json marshal %+v", err)
   165  			w.WriteHeader(http.StatusInternalServerError)
   166  		} else {
   167  			_, _ = w.Write(ret)
   168  		}
   169  		return
   170  	}
   171  	if int(end) > len(IPInfos) {
   172  		end = int64(len(IPInfos))
   173  	}
   174  
   175  	values := IPInfos[offset:end]
   176  
   177  	resp := Response{
   178  		Code:  200000,
   179  		Total: len(IPInfos),
   180  		Size:  len(values),
   181  		Data:  values,
   182  	}
   183  
   184  	if ret, err := json.Marshal(resp); err != nil {
   185  		log.Printf("json marshal %+v", err)
   186  		w.WriteHeader(http.StatusInternalServerError)
   187  	} else {
   188  		_, _ = w.Write(ret)
   189  	}
   190  	return
   191  }
   192  
   193  type IPv4Int uint32
   194  
   195  func (i IPv4Int) ip() net.IP {
   196  	ip := make(net.IP, net.IPv6len)
   197  	copy(ip, net.IPv4zero)
   198  	binary.BigEndian.PutUint32(ip.To4(), uint32(i))
   199  	return ip.To16()
   200  }
   201  
   202  func RandomIpv4Int() uint32 {
   203  	return rand.New(rand.NewSource(time.Now().UnixNano())).Uint32()
   204  }