mirror of
https://github.com/komodorio/helm-dashboard.git
synced 2026-03-24 11:48:04 +00:00
Bugfixes (#11)
* Don't offer rollback for the first revision * Fix the rollback bug * Cosmetics * Errors shown as alerts
This commit is contained in:
62
README.md
62
README.md
@@ -11,18 +11,22 @@ Prerequisites: `helm` and `kubectl` binaries installed and operational.
|
||||
Until we make our repo public, we have to use a custom way to install the plugin.
|
||||
|
||||
There is a need to build binary for plugin to function, run:
|
||||
|
||||
```shell
|
||||
go build -o bin/dashboard .
|
||||
```
|
||||
|
||||
To install, checkout the source code and run from source dir:
|
||||
|
||||
```shell
|
||||
helm plugin install .
|
||||
```
|
||||
|
||||
Local install of plugin just creates a symlink, so making the changes and rebuilding the binary would not require to reinstall a plugin.
|
||||
Local install of plugin just creates a symlink, so making the changes and rebuilding the binary would not require to
|
||||
reinstall a plugin.
|
||||
|
||||
To use the plugin, run in your terminal:
|
||||
|
||||
```shell
|
||||
helm dashboard
|
||||
```
|
||||
@@ -32,43 +36,51 @@ Then, use the web UI.
|
||||
## Uninstalling
|
||||
|
||||
To uninstall, run:
|
||||
|
||||
```shell
|
||||
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.
|
||||
We have two main channels for supporting the Helm Dashboard users: [Slack community](#TODO) for general conversations
|
||||
and [GitHub issues](https://github.com/komodorio/helm-dashboard/issues) for real bugs.
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Internal Milestone 1
|
||||
### First Public Version
|
||||
|
||||
- Helm Plugin Packaging
|
||||
- CLI launcher
|
||||
- Web Server with REST API
|
||||
|
||||
|
||||
### First Public Version
|
||||
Listing the installed applications
|
||||
View k8s resources created by the application (describe, status)
|
||||
Viewing revision history for application
|
||||
View manifest diffs between revisions, also changelogs etc
|
||||
Analytics reporting (telemetry)
|
||||
- Listing the installed applications
|
||||
- View k8s resources created by the application (describe, status)
|
||||
- Viewing revision history for application
|
||||
- View manifest diffs between revisions, also changelogs etc
|
||||
- Analytics reporting (telemetry)
|
||||
- Rollback to a revision
|
||||
- Check for repo updates & upgrade flow
|
||||
- Uninstalling the app completely
|
||||
- Switch clusters
|
||||
- Show manifest/describe upon clicking on resource
|
||||
|
||||
### Further Ideas
|
||||
Setting parameter values and installing
|
||||
Installing new app from repo
|
||||
Uninstalling the app completely
|
||||
Reconfiguring the application
|
||||
Rollback a revision
|
||||
- Have cleaner idea on the web API structure
|
||||
- Recognise & show ArgoCD-originating charts/objects, those `helm ls` does not show
|
||||
- Recognise the revisions that are rollbacks by their description and mark in timeline
|
||||
|
||||
Validate manifests before deploy and get better errors
|
||||
Switch clusters (?)
|
||||
Browsing repositories
|
||||
Adding new repository
|
||||
#### Topic "Validating Manifests"
|
||||
|
||||
Recognise & show ArgoCD-originating charts/objects
|
||||
Have cleaner idea on the web API structure
|
||||
See if we can build in Chechov or Validkube validation
|
||||
Show manifest/describe upon clicking on resource
|
||||
Recognise the revisions that are rollbacks by their description and mark in timeline
|
||||
- Validate manifests before deploy and get better errors
|
||||
- See if we can build in Chechov or Validkube validation
|
||||
|
||||
#### Iteration "Value Setting"
|
||||
|
||||
- Setting parameter values and installing
|
||||
- Reconfiguring the application
|
||||
|
||||
#### Iteration "Repo View"
|
||||
|
||||
- Browsing repositories
|
||||
- Adding new repository
|
||||
- Installing new app from repo
|
||||
|
||||
@@ -43,13 +43,12 @@ func NewRouter(abortWeb ControlChan, data *DataLayer) *gin.Engine {
|
||||
}
|
||||
|
||||
api.Use(contextSetter(data))
|
||||
api.Use(noCache)
|
||||
api.Use(errorHandler)
|
||||
|
||||
configureStatic(api)
|
||||
configureRoutes(abortWeb, data, api)
|
||||
|
||||
api.Use(noCache)
|
||||
api.Use(errorHandler)
|
||||
|
||||
return api
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ func (h *HelmHandler) Rollback(c *gin.Context) {
|
||||
_ = c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
c.Redirect(http.StatusOK, "/")
|
||||
c.Status(http.StatusAccepted)
|
||||
}
|
||||
|
||||
func (h *HelmHandler) History(c *gin.Context) {
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
</div>
|
||||
<h1><span class="name"></span>, revision <span class="rev"></span>
|
||||
<span class="float-end" id="actionButtons">
|
||||
<a id="btnUpgrade" class="opacity-10 btn btn-sm bg-secondary text-light bg-opacity-50 rounded-0 me-0 rounded-start ">Checking...</a><a id="btnUpgradeCheck" class="btn btn-sm text-muted btn-light border-secondary rounded-0 rounded-end ms-0" title="Check for newer chart version from repo"><i class="bi-repeat"></i><span class="spinner-border spinner-border-sm" style="display: none" role="status" aria-hidden="true"></span></a>
|
||||
<button id="btnUpgrade" class="opacity-10 btn btn-sm bg-secondary text-light bg-opacity-50 rounded-0 me-0 rounded-start ">Checking...</button><button id="btnUpgradeCheck" class="btn btn-sm text-muted btn-light border-secondary rounded-0 rounded-end ms-0" title="Check for newer chart version from repo"><i class="bi-repeat"></i><span class="spinner-border spinner-border-sm" style="display: none" role="status" aria-hidden="true"></span></button>
|
||||
|
||||
<a id="btnRollback" class="btn btn-sm bg-primary border border-secondary text-light" title="Rollback to this revision"><i class="bi-rewind-fill"></i> <span>Rollback</span></a>
|
||||
<a id="btnUninstall" class="btn btn-sm bg-danger border border-secondary text-light" title="Uninstall the chart"><i class="bi-trash-fill"></i> Uninstall</a>
|
||||
<button id="btnRollback" class="btn btn-sm bg-primary border border-secondary text-light" title="Rollback to this revision"><i class="bi-rewind-fill"></i> <span>Rollback</span></button>
|
||||
<button id="btnUninstall" class="btn btn-sm bg-danger border border-secondary text-light" title="Uninstall the chart"><i class="bi-trash-fill"></i> Uninstall</button>
|
||||
</span>
|
||||
</h1>
|
||||
Chart <b id="chartName"></b>: <i id="revDescr"></i>
|
||||
@@ -124,6 +124,13 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="errorAlert" class="display-none alert alert-sm alert-danger alert-dismissible position-absolute position-absolute top-0 start-50 translate-middle-x mt-3 border-danger" role="alert">
|
||||
<h4 class="alert-heading"><i class="bi-exclamation-triangle-fill"></i> <span></span></h4>
|
||||
<hr>
|
||||
<p style="white-space: pre-wrap"></p>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="describeModal"
|
||||
@@ -179,6 +186,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="text-center small mt-3">
|
||||
Brought to you by <img src="https://komodor.com/wp-content/uploads/2021/05/favicon.png" style="height: 1rem"> <a href="https://komodor.io">Komodor.io</a> |
|
||||
<i class="bi-github"></i>
|
||||
|
||||
@@ -2,8 +2,10 @@ const clusterSelect = $("#cluster");
|
||||
const chartsCards = $("#charts");
|
||||
const revRow = $("#sectionDetails .row");
|
||||
|
||||
function reportError(err) {
|
||||
alert(err) // TODO: nice modal/baloon/etc
|
||||
function reportError(err, xhr) {
|
||||
$("#errorAlert h4 span").text(err)
|
||||
$("#errorAlert p").text(xhr.responseText)
|
||||
$("#errorAlert").show()
|
||||
}
|
||||
|
||||
function revisionClicked(namespace, name, self) {
|
||||
@@ -20,11 +22,12 @@ function revisionClicked(namespace, name, self) {
|
||||
$("#revDescr").addClass("text-danger")
|
||||
}
|
||||
|
||||
if (false) { // TODO: hide if only one revision
|
||||
const rev = $("#specRev").data("last-rev") == elm.revision ? elm.revision - 1 : elm.revision
|
||||
console.log(rev, $("#specRev").data("first-rev"))
|
||||
if (!rev || getHashParam("revision") === $("#specRev").data("first-rev")) {
|
||||
$("#btnRollback").hide()
|
||||
} else {
|
||||
const rev = $("#specRev").data("last-rev") == elm.revision ? elm.revision - 1 : elm.revision
|
||||
$("#btnRollback").data("rev", rev).show().find("span").text("Rollback to #" + rev)
|
||||
$("#btnRollback").show().data("rev", rev).find("span").text("Rollback to #" + rev)
|
||||
}
|
||||
|
||||
const tab = getHashParam("tab")
|
||||
@@ -78,11 +81,14 @@ $("#userDefinedVals").change(function () {
|
||||
function loadContentWrapper() {
|
||||
let revDiff = 0
|
||||
const revision = parseInt(getHashParam("revision"));
|
||||
if (getHashParam("mode") === "diff-prev") {
|
||||
if (revision === $("#specRev").data("first-rev")) {
|
||||
revDiff = 0
|
||||
} else if (getHashParam("mode") === "diff-prev") {
|
||||
revDiff = revision - 1
|
||||
} else if (getHashParam("mode") === "diff-rev") {
|
||||
revDiff = $("#specRev").val()
|
||||
}
|
||||
|
||||
const flag = $("#userDefinedVals").prop("checked");
|
||||
loadContent(getHashParam("tab"), getHashParam("namespace"), getHashParam("chart"), revision, revDiff, flag)
|
||||
}
|
||||
@@ -139,6 +145,11 @@ function fillChartHistory(data, namespace, name) {
|
||||
for (let x = 0; x < data.length; x++) {
|
||||
const elm = data[x]
|
||||
$("#specRev").val(elm.revision).data("last-rev", elm.revision).data("last-chart-ver", elm.chart_ver)
|
||||
|
||||
if (!x) {
|
||||
$("#specRev").data("first-rev", elm.revision)
|
||||
}
|
||||
|
||||
const rev = $(`<div class="col-md-2 p-2 rounded border border-secondary bg-gradient bg-white">
|
||||
<span><b class="rev-number"></b> - <span class="rev-status"></span></span><br/>
|
||||
<span class="text-muted">Chart:</span> <span class="chart-ver"></span><br/>
|
||||
@@ -365,8 +376,8 @@ function buildChartCard(elm) {
|
||||
function loadChartsList() {
|
||||
$("#sectionList").show()
|
||||
chartsCards.empty().append("<div><span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span> Loading...</div>")
|
||||
$.getJSON("/api/helm/charts").fail(function () {
|
||||
reportError("Failed to get list of charts")
|
||||
$.getJSON("/api/helm/charts").fail(function (xhr) {
|
||||
reportError("Failed to get list of charts", xhr)
|
||||
}).done(function (data) {
|
||||
chartsCards.empty()
|
||||
data.forEach(function (elm) {
|
||||
@@ -558,8 +569,8 @@ $("#btnRollback").click(function () {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
}).fail(function () {
|
||||
reportError("Failed to rollback the chart")
|
||||
}).fail(function (xhr) {
|
||||
reportError("Failed to rollback the chart", xhr)
|
||||
}).done(function () {
|
||||
window.location.reload()
|
||||
})
|
||||
@@ -584,7 +595,11 @@ $("#btnRollback").click(function () {
|
||||
};
|
||||
const diff2htmlUi = new Diff2HtmlUI(targetElement, data, configuration);
|
||||
diff2htmlUi.draw()
|
||||
if (data) {
|
||||
$("#confirmModalBody").prepend("<p>Following changes will happen to cluster:</p>")
|
||||
} else {
|
||||
$("#confirmModalBody").html("<p>No changes will happen to cluster</p>")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user