Skip to content

Commit

Permalink
feat: use YAML format as experiment description (#1029)
Browse files Browse the repository at this point in the history
* chore(init): renew editor

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: update

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: bugs

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: update

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: error

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: error

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix(try): ci

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: diff to stdout

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix(debug): comment diff

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix(debug): ci

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: recover

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: update

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: update

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: yamlToExperiment

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: should set string when error occurred

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: update

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* chore: change log style

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: typo

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

* fix: no scheduler problem

Signed-off-by: Yue Yang <g1enyy0ung@gmail.com>

Co-authored-by: ti-srebot <66930949+ti-srebot@users.noreply.github.com>
  • Loading branch information
g1eny0ung and ti-srebot committed Oct 26, 2020
1 parent 8b3f975 commit 4c55adb
Show file tree
Hide file tree
Showing 30 changed files with 1,001 additions and 1,708 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -34,6 +34,7 @@ require (
github.com/lib/pq v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.8 // indirect
github.com/mgechev/revive v1.0.2-0.20200225072153-6219ca02fffb
github.com/mitchellh/mapstructure v1.3.3
github.com/morikuni/aec v1.0.0 // indirect
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
Expand Down
9 changes: 2 additions & 7 deletions go.sum
Expand Up @@ -49,7 +49,6 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIO
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
Expand All @@ -69,7 +68,6 @@ github.com/bazelbuild/rules_go v0.0.0-20190719190356-6dae44dc5cab/go.mod h1:MC23
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
Expand Down Expand Up @@ -283,7 +281,6 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
github.com/go-playground/overalls v0.0.0-20180201144345-22ec1a223b7c/go.mod h1:UqxAgEOt89sCiXlrc/ycnx00LVvUO/eS8tMUkWX4R7w=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o=
github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
Expand Down Expand Up @@ -336,7 +333,6 @@ github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
Expand Down Expand Up @@ -476,7 +472,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down Expand Up @@ -551,8 +546,9 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -1024,7 +1020,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
Expand Down
251 changes: 251 additions & 0 deletions pkg/apiserver/archive/archive.go
@@ -0,0 +1,251 @@
// Copyright 2020 Chaos Mesh Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package archive

import (
"context"
"fmt"
"net/http"
"time"

"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"

"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
"github.com/chaos-mesh/chaos-mesh/pkg/apiserver/utils"
"github.com/chaos-mesh/chaos-mesh/pkg/core"
)

// Service defines a handler service for archive experiments.
type Service struct {
archive core.ExperimentStore
event core.EventStore
}

// NewService returns an archive experiment service instance.
func NewService(
archive core.ExperimentStore,
event core.EventStore,
) *Service {
return &Service{
archive: archive,
event: event,
}
}

// Register mounts our HTTP handler on the mux.
func Register(r *gin.RouterGroup, s *Service) {
endpoint := r.Group("/archives")

endpoint.GET("", s.list)
endpoint.GET("/detail", s.detail)
endpoint.GET("/report", s.report)
}

// Archive defines the basic information of an archive.
type Archive struct {
UID string `json:"uid"`
Kind string `json:"kind"`
Namespace string `json:"namespace"`
Name string `json:"name"`
Action string `json:"action"`
StartTime time.Time `json:"start_time"`
FinishTime time.Time `json:"finish_time"`
}

// Detail represents an archive instance.
type Detail struct {
Archive
YAML core.ExperimentYAMLDescription `json:"yaml"`
}

// Report defines the report of archive experiments.
type Report struct {
Meta *Archive `json:"meta"`
Events []*core.Event `json:"events"`
TotalTime string `json:"total_time"`
TotalFaultTime string `json:"total_fault_time"`
}

// @Summary Get archived chaos experiments.
// @Description Get archived chaos experiments.
// @Tags archives
// @Produce json
// @Param namespace query string false "namespace"
// @Param name query string false "name"
// @Param kind query string false "kind" Enums(PodChaos, IoChaos, NetworkChaos, TimeChaos, KernelChaos, StressChaos)
// @Success 200 {array} Archive
// @Router /archives [get]
// @Failure 500 {object} utils.APIError
func (s *Service) list(c *gin.Context) {
kind := c.Query("kind")
name := c.Query("name")
ns := c.Query("namespace")

data, err := s.archive.ListMeta(context.Background(), kind, ns, name, true)
if err != nil {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInternalServer.NewWithNoMessage())
return
}

archives := make([]Archive, 0)

for _, d := range data {
archives = append(archives, Archive{
UID: d.UID,
Kind: d.Kind,
Namespace: d.Namespace,
Name: d.Name,
Action: d.Action,
StartTime: d.StartTime,
FinishTime: d.FinishTime,
})
}

c.JSON(http.StatusOK, archives)
}

// @Summary Get the detail of an archived chaos experiment.
// @Description Get the detail of an archived chaos experiment.
// @Tags archives
// @Produce json
// @Param uid query string true "uid"
// @Success 200 {object} Detail
// @Router /archives/detail [get]
// @Failure 500 {object} utils.APIError
func (s *Service) detail(c *gin.Context) {
var (
err error
yaml core.ExperimentYAMLDescription
detail Detail
)
uid := c.Query("uid")

if uid == "" {
c.Status(http.StatusBadRequest)
_ = c.Error(utils.ErrInvalidRequest.New("uid cannot be empty"))
return
}

data, err := s.archive.FindByUID(context.Background(), uid)
if err != nil {
if !gorm.IsRecordNotFoundError(err) {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInternalServer.NewWithNoMessage())
} else {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInvalidRequest.New("the archive is not found"))
}
return
}

switch data.Kind {
case v1alpha1.KindPodChaos:
yaml, err = data.ParsePodChaos()
case v1alpha1.KindIoChaos:
yaml, err = data.ParseIOChaos()
case v1alpha1.KindNetworkChaos:
yaml, err = data.ParseNetworkChaos()
case v1alpha1.KindTimeChaos:
yaml, err = data.ParseTimeChaos()
case v1alpha1.KindKernelChaos:
yaml, err = data.ParseKernelChaos()
case v1alpha1.KindStressChaos:
yaml, err = data.ParseStressChaos()
default:
err = fmt.Errorf("kind %s is not support", data.Kind)
}
if err != nil {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInternalServer.WrapWithNoMessage(err))
return
}

detail = Detail{
Archive: Archive{
UID: data.UID,
Kind: data.Kind,
Name: data.Name,
Namespace: data.Namespace,
Action: data.Action,
StartTime: data.StartTime,
FinishTime: data.FinishTime,
},
YAML: yaml,
}

c.JSON(http.StatusOK, detail)
}

// @Summary Get the report of an archived chaos experiment.
// @Description Get the report of an archived chaos experiment.
// @Tags archives
// @Produce json
// @Param uid query string true "uid"
// @Success 200 {array} Report
// @Router /archives/report [get]
// @Failure 500 {object} utils.APIError
func (s *Service) report(c *gin.Context) {
var (
err error
report Report
)
uid := c.Query("uid")

if uid == "" {
c.Status(http.StatusBadRequest)
_ = c.Error(utils.ErrInvalidRequest.New("uid cannot be empty"))
return
}

meta, err := s.archive.FindMetaByUID(context.Background(), uid)
if err != nil {
if !gorm.IsRecordNotFoundError(err) {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInternalServer.NewWithNoMessage())
} else {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInvalidRequest.New("the archive is not found"))
}
return
}
report.Meta = &Archive{
UID: meta.UID,
Kind: meta.Kind,
Namespace: meta.Namespace,
Name: meta.Name,
Action: meta.Action,
StartTime: meta.StartTime,
FinishTime: meta.FinishTime,
}

report.Events, err = s.event.ListByUID(context.TODO(), uid)
if err != nil {
c.Status(http.StatusInternalServerError)
_ = c.Error(utils.ErrInternalServer.NewWithNoMessage())
return
}

report.TotalTime = report.Meta.FinishTime.Sub(report.Meta.StartTime).String()

timeNow := time.Now()
timeAfter := timeNow
for _, et := range report.Events {
timeAfter = timeAfter.Add(et.FinishTime.Sub(*et.StartTime))
}
report.TotalFaultTime = timeAfter.Sub(timeNow).String()

c.JSON(http.StatusOK, report)
}

0 comments on commit 4c55adb

Please sign in to comment.