diff --git a/ui/package-lock.json b/ui/package-lock.json
index 50c96fdb6..b4c9b6f84 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -20942,7 +20942,8 @@
"semver": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz",
- "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA=="
+ "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==",
+ "dev": true
},
"send": {
"version": "0.17.1",
diff --git a/ui/package.json b/ui/package.json
index 6aaa62a97..d4c7f311e 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -56,7 +56,6 @@
"react-select": "3.0.8",
"react-tippy": "1.3.4",
"react-transition-group": "4.3.0",
- "semver": "7.1.3",
"typeface-open-sans": "0.0.75",
"typescript": "3.7.5"
},
diff --git a/ui/src/Components/AlertAck/index.js b/ui/src/Components/AlertAck/index.js
index 4f6839bc5..657682e6b 100644
--- a/ui/src/Components/AlertAck/index.js
+++ b/ui/src/Components/AlertAck/index.js
@@ -6,8 +6,6 @@ import { observer } from "mobx-react";
import moment from "moment";
-import satisfies from "semver/functions/satisfies";
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck } from "@fortawesome/free-solid-svg-icons/faCheck";
import { faCheckCircle } from "@fortawesome/free-solid-svg-icons/faCheckCircle";
@@ -142,38 +140,23 @@ const AlertAck = observer(
return;
}
- const isOpenAPI = satisfies(am.version, ">=0.16.0");
-
- const uri = isOpenAPI
- ? `${am.uri}/api/v2/silences`
- : `${am.uri}/api/v1/silences`;
-
- this.submitState.silencesByCluster[cluster].fetch = FetchPost(uri, {
- body: JSON.stringify(
- this.submitState.silencesByCluster[cluster].payload
- ),
- headers: {
- "Content-Type": "application/json",
- ...am.headers
+ this.submitState.silencesByCluster[cluster].fetch = FetchPost(
+ `${am.uri}/api/v2/silences`,
+ {
+ body: JSON.stringify(
+ this.submitState.silencesByCluster[cluster].payload
+ ),
+ headers: {
+ "Content-Type": "application/json",
+ ...am.headers
+ }
}
- })
+ )
.then(result => {
- if (isOpenAPI) {
- if (result.ok) {
- return result
- .json()
- .then(r => this.submitState.markDone(cluster));
- } else {
- this.maybeTryAgainAfterError(cluster);
- }
+ if (result.ok) {
+ return result.json().then(r => this.submitState.markDone(cluster));
} else {
- return result
- .json()
- .then(r =>
- r.status === "success"
- ? this.submitState.markDone(cluster)
- : this.maybeTryAgainAfterError(cluster)
- );
+ this.maybeTryAgainAfterError(cluster);
}
})
.catch(() => {
diff --git a/ui/src/Components/AlertAck/index.test.js b/ui/src/Components/AlertAck/index.test.js
index 98b33af45..03e20c8b0 100644
--- a/ui/src/Components/AlertAck/index.test.js
+++ b/ui/src/Components/AlertAck/index.test.js
@@ -38,7 +38,7 @@ beforeEach(() => {
readonly: false,
headers: { foo: "bar" },
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default"]
}
@@ -102,22 +102,8 @@ describe("", () => {
expect(toDiffableHtml(tree.html())).toMatch(/fa-exclamation-circle/);
});
- it("[v1] uses faCheckCircle after successful fetch", async () => {
- fetch.mockResponse(
- JSON.stringify({ status: "success", data: { silenceId: "123456789" } })
- );
- const tree = MountedAlertAck();
- const button = tree.find("span.badge");
- button.simulate("click");
- await expect(
- tree.instance().submitState.silencesByCluster["default"].fetch
- ).resolves.toBeUndefined();
- expect(toDiffableHtml(tree.html())).toMatch(/fa-check-circle/);
- });
-
- it("[v2] uses faCheckCircle after successful fetch", async () => {
+ it("uses faCheckCircle after successful fetch", async () => {
fetch.mockResponse(JSON.stringify({ silenceID: "123" }));
- alertStore.data.upstreams.instances[0].version = "0.16.2";
const tree = MountedAlertAck();
const button = tree.find("span.badge");
button.simulate("click");
@@ -166,9 +152,7 @@ describe("", () => {
});
it("sends correct payload", () => {
- fetch.mockResponse(
- JSON.stringify({ status: "success", data: { silenceId: "123456789" } })
- );
+ fetch.mockResponse(JSON.stringify({ silenceID: "123456789" }));
silenceFormStore.data.author = "karma/ui";
MountAndClick();
@@ -262,71 +246,13 @@ describe("", () => {
});
});
- it("[v1] sends POST request to /api/v1/silences", () => {
- MountAndClick();
- const uri = fetch.mock.calls[0][0];
- expect(uri).toBe("http://localhost/api/v1/silences");
- });
-
- it("[v2] sends POST request to /api/v2/silences", () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
+ it("sends POST request to /api/v2/silences", () => {
MountAndClick();
const uri = fetch.mock.calls[0][0];
expect(uri).toBe("http://localhost/api/v2/silences");
});
- it("[v1] will retry on another cluster member after fetch failure", async () => {
- fetch
- .mockResponseOnce(JSON.stringify({ status: "error" }))
- .mockResponseOnce(
- JSON.stringify({ status: "success", data: { silenceId: "123456789" } })
- );
- alertStore.data.upstreams = {
- clusters: { default: ["default", "fallback"] },
- instances: [
- {
- name: "default",
- uri: "http://am1.example.com",
- publicURI: "http://am1.example.com",
- readonly: false,
- headers: {},
- error: "",
- version: "0.15.0",
- cluster: "default",
- clusterMembers: ["default", "fallback"]
- },
- {
- name: "fallback",
- uri: "http://am2.example.com",
- publicURI: "http://am2.example.com",
- readonly: false,
- headers: {},
- error: "",
- version: "0.15.0",
- cluster: "default",
- clusterMembers: ["default", "fallback"]
- }
- ]
- };
-
- const tree = MountedAlertAck();
- const button = tree.find("span.badge");
- button.simulate("click");
- await expect(
- tree.instance().submitState.silencesByCluster["default"].fetch
- ).resolves.toBeUndefined();
- expect(fetch.mock.calls[0][0]).toBe(
- "http://am2.example.com/api/v1/silences"
- );
- await expect(
- tree.instance().submitState.silencesByCluster["default"].fetch
- ).resolves.toBeUndefined();
- expect(fetch.mock.calls[1][0]).toBe(
- "http://am1.example.com/api/v1/silences"
- );
- });
-
- it("[v2] will retry on another cluster member after fetch failure", async () => {
+ it("will retry on another cluster member after fetch failure", async () => {
fetch
.mockResponseOnce("error message", { status: 500 })
.mockResponseOnce(JSON.stringify({ silenceID: "123" }));
@@ -340,7 +266,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.16.2",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "fallback"]
},
@@ -351,7 +277,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.16.2",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "fallback"]
}
@@ -389,7 +315,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "fallback"]
}
@@ -403,7 +329,7 @@ describe("", () => {
tree.instance().submitState.silencesByCluster["default"].fetch
).resolves.toBeUndefined();
expect(fetch.mock.calls[0][0]).toBe(
- "http://am1.example.com/api/v1/silences"
+ "http://am1.example.com/api/v2/silences"
);
expect(consoleSpy).toHaveBeenCalledTimes(1);
});
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js
index 883139233..1c8a122ef 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js
@@ -28,7 +28,7 @@ beforeEach(() => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["am1"]
}
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js
index cf5769438..a1c6df152 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js
@@ -26,7 +26,7 @@ beforeEach(() => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["am1"]
}
diff --git a/ui/src/Components/ManagedSilence/DeleteSilence.js b/ui/src/Components/ManagedSilence/DeleteSilence.js
index 21317e000..c9caee3f2 100644
--- a/ui/src/Components/ManagedSilence/DeleteSilence.js
+++ b/ui/src/Components/ManagedSilence/DeleteSilence.js
@@ -4,8 +4,6 @@ import PropTypes from "prop-types";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
-import satisfies from "semver/functions/satisfies";
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrash } from "@fortawesome/free-solid-svg-icons/faTrash";
import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons/faExclamationCircle";
@@ -115,26 +113,6 @@ const DeleteSilenceModalContent = observer(
.filter(u => u.cluster === this.props.cluster)
.slice(0, 1)[0];
- parseAlertmanagerResponse = response => {
- /*
- {"status": "success"}
- or
- {
- "status": "error",
- "errorType": "bad_data",
- "error": "silence 706959fd-4590-4e21-b983-859ba6ec0e1a already expired"
- }
- */
- if (response.status === "success") {
- this.deleteState.setError(null);
- } else if (response.status === "error" && response.error) {
- this.deleteState.setError(response.error);
- } else {
- this.deleteState.setError(JSON.stringify(response));
- }
- this.deleteState.setDone();
- };
-
onFetchPreview = () => {
const { silence } = this.props;
@@ -169,32 +147,25 @@ const DeleteSilenceModalContent = observer(
const alertmanager = this.getAlertmanager();
- const isOpenAPI = satisfies(alertmanager.version, ">=0.16.0");
-
- const uri = isOpenAPI
- ? `${alertmanager.uri}/api/v2/silence/${silence.id}`
- : `${alertmanager.uri}/api/v1/silence/${silence.id}`;
-
- this.deleteState.fetch = FetchDelete(uri, {
- headers: alertmanager.headers
- })
+ this.deleteState.fetch = FetchDelete(
+ `${alertmanager.uri}/api/v2/silence/${silence.id}`,
+ {
+ headers: alertmanager.headers
+ }
+ )
.then(result => {
- if (isOpenAPI) {
- if (result.ok) {
- this.deleteState.setError(null);
- this.deleteState.setDone();
- } else {
- result.text().then(this.deleteState.setError);
- this.deleteState.setDone();
- }
+ if (result.ok) {
+ this.deleteState.setError(null);
+ this.deleteState.setDone();
} else {
- result.json().then(this.parseAlertmanagerResponse);
+ result.text().then(this.deleteState.setError);
+ this.deleteState.setDone();
}
})
.catch(err => {
console.trace(err);
this.deleteState.setDone();
- this.deleteState.setError(
+ return this.deleteState.setError(
`Delete request failed with: ${err.message}`
);
});
diff --git a/ui/src/Components/ManagedSilence/DeleteSilence.test.js b/ui/src/Components/ManagedSilence/DeleteSilence.test.js
index 0d1583d42..c30e6000e 100644
--- a/ui/src/Components/ManagedSilence/DeleteSilence.test.js
+++ b/ui/src/Components/ManagedSilence/DeleteSilence.test.js
@@ -18,7 +18,7 @@ beforeEach(() => {
silenceFormStore = new SilenceFormStore();
cluster = "am";
silence = MockSilence();
- fetch.mockResponse(JSON.stringify(MockAPIResponse()));
+ fetch.mockResponseOnce(JSON.stringify(MockAPIResponse()));
alertStore.data.upstreams = {
instances: [
@@ -28,7 +28,7 @@ beforeEach(() => {
uri: "http://localhost:9093",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {},
clusterMembers: ["am1"]
}
@@ -94,6 +94,17 @@ const VerifyResponse = async response => {
return tree;
};
+const VerifyError = async error => {
+ const tree = MountedDeleteSilenceModalContent();
+ await expect(tree.instance().previewState.fetch).resolves.toBeUndefined();
+
+ fetch.mockResponseOnce(error, { status: 500 });
+ tree.find(".btn-danger").simulate("click");
+ await expect(tree.instance().deleteState.fetch).resolves.toBeUndefined();
+
+ return tree;
+};
+
describe("", () => {
it("label is 'Delete' by default", () => {
const tree = MountedDeleteSilence();
@@ -147,8 +158,10 @@ describe("", () => {
expect(fetch).toHaveBeenCalled();
});
- it("renders ErrorMessage on failed fetch", async () => {
- jest.spyOn(console, "trace").mockImplementation(() => {});
+ it("renders ErrorMessage on failed preview fetch", async () => {
+ const consoleSpy = jest
+ .spyOn(console, "trace")
+ .mockImplementation(() => {});
fetch.resetMocks();
fetch.mockReject(new Error("Fetch error"));
@@ -156,9 +169,10 @@ describe("", () => {
await expect(tree.instance().previewState.fetch).resolves.toBeUndefined();
tree.update();
expect(tree.find("ErrorMessage")).toHaveLength(1);
+ expect(consoleSpy).toHaveBeenCalledTimes(1);
});
- it("renders ErrorMessage on fetch with non-JSON response", async () => {
+ it("renders ErrorMessage on preview fetch with non-JSON response", async () => {
fetch.mockResponseOnce("not json");
jest.spyOn(console, "trace").mockImplementation(() => {});
fetch.resetMocks();
@@ -170,16 +184,7 @@ describe("", () => {
expect(tree.find("ErrorMessage")).toHaveLength(1);
});
- it("[v1] sends a DELETE request after clicking 'Confirm' button", async () => {
- await VerifyResponse({ status: "success" });
- expect(fetch.mock.calls[1][0]).toBe(
- "http://localhost:9093/api/v1/silence/04d37636-2350-4878-b382-e0b50353230f"
- );
- expect(fetch.mock.calls[1][1]).toMatchObject({ method: "DELETE" });
- });
-
- it("[v2] sends a DELETE request after clicking 'Confirm' button", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
+ it("sends a DELETE request after clicking 'Confirm' button", async () => {
await VerifyResponse({ status: "success" });
expect(fetch.mock.calls[1][0]).toBe(
"http://localhost:9093/api/v2/silence/04d37636-2350-4878-b382-e0b50353230f"
@@ -187,27 +192,11 @@ describe("", () => {
expect(fetch.mock.calls[1][1]).toMatchObject({ method: "DELETE" });
});
- it("[v1] sends headers from alertmanager config", async () => {
+ it("sends headers from alertmanager config", async () => {
alertStore.data.upstreams.instances[0].headers = {
Authorization: "Basic ***"
};
await VerifyResponse({ status: "success" });
- expect(fetch.mock.calls[1][0]).toBe(
- "http://localhost:9093/api/v1/silence/04d37636-2350-4878-b382-e0b50353230f"
- );
- expect(fetch.mock.calls[1][1]).toMatchObject({
- credentials: "include",
- method: "DELETE",
- headers: { Authorization: "Basic ***" }
- });
- });
-
- it("[v1] sends headers from alertmanager config", async () => {
- alertStore.data.upstreams.instances[0].headers = {
- Authorization: "Basic ***"
- };
- alertStore.data.upstreams.instances[0].version = "0.16.2";
- await VerifyResponse({ status: "success" });
expect(fetch.mock.calls[1][0]).toBe(
"http://localhost:9093/api/v2/silence/04d37636-2350-4878-b382-e0b50353230f"
);
@@ -221,7 +210,7 @@ describe("", () => {
it("'Confirm' button is no-op after successful DELETE", async () => {
const tree = await VerifyResponse({ status: "success" });
expect(fetch.mock.calls[1][0]).toBe(
- "http://localhost:9093/api/v1/silence/04d37636-2350-4878-b382-e0b50353230f"
+ "http://localhost:9093/api/v2/silence/04d37636-2350-4878-b382-e0b50353230f"
);
expect(fetch.mock.calls[1][1]).toMatchObject({ method: "DELETE" });
@@ -232,58 +221,37 @@ describe("", () => {
expect(fetch.mock.calls).toHaveLength(2);
});
- it("renders SuccessMessage on 'success' response status", async () => {
+ it("renders SuccessMessage on successful response status", async () => {
const tree = await VerifyResponse({ status: "success" });
tree.update();
expect(tree.find("SuccessMessage")).toHaveLength(1);
});
- it("renders ErrorMessage on 'error' response status", async () => {
- const tree = await VerifyResponse({ status: "error", error: "fake error" });
+ it("renders ErrorMessage on failed delete fetch request", async () => {
+ const tree = await VerifyError("mock error");
+
+ tree.find(".btn-danger").simulate("click");
+ await expect(tree.instance().deleteState.fetch).resolves.toBeUndefined();
+
tree.update();
expect(tree.find("ErrorMessage")).toHaveLength(1);
});
- it("renders ErrorMessage on unhandled response status", async () => {
- const tree = await VerifyResponse({ status: "foo bar" });
- tree.update();
- expect(tree.find("ErrorMessage")).toHaveLength(1);
- });
-
- it("renders ErrorMessage on unhandled response body", async () => {
- const tree = await VerifyResponse({ foo: "bar" });
- tree.update();
- expect(tree.find("ErrorMessage")).toHaveLength(1);
- });
-
- it("[v1] renders ErrorMessage on failed fetch request", async () => {
- const tree = MountedDeleteSilenceModalContent();
- await expect(tree.instance().previewState.fetch).resolves.toBeUndefined();
-
- jest.spyOn(console, "trace").mockImplementation(() => {});
+ it("renders ErrorMessage on failed delete fetch", async () => {
+ const consoleSpy = jest
+ .spyOn(console, "trace")
+ .mockImplementation(() => {});
fetch.resetMocks();
+ fetch.mockResponseOnce(JSON.stringify(MockAPIResponse()));
fetch.mockReject(new Error("Fetch error"));
- tree.find(".btn-danger").simulate("click");
- await expect(tree.instance().deleteState.fetch).resolves.toBeUndefined();
-
- tree.update();
- expect(tree.find("ErrorMessage")).toHaveLength(1);
- });
-
- it("[v2] renders ErrorMessage on failed fetch request", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
const tree = MountedDeleteSilenceModalContent();
await expect(tree.instance().previewState.fetch).resolves.toBeUndefined();
- jest.spyOn(console, "trace").mockImplementation(() => {});
- fetch.resetMocks();
- fetch.mockResponseOnce("500 Internal Server Error", { status: 500 });
-
tree.find(".btn-danger").simulate("click");
await expect(tree.instance().deleteState.fetch).resolves.toBeUndefined();
-
tree.update();
expect(tree.find("ErrorMessage")).toHaveLength(1);
+ expect(consoleSpy).toHaveBeenCalledTimes(1);
});
});
diff --git a/ui/src/Components/ManagedSilence/SilenceComment.test.js b/ui/src/Components/ManagedSilence/SilenceComment.test.js
index f1f575a0e..c9aa463f2 100644
--- a/ui/src/Components/ManagedSilence/SilenceComment.test.js
+++ b/ui/src/Components/ManagedSilence/SilenceComment.test.js
@@ -47,7 +47,7 @@ const MockMultipleClusters = () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "fallback"]
},
@@ -58,7 +58,7 @@ const MockMultipleClusters = () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "fallback"]
},
@@ -69,7 +69,7 @@ const MockMultipleClusters = () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "second",
clusterMembers: ["second"]
}
diff --git a/ui/src/Components/ManagedSilence/SilenceDetails.test.js b/ui/src/Components/ManagedSilence/SilenceDetails.test.js
index 5695bd2e1..c711568ed 100644
--- a/ui/src/Components/ManagedSilence/SilenceDetails.test.js
+++ b/ui/src/Components/ManagedSilence/SilenceDetails.test.js
@@ -36,7 +36,7 @@ beforeEach(() => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
diff --git a/ui/src/Components/ManagedSilence/index.stories.js b/ui/src/Components/ManagedSilence/index.stories.js
index fdbfb9f7e..e950a95e0 100644
--- a/ui/src/Components/ManagedSilence/index.stories.js
+++ b/ui/src/Components/ManagedSilence/index.stories.js
@@ -32,7 +32,7 @@ storiesOf("ManagedSilence", module)
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
@@ -50,7 +50,7 @@ storiesOf("ManagedSilence", module)
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ro",
clusterMembers: ["readonly"]
}
diff --git a/ui/src/Components/ManagedSilence/index.test.js b/ui/src/Components/ManagedSilence/index.test.js
index 4ffdc9ad5..ab299a74e 100644
--- a/ui/src/Components/ManagedSilence/index.test.js
+++ b/ui/src/Components/ManagedSilence/index.test.js
@@ -35,7 +35,7 @@ beforeEach(() => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
@@ -98,7 +98,7 @@ describe("", () => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
});
});
@@ -114,7 +114,7 @@ describe("", () => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
},
{
@@ -125,7 +125,7 @@ describe("", () => {
publicURI: "http://example.com",
readonly: true,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
@@ -143,7 +143,7 @@ describe("", () => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
});
});
diff --git a/ui/src/Components/SilenceModal/AlertManagerInput/index.test.js b/ui/src/Components/SilenceModal/AlertManagerInput/index.test.js
index a6cf97797..71cf47468 100644
--- a/ui/src/Components/SilenceModal/AlertManagerInput/index.test.js
+++ b/ui/src/Components/SilenceModal/AlertManagerInput/index.test.js
@@ -30,7 +30,7 @@ beforeEach(() => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
},
@@ -41,7 +41,7 @@ beforeEach(() => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
},
@@ -52,7 +52,7 @@ beforeEach(() => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "am3",
clusterMembers: ["am3"]
}
diff --git a/ui/src/Components/SilenceModal/Browser/index.test.js b/ui/src/Components/SilenceModal/Browser/index.test.js
index 006616411..25ce5a651 100644
--- a/ui/src/Components/SilenceModal/Browser/index.test.js
+++ b/ui/src/Components/SilenceModal/Browser/index.test.js
@@ -38,7 +38,7 @@ beforeEach(() => {
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
diff --git a/ui/src/Components/SilenceModal/SilenceModalContent.test.js b/ui/src/Components/SilenceModal/SilenceModalContent.test.js
index 1c369203c..5a83f52ce 100644
--- a/ui/src/Components/SilenceModal/SilenceModalContent.test.js
+++ b/ui/src/Components/SilenceModal/SilenceModalContent.test.js
@@ -28,7 +28,7 @@ beforeEach(() => {
uri: "http://localhost:9093",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
diff --git a/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.js b/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.js
index 8e094b666..8a805db15 100644
--- a/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.js
+++ b/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.js
@@ -4,8 +4,6 @@ import PropTypes from "prop-types";
import { action, observable } from "mobx";
import { observer } from "mobx-react";
-import satisfies from "semver/functions/satisfies";
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCircleNotch } from "@fortawesome/free-solid-svg-icons/faCircleNotch";
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons/faCheckCircle";
@@ -33,18 +31,18 @@ const SubmitIcon = observer(({ stateValue }) => {
return ;
});
-const SilenceLink = ({ uri, silenceId }) => (
+const SilenceLink = ({ uri, silenceID }) => (
- {silenceId}
+ {silenceID}
);
SilenceLink.propTypes = {
uri: PropTypes.string.isRequired,
- silenceId: PropTypes.string.isRequired
+ silenceID: PropTypes.string.isRequired
};
const SilenceSubmitProgress = observer(
@@ -84,7 +82,7 @@ const SilenceSubmitProgress = observer(
maybeTryAgainAfterError = err => {
if (this.submitState.membersToTry.length) {
- this.handleAlertmanagerRequest();
+ return this.handleAlertmanagerRequest();
} else {
this.submitState.markFailed(err.message);
}
@@ -106,17 +104,10 @@ const SilenceSubmitProgress = observer(
if (am === undefined) {
const err = `Alertmanager instance "${member}" not found`;
console.error(err);
- this.maybeTryAgainAfterError(err);
- return;
+ return this.maybeTryAgainAfterError(err);
}
- const isOpenAPI = satisfies(am.version, ">=0.16.0");
-
- const uri = isOpenAPI
- ? `${am.uri}/api/v2/silences`
- : `${am.uri}/api/v1/silences`;
-
- this.submitState.fetch = FetchPost(uri, {
+ this.submitState.fetch = FetchPost(`${am.uri}/api/v2/silences`, {
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
@@ -124,51 +115,27 @@ const SilenceSubmitProgress = observer(
}
})
.then(result => {
- if (isOpenAPI) {
- if (result.ok) {
- return result
- .json()
- .then(r => this.parseOpenAPIResponse(am.publicURI, r));
- } else {
- return result.text().then(text => {
- this.submitState.markFailed(text);
- return text;
- });
- }
- } else {
+ if (result.ok) {
return result
.json()
- .then(r => this.parseAlertmanagerResponse(am.publicURI, r));
+ .then(r => this.parseOpenAPIResponse(am.publicURI, r));
+ } else {
+ return result.text().then(text => {
+ this.submitState.markFailed(text);
+ return text;
+ });
}
})
- .catch(err => {
- this.maybeTryAgainAfterError(err);
- });
+ .catch(this.maybeTryAgainAfterError);
};
parseOpenAPIResponse = (uri, response) => {
- const link = ;
+ const link = ;
this.submitState.markDone(link);
- // return silenceId so we can assert it in tests
+ // return silenceID so we can assert it in tests
return response.silenceID;
};
- parseAlertmanagerResponse = (uri, response) => {
- if (response.status === "success") {
- const link = (
-
- );
- this.submitState.markDone(link);
- } else if (response.status === "error") {
- this.submitState.markFailed(response.error);
- } else {
- this.submitState.markFailed(JSON.stringify(response));
- }
-
- // return status so we can assert it in tests
- return response.status;
- };
-
componentDidMount() {
const { members } = this.props;
this.submitState.membersToTry = [...members];
diff --git a/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.test.js b/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.test.js
index 8af0ca694..baf40f331 100644
--- a/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.test.js
+++ b/ui/src/Components/SilenceModal/SilenceSubmit/SilenceSubmitProgress.test.js
@@ -18,16 +18,19 @@ beforeEach(() => {
readonly: false,
headers: { foo: "bar" },
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "mockAlertmanager",
clusterMembers: ["mockAlertmanager"]
}
]
};
+
+ fetch.resetMocks();
});
afterEach(() => {
jest.restoreAllMocks();
+ fetch.resetMocks();
});
const MountedSilenceSubmitProgress = () => {
@@ -54,19 +57,11 @@ describe("", () => {
expect(fetch.mock.calls).toHaveLength(1);
});
- it("[v1] appends /api/v1/silences to the passed URI", async () => {
+ it("appends /api/v2/silences to the passed URI", async () => {
const tree = MountedSilenceSubmitProgress();
await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
const uri = fetch.mock.calls[0][0];
- expect(uri).toBe("http://localhost/api/v1/silences");
- });
-
- it("[v2] appends /api/v2/silences to the passed URI", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
- const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
- const uri = fetch.mock.calls[0][0];
- expect(uri).toBe("http://localhost/api/v1/silences");
+ expect(uri).toBe("http://localhost/api/v2/silences");
});
it("sends correct JSON payload", () => {
@@ -86,12 +81,9 @@ describe("", () => {
});
it("will retry on another cluster member after fetch failure", async () => {
- fetch.resetMocks();
fetch
.mockRejectOnce(new Error("mock error message"))
- .mockResponseOnce(
- JSON.stringify({ status: "success", data: { silenceId: "123456789" } })
- );
+ .mockResponseOnce(JSON.stringify({ silenceID: "123456789" }));
alertStore.data.upstreams = {
clusters: { ha: ["am1", "am2"] },
instances: [
@@ -102,7 +94,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
},
@@ -113,7 +105,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
}
@@ -136,11 +128,11 @@ describe("", () => {
);
await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
expect(fetch.mock.calls[0][0]).toBe(
- "http://am2.example.com/api/v1/silences"
+ "http://am2.example.com/api/v2/silences"
);
- await expect(tree.instance().submitState.fetch).resolves.toBe("success");
+ await expect(tree.instance().submitState.fetch).resolves.toBe("123456789");
expect(fetch.mock.calls[1][0]).toBe(
- "http://am1.example.com/api/v1/silences"
+ "http://am1.example.com/api/v2/silences"
);
});
@@ -160,7 +152,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
}
@@ -183,7 +175,7 @@ describe("", () => {
);
await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
expect(fetch.mock.calls[0][0]).toBe(
- "http://am1.example.com/api/v1/silences"
+ "http://am1.example.com/api/v2/silences"
);
expect(consoleSpy).toHaveBeenCalledTimes(1);
});
@@ -207,7 +199,7 @@ describe("", () => {
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
},
@@ -218,7 +210,7 @@ describe("", () => {
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "ha",
clusterMembers: ["am1", "am2"]
}
@@ -242,18 +234,16 @@ describe("", () => {
await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
expect(fetch.mock.calls).toHaveLength(1);
expect(fetch.mock.calls[0][0]).toBe(
- "http://am1.example.com/api/v1/silences"
+ "http://am1.example.com/api/v2/silences"
);
expect(logs).toEqual(['Alertmanager instance "am2" is read-only']);
expect(consoleSpy).toHaveBeenCalledTimes(1);
});
it("renders returned silence ID on successful fetch", async () => {
- fetch.mockResponseOnce(
- JSON.stringify({ status: "success", data: { silenceId: "123456789" } })
- );
+ fetch.mockResponseOnce(JSON.stringify({ silenceID: "123456789" }));
const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBe("success");
+ await expect(tree.instance().submitState.fetch).resolves.toBe("123456789");
// force re-render
tree.update();
const silenceLink = tree.find("a");
@@ -262,40 +252,15 @@ describe("", () => {
});
it("renders returned error message on failed fetch", async () => {
- fetch.mockRejectOnce(new Error("mock error message"));
+ fetch.mockResponseOnce("mock error message", { status: 500 });
const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBeUndefined();
+ await expect(tree.instance().submitState.fetch).resolves.toBe(
+ "mock error message"
+ );
expect(tree.text()).toBe("mockAlertmanagermock error message");
});
- it("[v1] renders success icon on successful fetch", async () => {
- fetch.mockResponseOnce(
- JSON.stringify({ status: "success", data: { silenceId: "123" } })
- );
- const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBe("success");
- tree.update();
- expect(tree.find("FontAwesomeIcon.text-success")).toHaveLength(1);
- expect(tree.find("FontAwesomeIcon.text-danger")).toHaveLength(0);
- });
-
- it("[v1] renders silence link on successful fetch", async () => {
- fetch.mockResponseOnce(
- JSON.stringify({ status: "success", data: { silenceId: "123" } })
- );
- const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBe("success");
- tree.update();
- expect(
- tree
- .find("a")
- .getDOMNode()
- .getAttribute("href")
- ).toBe("http://example.com/#/silences/123");
- });
-
- it("[v2] renders success icon on successful fetch", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
+ it("renders success icon on successful fetch", async () => {
fetch.mockResponseOnce(JSON.stringify({ silenceID: "123" }));
const tree = MountedSilenceSubmitProgress();
await expect(tree.instance().submitState.fetch).resolves.toBe("123");
@@ -304,8 +269,7 @@ describe("", () => {
expect(tree.find("FontAwesomeIcon.text-danger")).toHaveLength(0);
});
- it("[v2] renders silence link on successful fetch", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
+ it("renders silence link on successful fetch", async () => {
fetch.mockResponseOnce(JSON.stringify({ silenceID: "123" }));
const tree = MountedSilenceSubmitProgress();
await expect(tree.instance().submitState.fetch).resolves.toBe("123");
@@ -318,17 +282,7 @@ describe("", () => {
).toBe("http://example.com/#/silences/123");
});
- it("[v1] renders error icon on failed fetch", async () => {
- fetch.mockResponseOnce(JSON.stringify({ status: "error" }));
- const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBe("error");
- tree.update();
- expect(tree.find("FontAwesomeIcon.text-success")).toHaveLength(0);
- expect(tree.find("FontAwesomeIcon.text-danger")).toHaveLength(1);
- });
-
- it("[v2] renders error icon on failed fetch", async () => {
- alertStore.data.upstreams.instances[0].version = "0.16.2";
+ it("renders error icon on failed fetch", async () => {
fetch.mockResponseOnce("error message", { status: 500 });
const tree = MountedSilenceSubmitProgress();
await expect(tree.instance().submitState.fetch).resolves.toBe(
@@ -338,14 +292,4 @@ describe("", () => {
expect(tree.find("FontAwesomeIcon.text-success")).toHaveLength(0);
expect(tree.find("FontAwesomeIcon.text-danger")).toHaveLength(1);
});
-
- it("renders unhandled 'status' values in the response as error", async () => {
- fetch.mockResponseOnce(JSON.stringify({ status: "unhandled" }));
- const tree = MountedSilenceSubmitProgress();
- await expect(tree.instance().submitState.fetch).resolves.toBe("unhandled");
- tree.update();
- expect(tree.find("FontAwesomeIcon.text-success")).toHaveLength(0);
- expect(tree.find("FontAwesomeIcon.text-danger")).toHaveLength(1);
- expect(tree.text()).toBe('mockAlertmanager{"status":"unhandled"}');
- });
});
diff --git a/ui/src/Components/SilenceModal/index.stories.js b/ui/src/Components/SilenceModal/index.stories.js
index 7afee41d6..abc9a6b21 100644
--- a/ui/src/Components/SilenceModal/index.stories.js
+++ b/ui/src/Components/SilenceModal/index.stories.js
@@ -50,7 +50,7 @@ storiesOf("SilenceModal", module)
readonly: false,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default"]
}
@@ -124,7 +124,7 @@ storiesOf("SilenceModal", module)
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["readonly"]
}
@@ -189,7 +189,7 @@ storiesOf("SilenceModal", module)
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
@@ -252,7 +252,7 @@ storiesOf("SilenceModal", module)
publicURI: "http://example.com",
readonly: false,
error: "",
- version: "0.15.3",
+ version: "0.17.0",
headers: {}
}
],
diff --git a/ui/src/Stores/AlertStore.test.js b/ui/src/Stores/AlertStore.test.js
index 98c5e67c7..f02cd8f62 100644
--- a/ui/src/Stores/AlertStore.test.js
+++ b/ui/src/Stores/AlertStore.test.js
@@ -33,7 +33,7 @@ describe("AlertStore.data", () => {
readonly: false,
headers: { foo: "bar" },
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "readonly"]
},
@@ -44,7 +44,7 @@ describe("AlertStore.data", () => {
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["default", "readonly"]
}
@@ -69,7 +69,7 @@ describe("AlertStore.data", () => {
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["ro1", "ro2"]
},
@@ -80,7 +80,7 @@ describe("AlertStore.data", () => {
readonly: true,
headers: {},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
cluster: "default",
clusterMembers: ["ro1", "ro2"]
}
diff --git a/ui/src/__mocks__/Alerts.js b/ui/src/__mocks__/Alerts.js
index 9b6225f18..1244a7d4f 100644
--- a/ui/src/__mocks__/Alerts.js
+++ b/ui/src/__mocks__/Alerts.js
@@ -75,7 +75,7 @@ const MockAlertmanager = () => ({
Authorization: "Basic foo bar"
},
error: "",
- version: "0.15.0",
+ version: "0.17.0",
clusterMembers: ["default"]
});