Skip to content

Commit de0024c

Browse files
authored
Check for newer version available (#47)
* Add helm version requirement notes * Check for newer version and offer upgrade * fix lint
1 parent b0067e3 commit de0024c

File tree

8 files changed

+96
-19
lines changed

8 files changed

+96
-19
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ go 1.18
44

55
require (
66
github.com/gin-gonic/gin v1.8.1
7+
github.com/hashicorp/go-version v1.6.0
78
github.com/hexops/gotextdiff v1.0.3
89
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
910
github.com/sirupsen/logrus v1.9.0
10-
github.com/toqueteos/webbrowser v1.2.0
1111
gopkg.in/yaml.v3 v3.0.1
1212
helm.sh/helm/v3 v3.9.4
1313
k8s.io/apimachinery v0.25.0-alpha.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
3131
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
3232
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
3333
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
34+
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
35+
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
3436
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
3537
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
3638
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -78,8 +80,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
7880
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
7981
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
8082
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
81-
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
82-
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
8383
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
8484
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
8585
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=

pkg/dashboard/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func contextSetter(data *subproc.DataLayer) gin.HandlerFunc {
4444
}
4545
}
4646

47-
func NewRouter(abortWeb utils.ControlChan, data *subproc.DataLayer, version string) *gin.Engine {
47+
func NewRouter(abortWeb utils.ControlChan, data *subproc.DataLayer) *gin.Engine {
4848
var api *gin.Engine
4949
if os.Getenv("DEBUG") == "" {
5050
api = gin.New()
@@ -58,20 +58,20 @@ func NewRouter(abortWeb utils.ControlChan, data *subproc.DataLayer, version stri
5858
api.Use(errorHandler)
5959

6060
configureStatic(api)
61-
configureRoutes(abortWeb, data, api, version)
61+
configureRoutes(abortWeb, data, api)
6262

6363
return api
6464
}
6565

66-
func configureRoutes(abortWeb utils.ControlChan, data *subproc.DataLayer, api *gin.Engine, version string) {
66+
func configureRoutes(abortWeb utils.ControlChan, data *subproc.DataLayer, api *gin.Engine) {
6767
// server shutdown handler
6868
api.DELETE("/", func(c *gin.Context) {
6969
abortWeb <- struct{}{}
7070
c.Status(http.StatusAccepted)
7171
})
7272

7373
api.GET("/status", func(c *gin.Context) {
74-
c.String(http.StatusOK, version)
74+
c.IndentedJSON(http.StatusOK, data.VersionInfo)
7575
})
7676

7777
configureHelms(api.Group("/api/helm"), data)

pkg/dashboard/server.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package dashboard
22

33
import (
44
"context"
5+
"encoding/json"
56
"github.com/gin-gonic/gin"
7+
"github.com/hashicorp/go-version"
68
"github.com/komodorio/helm-dashboard/pkg/dashboard/scanners"
79
"github.com/komodorio/helm-dashboard/pkg/dashboard/subproc"
810
"github.com/komodorio/helm-dashboard/pkg/dashboard/utils"
911
log "github.com/sirupsen/logrus"
1012
"net/http"
1113
"os"
14+
"time"
1215
)
1316

1417
func StartServer(version string) (string, utils.ControlChan) {
@@ -19,6 +22,9 @@ func StartServer(version string) (string, utils.ControlChan) {
1922
os.Exit(1) // TODO: propagate error instead?
2023
}
2124

25+
data.VersionInfo = &subproc.VersionInfo{CurVer: version}
26+
go checkUpgrade(data.VersionInfo)
27+
2228
discoverScanners(&data)
2329

2430
address := os.Getenv("HD_BIND")
@@ -33,7 +39,7 @@ func StartServer(version string) (string, utils.ControlChan) {
3339
}
3440

3541
abort := make(utils.ControlChan)
36-
api := NewRouter(abort, &data, version)
42+
api := NewRouter(abort, &data)
3743
done := startBackgroundServer(address, api, abort)
3844

3945
return "http://" + address, done
@@ -75,3 +81,44 @@ func discoverScanners(data *subproc.DataLayer) {
7581
}
7682
}
7783
}
84+
85+
func checkUpgrade(d *subproc.VersionInfo) {
86+
url := "https://api.github.com/repos/komodorio/helm-dashboard/releases/latest"
87+
type GHRelease struct {
88+
Name string `json:"name"`
89+
}
90+
91+
var myClient = &http.Client{Timeout: 5 * time.Second}
92+
r, err := myClient.Get(url)
93+
if err != nil {
94+
log.Warnf("Failed to check for new version: %s", err)
95+
return
96+
}
97+
defer r.Body.Close()
98+
99+
target := new(GHRelease)
100+
err = json.NewDecoder(r.Body).Decode(target)
101+
if err != nil {
102+
log.Warnf("Failed to decode new release version: %s", err)
103+
return
104+
}
105+
d.LatestVer = target.Name
106+
107+
v1, err := version.NewVersion(d.CurVer)
108+
if err != nil {
109+
log.Warnf("Failed to parse version: %s", err)
110+
v1 = &version.Version{}
111+
}
112+
113+
v2, err := version.NewVersion(d.LatestVer)
114+
if err != nil {
115+
log.Warnf("Failed to parse version: %s", err)
116+
} else {
117+
if v1.LessThan(v2) {
118+
log.Warnf("Newer Helm Dashboard version is available: %s", d.LatestVer)
119+
log.Warnf("Upgrade instructions: https://github.com/komodorio/helm-dashboard#installing")
120+
} else {
121+
log.Debugf("Got latest version from GH: %s", d.LatestVer)
122+
}
123+
}
124+
}

pkg/dashboard/static/datadog.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
})(window,document,'script','https://www.datadoghq-browser-agent.com/datadog-rum-v4.js','DD_RUM')
66
DD_RUM.onReady(function() {
77
const xhr = new XMLHttpRequest();
8-
xhr.onreadystatechange = function() {
9-
const version = xhr.responseText;
8+
xhr.onload = function() {
9+
const version = JSON.parse(xhr.responseText).VerCur;
1010
if (xhr.readyState === XMLHttpRequest.DONE && version!=="dev") {
1111
DD_RUM.init({
1212
clientToken: 'pub16d64cd1c00cf073ce85af914333bf72',

pkg/dashboard/static/index.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,11 @@ <h1><a href="/">Helm Dashboard</a></h1>
5454
<a class="nav-link px-3 section-repo">Repository</a>
5555
</li>
5656
<li class="nav-item dropdown">
57-
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"
57+
<a class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown"
5858
aria-expanded="false">
59+
<span class="position-absolute top-50 start-0 translate-middle p-1 bg-danger border border-light rounded-circle new-version-pill display-none">
60+
<span class="visually-hidden">New version</span>
61+
</span>
5962
Help
6063
</a>
6164
<ul class="dropdown-menu fs-80">
@@ -67,6 +70,13 @@ <h1><a href="/">Helm Dashboard</a></h1>
6770
<hr class="dropdown-divider">
6871
</li>
6972
<li><a class="dropdown-item disabled" href="#">Version <span id="toolVersion"></span></a></li>
73+
<li class="">
74+
<a class="dropdown-item position-relative" href="https://github.com/komodorio/helm-dashboard#installing" target="_blank">
75+
<span class="position-absolute top-50 start-0 translate-middle p-1 bg-danger border border-light rounded-circle new-version-pill display-none">
76+
<span class="visually-hidden">New version</span>
77+
</span>
78+
Upgrade to <span id="toolVersionUpgrade"></span>
79+
</a></li>
7080
</ul>
7181
</li>
7282

pkg/dashboard/static/scripts.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ $(function () {
2222
}
2323
})
2424

25-
$.get("/status").fail(function (xhr) {
25+
$.getJSON("/status").fail(function (xhr) {
2626
reportError("Failed to get tool version", xhr)
2727
}).done(function (data) {
2828
fillToolVersion(data)
@@ -51,18 +51,20 @@ function initView() {
5151
$("#topNav ul a").click(function () {
5252
const self = $(this)
5353

54+
if (self.hasClass("section-repo")) {
55+
setHashParam("section", "repository")
56+
} else if (self.hasClass("section-installed")) {
57+
setHashParam("section", null)
58+
} else {
59+
return
60+
}
61+
5462
$("#topNav ul a").removeClass("active")
5563

5664
const ctx = getHashParam("context")
5765
setHashParam(null, null)
5866
setHashParam("context", ctx)
5967

60-
if (self.hasClass("section-repo")) {
61-
setHashParam("section", "repository")
62-
} else {
63-
setHashParam("section", null)
64-
}
65-
6668
initView()
6769
})
6870

@@ -192,6 +194,14 @@ $(".bi-power").click(function () {
192194
})
193195

194196
function isNewerVersion(oldVer, newVer) {
197+
if (oldVer && oldVer[0] === 'v') {
198+
oldVer = oldVer.substring(1)
199+
}
200+
201+
if (newVer && newVer[0] === 'v') {
202+
newVer = newVer.substring(1)
203+
}
204+
195205
const oldParts = oldVer.split('.')
196206
const newParts = newVer.split('.')
197207
for (let i = 0; i < newParts.length; i++) {
@@ -204,5 +214,9 @@ function isNewerVersion(oldVer, newVer) {
204214
}
205215

206216
function fillToolVersion(data) {
207-
$("#toolVersion").append($('<a>' + data + '</a>'))
217+
$("#toolVersion").text(data.CurVer)
218+
if (isNewerVersion(data.CurVer, data.LatestVer)) {
219+
$("#toolVersionUpgrade").text(data.LatestVer)
220+
$(".new-version-pill").show()
221+
}
208222
}

pkg/dashboard/subproc/data.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ type DataLayer struct {
2525
Helm string
2626
Kubectl string
2727
Scanners []Scanner
28+
VersionInfo *VersionInfo
29+
}
30+
31+
type VersionInfo struct {
32+
CurVer string
33+
LatestVer string
2834
}
2935

3036
func (d *DataLayer) runCommand(cmd ...string) (string, error) {

0 commit comments

Comments
 (0)