...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package utils
17
18 import (
19 "fmt"
20 "net/http"
21 "strings"
22
23 "github.com/gin-gonic/gin"
24 "github.com/joomcode/errorx"
25 apierrors "k8s.io/apimachinery/pkg/api/errors"
26
27 "github.com/chaos-mesh/chaos-mesh/pkg/log"
28 )
29
30 var (
31 ErrNS = errorx.NewNamespace("error.api")
32 ErrUnknown = ErrNS.NewType("unknown")
33 ErrBadRequest = ErrNS.NewType("bad_request")
34 ErrNotFound = ErrNS.NewType("resource_not_found")
35 ErrInternalServer = ErrNS.NewType("internal_server_error")
36
37 ErrNoClusterPrivilege = ErrNS.NewType("no_cluster_privilege")
38 ErrNoNamespacePrivilege = ErrNS.NewType("no_namespace_privilege")
39 )
40
41 type APIError struct {
42 Code int `json:"code"`
43 Type string `json:"type"`
44 Message string `json:"message"`
45 FullText string `json:"full_text"`
46 }
47
48 func SetAPIError(c *gin.Context, err *errorx.Error) {
49 typeName := errorx.GetTypeName(err)
50
51 var code int
52 switch typeName {
53 case ErrBadRequest.FullName():
54 code = http.StatusBadRequest
55 case ErrNoClusterPrivilege.FullName(), ErrNoNamespacePrivilege.FullName():
56 code = http.StatusUnauthorized
57 case ErrNotFound.FullName():
58 code = http.StatusNotFound
59 case ErrUnknown.FullName(), ErrInternalServer.FullName():
60 code = http.StatusInternalServerError
61 default:
62 code = http.StatusInternalServerError
63 }
64
65 apiError := APIError{
66 Code: code,
67 Type: typeName,
68 Message: err.Error(),
69 FullText: fmt.Sprintf("%+v", err),
70 }
71
72 log.L().WithName("auth middleware").Error(err.Cause(), typeName)
73 c.AbortWithStatusJSON(code, &apiError)
74 }
75
76 func SetAPImachineryError(c *gin.Context, err error) {
77 if apierrors.IsForbidden(err) && strings.Contains(err.Error(), "at the cluster scope") {
78 SetAPIError(c, ErrNoClusterPrivilege.WrapWithNoMessage(err))
79
80 return
81 } else if apierrors.IsForbidden(err) && strings.Contains(err.Error(), "in the namespace") {
82 SetAPIError(c, ErrNoNamespacePrivilege.WrapWithNoMessage(err))
83
84 return
85 } else if apierrors.IsNotFound(err) {
86 SetAPIError(c, ErrNotFound.WrapWithNoMessage(err))
87
88 return
89 }
90
91 SetAPIError(c, ErrInternalServer.WrapWithNoMessage(err))
92 }
93