mirror of https://github.com/k3s-io/k3s
119 lines
2.6 KiB
Go
119 lines
2.6 KiB
Go
package quobyte
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"log"
|
|
"math/rand"
|
|
"net/http"
|
|
"reflect"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
emptyResponse string = "Empty result and no error occured"
|
|
)
|
|
|
|
type request struct {
|
|
ID string `json:"id"`
|
|
Version string `json:"jsonrpc"`
|
|
Method string `json:"method"`
|
|
Params interface{} `json:"params"`
|
|
}
|
|
|
|
type response struct {
|
|
ID string `json:"id"`
|
|
Version string `json:"jsonrpc"`
|
|
Result *json.RawMessage `json:"result"`
|
|
Error *json.RawMessage `json:"error"`
|
|
}
|
|
|
|
type rpcError struct {
|
|
Code int64 `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
func (err *rpcError) decodeErrorCode() string {
|
|
switch err.Code {
|
|
case -32600:
|
|
return "ERROR_CODE_INVALID_REQUEST"
|
|
case -32603:
|
|
return "ERROR_CODE_JSON_ENCODING_FAILED"
|
|
case -32601:
|
|
return "ERROR_CODE_METHOD_NOT_FOUND"
|
|
case -32700:
|
|
return "ERROR_CODE_PARSE_ERROR"
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func encodeRequest(method string, params interface{}) ([]byte, error) {
|
|
return json.Marshal(&request{
|
|
// Generate random ID and convert it to a string
|
|
ID: strconv.FormatInt(rand.Int63(), 10),
|
|
Version: "2.0",
|
|
Method: method,
|
|
Params: params,
|
|
})
|
|
}
|
|
|
|
func decodeResponse(ioReader io.Reader, reply interface{}) error {
|
|
var resp response
|
|
if err := json.NewDecoder(ioReader).Decode(&resp); err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
var rpcErr rpcError
|
|
if err := json.Unmarshal(*resp.Error, &rpcErr); err != nil {
|
|
return err
|
|
}
|
|
|
|
if rpcErr.Message != "" {
|
|
return errors.New(rpcErr.Message)
|
|
}
|
|
|
|
respError := rpcErr.decodeErrorCode()
|
|
if respError != "" {
|
|
return errors.New(respError)
|
|
}
|
|
}
|
|
|
|
if resp.Result != nil && reply != nil {
|
|
return json.Unmarshal(*resp.Result, reply)
|
|
}
|
|
|
|
return errors.New(emptyResponse)
|
|
}
|
|
|
|
func (client QuobyteClient) sendRequest(method string, request interface{}, response interface{}) error {
|
|
etype := reflect.ValueOf(request).Elem()
|
|
field := etype.FieldByName("RetryPolicy")
|
|
if field.IsValid() {
|
|
field.SetString(client.GetAPIRetryPolicy())
|
|
}
|
|
message, err := encodeRequest(method, request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req, err := http.NewRequest("POST", client.url, bytes.NewBuffer(message))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.SetBasicAuth(client.username, client.password)
|
|
resp, err := client.client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
|
log.Printf("Warning: HTTP status code for request is %s\n", strconv.Itoa(resp.StatusCode))
|
|
}
|
|
return decodeResponse(resp.Body, &response)
|
|
}
|