Skip to content

Commit

Permalink
Add option to execute Tests for release (#178)
Browse files Browse the repository at this point in the history
* Add button to execute tests

* Create API to execute tests

* Add modal for Test response

* Make API call to execute tests and show response in modal

* Clean up

* Update docs - feature execute tests for a release

* Add arg '--logs' to 'helm test' cmd

* Wait for API to complete before sending back response to frontend

* Add loading spinner until reponse for 'helm test' is returned from backend by API

* Clean-up

Co-authored-by: Harshit Mehta <harshitm@nvidia.com>
  • Loading branch information
harshit-mehtaa and Harshit Mehta committed Jan 12, 2023
1 parent af1c09a commit 83e4348
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ The official helm chart is [available here](https://github.com/komodorio/helm-ch

Download the appropriate [release package](https://github.com/komodorio/helm-dashboard/releases) for your platform, unpack it and just run `dashboard` binary from it.

## Execute Helm tests

For all the release(s) (istalled helm charts), you can execute helm tests for that release. For the tests to execute successfully, you need to have existing tests for that helm chart

You can execute `helm test` for the specific release as below:
![](screenshot_run_test.png)

The result of executed `helm test` for the release will be disapled as below:
![](screenshot_run_test_result.png)

## Scanner Integrations

Upon startup, Helm Dashboard detects the presence of [Trivy](https://github.com/aquasecurity/trivy)
Expand Down
1 change: 1 addition & 0 deletions pkg/dashboard/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func configureHelms(api *gin.RouterGroup, data *subproc.DataLayer) {
api.GET("/charts/:section", h.GetInfoSection)
api.GET("/charts/show", h.Show)
api.POST("/charts/install", h.Install)
api.POST("/charts/tests", h.Tests)
api.POST("/charts/rollback", h.Rollback)

api.GET("/repo", h.RepoList)
Expand Down
16 changes: 16 additions & 0 deletions pkg/dashboard/handlers/helmHandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ func (h *HelmHandler) Install(c *gin.Context) {
c.String(http.StatusAccepted, out)
}

func (h *HelmHandler) Tests(c *gin.Context) {
qp, err := utils.GetQueryProps(c, false)
if err != nil {
_ = c.AbortWithError(http.StatusBadRequest, err)
return
}

out, err := h.Data.RunTests(qp.Namespace, qp.Name)
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}

c.String(http.StatusOK, out)
}

func (h *HelmHandler) GetInfoSection(c *gin.Context) {
qp, err := utils.GetQueryProps(c, true)
if err != nil {
Expand Down
15 changes: 15 additions & 0 deletions pkg/dashboard/static/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,18 @@ $("#btnAddRepository").click(function () {
setHashParam("section", "repository")
window.location.reload()
})

$("#btnTest").click(function() {
$("#testModal .test-result").empty().prepend('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
$.ajax({
type: 'POST',
url: "/api/helm/charts/tests" + "?namespace=" + getHashParam("namespace") + "&name=" + getHashParam("chart")
}).fail(function (xhr) {
reportError("Failed to execute test for chart", xhr)
}).done(function (data) {
$("#testModal .test-result").empty().html(data.replaceAll("\n", "<br>"))
})

const myModal = new bootstrap.Modal(document.getElementById('testModal'), {});
myModal.show()
})
23 changes: 23 additions & 0 deletions pkg/dashboard/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ <h1 class="name float-start">Name</h1>
<button id="btnRollback" class="btn btn-sm btn-light bg-white border border-secondary me-2"
title="Rollback to this revision"><i class="bi-arrow-repeat"></i> <span>Rollback</span>
</button>
<button id="btnTest" class="btn btn-sm btn-light bg-white border border-secondary"
title="Run tests for this chart"><i class="bi-check-circle"></i> <span>Run tests</span>
</button>
<button id="btnUninstall" class="btn btn-sm btn-light bg-white border border-secondary"
title="Uninstall the chart"><i class="bi-trash3"></i> Uninstall
</button>
Expand Down Expand Up @@ -417,6 +420,26 @@ <h4 class="modal-title" id="upgradeModalLabel">
</div>
</div>

<div class="modal" id="testModal" tabindex="-1">
<div class="modal-dialog modal-dialog modal-dialog-scrollable modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="testModalLabel">
<span class="type">Test results</span>
</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body border-bottom fs-5">
<div class="row">
<div class="col">
<span class="test-result"></span>
</div>
</div>
</div>
</div>
</div>
</div>

<!-- Modal -->
<div class="modal fade" id="PowerOffModal" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true">
<div class="modal-dialog">
Expand Down
4 changes: 4 additions & 0 deletions pkg/dashboard/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,8 @@ nav .nav-tabs .nav-link.active {

#sectionRepo .repo-details ul .row:hover .btn {
visibility: visible;
}

.test-result {
font-size: 1rem;
}
11 changes: 11 additions & 0 deletions pkg/dashboard/subproc/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,17 @@ func (d *DataLayer) ChartInstall(namespace string, name string, repoChart string
return out, nil
}

func (d *DataLayer) RunTests(namespace string, name string) (string, error) {
cmd := []string{"test", name, "--namespace", namespace, "--logs"}

out, err := d.runCommandHelm(cmd...)
if err != nil {
return "", err
}

return out, nil
}

func RevisionDiff(functor SectionFn, ext string, namespace string, name string, revision1 int, revision2 int, flag bool) (string, error) {
if revision1 == 0 || revision2 == 0 {
log.Debugf("One of revisions is zero: %d %d", revision1, revision2)
Expand Down
Binary file added screenshot_run_test.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshot_run_test_result.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 83e4348

Please sign in to comment.