Skip to content

Commit

Permalink
feat: add option to ignore services on the dashboard (#26)
Browse files Browse the repository at this point in the history
* feat: add option to ignore services on the dashboard

* feat: add green case to demo mode and refine dashboard

* fix: update to go 1.21 for the slices package

* fix: sort unstable apps as well
  • Loading branch information
tessig authored Apr 18, 2024
1 parent 1fafac4 commit cd927b1
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 140 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ '1.18', '1.*' ]
go: [ '1.21', '1.*' ]
name: Tests
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -50,4 +50,4 @@ jobs:
- name: Goimports
run: |
go run golang.org/x/tools/cmd/goimports@latest -w .
git diff --quiet || (echo 'goimports requires code cleanup:' ; git diff ; exit 1)
git diff --quiet || (echo 'goimports requires code cleanup:' ; git diff ; exit 1)
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION=2.2.1
VERSION=2.2.2

.PHONY: docker dockerpublish test run run-demo

Expand Down
28 changes: 22 additions & 6 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Docker: `aoepeople/vistecture-dashboard`

Works together with [Vistecture](https://github.com/aoepeople/vistecture) and shows the state of the vistecture architecture in kubernetes like this:

![Vistecture_Dashboard](screenshot.jpg)
![Vistecture_Dashboard](screenshot.png)


## Usage ##
Expand All @@ -13,7 +13,7 @@ You can use the Dockerimage: `aoepeople/vistecture-dashboard`

### Example Project

```
```shell
docker run --rm -ti -p 8080:8080 aoepeople/vistecture-dashboard
```

Expand All @@ -38,7 +38,7 @@ The following "Properties" are used to control dashboard behaviour
- `k8sDeploymentName`: Override the name of the deployment in kubernetes that is checked(default = appname)
- `k8sHealthCheckServiceName`: Override service name that is used to check health (default = appname)
- `k8sHealthCheckThroughIngress`: If the app should be checked from public (ingress is required for the service)
- `k8sType`: set to "job" if the application is not represented by an deployment in kubernetes, but it is just a job
- `k8sType`: set to "job" if the application is not represented by a deployment in kubernetes, but it is just a job

### Healtcheck Format:

Expand Down Expand Up @@ -66,15 +66,31 @@ If a Healthcheck path is configured for the application the following format is
}
```

## Development: ##
### Ignore/Silence services

T ignore failing services you can provide their `name` as ignore flags, e.g.

```shell
go run vistecture-dashboard.go -Demo -ignore akeneo -ignore flamingo
```

respectively adjust the command in your dockerfile

```dockerfile
CMD ["-config", "/definition/project.yml", "-ignore", "myApp", "-ignore", "otherApp"]
```
# run

## Development:

run

```shell
go run vistecture-dashboard.go
```

For a demo display please use:
```

```shell
go run vistecture-dashboard.go -config=example/project.yml -Demo
```

Expand Down
6 changes: 6 additions & 0 deletions example/services/service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: service
title: Example Service
summary: This is an example
properties:
deployment: kubernetes
k8sHealthCheckServiceName: localhost
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/AOEpeople/vistecture-dashboard/v2

go 1.18
go 1.21

require (
github.com/AOEpeople/vistecture/v2 v2.5.2
Expand Down
Binary file removed screenshot.jpg
Binary file not shown.
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 47 additions & 9 deletions src/interfaces/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@ import (
"html/template"
"io"
"log"
"net"
"net/http"
"os"
"path"
"sort"
"strconv"
"strings"
"time"

"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/AOEpeople/vistecture-dashboard/v2/src/model/kube"
"github.com/AOEpeople/vistecture-dashboard/v2/src/model/vistecture"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

type (
DashboardController struct {
ProjectPath string
Templates string
Listen string
DemoMode bool
ProjectPath string
Templates string
Listen string
IgnoredServices []string
DemoMode bool
}

ByName []kube.AppDeploymentInfo

// templateData holds info for Dashboard Rendering
templateData struct {
Failed, Unhealthy, Healthy, Unknown, Unstable []kube.AppDeploymentInfo
Now time.Time
Failed, Unhealthy, Healthy, Unknown, Unstable, Ignored []kube.AppDeploymentInfo
Now time.Time
}
)

Expand All @@ -39,9 +44,16 @@ func (d *DashboardController) Server() error {
// load once (will panic before we start listen)
project := vistecture.LoadProject(d.ProjectPath)

var fakeHealthcheckPort int32
if d.DemoMode {
portReceive := make(chan int32)
go serveDemoHealthCheck(portReceive)
fakeHealthcheckPort = <-portReceive
}

// Prepare the status fetcher (will run in background and starts regual checks)
statusFetcher := kube.NewStatusFetcher(project.Applications, d.DemoMode)
go statusFetcher.FetchStatusInRegularInterval()
statusFetcher := kube.NewStatusFetcher(project.Applications, d.DemoMode, fakeHealthcheckPort)
go statusFetcher.FetchStatusInRegularInterval(d.IgnoredServices)

http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(path.Join(d.Templates, "static")))))
http.Handle("/metrics", promhttp.Handler())
Expand All @@ -61,6 +73,8 @@ func (d *DashboardController) dashBoardHandler(rw http.ResponseWriter, _ *http.R
result := statusFetcher.GetCurrentResult()
for _, deployment := range result {
switch deployment.AppStateInfo.State {
case kube.State_ignored:
viewdata.Ignored = append(viewdata.Ignored, deployment)
case kube.State_unknown:
viewdata.Unknown = append(viewdata.Unknown, deployment)
case kube.State_unhealthy:
Expand All @@ -74,8 +88,10 @@ func (d *DashboardController) dashBoardHandler(rw http.ResponseWriter, _ *http.R
}
}

sort.Sort(ByName(viewdata.Ignored))
sort.Sort(ByName(viewdata.Unknown))
sort.Sort(ByName(viewdata.Unhealthy))
sort.Sort(ByName(viewdata.Unstable))
sort.Sort(ByName(viewdata.Failed))
sort.Sort(ByName(viewdata.Healthy))

Expand All @@ -87,11 +103,15 @@ func (d *DashboardController) renderDashboardStatus(rw http.ResponseWriter, view
tpl := template.New("dashboard")

tpl.Funcs(template.FuncMap{
"ignored": func() uint { return kube.State_ignored },
"unknown": func() uint { return kube.State_unknown },
"unhealthy": func() uint { return kube.State_unhealthy },
"failed": func() uint { return kube.State_failed },
"healthy": func() uint { return kube.State_healthy },
"unstable": func() uint { return kube.State_unstable },
"splitLines": func(s string) []string {
return strings.Split(s, "\n")
},
})

b, err := os.ReadFile(path.Join(d.Templates, "dashboard.html"))
Expand Down Expand Up @@ -131,3 +151,21 @@ func e(rw http.ResponseWriter, err error) {
rw.Header().Set("content-type", "text/plain")
_, _ = fmt.Fprintf(rw, "%+v", err)
}

func serveDemoHealthCheck(fakeHealthcheckPort chan<- int32) {
ln, err := net.Listen("tcp", "")
if err != nil {
log.Fatal(err)
}
log.Println("Demo mode enabled: start fake health check on " + ln.Addr().String())
_, p, _ := net.SplitHostPort(ln.Addr().String())
pp, _ := strconv.Atoi(p)
fakeHealthcheckPort <- int32(pp)

err = http.Serve(ln, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
if err != nil {
log.Fatal("fake health check failed: ", err)
}
}
Loading

0 comments on commit cd927b1

Please sign in to comment.