...
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 "github.com/prometheus/client_golang/prometheus"
28 "go.uber.org/fx"
29 controllermetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
30
31 config "github.com/chaos-mesh/chaos-mesh/pkg/config"
32 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/apivalidator"
33 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/swaggerserver"
34 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/uiserver"
35 "github.com/chaos-mesh/chaos-mesh/pkg/metrics"
36 )
37
38 var (
39
40 Module = fx.Options(
41 fx.Provide(
42 newEngine,
43 newAPIRouter,
44 ),
45 handlerModule,
46 fx.Provide(func() prometheus.Registerer {
47 return controllermetrics.Registry
48 }),
49 fx.Invoke(metrics.NewChaosDashboardMetricsCollector),
50 fx.Invoke(register),
51 )
52 )
53
54 func register(r *gin.Engine, conf *config.ChaosDashboardConfig) {
55 listenAddr := net.JoinHostPort(conf.ListenHost, fmt.Sprintf("%d", conf.ListenPort))
56
57 go r.Run(listenAddr)
58 }
59
60 func newEngine(config *config.ChaosDashboardConfig) *gin.Engine {
61 r := gin.Default()
62
63 if config.EnableProfiling {
64
65 pprof.Register(r)
66 }
67
68 if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
69 v.RegisterValidation("NameValid", apivalidator.NameValid)
70 v.RegisterValidation("NamespaceSelectorsValid", apivalidator.NamespaceSelectorsValid)
71 v.RegisterValidation("MapSelectorsValid", apivalidator.MapSelectorsValid)
72 v.RegisterValidation("RequirementSelectorsValid", apivalidator.RequirementSelectorsValid)
73 v.RegisterValidation("PhaseSelectorsValid", apivalidator.PhaseSelectorsValid)
74 v.RegisterValidation("CronValid", apivalidator.CronValid)
75 v.RegisterValidation("DurationValid", apivalidator.DurationValid)
76 v.RegisterValidation("ValueValid", apivalidator.ValueValid)
77 v.RegisterValidation("PodsValid", apivalidator.PodsValid)
78 v.RegisterValidation("RequiredFieldEqual", apivalidator.RequiredFieldEqualValid, true)
79 v.RegisterValidation("PhysicalMachineValid", apivalidator.PhysicalMachineValid)
80 }
81
82 ui := uiserver.AssetsFS()
83 if ui != nil {
84 r.NoRoute(func(c *gin.Context) {
85 c.FileFromFS(c.Request.URL.Path, ui)
86 })
87 } else {
88 r.GET("/", func(c *gin.Context) {
89 c.String(http.StatusOK, "Dashboard UI is not built.")
90 })
91 }
92
93 return r
94 }
95
96 func newAPIRouter(r *gin.Engine) *gin.RouterGroup {
97 api := r.Group("/api")
98
99 api.GET("/swagger/*any", swaggerserver.Handler)
100
101 return api
102 }
103