diff --git a/ui/src/Components/SilenceModal/AlertManagerInput/index.js b/ui/src/Components/SilenceModal/AlertManagerInput/index.js
index 08adab106..4d5a5b581 100644
--- a/ui/src/Components/SilenceModal/AlertManagerInput/index.js
+++ b/ui/src/Components/SilenceModal/AlertManagerInput/index.js
@@ -7,16 +7,13 @@ import { observer } from "mobx-react";
import ReactSelect from "react-select";
import { AlertStore } from "Stores/AlertStore";
-import { SilenceFormStore } from "Stores/SilenceFormStore";
+import {
+ SilenceFormStore,
+ AlertmanagerClustersToOption
+} from "Stores/SilenceFormStore";
import { MultiSelect, ReactSelectStyles } from "Components/MultiSelect";
import { ValidationError } from "Components/MultiSelect/ValidationError";
-const AlertmanagerClustersToOption = clusterDict =>
- Object.entries(clusterDict).map(([clusterID, clusterMembers]) => ({
- label: clusterMembers.join(" | "),
- value: clusterMembers
- }));
-
const AlertManagerInput = observer(
class AlertManagerInput extends MultiSelect {
static propTypes = {
@@ -77,6 +74,7 @@ const AlertManagerInput = observer(
options={AlertmanagerClustersToOption(
alertStore.data.upstreams.clusters
)}
+ getOptionValue={JSON.stringify}
placeholder={
silenceFormStore.data.wasValidated ? (
diff --git a/ui/src/Components/SilenceModal/SilenceForm.test.js b/ui/src/Components/SilenceModal/SilenceForm.test.js
index 1927b6a50..ca7cbc67c 100644
--- a/ui/src/Components/SilenceModal/SilenceForm.test.js
+++ b/ui/src/Components/SilenceModal/SilenceForm.test.js
@@ -167,9 +167,7 @@ describe("", () => {
matcher.name = "job";
matcher.values = [{ label: "node_exporter", value: "node_exporter" }];
silenceFormStore.data.matchers = [matcher];
- silenceFormStore.data.alertmanagers = [
- { label: "am1", value: "http://example.com" }
- ];
+ silenceFormStore.data.alertmanagers = [{ label: "am1", value: ["am1"] }];
silenceFormStore.data.author = "me@example.com";
silenceFormStore.data.comment = "fake silence";
const tree = ShallowSilenceForm();
diff --git a/ui/src/Components/SilenceModal/SilencePreview/index.test.js b/ui/src/Components/SilenceModal/SilencePreview/index.test.js
index 9288082bc..5b4d278c6 100644
--- a/ui/src/Components/SilenceModal/SilencePreview/index.test.js
+++ b/ui/src/Components/SilenceModal/SilencePreview/index.test.js
@@ -75,6 +75,34 @@ describe("", () => {
expect(fetch).toHaveBeenCalled();
});
+ it("fetch uses correct filters with single Alertmanager instance", async () => {
+ fetch.mockResponse(JSON.stringify(MockAPIResponse()));
+ silenceFormStore.data.alertmanagers = [
+ { label: "amName", value: ["amValue"] }
+ ];
+
+ const tree = MountedSilencePreview();
+ await expect(tree.instance().matchedAlerts.fetch).resolves.toBeUndefined();
+ expect(fetch).toHaveBeenCalledWith(
+ "./alerts.json?q=foo%3Dbar&q=%40alertmanager%3D~%5E%28amValue%29%24",
+ { credentials: "include" }
+ );
+ });
+
+ it("fetch uses correct filters with multiple Alertmanager instances", async () => {
+ fetch.mockResponse(JSON.stringify(MockAPIResponse()));
+ silenceFormStore.data.alertmanagers = [
+ { label: "cluster", value: ["am1", "am2"] }
+ ];
+
+ const tree = MountedSilencePreview();
+ await expect(tree.instance().matchedAlerts.fetch).resolves.toBeUndefined();
+ expect(fetch).toHaveBeenCalledWith(
+ "./alerts.json?q=foo%3Dbar&q=%40alertmanager%3D~%5E%28am1%7Cam2%29%24",
+ { credentials: "include" }
+ );
+ });
+
it("matches snapshot", async () => {
fetch.mockResponse(JSON.stringify(MockAPIResponse()));
diff --git a/ui/src/Stores/SilenceFormStore.js b/ui/src/Stores/SilenceFormStore.js
index 76ca3a5ed..5bb676945 100644
--- a/ui/src/Stores/SilenceFormStore.js
+++ b/ui/src/Stores/SilenceFormStore.js
@@ -19,6 +19,12 @@ const NewEmptyMatcher = () => {
const MatcherValueToObject = value => ({ label: value, value: value });
+const AlertmanagerClustersToOption = clusterDict =>
+ Object.entries(clusterDict).map(([clusterID, clusterMembers]) => ({
+ label: clusterMembers.join(" | "),
+ value: clusterMembers
+ }));
+
const SilenceFormStage = Object.freeze({
UserInput: "form",
Preview: "preview",
@@ -155,12 +161,10 @@ class SilenceFormStore {
fillFormFromSilence(alertmanager, silence) {
this.silenceID = silence.id;
- this.alertmanagers = [
- {
- label: alertmanager.name,
- value: alertmanager.publicURI
- }
- ];
+
+ this.alertmanagers = AlertmanagerClustersToOption({
+ [alertmanager.cluster]: alertmanager.clusterMembers
+ });
const matchers = [];
for (const m of silence.matchers) {
@@ -214,8 +218,8 @@ class SilenceFormStore {
m.values.length > 1
? `(${m.values.map(v => v.value).join("|")})`
: m.values.length === 1
- ? m.values[0].value
- : "",
+ ? m.values[0].value
+ : "",
isRegex: m.isRegex
})),
startsAt: this.startsAt
@@ -270,5 +274,6 @@ export {
SilenceFormStore,
SilenceFormStage,
NewEmptyMatcher,
- MatcherValueToObject
+ MatcherValueToObject,
+ AlertmanagerClustersToOption
};
diff --git a/ui/src/Stores/SilenceFormStore.test.js b/ui/src/Stores/SilenceFormStore.test.js
index ea1b52e15..44b9195bc 100644
--- a/ui/src/Stores/SilenceFormStore.test.js
+++ b/ui/src/Stores/SilenceFormStore.test.js
@@ -31,7 +31,7 @@ const MockGroup = () => {
const MockAlertmanagerOption = () => ({
label: "default",
- value: "http://localhost"
+ value: ["default"]
});
const MockMatcher = (name, values) => {
@@ -209,7 +209,7 @@ describe("SilenceFormStore.data", () => {
expect(store.data.alertmanagers).toHaveLength(1);
expect(store.data.alertmanagers[0]).toMatchObject({
label: alertmanager.name,
- value: alertmanager.publicURI
+ value: [alertmanager.name]
});
expect(store.data.matchers).toHaveLength(2);