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 }