yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/ecloud/request.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 ecloud
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"strings"
    22  	"time"
    23  
    24  	"yunion.io/x/jsonutils"
    25  	"yunion.io/x/pkg/errors"
    26  
    27  	"yunion.io/x/onecloud/pkg/httperrors"
    28  	"yunion.io/x/onecloud/pkg/util/httputils"
    29  )
    30  
    31  type IRequest interface {
    32  	GetScheme() string
    33  	GetMethod() string
    34  	SetMethod(string)
    35  	GetEndpoint() string
    36  	GetServerPath() string
    37  	GetPort() string
    38  	GetRegionId() string
    39  	GetHeaders() map[string]string
    40  	GetQueryParams() map[string]string
    41  	GetBodyReader() io.Reader
    42  	GetVersion() string
    43  	GetTimestamp() string
    44  	GetReadTimeout() time.Duration
    45  	GetConnectTimeout() time.Duration
    46  	GetHTTPSInsecure() bool
    47  	SetHTTPSInsecure(bool)
    48  	GetUserAgent() map[string]string
    49  	ForMateResponseBody(jrbody jsonutils.JSONObject) (jsonutils.JSONObject, error)
    50  }
    51  
    52  type SJSONRequest struct {
    53  	SBaseRequest
    54  	Data jsonutils.JSONObject
    55  }
    56  
    57  func NewJSONRequest(data jsonutils.JSONObject) *SJSONRequest {
    58  	jr := &SJSONRequest{
    59  		Data:         data,
    60  		SBaseRequest: *NewBaseRequest(),
    61  	}
    62  	headers := jr.GetHeaders()
    63  	headers["Content-Type"] = "application/json"
    64  	return jr
    65  }
    66  
    67  func (jr *SJSONRequest) GetBodyReader() io.Reader {
    68  	if jr.Data == nil {
    69  		return nil
    70  	}
    71  	return strings.NewReader(jr.Data.String())
    72  }
    73  
    74  type SApiRequest struct {
    75  	SJSONRequest
    76  	RegionId string
    77  }
    78  
    79  func NewApiRequest(regionId string, serverPath string, query map[string]string, data jsonutils.JSONObject) *SApiRequest {
    80  	r := SApiRequest{
    81  		RegionId:     regionId,
    82  		SJSONRequest: *NewJSONRequest(data),
    83  	}
    84  	r.ServerPath = serverPath
    85  	mergeMap(r.GetQueryParams(), query)
    86  	return &r
    87  }
    88  
    89  func (rr *SApiRequest) GetScheme() string {
    90  	return "https"
    91  }
    92  
    93  func (rr *SApiRequest) GetPort() string {
    94  	return "8443"
    95  }
    96  
    97  func (rr *SApiRequest) GetEndpoint() string {
    98  	return fmt.Sprintf("api-%s.cmecloud.cn", rr.RegionId)
    99  }
   100  
   101  type SConsoleRequest struct {
   102  	SJSONRequest
   103  	RegionId string
   104  }
   105  
   106  func NewConsoleRequest(regionId string, serverPath string, query map[string]string, data jsonutils.JSONObject) *SConsoleRequest {
   107  	r := SConsoleRequest{
   108  		RegionId:     regionId,
   109  		SJSONRequest: *NewJSONRequest(data),
   110  	}
   111  	r.ServerPath = serverPath
   112  	mergeMap(r.GetQueryParams(), query)
   113  	return &r
   114  }
   115  
   116  func (rr *SConsoleRequest) GetScheme() string {
   117  	return "https"
   118  }
   119  
   120  func (rr *SConsoleRequest) GetPort() string {
   121  	return "8443"
   122  }
   123  
   124  func (rr *SConsoleRequest) GetEndpoint() string {
   125  	return fmt.Sprintf("console-%s.cmecloud.cn", rr.RegionId)
   126  }
   127  
   128  func mergeMap(m1, m2 map[string]string) {
   129  	if m2 == nil {
   130  		return
   131  	}
   132  	for k, v := range m2 {
   133  		m1[k] = v
   134  	}
   135  }
   136  
   137  type SBaseRequest struct {
   138  	Scheme         string
   139  	Method         string
   140  	Endpoint       string
   141  	ServerPath     string
   142  	Port           string
   143  	RegionId       string
   144  	ReadTimeout    time.Duration
   145  	ConnectTimeout time.Duration
   146  	isInsecure     *bool
   147  
   148  	QueryParams map[string]string
   149  	Headers     map[string]string
   150  	Content     []byte
   151  }
   152  
   153  func NewBaseRequest() *SBaseRequest {
   154  	return &SBaseRequest{
   155  		QueryParams: map[string]string{},
   156  		Headers:     map[string]string{},
   157  	}
   158  }
   159  
   160  func (br *SBaseRequest) GetScheme() string {
   161  	return br.Scheme
   162  }
   163  
   164  func (br *SBaseRequest) GetMethod() string {
   165  	return br.Method
   166  }
   167  
   168  func (br *SBaseRequest) SetMethod(method string) {
   169  	br.Method = method
   170  }
   171  
   172  func (br *SBaseRequest) GetEndpoint() string {
   173  	return br.Endpoint
   174  }
   175  
   176  func (br *SBaseRequest) GetServerPath() string {
   177  	return br.ServerPath
   178  }
   179  
   180  func (br *SBaseRequest) GetPort() string {
   181  	return br.Port
   182  }
   183  
   184  func (br *SBaseRequest) GetRegionId() string {
   185  	return br.RegionId
   186  }
   187  
   188  func (br *SBaseRequest) GetHeaders() map[string]string {
   189  	return br.Headers
   190  }
   191  
   192  func (br *SBaseRequest) GetQueryParams() map[string]string {
   193  	return br.QueryParams
   194  }
   195  
   196  func (br *SBaseRequest) GetBodyReader() io.Reader {
   197  	if len(br.Content) > 0 {
   198  		return bytes.NewReader(br.Content)
   199  	}
   200  	return nil
   201  }
   202  
   203  func (br *SBaseRequest) GetVersion() string {
   204  	return "2016-12-05"
   205  }
   206  
   207  func (br *SBaseRequest) GetTimestamp() string {
   208  	sh, _ := time.LoadLocation("Asia/Shanghai")
   209  	return time.Now().In(sh).Format("2006-01-02T15:04:05Z")
   210  }
   211  
   212  func (br *SBaseRequest) GetReadTimeout() time.Duration {
   213  	return br.ReadTimeout
   214  }
   215  
   216  func (br *SBaseRequest) GetConnectTimeout() time.Duration {
   217  	return br.ConnectTimeout
   218  }
   219  
   220  func (br *SBaseRequest) GetHTTPSInsecure() bool {
   221  	if br.isInsecure == nil {
   222  		return false
   223  	}
   224  	return *br.isInsecure
   225  }
   226  
   227  func (br *SBaseRequest) SetHTTPSInsecure(isInsecure bool) {
   228  	br.isInsecure = &isInsecure
   229  }
   230  
   231  func (br *SBaseRequest) GetUserAgent() map[string]string {
   232  	return nil
   233  }
   234  
   235  func (br *SBaseRequest) ForMateResponseBody(jrbody jsonutils.JSONObject) (jsonutils.JSONObject, error) {
   236  	if jrbody == nil || !jrbody.Contains("state") {
   237  		return nil, ErrMissKey{
   238  			Key: "state",
   239  			Jo:  jrbody,
   240  		}
   241  	}
   242  	state, _ := jrbody.GetString("state")
   243  	switch state {
   244  	case "OK":
   245  		if !jrbody.Contains("body") {
   246  			return nil, ErrMissKey{
   247  				Key: "body",
   248  				Jo:  jrbody,
   249  			}
   250  		}
   251  		body, _ := jrbody.Get("body")
   252  		return body, nil
   253  	default:
   254  		if jrbody.Contains("errorMessage") {
   255  			msg, _ := jrbody.GetString("errorMessage")
   256  			if strings.Contains(msg, "Invalid parameter AccessKey") {
   257  				return nil, errors.Wrapf(httperrors.ErrInvalidAccessKey, msg)
   258  			}
   259  			return nil, &httputils.JSONClientError{Code: 400, Details: msg}
   260  		}
   261  		return nil, &httputils.JSONClientError{Code: 400, Details: jrbody.String()}
   262  	}
   263  }