diff --git a/Makefile b/Makefile index bf76288292..bff5f5d3a1 100644 --- a/Makefile +++ b/Makefile @@ -25,14 +25,14 @@ endif # Enable GO111MODULE=on explicitly, disable it with GO111MODULE=off when necessary. export GO111MODULE := on -GOOS := $(if $(GOOS),$(GOOS),"") +GOOS := $(if $(GOOS),$(GOOS),"") GOARCH := $(if $(GOARCH),$(GOARCH),"") GOENV := GO15VENDOREXPERIMENT="1" CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) -CGOENV := GO15VENDOREXPERIMENT="1" CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) +CGOENV := GO15VENDOREXPERIMENT="1" CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) GO := $(GOENV) go CGO := $(CGOENV) go GOTEST := TEST_USE_EXISTING_CLUSTER=false NO_PROXY="${NO_PROXY},testhost" go test -SHELL := bash +SHELL := bash PACKAGE_LIST := echo $$(go list ./... | grep -vE "chaos-mesh/test|pkg/ptrace|zz_generated|vendor") github.com/chaos-mesh/chaos-mesh/api/v1alpha1 diff --git a/cmd/chaos-dashboard/main.go b/cmd/chaos-dashboard/main.go index cbe36cc58c..d0ad287fab 100644 --- a/cmd/chaos-dashboard/main.go +++ b/cmd/chaos-dashboard/main.go @@ -38,7 +38,7 @@ import ( ) var ( - log = ctrl.Log.WithName("setup") + log = ctrl.Log.WithName("dashboard") ) var ( @@ -46,7 +46,7 @@ var ( ) // @title Chaos Mesh Dashboard API -// @version 1.2 +// @version 2.0 // @description Swagger docs for Chaos Mesh Dashboard. If you encounter any problems with API, please click on the issues link below to report bugs or questions. // @contact.name Issues @@ -66,25 +66,26 @@ func main() { } ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + mainLog := log.WithName("main") - dashboardConfig, err := config.EnvironChaosDashboard() + dashboardConfig, err := config.GetChaosDashboardEnv() if err != nil { - log.Error(err, "main: invalid ChaosDashboardConfig") + mainLog.Error(err, "invalid ChaosDashboardConfig") os.Exit(1) } dashboardConfig.Version = version.Get().GitVersion persistTTLConfigParsed, err := config.ParsePersistTTLConfig(dashboardConfig.PersistTTL) if err != nil { - log.Error(err, "main: invalid PersistTTLConfig") + mainLog.Error(err, "invalid PersistTTLConfig") os.Exit(1) } - controllerRuntimeStopCh := ctrl.SetupSignalHandler() + ctrlRuntimeStopCh := ctrl.SetupSignalHandler() app := fx.New( fx.Provide( func() (<-chan struct{}, *config.ChaosDashboardConfig, *ttlcontroller.TTLconfig) { - return controllerRuntimeStopCh, dashboardConfig, persistTTLConfigParsed + return ctrlRuntimeStopCh, dashboardConfig, persistTTLConfigParsed }, dbstore.NewDBStore, collector.NewServer, @@ -97,5 +98,4 @@ func main() { ) app.Run() - <-controllerRuntimeStopCh } diff --git a/pkg/apiserver/archive/archive_test.go b/pkg/apiserver/archive/archive_test.go index 5e140a27fa..8ad5d8f43e 100644 --- a/pkg/apiserver/archive/archive_test.go +++ b/pkg/apiserver/archive/archive_test.go @@ -55,10 +55,6 @@ func (m *MockExperimentStore) ListMeta(ctx context.Context, kind, namespace, nam var err error if kind == "testKind" { expMeta := &core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: "testUID", Kind: "testKind", Name: "testName", @@ -84,10 +80,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindPodChaos, Name: "testName", @@ -104,10 +96,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindIOChaos, Name: "testName", @@ -124,10 +112,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindNetworkChaos, Name: "testName", @@ -144,10 +128,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindTimeChaos, Name: "testName", @@ -164,10 +144,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindKernelChaos, Name: "testName", @@ -184,10 +160,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. jsonStr, _ := json.Marshal(chaos) res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindStressChaos, Name: "testName", @@ -202,10 +174,6 @@ func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core. case "testOtherChaos": res = &core.Experiment{ ExperimentMeta: core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: "OtherChaos", Name: "testName", @@ -231,10 +199,6 @@ func (m *MockExperimentStore) FindMetaByUID(ctx context.Context, UID string) (*c switch UID { case "tsetUID": res = &core.ExperimentMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: "testUID", Kind: "testKind", Name: "testName", @@ -281,10 +245,6 @@ func (m *MockScheduleStore) ListMeta(ctx context.Context, namespace, name string var err error if name == "testScheduleName" { schMeta := &core.ScheduleMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: "testUID", Kind: "testKind", Name: "testScheduleName", @@ -310,10 +270,6 @@ func (m *MockScheduleStore) FindByUID(ctx context.Context, UID string) (*core.Sc jsonStr, _ := json.Marshal(sch) res = &core.Schedule{ ScheduleMeta: core.ScheduleMeta{ - ID: 0, - CreatedAt: time.Time{}, - UpdatedAt: time.Time{}, - DeletedAt: nil, UID: UID, Kind: v1alpha1.KindPodChaos, Name: "testName", diff --git a/pkg/apiserver/server.go b/pkg/apiserver/server.go index 97f6ea4bf8..42e80463f9 100644 --- a/pkg/apiserver/server.go +++ b/pkg/apiserver/server.go @@ -49,7 +49,7 @@ func serverRegister(r *gin.Engine, conf *config.ChaosDashboardConfig) { go r.Run(listenAddr) } -func newEngine() *gin.Engine { +func newEngine(config *config.ChaosDashboardConfig) *gin.Engine { r := gin.Default() // default is "/debug/pprof/" @@ -70,20 +70,28 @@ func newEngine() *gin.Engine { v.RegisterValidation("RequiredFieldEqual", apivalidator.RequiredFieldEqualValid, true) } - moveToUIRoot := func(c *gin.Context) { - c.Redirect(http.StatusMovedPermanently, "/dashboard") - } - - r.GET("/", moveToUIRoot) ui := uiserver.AssetsFS() if ui != nil { - newDashboardRouter(r, ui) + r.GET("/", func(c *gin.Context) { + c.FileFromFS("/", ui) + }) + // `/:foo/*bar` from https://en.wikipedia.org/wiki/Foobar, the name itself has no meaning. + // + // This handle just internally redirects all no-exact routes to the root directory of static files because the UI is a single page application and only has one entry (index.html). + r.GET("/:foo/*bar", func(c *gin.Context) { + c.FileFromFS("/", ui) + }) + + renderStatic := func(c *gin.Context) { + c.FileFromFS(c.Request.URL.Path, ui) + } + r.GET("/static/*any", renderStatic) + r.GET("/favicon.ico", renderStatic) } else { - r.GET("/dashboard", func(c *gin.Context) { + r.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "Dashboard UI is not built. Please run `UI=1 make`.") }) } - r.NoRoute(moveToUIRoot) return r } @@ -96,15 +104,3 @@ func newAPIRouter(r *gin.Engine) *gin.RouterGroup { return api } - -func newDashboardRouter(r *gin.Engine, ui http.FileSystem) { - renderRequest := func(c *gin.Context) { - c.FileFromFS(c.Request.URL.Path, ui) - } - - r.GET("/dashboard/*any", func(c *gin.Context) { - c.FileFromFS("/", ui) - }) - r.GET("/static/*any", renderRequest) - r.GET("/favicon.ico", renderRequest) -} diff --git a/pkg/config/dashboard/dashboard.go b/pkg/config/dashboard/dashboard.go index 1778b95dfd..f3f661bcc3 100644 --- a/pkg/config/dashboard/dashboard.go +++ b/pkg/config/dashboard/dashboard.go @@ -37,7 +37,6 @@ type ChaosDashboardConfig struct { // EnableFilterNamespace will filter namespace with annotation. Only the pods/containers in namespace // annotated with `chaos-mesh.org/inject=enabled` will be injected EnableFilterNamespace bool `envconfig:"ENABLE_FILTER_NAMESPACE" default:"false"` - // SecurityMode will use the token login by the user if set to true SecurityMode bool `envconfig:"SECURITY_MODE" default:"true" json:"security_mode"` DNSServerCreate bool `envconfig:"DNS_SERVER_CREATE" default:"false" json:"dns_server_create"` @@ -60,8 +59,8 @@ type DatabaseConfig struct { Secret string `envconfig:"DATABASE_SECRET"` } -// EnvironChaosDashboard returns the settings from the environment. -func EnvironChaosDashboard() (*ChaosDashboardConfig, error) { +// GetChaosDashboardEnv gets all env variables related to dashboard. +func GetChaosDashboardEnv() (*ChaosDashboardConfig, error) { cfg := ChaosDashboardConfig{} err := envconfig.Process("", &cfg) return &cfg, err diff --git a/pkg/core/experiment.go b/pkg/core/experiment.go index cf7c3ba815..caf85c12a1 100644 --- a/pkg/core/experiment.go +++ b/pkg/core/experiment.go @@ -20,6 +20,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/jinzhu/gorm" + "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" ) @@ -64,18 +66,15 @@ type Experiment struct { // ExperimentMeta defines the metadata of an experiment. Use in db. type ExperimentMeta struct { - ID uint `gorm:"primary_key" json:"id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - DeletedAt *time.Time `sql:"index" json:"deleted_at"` - UID string `gorm:"index:uid" json:"uid"` - Kind string `json:"kind"` - Name string `json:"name"` - Namespace string `json:"namespace"` - Action string `json:"action"` - StartTime time.Time `json:"start_time"` - FinishTime time.Time `json:"finish_time"` - Archived bool `json:"archived"` + gorm.Model + UID string `gorm:"index:uid" json:"uid"` + Kind string `json:"kind"` + Name string `json:"name"` + Namespace string `json:"namespace"` + Action string `json:"action"` + StartTime time.Time `json:"start_time"` + FinishTime time.Time `json:"finish_time"` + Archived bool `json:"archived"` } // ExperimentInfo defines a form data of Experiment from API. diff --git a/pkg/core/schedule.go b/pkg/core/schedule.go index 2aed45c4a1..887370a194 100644 --- a/pkg/core/schedule.go +++ b/pkg/core/schedule.go @@ -17,6 +17,8 @@ import ( "context" "time" + "github.com/jinzhu/gorm" + "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" ) @@ -61,18 +63,15 @@ type Schedule struct { // ScheduleMeta defines the metadata of a schedule instance. Use in db. type ScheduleMeta struct { - ID uint `gorm:"primary_key" json:"id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - DeletedAt *time.Time `sql:"index" json:"deleted_at"` - UID string `gorm:"index:uid" json:"uid"` - Kind string `json:"kind"` - Name string `json:"name"` - Namespace string `json:"namespace"` - Action string `json:"action"` - StartTime time.Time `json:"start_time"` - FinishTime time.Time `json:"finish_time"` - Archived bool `json:"archived"` + gorm.Model + UID string `gorm:"index:schedule_uid" json:"uid"` + Kind string `json:"kind"` + Name string `json:"name"` + Namespace string `json:"namespace"` + Action string `json:"action"` + StartTime time.Time `json:"start_time"` + FinishTime time.Time `json:"finish_time"` + Archived bool `json:"archived"` } // ScheduleInfo defines a form data of schedule from API. diff --git a/pkg/core/workflow.go b/pkg/core/workflow.go index b62cd00c26..dffdb9cd18 100644 --- a/pkg/core/workflow.go +++ b/pkg/core/workflow.go @@ -19,6 +19,7 @@ import ( "strings" "time" + "github.com/jinzhu/gorm" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -49,15 +50,14 @@ const ( // WorkflowMeta defines the root structure of a workflow. type WorkflowMeta struct { - ID uint `gorm:"primary_key" json:"id"` - Namespace string `json:"namespace"` - Name string `json:"name"` - // the entry node name - Entry string `json:"entry"` + gorm.Model + UID string `gorm:"index:workflow_uid" json:"uid"` + Namespace string `json:"namespace"` + Name string `json:"name"` + Entry string `json:"entry"` // the entry node name CreatedAt string `json:"created_at"` EndTime string `json:"end_time"` Status WorkflowStatus `json:"status,omitempty"` - UID string `gorm:"index:uid" json:"uid"` Archived bool `json:"-"` } diff --git a/pkg/store/event/event.go b/pkg/store/event/event.go index 1bb87f3172..d7f30db806 100644 --- a/pkg/store/event/event.go +++ b/pkg/store/event/event.go @@ -21,20 +21,16 @@ import ( "time" "github.com/jinzhu/gorm" - ctrl "sigs.k8s.io/controller-runtime" "github.com/chaos-mesh/chaos-mesh/pkg/core" "github.com/chaos-mesh/chaos-mesh/pkg/store/dbstore" ) -var log = ctrl.Log.WithName("store/event") - // NewStore return a new EventStore. func NewStore(db *dbstore.DB) core.EventStore { db.AutoMigrate(&core.Event{}) - es := &eventStore{db} - return es + return &eventStore{db} } type eventStore struct { @@ -250,23 +246,3 @@ func constructQueryArgs(experimentName, experimentNamespace, uid, kind, createTi return query, args } - -func splitArray(arr []uint, num int) [][]uint { - max := int(len(arr)) - if max < num { - return nil - } - var segments = make([][]uint, 0) - quantity := max / num - end := int(0) - for i := int(1); i <= num; i++ { - point := i * quantity - if i != num { - segments = append(segments, arr[i-1+end:point]) - } else { - segments = append(segments, arr[i-1+end:]) - } - end = point - i - } - return segments -} diff --git a/pkg/store/experiment/experiment.go b/pkg/store/experiment/experiment.go index 12ce429cb0..29ea1261be 100644 --- a/pkg/store/experiment/experiment.go +++ b/pkg/store/experiment/experiment.go @@ -30,9 +30,7 @@ var log = ctrl.Log.WithName("store/experiment") func NewStore(db *dbstore.DB) core.ExperimentStore { db.AutoMigrate(&core.Experiment{}) - es := &experimentStore{db} - - return es + return &experimentStore{db} } // DeleteIncompleteExperiments call core.ExperimentStore.DeleteIncompleteExperiments to deletes all incomplete experiments. diff --git a/pkg/store/schedule/schedule.go b/pkg/store/schedule/schedule.go index eec6d033d4..57cbf75530 100644 --- a/pkg/store/schedule/schedule.go +++ b/pkg/store/schedule/schedule.go @@ -30,9 +30,7 @@ var log = ctrl.Log.WithName("store/schedule") func NewStore(db *dbstore.DB) core.ScheduleStore { db.AutoMigrate(&core.Schedule{}) - es := &ScheduleStore{db} - - return es + return &ScheduleStore{db} } // DeleteIncompleteSchedules call core.ScheduleStore.DeleteIncompleteSchedules to deletes all incomplete schedules. diff --git a/pkg/store/workflow/workflow.go b/pkg/store/workflow/workflow.go index 2da4873bca..e7a30622d6 100644 --- a/pkg/store/workflow/workflow.go +++ b/pkg/store/workflow/workflow.go @@ -28,7 +28,8 @@ type WorkflowStore struct { func NewStore(db *dbstore.DB) core.WorkflowStore { db.AutoMigrate(&core.WorkflowEntity{}) - return &WorkflowStore{db: db} + + return &WorkflowStore{db} } func (it *WorkflowStore) List(ctx context.Context, namespace, name string, archived bool) ([]*core.WorkflowEntity, error) { diff --git a/ui/package.json b/ui/package.json index 6c9f694d89..b6cb2ae8a5 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "chaos-mesh-dashboard", - "version": "1.0.0", + "version": "2.0.0", "description": "A Web UI for Chaos Mesh", "private": true, "dependencies": { diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 37996f41c3..0a3836d6eb 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -6,7 +6,7 @@ import store from './store' const App = () => ( - +