Display resource health aggregate icons on list of releases (#235)

* Display aggregate resource health status

* Reuse old API request, show icons

* Take progress indication from deployment conditions

* Improve status

* Cleanup

* Fixups

* Squares approach
This commit is contained in:
Andrey Pokhilko
2023-03-13 12:56:31 +00:00
committed by GitHub
parent 47dae4d35a
commit 57d4d073e9
7 changed files with 175 additions and 51 deletions

View File

@@ -149,7 +149,7 @@ function showResources(namespace, chart, revision) {
const resBody = $("#nav-resources .body");
const interestingResources = ["STATEFULSET", "DEAMONSET", "DEPLOYMENT"];
resBody.empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>');
let url = "/api/helm/releases/" + namespace + "/" + chart + "/resources"
let url = "/api/helm/releases/" + namespace + "/" + chart + "/resources?health=true"
$.getJSON(url).fail(function (xhr) {
reportError("Failed to get list of resources", xhr)
}).done(function (data) {
@@ -180,22 +180,29 @@ function showResources(namespace, chart, revision) {
resBody.append(resBlock)
let ns = res.metadata.namespace ? res.metadata.namespace : namespace
$.getJSON("/api/k8s/" + res.kind.toLowerCase() + "/get?name=" + res.metadata.name + "&namespace=" + ns).fail(function () {
//reportError("Failed to get list of resources")
}).done(function (data) {
const badge = $("<span class='badge me-2 fw-normal'></span>").text(data.status.phase);
if (["Available", "Active", "Established", "Bound", "Ready"].includes(data.status.phase)) {
for (let k = 0; k < res.status.conditions.length; k++) {
if (res.status.conditions[k].type !== "hdHealth") { // it's our custom condition type
continue
}
const cond = res.status.conditions[k]
const badge = $("<span class='badge me-2 fw-normal'></span>").text(cond.reason);
if (cond.status === "Healthy") {
badge.addClass("bg-success text-dark")
} else if (["Exists"].includes(data.status.phase)) {
badge.addClass("bg-success text-dark bg-opacity-50")
} else if (["Progressing"].includes(data.status.phase)) {
} else if (cond.status === "Progressing") {
badge.addClass("bg-warning")
} else {
badge.addClass("bg-danger")
}
if (["Exists"].includes(cond.reason)) {
badge.addClass("bg-opacity-50")
}
const statusBlock = resBlock.find(".res-status");
statusBlock.empty().append(badge).attr("title", data.status.phase)
const statusMessage = getStatusMessage(data.status)
statusBlock.empty().append(badge).attr("title", cond.reason)
const statusMessage = cond.message
resBlock.find(".res-statusmsg").html("<span class='text-muted small me-2'>" + (statusMessage ? statusMessage : '') + "</span>")
if (badge.text() !== "NotFound" && revision == $("#specRev").data("last-rev")) {
@@ -219,21 +226,11 @@ function showResources(namespace, chart, revision) {
if (badge.hasClass("bg-danger")) {
resBlock.find(".res-statusmsg").append("<a href='" + KomodorCTALink + "' class='btn btn-primary btn-sm fw-normal fs-80' target='_blank'>Troubleshoot in Komodor <i class='bi-box-arrow-up-right'></i></a>")
}
})
}
}
})
}
function getStatusMessage(status) {
if (!status) {
return
}
if (status.conditions) {
return status.conditions[0].message || status.conditions[0].reason
}
return status.message || status.reason
}
function showDescribe(ns, kind, name, badge) {
$("#describeModal .offcanvas-header p").text(kind)
$("#describeModalLabel").text(name).append(badge.addClass("ms-3 small fw-normal"))

View File

@@ -93,7 +93,7 @@ function buildChartCard(elm) {
if (data[0].isSuggestedRepo) {
icon.addClass("bi-plus-circle-fill text-primary")
icon.text(" ADD REPO")
icon.attr("data-bs-title", "Add '" + data[0].repository+"' to list of known repositories")
icon.attr("data-bs-title", "Add '" + data[0].repository + "' to list of known repositories")
} else {
icon.addClass("bi-arrow-up-circle-fill text-primary")
icon.text(" UPGRADE")
@@ -101,12 +101,41 @@ function buildChartCard(elm) {
}
card.find(".rel-chart div").append(icon)
const tooltipTriggerList = card.find('[data-bs-toggle="tooltip"]')
const tooltipTriggerList = card.find('.rel-chart [data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
sendStats('upgradeIconShown', {'isProbable': data[0].isSuggestedRepo})
}
})
// check resource health status
$.getJSON("/api/helm/releases/" + elm.namespace + "/" + elm.name + "/resources?health=true").fail(function (xhr) {
reportError("Failed to find chart in repo", xhr)
}).done(function (data) {
for (let i = 0; i < data.length; i++) {
const res = data[i]
for (let k = 0; k < res.status.conditions.length; k++) {
if (res.status.conditions[k].type !== "hdHealth") { // it's our custom condition type
continue
}
const cond = res.status.conditions[k]
const square=$("<span class='me-1 mb-1 square rounded rounded-1' data-bs-toggle='tooltip'>&nbsp;</span>")
if (cond.status === "Healthy") {
square.addClass("bg-success")
} else if (cond.status === "Progressing") {
square.addClass("bg-warning")
} else {
square.addClass("bg-danger")
}
square.attr("data-bs-title", cond.status+" "+res.kind+" '"+res.metadata.name+"'")
card.find(".rel-status div").append(square)
}
}
const tooltipTriggerList = card.find('.rel-status [data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
})
return card;
}

View File

@@ -302,6 +302,11 @@
"name": "name",
"in": "path",
"description": "Name of Helm release"
},
{
"name": "health",
"in": "query",
"description": "Flag to query k8s health status of resources"
}
],
"get": {

View File

@@ -300,4 +300,23 @@ nav .nav-tabs .nav-link.active {
.test-result {
font-size: 1rem;
}
.square {
width: 0.55rem;
height: 0.55rem;
display: inline-block;
border-radius: 0.1rem!important;
}
.square.bg-danger {
background-color: #ff0072!important;
}
.square.bg-warning {
background-color: #ffa800!important;
}
.square.bg-success {
background-color: #00c2ab!important;
}