...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/apiserver/server.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/apiserver

     1  // Copyright 2020 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package apiserver
    15  
    16  import (
    17  	"fmt"
    18  	"net/http"
    19  
    20  	"go.uber.org/fx"
    21  
    22  	"github.com/gin-contrib/pprof"
    23  	"github.com/gin-gonic/gin"
    24  	"github.com/gin-gonic/gin/binding"
    25  	"github.com/go-playground/validator/v10"
    26  
    27  	apiutils "github.com/chaos-mesh/chaos-mesh/pkg/apiserver/utils"
    28  	"github.com/chaos-mesh/chaos-mesh/pkg/apivalidator"
    29  	"github.com/chaos-mesh/chaos-mesh/pkg/config"
    30  	"github.com/chaos-mesh/chaos-mesh/pkg/swaggerserver"
    31  	"github.com/chaos-mesh/chaos-mesh/pkg/uiserver"
    32  )
    33  
    34  var (
    35  	// Module includes the providers (gin engine and api router) and the registers.
    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 := fmt.Sprintf("%s:%d", conf.ListenHost, conf.ListenPort)
    48  
    49  	go r.Run(listenAddr)
    50  }
    51  
    52  func newEngine() *gin.Engine {
    53  	r := gin.Default()
    54  
    55  	// default is "/debug/pprof/"
    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  	moveToUIRoot := func(c *gin.Context) {
    74  		c.Redirect(http.StatusMovedPermanently, "/dashboard")
    75  	}
    76  
    77  	r.GET("/", moveToUIRoot)
    78  	ui := uiserver.AssetsFS()
    79  	if ui != nil {
    80  		newDashboardRouter(r, ui)
    81  	} else {
    82  		r.GET("/dashboard", func(c *gin.Context) {
    83  			c.String(http.StatusOK, "Dashboard UI is not built. Please run `UI=1 make`.")
    84  		})
    85  	}
    86  	r.NoRoute(moveToUIRoot)
    87  
    88  	return r
    89  }
    90  
    91  func newAPIRouter(r *gin.Engine) *gin.RouterGroup {
    92  	api := r.Group("/api")
    93  	{
    94  		api.GET("/swagger/*any", swaggerserver.Handler())
    95  	}
    96  
    97  	return api
    98  }
    99  
   100  func newDashboardRouter(r *gin.Engine, ui http.FileSystem) {
   101  	renderRequest := func(c *gin.Context) {
   102  		c.FileFromFS(c.Request.URL.Path, ui)
   103  	}
   104  
   105  	r.GET("/dashboard/*any", func(c *gin.Context) {
   106  		c.FileFromFS("/", ui)
   107  	})
   108  	r.GET("/static/*any", renderRequest)
   109  	r.GET("/favicon.ico", renderRequest)
   110  }
   111