From 44ac352713d81008fed1ce3ba7c91e497ef93a1b Mon Sep 17 00:00:00 2001 From: treywelsh Date: Thu, 20 Dec 2018 11:47:56 +0100 Subject: [PATCH] B #2678 GOCA - parse error code of the ONE response --- src/oca/go/src/goca/goca.go | 74 +++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/src/oca/go/src/goca/goca.go b/src/oca/go/src/goca/goca.go index a8c7ba5f63..4c293a19fe 100644 --- a/src/oca/go/src/goca/goca.go +++ b/src/oca/go/src/goca/goca.go @@ -1,7 +1,6 @@ package goca import ( - "errors" "fmt" "io/ioutil" "os" @@ -14,6 +13,53 @@ var ( client *oneClient ) +// OneClientErrCode is the error code from the OpenNebula response +type OneClientErrCode int + +const ( + // OneSuccess code for a successful response + OneSuccess = 0x0000 + + // OneAuthenticationError code if the user could not be authenticated + OneAuthenticationError = 0x0100 + + // OneAuthorizationError code if the user is not authorized to perform the requested action + OneAuthorizationError = 0x0200 + + // OneNoExistsError code if the requested resource does not exist + OneNoExistsError = 0x0400 + + // OneActionError code if the state is wrong to perform the action + OneActionError = 0x0800 + + // OneXmlRpcApiError code if there is wrong parameter passed, e.g. param should be -1 or -2, but -3 was received + OneXMLRPCAPIError = 0x1000 + + // OneInteralError code if there is an internal error, e.g. the resource could not be loaded from the DB + OneInteralError = 0x2000 +) + +func (s OneClientErrCode) String() string { + switch s { + case OneSuccess: + return "SUCCESS" + case OneAuthenticationError: + return "AUTHENTICATION" + case OneAuthorizationError: + return "AUTHORIZATION" + case OneNoExistsError: + return "NO_EXISTS" + case OneActionError: + return "ACTION" + case OneXMLRPCAPIError: + return "XML_RPC_API" + case OneInteralError: + return "INTERNAL" + default: + return "" + } +} + // OneConfig contains the information to communicate with OpenNebula type OneConfig struct { // Token is the authentication string. In the format of : @@ -47,6 +93,16 @@ func (r *BadResponseError) Error() string { return fmt.Sprintf("Unexpected XML-RPC response, Expected: %s", r.expectedType) } +// ResponseError contains the error datas from an OpenNebula error reponse +type ResponseError struct { + Code OneClientErrCode + msg string +} + +func (e *ResponseError) Error() string { + return fmt.Sprintf("%s (%s)", e.msg, e.Code.String()) +} + type response struct { status bool body string @@ -148,6 +204,7 @@ func (c *oneClient) Call(method string, args ...interface{}) (*response, error) body string bodyInt int64 bodyBool bool + errCode int64 ) if c.xmlrpcClientError != nil { @@ -182,15 +239,18 @@ func (c *oneClient) Call(method string, args ...interface{}) (*response, error) } } - // TODO: errCode? result[2] + errCode, ok = result[2].(int64) + if ok == false { + return nil, &BadResponseError{expectedType: "Index 2: Int"} + } + + if status == false { + return nil, &ResponseError{Code: OneClientErrCode(errCode), msg: body} + } r := &response{status, body, int(bodyInt), bodyBool} - if status == false { - err = errors.New(body) - } - - return r, err + return r, nil } // Body accesses the body of the response