mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
Update silence form to work with multiple Alertmanager instances
This commit is contained in:
@@ -27,7 +27,7 @@ var Silence = (function() {
|
||||
if ($("#endsAt").data("DateTimePicker")) {
|
||||
payload.endsAt = $("#endsAt").data("DateTimePicker").date();
|
||||
}
|
||||
$.each($("#newSilenceForm .selectpicker"), function(i, elem) {
|
||||
$.each($("#newSilenceForm select.silence-label-picker"), function(i, elem) {
|
||||
var labelKey = $(elem).data("label-key");
|
||||
var values = $(elem).selectpicker("val");
|
||||
if (values && values.length > 0) {
|
||||
@@ -74,8 +74,12 @@ var Silence = (function() {
|
||||
$("#silence-end-description").html(endsAtDesc);
|
||||
};
|
||||
|
||||
var silenceFormAlertmanagerURL = function() {
|
||||
return $("#newSilenceForm .silence-alertmanager-picker").selectpicker("val");
|
||||
};
|
||||
|
||||
var silenceFormJSONRender = function() {
|
||||
var d = "curl " + $("#silenceModal").data("silence-api") +
|
||||
var d = "curl $AlertmanagerURI" +
|
||||
"\n -X POST --data " +
|
||||
JSON.stringify(silenceFormData(), undefined, 2);
|
||||
$("#silenceJSONBlob").html(d);
|
||||
@@ -127,6 +131,47 @@ var Silence = (function() {
|
||||
silenceFormCalculateDuration();
|
||||
};
|
||||
|
||||
var sendSilencePOST = function(url, payload) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify(payload),
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
// default to whatever error text we can get
|
||||
var err = xhr.responseText || errorThrown || textStatus;
|
||||
if (xhr.responseText) {
|
||||
// if we have a reponse text try to decode it as JSON
|
||||
// it should be error from Alertmanager (it we were able to connect)
|
||||
try {
|
||||
var j = JSON.parse(xhr.responseText);
|
||||
if (j.error !== undefined) {
|
||||
err = j.error;
|
||||
}
|
||||
} catch (error) {
|
||||
// can't parse json, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
var errContent = Templates.Render("silenceFormError", {error: err});
|
||||
$("#newSilenceAlert").html(errContent).removeClass("hidden");
|
||||
},
|
||||
success: function(data) {
|
||||
// FIXME this is per instance now, so needs to be handled differently
|
||||
if (data.status == "success") {
|
||||
$("#newSilenceAlert").addClass("hidden");
|
||||
$("#newSilenceForm").html(Templates.Render("silenceFormSuccess", {
|
||||
silenceID: data.data.silenceId
|
||||
}));
|
||||
} else {
|
||||
var err = "Invalid response from Alertmanager API: " + JSON.stringify(data);
|
||||
var errContent = Templates.Render("silenceFormError", {error: err});
|
||||
$("#newSilenceAlert").html(errContent).removeClass("hidden");
|
||||
}
|
||||
},
|
||||
dataType: "json"
|
||||
});
|
||||
};
|
||||
|
||||
// modal form for creating new silences
|
||||
var setupSilenceForm = function() {
|
||||
var modal = $("#silenceModal");
|
||||
@@ -151,6 +196,7 @@ var Silence = (function() {
|
||||
success: function(data) {
|
||||
var modal = $("#silenceModal");
|
||||
var labels = {};
|
||||
var alertmanagers = {};
|
||||
$.each(data.groups, function(i, group) {
|
||||
$.each(group.alerts, function(j, alert) {
|
||||
$.each(alert.labels, function(labelKey, labelVal) {
|
||||
@@ -166,21 +212,24 @@ var Silence = (function() {
|
||||
};
|
||||
}
|
||||
});
|
||||
$.each(alert.alertmanager, function(i, alertmanager){
|
||||
alertmanagers[alertmanager.name] = alertmanager;
|
||||
});
|
||||
});
|
||||
});
|
||||
modal.find(".modal-body").html(
|
||||
Templates.Render("silenceForm", {labels: labels})
|
||||
Templates.Render("silenceForm", {
|
||||
labels: labels,
|
||||
alertmanagers: alertmanagers,
|
||||
selectedAlertmanagers: elem.data("alertmanagers").split(",")
|
||||
})
|
||||
);
|
||||
$.each($(".selectpicker"), function(i, elem) {
|
||||
$.each($(".silence-alertmanager-picker"), function(i, elem) {
|
||||
$(elem).selectpicker();
|
||||
});
|
||||
$.each($(".silence-label-picker"), function(i, elem) {
|
||||
$(elem).selectpicker({
|
||||
iconBase: "fa",
|
||||
tickIcon: "fa-check",
|
||||
width: "fit",
|
||||
selectAllText: "<i class='fa fa-check-square-o'></i>",
|
||||
deselectAllText: "<i class='fa fa-square-o'></i>",
|
||||
noneSelectedText: "<span class='label label-list label-default'>" + $(this).data("label-key") + ": </span>",
|
||||
multipleSeparator: " ",
|
||||
selectedTextFormat: "count > 1",
|
||||
countSelectedText: function (numSelected) {
|
||||
return "<span class='label label-list label-warning'>" +
|
||||
$(elem).data("label-key") + ": " + numSelected + " values selected</span>";
|
||||
@@ -244,43 +293,8 @@ var Silence = (function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
var url = modal.data("silence-api");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify(payload),
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
// default to whatever error text we can get
|
||||
var err = xhr.responseText || errorThrown || textStatus;
|
||||
if (xhr.responseText) {
|
||||
// if we have a reponse text try to decode it as JSON
|
||||
// it should be error from Alertmanager (it we were able to connect)
|
||||
try {
|
||||
var j = JSON.parse(xhr.responseText);
|
||||
if (j.error !== undefined) {
|
||||
err = j.error;
|
||||
}
|
||||
} catch (error) {
|
||||
// can't parse json, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
var errContent = Templates.Render("silenceFormError", {error: err});
|
||||
$("#newSilenceAlert").html(errContent).removeClass("hidden");
|
||||
},
|
||||
success: function(data) {
|
||||
if (data.status == "success") {
|
||||
$("#newSilenceAlert").addClass("hidden");
|
||||
$("#newSilenceForm").html(Templates.Render("silenceFormSuccess", {
|
||||
silenceID: data.data.silenceId
|
||||
}));
|
||||
} else {
|
||||
var err = "Invalid response from Alertmanager API: " + JSON.stringify(data);
|
||||
var errContent = Templates.Render("silenceFormError", {error: err});
|
||||
$("#newSilenceAlert").html(errContent).removeClass("hidden");
|
||||
}
|
||||
},
|
||||
dataType: "json"
|
||||
$.each(silenceFormAlertmanagerURL(), function(i, uri){
|
||||
sendSilencePOST(uri, payload);
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
@@ -79,12 +79,18 @@
|
||||
<%= Templates.Render('buttonLabel', {elem: 'span', attrs: attrs, label: {key: '@state', value: alert.state, text: '@state: ' + alert.state}}) %>
|
||||
<% if (alert.silencedBy.length == 0) { %>
|
||||
<% var labels = [] %>
|
||||
<% var alertmanagers = [] %>
|
||||
<% _.each(Alerts.SortMapByKey(alert.labels), function(label) { %>
|
||||
<% labels.push(label.key + '=' + label.value) %>
|
||||
<% }) %>
|
||||
<% _.each(alert.alertmanager, function(alertmanager){ %>
|
||||
<% alertmanagers.push(alertmanager.name) %>
|
||||
<% }) %>
|
||||
<% alertmanagers.sort() %>
|
||||
<span class="label label-list label-success cursor-pointer"
|
||||
type="button"
|
||||
data-labels="<%= labels.join(',') %>"
|
||||
data-alertmanagers="<%= alertmanagers.join(',') %>"
|
||||
data-alertname="<%= alert.labels.alertname %>"
|
||||
data-toggle="modal"
|
||||
data-target="#silenceModal">
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="silenceModal" tabindex="-1" role="dialog" data-silence-api="{{ .SilencesApi }}">
|
||||
<div class="modal fade" id="silenceModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header text-center">
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
<script type="application/json" id="silence-form">
|
||||
<div id="newSilenceAlert" class="alert alert-danger hidden" role="alert"></div>
|
||||
<form id="newSilenceForm">
|
||||
<div>
|
||||
<label class="control-label">Alertmanager</label>
|
||||
<select class="selectpicker silence-alertmanager-picker"
|
||||
data-style="silence-label-select"
|
||||
data-icon-base="fa"
|
||||
data-tick-icon="fa-check"
|
||||
data-width="fit"
|
||||
data-select-all-text="<i class='fa fa-check-square-o'></i>"
|
||||
data-deselect-all-text="<i class='fa fa-square-o'></i>"
|
||||
data-multiple-separator=" "
|
||||
<% if (Object.keys(alertmanagers).length > 1) { %>data-actions-box="true"<% } %>
|
||||
multiple
|
||||
required>
|
||||
<% _.each(alertmanagers, function(am) { %>
|
||||
<option <% if (_.contains(selectedAlertmanagers, am.name)) { %>selected="selected"<% } %>
|
||||
value="<%= am.uri %>"
|
||||
data-content="<span class='label label-list label-primary'><%- am.name %></span>">
|
||||
<%- am.name %>
|
||||
</option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="control-label">Labels to match</label>
|
||||
<table class="table table-condensed silence-label-selects">
|
||||
<% if (Object.keys(labels).length > 0) { %>
|
||||
@@ -15,6 +38,13 @@
|
||||
<select class="selectpicker silence-label-picker"
|
||||
data-label-key="<%= label.key %>"
|
||||
data-style="silence-label-select"
|
||||
data-icon-base="fa"
|
||||
data-tick-icon="fa-check"
|
||||
data-width="fit"
|
||||
data-select-all-text="<i class='fa fa-check-square-o'></i>"
|
||||
data-deselect-all-text="<i class='fa fa-square-o'></i>"
|
||||
data-multiple-separator=" "
|
||||
data-selected-text-format="count > 1"
|
||||
<% if (Object.keys(label.value).length > 10) { %>data-live-search="true"<% } %>
|
||||
<% if (Object.keys(label.value).length > 1) { %>data-actions-box="true"<% } %>
|
||||
multiple>
|
||||
|
||||
File diff suppressed because one or more lines are too long
7
views.go
7
views.go
@@ -39,12 +39,6 @@ func index(c *gin.Context) {
|
||||
defaultUsed = false
|
||||
}
|
||||
|
||||
// FIXME
|
||||
//silencesAPI, err := transport.JoinURL(config.Config.AlertmanagerURI, "api/v1/silences")
|
||||
//if err != nil {
|
||||
// log.Errorf("Can't generate silences API URL: %s", err)
|
||||
//}
|
||||
|
||||
c.HTML(http.StatusOK, "templates/index.html", gin.H{
|
||||
"Version": version,
|
||||
"SentryDSN": config.Config.SentryPublicDSN,
|
||||
@@ -56,7 +50,6 @@ func index(c *gin.Context) {
|
||||
"DefaultUsed": defaultUsed,
|
||||
"StaticColorLabels": strings.Join(config.Config.ColorLabelsStatic, " "),
|
||||
"WebPrefix": config.Config.WebPrefix,
|
||||
"SilencesApi": "FIXME",
|
||||
})
|
||||
|
||||
log.Infof("[%s] %s %s took %s", c.ClientIP(), c.Request.Method, c.Request.RequestURI, time.Since(start))
|
||||
|
||||
Reference in New Issue
Block a user