github.com/polarismesh/polaris@v1.17.8/plugin/cmdb/memory/fetcher.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 memory
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/json"
    23  	"errors"
    24  	"io/ioutil"
    25  	"net/http"
    26  
    27  	"github.com/polarismesh/polaris/common/utils"
    28  )
    29  
    30  const (
    31  	FetchSuccess    = 200000 // 成功
    32  	FetchForbiden   = 401000 // 无权限
    33  	FetchBadRequest = 400001 // 分页参数错误
    34  	FetchException  = 500000 // 服务端错误
    35  )
    36  
    37  // IPs
    38  type IPs struct {
    39  	Hosts   map[string]IP
    40  	Mask    []IP
    41  	Backoff *IP
    42  }
    43  
    44  // Fetcher fetcher by get cmdb data
    45  type Fetcher interface {
    46  	GetIPs() ([]IPInfo, IPs, error)
    47  }
    48  
    49  type fetcher struct {
    50  	url   string
    51  	token string
    52  }
    53  
    54  // GetIPs get all ips from server
    55  func (f *fetcher) GetIPs() ([]IPInfo, IPs, error) {
    56  	ret := IPs{
    57  		Hosts: map[string]IP{},
    58  		Mask:  make([]IP, 0, 8),
    59  	}
    60  
    61  	values, err := f.getFromRemote()
    62  	if err != nil {
    63  		return nil, IPs{}, err
    64  	}
    65  
    66  	for i := range values {
    67  		item := values[i]
    68  		if item.Type == Host {
    69  			data, _ := NewIP(item)
    70  			ret.Hosts[item.IP] = data
    71  			continue
    72  		}
    73  
    74  		if item.Type == Mask {
    75  			data, err := NewIP(item)
    76  			if err != nil {
    77  				return nil, ret, err
    78  			}
    79  			ret.Mask = append(ret.Mask, data)
    80  			continue
    81  		}
    82  
    83  		if item.Type == Backoff {
    84  			data, _ := NewIP(item)
    85  			ret.Backoff = &data
    86  		}
    87  	}
    88  
    89  	return values, ret, nil
    90  }
    91  
    92  func (f *fetcher) getFromRemote() ([]IPInfo, error) {
    93  	if f.url == "" {
    94  		return []IPInfo{}, nil
    95  	}
    96  
    97  	requestId := utils.NewUUID()
    98  
    99  	total := 0
   100  	curQuery := 0
   101  	pageNo := 0
   102  	first := true
   103  	values := make([]IPInfo, 0, 1)
   104  	for {
   105  		if curQuery >= total && !first {
   106  			break
   107  		}
   108  		pageNo++
   109  		body, err := json.Marshal(Request{
   110  			RequestID: requestId,
   111  			PageNo:    int64(pageNo),
   112  			PageSize:  100,
   113  		})
   114  		if err != nil {
   115  			return nil, err
   116  		}
   117  		hreq, err := http.NewRequest(http.MethodPost, f.url, bytes.NewBuffer(body))
   118  		if err != nil {
   119  			return nil, err
   120  		}
   121  		hreq.Header.Set("Authorization", f.token)
   122  		hreq.Header.Set("Content-Type", "application/json")
   123  		resp, err := http.DefaultClient.Do(hreq)
   124  		if err != nil {
   125  			return nil, err
   126  		}
   127  
   128  		defer resp.Body.Close()
   129  
   130  		data, err := ioutil.ReadAll(resp.Body)
   131  		if err != nil {
   132  			return nil, err
   133  		}
   134  
   135  		queryResp := &Response{}
   136  		if err := json.Unmarshal(data, queryResp); err != nil {
   137  			return nil, err
   138  		}
   139  		if queryResp.Code != FetchSuccess {
   140  			return nil, errors.New(queryResp.Info)
   141  		}
   142  		if total == 0 {
   143  			total = int(queryResp.Total)
   144  			values = make([]IPInfo, 0, total)
   145  		}
   146  		curQuery += int(queryResp.Size)
   147  		values = append(values, queryResp.Data...)
   148  		first = false
   149  	}
   150  
   151  	return values, nil
   152  }