From 9f4ee09a56a321bbf7db712242f1a29221319dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Sat, 1 Dec 2018 10:47:24 +0000 Subject: [PATCH] fix(ui): only show one silence per Alertmanager cluster HA clusters share silences which means that they are currently duplicated for each alertmanager instance in that cluster --- .../Grid/AlertGrid/AlertGroup/Alert/index.js | 53 +++++++++++++------ .../AlertGrid/AlertGroup/Alert/index.test.js | 29 ++++++++++ .../AlertGrid/AlertGroup/Silence/index.js | 2 +- .../AlertGroup/Silence/index.test.js | 1 + ui/src/Models/API.js | 1 + ui/src/__mocks__/Alerts.js | 1 + 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js index 20317401b..650582ea7 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js @@ -45,18 +45,35 @@ const Alert = observer( BorderClassMap[alert.state] || "border-warning" ]; + let silences = {}; + for (let am of alert.alertmanager) { + if (!silences[am.cluster]) { + silences[am.cluster] = { + alertmanager: am, + silences: [] + }; + } + for (let silenceID of am.silencedBy) { + if (!silences[am.cluster].silences.includes(silenceID)) { + silences[am.cluster].silences.push(silenceID); + } + } + } + return (
  • - {alert.annotations.filter(a => a.isLink === false).map(a => ( - - ))} + {alert.annotations + .filter(a => a.isLink === false) + .map(a => ( + + ))}
    ) : null} - {alert.annotations.filter(a => a.isLink === true).map(a => ( - - ))} - {alert.alertmanager.map(am => - am.silencedBy.map(silenceID => ( + {alert.annotations + .filter(a => a.isLink === true) + .map(a => ( + + ))} + {Object.values(silences).map(clusterSilences => + clusterSilences.silences.map(silenceID => ( diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js index 0f40aff00..f5efc1a1b 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js @@ -96,6 +96,35 @@ describe("", () => { expect(silence.html()).toMatch(/silence123456789/); }); + it("renders only one silence for HA cluster", () => { + const alert = MockedAlert(); + alert.alertmanager = [ + { + name: "am1", + cluster: "ha", + state: "suppressed", + startsAt: "2018-08-14T17:36:40.017867056Z", + endsAt: "0001-01-01T00:00:00Z", + source: "localhost/am1", + silencedBy: ["silence123456789"] + }, + { + name: "am2", + cluster: "ha", + state: "suppressed", + startsAt: "2018-08-14T17:36:40.017867056Z", + endsAt: "0001-01-01T00:00:00Z", + source: "localhost/am2", + silencedBy: ["silence123456789"] + } + ]; + const group = MockAlertGroup({}, [alert], [], {}); + const tree = MountedAlert(alert, group, false, false); + const silence = tree.find("Silence"); + expect(silence).toHaveLength(1); + expect(silence.html()).toMatch(/silence123456789/); + }); + it("uses BorderClassMap.active when @state=active", () => { const alert = MockedAlert(); alert.state = "active"; diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.js index 4e26a0e13..97f1c6262 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.js @@ -249,7 +249,7 @@ const Silence = inject("alertStore")( // and we need to lookup the actual silence data in the store. // Data might be missing from the store so first check if we have // anything for this alertmanager instance - const amSilences = alertStore.data.silences[alertmanagerState.name]; + const amSilences = alertStore.data.silences[alertmanagerState.cluster]; if (!amSilences) return null; // next check if alertmanager has our silence ID diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js index e3a0c412f..7071ed80b 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js @@ -17,6 +17,7 @@ const mockAfterUpdate = jest.fn(); const alertmanager = { name: "default", + cluster: "default", state: "suppressed", startsAt: "2000-01-01T10:00:00Z", endsAt: "0001-01-01T00:00:00Z", diff --git a/ui/src/Models/API.js b/ui/src/Models/API.js index d21ef96dd..3c295d48b 100644 --- a/ui/src/Models/API.js +++ b/ui/src/Models/API.js @@ -11,6 +11,7 @@ const Annotation = PropTypes.exact({ const APIAlertAlertmanagerState = PropTypes.exact({ name: PropTypes.string.isRequired, + cluster: PropTypes.string.isRequired, state: AlertState.isRequired, startsAt: PropTypes.string.isRequired, endsAt: PropTypes.string.isRequired, diff --git a/ui/src/__mocks__/Alerts.js b/ui/src/__mocks__/Alerts.js index 82b74eb77..3bc685d0e 100644 --- a/ui/src/__mocks__/Alerts.js +++ b/ui/src/__mocks__/Alerts.js @@ -14,6 +14,7 @@ const MockAlert = (annotations, labels, state) => ({ alertmanager: [ { name: "default", + cluster: "default", state: "active", startsAt: "2018-08-14T17:36:40.017867056Z", endsAt: "0001-01-01T00:00:00Z",