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