...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package apiserver
15
16 import (
17 "fmt"
18 "net"
19 "net/http"
20
21 "github.com/gin-contrib/pprof"
22 "github.com/gin-gonic/gin"
23 "github.com/gin-gonic/gin/binding"
24 "github.com/go-playground/validator/v10"
25 "go.uber.org/fx"
26
27 apiutils "github.com/chaos-mesh/chaos-mesh/pkg/apiserver/utils"
28 "github.com/chaos-mesh/chaos-mesh/pkg/apivalidator"
29 config "github.com/chaos-mesh/chaos-mesh/pkg/config/dashboard"
30 "github.com/chaos-mesh/chaos-mesh/pkg/swaggerserver"
31 "github.com/chaos-mesh/chaos-mesh/pkg/uiserver"
32 )
33
34 var (
35
36 Module = fx.Options(
37 fx.Provide(
38 newEngine,
39 newAPIRouter,
40 ),
41 handlerModule,
42 fx.Invoke(serverRegister),
43 )
44 )
45
46 func serverRegister(r *gin.Engine, conf *config.ChaosDashboardConfig) {
47 listenAddr := net.JoinHostPort(conf.ListenHost, fmt.Sprintf("%d", conf.ListenPort))
48
49 go r.Run(listenAddr)
50 }
51
52 func newEngine(config *config.ChaosDashboardConfig) *gin.Engine {
53 r := gin.Default()
54
55
56 pprof.Register(r)
57
58 r.Use(apiutils.MWHandleErrors())
59
60 if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
61 v.RegisterValidation("NameValid", apivalidator.NameValid)
62 v.RegisterValidation("NamespaceSelectorsValid", apivalidator.NamespaceSelectorsValid)
63 v.RegisterValidation("MapSelectorsValid", apivalidator.MapSelectorsValid)
64 v.RegisterValidation("RequirementSelectorsValid", apivalidator.RequirementSelectorsValid)
65 v.RegisterValidation("PhaseSelectorsValid", apivalidator.PhaseSelectorsValid)
66 v.RegisterValidation("CronValid", apivalidator.CronValid)
67 v.RegisterValidation("DurationValid", apivalidator.DurationValid)
68 v.RegisterValidation("ValueValid", apivalidator.ValueValid)
69 v.RegisterValidation("PodsValid", apivalidator.PodsValid)
70 v.RegisterValidation("RequiredFieldEqual", apivalidator.RequiredFieldEqualValid, true)
71 }
72
73 ui := uiserver.AssetsFS()
74 if ui != nil {
75 r.GET("/", func(c *gin.Context) {
76 c.FileFromFS("/", ui)
77 })
78
79
80
81 r.GET("/:foo", func(c *gin.Context) {
82 c.FileFromFS("/", ui)
83 })
84 r.GET("/:foo/*bar", func(c *gin.Context) {
85 c.FileFromFS("/", ui)
86 })
87
88 renderStatic := func(c *gin.Context) {
89 c.FileFromFS(c.Request.URL.Path, ui)
90 }
91 r.GET("/static/*any", renderStatic)
92 r.GET("/favicon.ico", renderStatic)
93 } else {
94 r.GET("/", func(c *gin.Context) {
95 c.String(http.StatusOK, "Dashboard UI is not built. Please run `UI=1 make`.")
96 })
97 }
98
99 return r
100 }
101
102 func newAPIRouter(r *gin.Engine) *gin.RouterGroup {
103 api := r.Group("/api")
104 {
105 api.GET("/swagger/*any", swaggerserver.Handler())
106 }
107
108 return api
109 }
110