From be2d08f01350cdeb140a5b8083e551c4a1b41002 Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Mon, 20 Jun 2016 18:29:27 -0500 Subject: [PATCH] ciao-controller: Add proper http return codes to showServerDetails The function showServerDetails attending calls from /v2.1/{tenant}/servers/{server} GET Method was returning 500 InternalServerError for all error cases, this fix covers Unauthorized, NotFound and InternalServer return errors for each corresponding case. To accomplish this we made next: 1. Created the function 'returnErrorCode' to avoid code and call it with the corresponding values where needed. 2. Also we are adding two structures (HTTPReturnCodeData and HTTPReturnCode) which will be marshalled to return RESPONSE BODY for the call as OpenStack does, but adding a generic "error". http://developer.openstack.org/api-guide/compute/faults.html Fixes #158 Signed-off-by: Leoswaldo Macias --- ciao-controller/compute.go | 24 ++++++++++++++++++++---- payloads/compute.go | 16 ++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ciao-controller/compute.go b/ciao-controller/compute.go index 26377393c..1b64e416f 100644 --- a/ciao-controller/compute.go +++ b/ciao-controller/compute.go @@ -452,6 +452,22 @@ func instanceToServer(context *controller, instance *types.Instance) (payloads.S return server, nil } +// returnErrorCode returns error codes for the http call +func returnErrorCode(w http.ResponseWriter, httpError int, message string) { + var returnCode payloads.HTTPReturnErrorCode + returnCode.Error.Code = httpError + returnCode.Error.Name = http.StatusText(returnCode.Error.Code) + returnCode.Error.Message = message + + b, err := json.Marshal(returnCode) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + http.Error(w, string(b), httpError) +} + func showServerDetails(w http.ResponseWriter, r *http.Request, context *controller) { vars := mux.Vars(r) tenant := vars["tenant"] @@ -461,24 +477,24 @@ func showServerDetails(w http.ResponseWriter, r *http.Request, context *controll dumpRequest(r) if validateToken(context, r) == false { - http.Error(w, "Invalid token", http.StatusInternalServerError) + returnErrorCode(w, http.StatusUnauthorized, "Invalid token") return } instance, err := context.ds.GetInstance(instanceID) if err != nil { - http.Error(w, "Instance not available", http.StatusInternalServerError) + returnErrorCode(w, http.StatusNotFound, "Instance could not be found") return } if instance.TenantID != tenant { - http.Error(w, "Instance not available", http.StatusInternalServerError) + returnErrorCode(w, http.StatusNotFound, "Instance does not belong to tenant") return } server.Server, err = instanceToServer(context, instance) if err != nil { - http.Error(w, "Instance not available", http.StatusInternalServerError) + returnErrorCode(w, http.StatusNotFound, "Instance could not be found") return } diff --git a/payloads/compute.go b/payloads/compute.go index 2a0b5cf29..ebe8d8375 100644 --- a/payloads/compute.go +++ b/payloads/compute.go @@ -451,3 +451,19 @@ func NewCiaoEvents() (events CiaoEvents) { events.Events = []CiaoEvent{} return } + +// HTTPErrorData represents the HTTP response body for +// a compute API request error. +type HTTPErrorData struct { + Code int `json:"code"` + Name string `json:"name"` + Message string `json:"message"` +} + +// HTTPReturnErrorCode represents the unmarshalled version for Return codes +// when a API call is made and you need to return explicit data of +// the call as OpenStack format +// http://developer.openstack.org/api-guide/compute/faults.html +type HTTPReturnErrorCode struct { + Error HTTPErrorData `json:"error"` +}