Skip to content

Commit

Permalink
Chart details draft (#4)
Browse files Browse the repository at this point in the history
* Add logo

* Refactor out structs

* Data layer context-awareness

* Mod

* Data layer improvements

* Progress

* Progress

* Progress

* Figured the time format shorter

* Statuses colors

* Sticky URL

* Calculate some diffs inside

* Separate checks

* Scrap gofmt

* Skip custom test in GH

* Shows some colorful diff
  • Loading branch information
undera authored Aug 31, 2022
1 parent d9a88fe commit 1580c2e
Show file tree
Hide file tree
Showing 16 changed files with 697 additions and 201 deletions.
15 changes: 8 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@ jobs:
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
- name: Series of tests
- name: Unit tests
run: |
GO_FILES=$(find . -iname '*.go' -type f) # All the .go files, excluding vendor/
test -z $(gofmt -s -l $GO_FILES) # Fail if a .go file hasn't been formatted with gofmt
go test -v -race ./... # Run all the tests with the race detector enabled
- name: Static analysis
run: |
go vet ./... # go vet is the official Go static analyzer
- name: Cyclomatic complexity
run: |
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
/home/runner/go/bin/gocyclo -over 19 cmd pkg # forbid code with huge/complex functions
go build main.go
/home/runner/go/bin/gocyclo -over 19 main.go pkg # forbid code with huge/complex functions
- name: Dry Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --snapshot --rm-dist
- name: Test Binary is Runnable
run: "dist/helm-dashboard_linux_amd64_v1/helm-dashboard --help"
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
# Go workspace file
go.work

/bin
/bin
/.idea/
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ To uninstall, run:
helm plugin uninstall dashboard
```

## Support Channels

We have two main channels for supporting the tool users: [Slack community](#TODO) for general conversations and [GitHub issues](https://github.com/komodorio/helm-dashboard/issues) for real bugs.

## Roadmap

Expand Down Expand Up @@ -59,3 +62,6 @@ Validate manifests before deploy and get better errors
Switch clusters (?)
Browsing repositories
Adding new repository

Recognise & show ArgoCD-originating charts/objects
Have cleaner idea on the web API structure
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ module github.com/komodorio/helm-dashboard
go 1.18

require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/gin-gonic/gin v1.8.1
github.com/hexops/gotextdiff v1.0.3
github.com/sirupsen/logrus v1.8.1
github.com/toqueteos/webbrowser v1.2.0
helm.sh/helm/v3 v3.9.4
)

require (
Expand All @@ -14,7 +17,6 @@ require (
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.0 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
Expand Down
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand All @@ -19,8 +21,9 @@ github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down Expand Up @@ -100,3 +103,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
helm.sh/helm/v3 v3.9.4 h1:TCI1QhJUeLVOdccfdw+vnSEO3Td6gNqibptB04QtExY=
helm.sh/helm/v3 v3.9.4/go.mod h1:3eaWAIqzvlRSD06gR9MMwmp2KBKwlu9av1/1BZpjeWY=
121 changes: 95 additions & 26 deletions pkg/dashboard/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,33 @@ package dashboard

import (
"embed"
"errors"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"net/http"
"os"
"path"
"strconv"
)

//go:embed static/*
var staticFS embed.FS

func newRouter(abortWeb ControlChan, data DataLayer) *gin.Engine {
func errorHandler(c *gin.Context) {
c.Next()

errs := ""
for _, err := range c.Errors {
log.Debugf("Error: %s", err)
errs += err.Error() + "\n"
}

if errs != "" {
c.String(http.StatusInternalServerError, errs)
}
}

func NewRouter(abortWeb ControlChan, data DataLayer) *gin.Engine {
var api *gin.Engine
if os.Getenv("DEBUG") == "" {
api = gin.New()
Expand All @@ -21,6 +37,84 @@ func newRouter(abortWeb ControlChan, data DataLayer) *gin.Engine {
api = gin.Default()
}

api.Use(errorHandler)
configureStatic(api)

configureRoutes(abortWeb, data, api)
return api
}

func configureRoutes(abortWeb ControlChan, data DataLayer, api *gin.Engine) {
// server shutdown handler
api.DELETE("/", func(c *gin.Context) {
abortWeb <- struct{}{}
})

api.GET("/api/helm/charts", func(c *gin.Context) {
res, err := data.ListInstalled()
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

api.GET("/api/kube/contexts", func(c *gin.Context) {
res, err := data.ListContexts()
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

api.GET("/api/helm/charts/history", func(c *gin.Context) {
cName := c.Query("chart")
cNamespace := c.Query("namespace")
if cName == "" {
_ = c.AbortWithError(http.StatusBadRequest, errors.New("missing required query string parameter: chart"))
return
}

res, err := data.ChartHistory(cNamespace, cName)
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

api.GET("/api/helm/charts/manifest/diff", func(c *gin.Context) {
cName := c.Query("chart")
cNamespace := c.Query("namespace")
if cName == "" {
_ = c.AbortWithError(http.StatusBadRequest, errors.New("missing required query string parameter: chart"))
return
}

cRev1, err := strconv.Atoi(c.Query("revision1"))
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}

cRev2, err := strconv.Atoi(c.Query("revision2"))
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}

res, err := data.RevisionManifestsDiff(cNamespace, cName, cRev1, cRev2)
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

}

func configureStatic(api *gin.Engine) {
fs := http.FS(staticFS)

// local dev speed-up
Expand Down Expand Up @@ -48,29 +142,4 @@ func newRouter(abortWeb ControlChan, data DataLayer) *gin.Engine {
c.FileFromFS(c.Request.URL.Path, fs)
})
}

// server shutdown handler
api.DELETE("/", func(c *gin.Context) {
abortWeb <- struct{}{}
})

api.GET("/api/helm/charts", func(c *gin.Context) {
res, err := data.ListInstalled()
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

api.GET("/api/kube/contexts", func(c *gin.Context) {
res, err := data.ListContexts()
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.IndentedJSON(http.StatusOK, res)
})

return api
}
Loading

0 comments on commit 1580c2e

Please sign in to comment.