mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
K8s/Folders: Fix folder status error message (#95464)
* Fix folder status error message * Add test for folder creation response message * Add TestFoldersCreateAPIEndpointK8S fixes * Fix message returned when user has no permissions
This commit is contained in:
parent
69f185b459
commit
4a13580a2f
@ -1,6 +1,7 @@
|
|||||||
package apierrors
|
package apierrors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -48,20 +49,36 @@ func ToFolderErrorResponse(err error) response.Response {
|
|||||||
|
|
||||||
func ToFolderStatusError(err error) k8sErrors.StatusError {
|
func ToFolderStatusError(err error) k8sErrors.StatusError {
|
||||||
resp := ToFolderErrorResponse(err)
|
resp := ToFolderErrorResponse(err)
|
||||||
|
defaultErr := k8sErrors.StatusError{
|
||||||
|
ErrStatus: metav1.Status{
|
||||||
|
Message: "Folder API error",
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
normResp, ok := resp.(*response.NormalResponse)
|
normResp, ok := resp.(*response.NormalResponse)
|
||||||
if !ok {
|
if !ok {
|
||||||
return k8sErrors.StatusError{
|
return defaultErr
|
||||||
ErrStatus: metav1.Status{
|
}
|
||||||
Message: "Folder API error",
|
|
||||||
Code: http.StatusInternalServerError,
|
var dat map[string]interface{}
|
||||||
},
|
if err := json.Unmarshal(normResp.Body(), &dat); err != nil {
|
||||||
}
|
return defaultErr
|
||||||
|
}
|
||||||
|
|
||||||
|
m, ok := dat["message"]
|
||||||
|
if !ok {
|
||||||
|
return defaultErr
|
||||||
|
}
|
||||||
|
|
||||||
|
message, ok := m.(string)
|
||||||
|
if !ok {
|
||||||
|
return defaultErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return k8sErrors.StatusError{
|
return k8sErrors.StatusError{
|
||||||
ErrStatus: metav1.Status{
|
ErrStatus: metav1.Status{
|
||||||
Message: normResp.ErrMessage(),
|
Message: message,
|
||||||
Code: int32(normResp.Status()),
|
Code: int32(normResp.Status()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -807,7 +807,14 @@ func (fk8s *folderK8sHandler) writeError(c *contextmodel.ReqContext, err error)
|
|||||||
//nolint:errorlint
|
//nolint:errorlint
|
||||||
statusError, ok := err.(*k8sErrors.StatusError)
|
statusError, ok := err.(*k8sErrors.StatusError)
|
||||||
if ok {
|
if ok {
|
||||||
c.JsonApiErr(int(statusError.Status().Code), statusError.Status().Message, err)
|
message := statusError.Status().Message
|
||||||
|
// #TODO: Is there a better way to set the correct meesage? Instead of "access denied to folder", currently we are
|
||||||
|
// returning something like `folders.folder.grafana.app is forbidden: User "" cannot create resource "folders" in
|
||||||
|
// API group "folder.grafana.app" in the namespace "default": folder``
|
||||||
|
if statusError.Status().Code == http.StatusForbidden {
|
||||||
|
message = dashboards.ErrFolderAccessDenied.Error()
|
||||||
|
}
|
||||||
|
c.JsonApiErr(int(statusError.Status().Code), message, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
errhttp.Write(c.Req.Context(), err, c.Resp)
|
errhttp.Write(c.Req.Context(), err, c.Resp)
|
||||||
|
@ -657,13 +657,14 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
folderWithoutParentInput := "{ \"uid\": \"uid\", \"title\": \"Folder\"}"
|
folderWithoutParentInput := "{ \"uid\": \"uid\", \"title\": \"Folder\"}"
|
||||||
folderWithoutUID := "{ \"title\": \"Folder without UID\"}"
|
folderWithoutUID := "{ \"title\": \"Folder without UID\"}"
|
||||||
folderWithTitleEmpty := "{ \"title\": \"\"}"
|
folderWithTitleEmpty := "{ \"title\": \"\"}"
|
||||||
folderWithInvalidUid := "{ \"uid\": \"------------\"}"
|
folderWithInvalidUid := "{ \"uid\": \"::::::::::::\", \"title\": \"Another folder\"}"
|
||||||
folderWithUIDTooLong := "{ \"uid\": \"asdfghjklqwertyuiopzxcvbnmasdfghjklqwertyuiopzxcvbnmasdfghjklqwertyuiopzxcvbnm\"}"
|
folderWithUIDTooLong := "{ \"uid\": \"asdfghjklqwertyuiopzxcvbnmasdfghjklqwertyuiopzxcvbnmasdfghjklqwertyuiopzxcvbnm\", \"title\": \"Third folder\"}"
|
||||||
folderWithSameName := "{\"title\": \"same name\"}"
|
folderWithSameName := "{\"title\": \"same name\"}"
|
||||||
|
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
description string
|
description string
|
||||||
expectedCode int
|
expectedCode int
|
||||||
|
expectedMessage string
|
||||||
expectedFolderSvcError error
|
expectedFolderSvcError error
|
||||||
permissions []resourcepermissions.SetResourcePermissionCommand
|
permissions []resourcepermissions.SetResourcePermissionCommand
|
||||||
input string
|
input string
|
||||||
@ -688,15 +689,19 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "folder creation fails without permissions to create a folder",
|
description: "folder creation fails without permissions to create a folder",
|
||||||
input: folderWithoutParentInput,
|
input: folderWithoutParentInput,
|
||||||
expectedCode: http.StatusForbidden,
|
expectedCode: http.StatusForbidden,
|
||||||
permissions: []resourcepermissions.SetResourcePermissionCommand{},
|
expectedMessage: dashboards.ErrFolderAccessDenied.Error(),
|
||||||
|
permissions: []resourcepermissions.SetResourcePermissionCommand{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "folder creation fails given folder service error %s",
|
// #TODO This test case doesn't set up the conditions it describes. We should have created a folder with the same UID before
|
||||||
input: folderWithoutUID,
|
// creating a second one and failing to do so successfully.
|
||||||
expectedCode: http.StatusConflict,
|
description: "folder creation fails given folder service error %s",
|
||||||
|
input: folderWithoutUID,
|
||||||
|
expectedCode: http.StatusConflict,
|
||||||
|
// expectedMessage: dashboards.ErrFolderWithSameUIDExists.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrFolderWithSameUIDExists,
|
expectedFolderSvcError: dashboards.ErrFolderWithSameUIDExists,
|
||||||
createSecondRecord: true,
|
createSecondRecord: true,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
@ -705,6 +710,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
description: "folder creation fails given folder service error %s",
|
description: "folder creation fails given folder service error %s",
|
||||||
input: folderWithTitleEmpty,
|
input: folderWithTitleEmpty,
|
||||||
expectedCode: http.StatusBadRequest,
|
expectedCode: http.StatusBadRequest,
|
||||||
|
expectedMessage: dashboards.ErrFolderTitleEmpty.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrFolderTitleEmpty,
|
expectedFolderSvcError: dashboards.ErrFolderTitleEmpty,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
},
|
},
|
||||||
@ -712,6 +718,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
description: "folder creation fails given folder service error %s",
|
description: "folder creation fails given folder service error %s",
|
||||||
input: folderWithInvalidUid,
|
input: folderWithInvalidUid,
|
||||||
expectedCode: http.StatusBadRequest,
|
expectedCode: http.StatusBadRequest,
|
||||||
|
expectedMessage: dashboards.ErrDashboardInvalidUid.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrDashboardInvalidUid,
|
expectedFolderSvcError: dashboards.ErrDashboardInvalidUid,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
},
|
},
|
||||||
@ -719,6 +726,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
description: "folder creation fails given folder service error %s",
|
description: "folder creation fails given folder service error %s",
|
||||||
input: folderWithUIDTooLong,
|
input: folderWithUIDTooLong,
|
||||||
expectedCode: http.StatusBadRequest,
|
expectedCode: http.StatusBadRequest,
|
||||||
|
expectedMessage: dashboards.ErrDashboardUidTooLong.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrDashboardUidTooLong,
|
expectedFolderSvcError: dashboards.ErrDashboardUidTooLong,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
},
|
},
|
||||||
@ -726,6 +734,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
description: "folder creation fails given folder service error %s",
|
description: "folder creation fails given folder service error %s",
|
||||||
input: folderWithSameName,
|
input: folderWithSameName,
|
||||||
expectedCode: http.StatusConflict,
|
expectedCode: http.StatusConflict,
|
||||||
|
expectedMessage: dashboards.ErrFolderSameNameExists.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrFolderSameNameExists,
|
expectedFolderSvcError: dashboards.ErrFolderSameNameExists,
|
||||||
createSecondRecord: true,
|
createSecondRecord: true,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
@ -734,6 +743,7 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
description: "folder creation fails given folder service error %s",
|
description: "folder creation fails given folder service error %s",
|
||||||
input: folderWithoutParentInput,
|
input: folderWithoutParentInput,
|
||||||
expectedCode: http.StatusPreconditionFailed,
|
expectedCode: http.StatusPreconditionFailed,
|
||||||
|
expectedMessage: dashboards.ErrFolderVersionMismatch.Error(),
|
||||||
expectedFolderSvcError: dashboards.ErrFolderVersionMismatch,
|
expectedFolderSvcError: dashboards.ErrFolderVersionMismatch,
|
||||||
createSecondRecord: true,
|
createSecondRecord: true,
|
||||||
permissions: folderCreatePermission,
|
permissions: folderCreatePermission,
|
||||||
@ -792,7 +802,12 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, tc.expectedCode, resp.StatusCode)
|
require.Equal(t, tc.expectedCode, resp.StatusCode)
|
||||||
|
|
||||||
folder := dtos.Folder{}
|
type folderWithMessage struct {
|
||||||
|
dtos.Folder
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
folder := folderWithMessage{}
|
||||||
err = json.NewDecoder(resp.Body).Decode(&folder)
|
err = json.NewDecoder(resp.Body).Decode(&folder)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, resp.Body.Close())
|
require.NoError(t, resp.Body.Close())
|
||||||
@ -801,6 +816,10 @@ func TestFoldersCreateAPIEndpointK8S(t *testing.T) {
|
|||||||
require.Equal(t, "uid", folder.UID)
|
require.Equal(t, "uid", folder.UID)
|
||||||
require.Equal(t, "Folder", folder.Title)
|
require.Equal(t, "Folder", folder.Title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tc.expectedMessage != "" {
|
||||||
|
require.Equal(t, tc.expectedMessage, folder.Message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user