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
This commit is contained in:
Łukasz Mierzwa
2018-12-01 10:47:24 +00:00
parent 3a905b748e
commit 9f4ee09a56
6 changed files with 71 additions and 16 deletions
@@ -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 (
<li className={classNames.join(" ")}>
<div>
{alert.annotations.filter(a => a.isLink === false).map(a => (
<RenderNonLinkAnnotation
key={a.name}
name={a.name}
value={a.value}
visible={a.visible}
afterUpdate={afterUpdate}
/>
))}
{alert.annotations
.filter(a => a.isLink === false)
.map(a => (
<RenderNonLinkAnnotation
key={a.name}
name={a.name}
value={a.value}
visible={a.visible}
afterUpdate={afterUpdate}
/>
))}
</div>
<AlertMenu
group={group}
@@ -81,15 +98,21 @@ const Alert = observer(
value={alert.receiver}
/>
) : null}
{alert.annotations.filter(a => a.isLink === true).map(a => (
<RenderLinkAnnotation key={a.name} name={a.name} value={a.value} />
))}
{alert.alertmanager.map(am =>
am.silencedBy.map(silenceID => (
{alert.annotations
.filter(a => a.isLink === true)
.map(a => (
<RenderLinkAnnotation
key={a.name}
name={a.name}
value={a.value}
/>
))}
{Object.values(silences).map(clusterSilences =>
clusterSilences.silences.map(silenceID => (
<Silence
key={silenceID}
silenceFormStore={silenceFormStore}
alertmanagerState={am}
alertmanagerState={clusterSilences.alertmanager}
silenceID={silenceID}
afterUpdate={afterUpdate}
/>
@@ -96,6 +96,35 @@ describe("<Alert />", () => {
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";
@@ -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
@@ -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",
+1
View File
@@ -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,
+1
View File
@@ -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",