yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/ucloud/utils.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ucloud 16 17 import ( 18 "reflect" 19 20 "yunion.io/x/jsonutils" 21 "yunion.io/x/log" 22 ) 23 24 func unmarshalResult(resp jsonutils.JSONObject, respErr error, resultKey string, result interface{}) error { 25 if respErr != nil { 26 return respErr 27 } 28 29 if result == nil { 30 return nil 31 } 32 33 if len(resultKey) > 0 { 34 respErr = resp.Unmarshal(result, resultKey) 35 } else { 36 respErr = resp.Unmarshal(result) 37 } 38 39 if respErr != nil { 40 log.Errorf("unmarshal json error %s", respErr) 41 } 42 43 return nil 44 } 45 46 func doListPart(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) (int, int, error) { 47 params.SetAction(action) 48 ret, err := jsonRequest(client, params) 49 if err != nil { 50 return 0, 0, err 51 } 52 53 total, _ := ret.Int("TotalCount") 54 // if err != nil { 55 // log.Debugf("%s TotalCount %s", action, err.Error()) 56 //} 57 58 var lst []jsonutils.JSONObject 59 lst, err = ret.GetArray(resultKey) 60 if err != nil { 61 return 0, 0, nil 62 } 63 64 resultValue := reflect.Indirect(reflect.ValueOf(result)) 65 elemType := resultValue.Type().Elem() 66 for i := range lst { 67 elemPtr := reflect.New(elemType) 68 err = lst[i].Unmarshal(elemPtr.Interface()) 69 if err != nil { 70 return 0, 0, err 71 } 72 resultValue.Set(reflect.Append(resultValue, elemPtr.Elem())) 73 } 74 return int(total), len(lst), nil 75 } 76 77 // 执行操作 78 func DoAction(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) error { 79 params.SetAction(action) 80 resp, err := jsonRequest(client, params) 81 return unmarshalResult(resp, err, resultKey, result) 82 } 83 84 // 遍历所有结果 85 func DoListAll(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) error { 86 pageLimit := 100 87 offset := 0 88 89 resultValue := reflect.Indirect(reflect.ValueOf(result)) 90 params.SetPagination(pageLimit, offset) 91 for { 92 total, part, err := doListPart(client, action, params, resultKey, result) 93 if err != nil { 94 return err 95 } 96 // total 大于零的情况下通过total字段判断列表是否遍历完成。total不存在或者为0的情况下,通过返回列表的长度判断是否遍历完成 97 if (total > 0 && resultValue.Len() >= total) || (total == 0 && pageLimit > part) { 98 break 99 } 100 101 params.SetPagination(pageLimit, offset+resultValue.Len()) 102 } 103 return nil 104 }