yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/client/requests/requests.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 requests
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"net/url"
    21  	"sort"
    22  	"strings"
    23  )
    24  
    25  type IRequest interface {
    26  	GetScheme() string
    27  	GetMethod() string
    28  	GetDomain() string
    29  	GetPort() string
    30  	GetRegionId() string
    31  	GetProjectId() string
    32  	GetHost() string
    33  	GetURI() string
    34  	GetHeaders() map[string]string
    35  	GetQueryParams() map[string]string
    36  	GetFormParams() map[string]string
    37  	GetContent() []byte
    38  	GetBodyReader() io.Reader
    39  	GetProduct() string
    40  	GetVersion() string
    41  
    42  	SetStringToSign(stringToSign string)
    43  	GetStringToSign() string
    44  
    45  	SetDomain(domain string)
    46  	SetContent(content []byte)
    47  	SetScheme(scheme string)
    48  	BuildUrl() string
    49  	BuildQueries() string
    50  
    51  	AddHeaderParam(key, value string)
    52  	AddQueryParam(key, value string)
    53  	AddFormParam(key, value string)
    54  }
    55  
    56  type SRequest struct {
    57  	Scheme   string // HTTP、HTTPS
    58  	Method   string // GET、PUT、DELETE、POST、PATCH
    59  	Domain   string // myhuaweicloud.com
    60  	Port     string // 80
    61  	RegionId string // cn-north-1
    62  
    63  	product   string // 弹性云服务 ECS : ecs
    64  	version   string // API版本: v2
    65  	projectId string // 项目ID: 43cbe5e77aaf4665bbb962062dc1fc9d.可以为空。
    66  
    67  	resourcePath string // /users/{user_id}/groups
    68  	QueryParams  map[string]string
    69  	Headers      map[string]string
    70  	FormParams   map[string]string
    71  	Content      []byte
    72  
    73  	queries string
    74  
    75  	stringToSign string
    76  }
    77  
    78  func (self *SRequest) GetProjectId() string {
    79  	return self.projectId
    80  }
    81  
    82  func (self *SRequest) GetScheme() string {
    83  	return self.Scheme
    84  }
    85  
    86  func (self *SRequest) GetMethod() string {
    87  	return self.Method
    88  }
    89  
    90  func (self *SRequest) GetDomain() string {
    91  	return self.Domain
    92  }
    93  
    94  func (self *SRequest) GetPort() string {
    95  	return self.Port
    96  }
    97  
    98  func (self *SRequest) GetRegionId() string {
    99  	return self.RegionId
   100  }
   101  
   102  func (self *SRequest) GetHeaders() map[string]string {
   103  	return self.Headers
   104  }
   105  
   106  func (self *SRequest) GetQueryParams() map[string]string {
   107  	return self.QueryParams
   108  }
   109  
   110  func (self *SRequest) GetFormParams() map[string]string {
   111  	return self.FormParams
   112  }
   113  
   114  func (self *SRequest) GetContent() []byte {
   115  	return self.Content
   116  }
   117  
   118  func (self *SRequest) GetBodyReader() io.Reader {
   119  	if self.FormParams != nil && len(self.FormParams) > 0 {
   120  		formData := GetUrlFormedMap(self.FormParams)
   121  		return strings.NewReader(formData)
   122  	} else {
   123  		return strings.NewReader(string(self.Content))
   124  	}
   125  }
   126  
   127  func (self *SRequest) GetProduct() string {
   128  	return self.product
   129  }
   130  
   131  func (self *SRequest) GetVersion() string {
   132  	return self.version
   133  }
   134  
   135  func (self *SRequest) SetStringToSign(stringToSign string) {
   136  	self.stringToSign = stringToSign
   137  }
   138  
   139  func (self *SRequest) GetStringToSign() string {
   140  	return self.stringToSign
   141  }
   142  
   143  func (self *SRequest) SetDomain(domain string) {
   144  	self.Domain = domain
   145  }
   146  
   147  func (self *SRequest) SetContent(content []byte) {
   148  	self.Content = content
   149  }
   150  
   151  func (self *SRequest) SetScheme(scheme string) {
   152  	self.Scheme = scheme
   153  }
   154  
   155  func (self *SRequest) BuildUrl() string {
   156  	scheme := strings.ToLower(self.Scheme)
   157  	baseUrl := fmt.Sprintf("%s://%s", scheme, self.GetHost())
   158  	queries := self.BuildQueries()
   159  	if len(queries) > 0 {
   160  		return baseUrl + self.GetURI() + "?" + queries
   161  	} else {
   162  		return baseUrl + self.GetURI()
   163  	}
   164  }
   165  
   166  func (self *SRequest) GetHost() string {
   167  	scheme := strings.ToLower(self.Scheme)
   168  	host := self.getEndpoint()
   169  	if len(self.Port) > 0 {
   170  		if (scheme == "http" && self.Port == "80") || (scheme == "https" && self.Port == "443") {
   171  			host = fmt.Sprintf("%s:%s", host, self.Port)
   172  		}
   173  	}
   174  
   175  	return host
   176  }
   177  
   178  func (self *SRequest) GetURI() string {
   179  	// URI
   180  	uri := ""
   181  	for _, m := range []string{self.version, self.projectId} {
   182  		if len(m) > 0 {
   183  			uri += fmt.Sprintf("/%s", m)
   184  		}
   185  	}
   186  
   187  	if len(self.resourcePath) > 0 {
   188  		s := ""
   189  		if !strings.HasPrefix(self.resourcePath, "/") {
   190  			s = "/"
   191  		}
   192  
   193  		if strings.HasSuffix(self.resourcePath, "/") {
   194  			strings.TrimSuffix(s, "/")
   195  		}
   196  
   197  		uri = uri + s + self.resourcePath
   198  	}
   199  
   200  	return uri
   201  }
   202  
   203  func (self *SRequest) getEndpoint() string {
   204  	// ecs.cn-north-1.myhuaweicloud.com
   205  	items := []string{}
   206  	for _, item := range []string{self.product, self.RegionId, self.Domain} {
   207  		if len(item) > 0 {
   208  			items = append(items, item)
   209  		}
   210  	}
   211  
   212  	return strings.Join(items, ".")
   213  }
   214  
   215  func (self *SRequest) BuildQueries() string {
   216  	self.queries = GetUrlFormedMap(self.QueryParams)
   217  	return self.queries
   218  }
   219  
   220  func (self *SRequest) AddHeaderParam(key, value string) {
   221  	self.Headers[key] = value
   222  }
   223  
   224  func (self *SRequest) AddQueryParam(key, value string) {
   225  	self.QueryParams[key] = value
   226  }
   227  
   228  func (self *SRequest) AddFormParam(key, value string) {
   229  	self.FormParams[key] = value
   230  }
   231  
   232  func GetUrlFormedMap(source map[string]string) string {
   233  	// 按key排序后编译
   234  	keys := make([]string, 0)
   235  	for k := range source {
   236  		keys = append(keys, k)
   237  	}
   238  
   239  	sort.Slice(keys, func(i, j int) bool {
   240  		return strings.ToLower(keys[i]) < strings.ToLower(keys[j])
   241  	})
   242  
   243  	urlEncoder := url.Values{}
   244  	for _, k := range keys {
   245  		urlEncoder.Add(k, source[k])
   246  	}
   247  
   248  	return urlEncoder.Encode()
   249  }
   250  
   251  func defaultRequest() (request *SRequest) {
   252  	request = &SRequest{
   253  		Scheme:      "HTTPS",
   254  		Method:      "GET",
   255  		QueryParams: make(map[string]string),
   256  		Headers:     map[string]string{},
   257  		FormParams:  make(map[string]string),
   258  	}
   259  	return
   260  }
   261  
   262  func NewResourceRequest(domain, method, product, version, region, project, resourcePath string) *SRequest {
   263  	return &SRequest{
   264  		Scheme:       "HTTPS",
   265  		Method:       method,
   266  		Domain:       domain,
   267  		product:      product,
   268  		RegionId:     region,
   269  		version:      version,
   270  		projectId:    project,
   271  		resourcePath: resourcePath,
   272  		QueryParams:  make(map[string]string),
   273  		Headers:      map[string]string{},
   274  		FormParams:   make(map[string]string),
   275  	}
   276  }