add force option for update silence
This commit is contained in:
parent
f284486570
commit
6fd687cc90
4 changed files with 95 additions and 23 deletions
|
@ -87,6 +87,8 @@ class AlertmanagerClient:
|
|||
fingerprint: str,
|
||||
user: Optional[str] = None,
|
||||
duration_seconds: Optional[int] = None,
|
||||
*,
|
||||
force: bool = False,
|
||||
) -> str:
|
||||
logger.debug(
|
||||
f"Reading silence for alert with fingerprint {fingerprint} from cache"
|
||||
|
@ -107,11 +109,12 @@ class AlertmanagerClient:
|
|||
f"Updating silence with ID {silence_id} for alert with fingerprint {fingerprint}"
|
||||
)
|
||||
|
||||
if duration_seconds is None:
|
||||
if expire_time is not None:
|
||||
raise SilenceExtendError(
|
||||
f"Cannot extend silence ID {silence_id} with static duration."
|
||||
)
|
||||
# If silence in cache had a duration, and the new silence doesn't have a duration
|
||||
# then we cannot update this silence.
|
||||
if not force and duration_seconds is None and expire_time is not None:
|
||||
raise SilenceExtendError(
|
||||
f"Cannot extend silence ID {silence_id} with static duration."
|
||||
)
|
||||
|
||||
silence = await self.get_silence(silence_id)
|
||||
if user is None:
|
||||
|
@ -123,10 +126,17 @@ class AlertmanagerClient:
|
|||
)
|
||||
|
||||
async def create_or_update_silence(
|
||||
self, fingerprint: str, user: str, duration_seconds: Optional[int] = None
|
||||
self,
|
||||
fingerprint: str,
|
||||
user: str,
|
||||
duration_seconds: Optional[int] = None,
|
||||
*,
|
||||
force: bool = False,
|
||||
) -> str:
|
||||
try:
|
||||
silence_id = await self.update_silence(fingerprint, user, duration_seconds)
|
||||
silence_id = await self.update_silence(
|
||||
fingerprint, user, duration_seconds, force=force
|
||||
)
|
||||
except SilenceNotFoundError:
|
||||
silence_id = await self.create_silence(fingerprint, user, duration_seconds)
|
||||
return silence_id
|
||||
|
|
|
@ -135,6 +135,7 @@ class AckAlertCommand(BaseAlertCommand):
|
|||
alert_fingerprint,
|
||||
self.room.user_name(self.sender),
|
||||
duration_seconds,
|
||||
force=True
|
||||
)
|
||||
except AlertNotFoundError as e:
|
||||
logger.warning(f"Unable to create silence: {e}")
|
||||
|
|
|
@ -25,7 +25,7 @@ from matrix_alertbot.errors import (
|
|||
|
||||
|
||||
async def update_silence_raise_silence_not_found(
|
||||
fingerprint: str, user: str, duration_seconds: int
|
||||
fingerprint: str, user: str, duration_seconds: int, *, force: bool = False
|
||||
) -> str:
|
||||
raise SilenceNotFoundError
|
||||
|
||||
|
@ -439,7 +439,7 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
fake_cache.set.assert_called_once_with("fingerprint1", "silence1", expire=86400)
|
||||
|
||||
@freeze_time(datetime.utcfromtimestamp(0))
|
||||
async def test_update_silence_with_duration(self) -> None:
|
||||
async def test_update_silence_raise_extend_error(self) -> None:
|
||||
fake_cache = FakeCache()
|
||||
|
||||
async with FakeAlertmanagerServerWithoutSilence() as fake_alertmanager_server:
|
||||
|
@ -455,6 +455,47 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
await alertmanager_client.get_silence("silence2")
|
||||
self.assertEqual({"fingerprint1": ("silence1", 86400)}, fake_cache.cache)
|
||||
|
||||
@freeze_time(datetime.utcfromtimestamp(0))
|
||||
async def test_update_silence_remove_duration(self) -> None:
|
||||
fake_cache = FakeCache()
|
||||
|
||||
async with FakeAlertmanagerServerWithoutSilence() as fake_alertmanager_server:
|
||||
port = fake_alertmanager_server.port
|
||||
alertmanager_client = AlertmanagerClient(
|
||||
f"http://localhost:{port}", fake_cache
|
||||
)
|
||||
async with aiotools.closing_async(alertmanager_client):
|
||||
silence_id1 = await alertmanager_client.create_silence(
|
||||
"fingerprint1", "user", 86400
|
||||
)
|
||||
silence_id2 = await alertmanager_client.update_silence(
|
||||
"fingerprint1", force=True
|
||||
)
|
||||
silence2 = await alertmanager_client.get_silence("silence2")
|
||||
|
||||
self.assertEqual("silence1", silence_id1)
|
||||
self.assertEqual("silence2", silence_id2)
|
||||
self.assertEqual(
|
||||
{
|
||||
"id": "silence2",
|
||||
"status": {"state": "active"},
|
||||
"matchers": [
|
||||
{
|
||||
"name": "alertname",
|
||||
"value": "alert1",
|
||||
"isRegex": False,
|
||||
"isEqual": True,
|
||||
}
|
||||
],
|
||||
"createdBy": "user",
|
||||
"startsAt": "1970-01-01T00:00:00",
|
||||
"endsAt": "1970-01-01T03:00:00",
|
||||
"comment": "Acknowledge alert from Matrix",
|
||||
},
|
||||
silence2,
|
||||
)
|
||||
self.assertEqual({"fingerprint1": ("silence2", None)}, fake_cache.cache)
|
||||
|
||||
@freeze_time(datetime.utcfromtimestamp(0))
|
||||
async def test_update_silence_override_user_and_duration(self) -> None:
|
||||
fake_cache = FakeCache()
|
||||
|
@ -509,7 +550,9 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
|
||||
self.assertEqual("silence1", silence_id1)
|
||||
fake_update_silence.assert_called_once_with("fingerprint1", "user", 86400)
|
||||
fake_update_silence.assert_called_once_with(
|
||||
"fingerprint1", "user", 86400, force=False
|
||||
)
|
||||
fake_create_silence.assert_called_once_with("fingerprint1", "user", 86400)
|
||||
|
||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "update_silence")
|
||||
|
@ -527,7 +570,9 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
|
||||
self.assertEqual("silence1", silence_id1)
|
||||
fake_update_silence.assert_called_once_with("fingerprint1", "user", 86400)
|
||||
fake_update_silence.assert_called_once_with(
|
||||
"fingerprint1", "user", 86400, force=False
|
||||
)
|
||||
fake_create_silence.assert_not_called()
|
||||
|
||||
@freeze_time(datetime.utcfromtimestamp(0))
|
||||
|
@ -623,7 +668,9 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
|
||||
self.assertEqual("silence1", silence_id1)
|
||||
fake_update_silence.assert_called_once_with("fingerprint1", "user", None)
|
||||
fake_update_silence.assert_called_once_with(
|
||||
"fingerprint1", "user", None, force=False
|
||||
)
|
||||
fake_create_silence.assert_called_once_with("fingerprint1", "user", None)
|
||||
|
||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "update_silence")
|
||||
|
@ -641,7 +688,9 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
|
||||
self.assertEqual("silence1", silence_id1)
|
||||
fake_update_silence.assert_called_once_with("fingerprint1", "user", None)
|
||||
fake_update_silence.assert_called_once_with(
|
||||
"fingerprint1", "user", None, force=False
|
||||
)
|
||||
fake_create_silence.assert_not_called()
|
||||
|
||||
@freeze_time(datetime.utcfromtimestamp(0))
|
||||
|
|
|
@ -32,7 +32,11 @@ def cache_get_item(key: str) -> str:
|
|||
|
||||
|
||||
async def create_silence(
|
||||
fingerprint: str, user: str, duration_seconds: Optional[int] = None
|
||||
fingerprint: str,
|
||||
user: str,
|
||||
duration_seconds: Optional[int] = None,
|
||||
*,
|
||||
force: bool = True,
|
||||
) -> str:
|
||||
if fingerprint == "fingerprint1":
|
||||
return "silence1"
|
||||
|
@ -42,7 +46,11 @@ async def create_silence(
|
|||
|
||||
|
||||
async def create_silence_raise_alertmanager_error(
|
||||
fingerprint: str, user: str, duration_seconds: Optional[int] = None
|
||||
fingerprint: str,
|
||||
user: str,
|
||||
duration_seconds: Optional[int] = None,
|
||||
*,
|
||||
force: bool = True,
|
||||
) -> str:
|
||||
if fingerprint == "fingerprint1":
|
||||
raise AlertmanagerError
|
||||
|
@ -50,7 +58,11 @@ async def create_silence_raise_alertmanager_error(
|
|||
|
||||
|
||||
async def create_silence_raise_alert_not_found_error(
|
||||
fingerprint: str, user: str, duration_seconds: Optional[int] = None
|
||||
fingerprint: str,
|
||||
user: str,
|
||||
duration_seconds: Optional[int] = None,
|
||||
*,
|
||||
force: bool = True,
|
||||
) -> str:
|
||||
if fingerprint == "fingerprint1":
|
||||
raise AlertNotFoundError
|
||||
|
@ -80,7 +92,9 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
self.fake_cache.__contains__.return_value = True
|
||||
|
||||
self.fake_alertmanager_client = Mock(spec=AlertmanagerClient)
|
||||
self.fake_alertmanager_client.create_silence.side_effect = create_silence
|
||||
self.fake_alertmanager_client.create_or_update_silence.side_effect = (
|
||||
create_silence
|
||||
)
|
||||
|
||||
# Create a fake room to play with
|
||||
self.fake_room = Mock(spec=nio.MatrixRoom)
|
||||
|
@ -208,7 +222,6 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
fake_cache_dict = {self.fake_alert_event_id: "fingerprint1"}
|
||||
|
||||
self.fake_cache.__getitem__.side_effect = fake_cache_dict.__getitem__
|
||||
self.fake_alertmanager_client.create_or_update_silence.return_value = "silence1"
|
||||
|
||||
command = AckAlertCommand(
|
||||
self.fake_matrix_client,
|
||||
|
@ -224,7 +237,7 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
|
||||
# Check that we attempted to create silences
|
||||
self.fake_alertmanager_client.create_or_update_silence.assert_called_once_with(
|
||||
"fingerprint1", self.fake_sender, None
|
||||
"fingerprint1", self.fake_sender, None, force=True
|
||||
)
|
||||
fake_send_text_to_room.assert_called_once_with(
|
||||
self.fake_matrix_client,
|
||||
|
@ -241,7 +254,6 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
"""Tests the callback for InviteMemberEvents"""
|
||||
# Tests that the bot attempts to join a room after being invited to it
|
||||
fake_cache_dict = {self.fake_alert_event_id: "fingerprint1"}
|
||||
self.fake_alertmanager_client.create_or_update_silence.return_value = "silence1"
|
||||
|
||||
self.fake_cache.__getitem__.side_effect = fake_cache_dict.__getitem__
|
||||
|
||||
|
@ -260,7 +272,7 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
|
||||
# Check that we attempted to create silences
|
||||
self.fake_alertmanager_client.create_or_update_silence.assert_called_once_with(
|
||||
"fingerprint1", self.fake_sender, 864000
|
||||
"fingerprint1", self.fake_sender, 864000, force=True
|
||||
)
|
||||
fake_send_text_to_room.assert_called_once_with(
|
||||
self.fake_matrix_client,
|
||||
|
@ -301,7 +313,7 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
|
||||
# Check that we attempted to create silences
|
||||
self.fake_alertmanager_client.create_or_update_silence.assert_called_once_with(
|
||||
"fingerprint1", self.fake_sender, None
|
||||
"fingerprint1", self.fake_sender, None, force=True
|
||||
)
|
||||
fake_send_text_to_room.assert_called_once_with(
|
||||
self.fake_matrix_client,
|
||||
|
@ -340,7 +352,7 @@ class CommandTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
|
||||
# Check that we attempted to create silences
|
||||
self.fake_alertmanager_client.create_or_update_silence.assert_called_once_with(
|
||||
"fingerprint1", self.fake_sender, None
|
||||
"fingerprint1", self.fake_sender, None, force=True
|
||||
)
|
||||
fake_send_text_to_room.assert_called_once_with(
|
||||
self.fake_matrix_client,
|
||||
|
|
Loading…
Reference in a new issue