adding tests to agent alert actions and a bunch of fixes
This commit is contained in:
@@ -6,7 +6,7 @@ from itertools import cycle
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone as djangotime
|
||||
from model_bakery.recipe import Recipe, foreign_key
|
||||
from model_bakery.recipe import Recipe, foreign_key, seq
|
||||
|
||||
|
||||
def generate_agent_id(hostname):
|
||||
@@ -30,8 +30,7 @@ agent = Recipe(
|
||||
hostname="DESKTOP-TEST123",
|
||||
version="1.3.0",
|
||||
monitoring_type=cycle(["workstation", "server"]),
|
||||
salt_id=generate_agent_id("DESKTOP-TEST123"),
|
||||
agent_id="71AHC-AA813-HH1BC-AAHH5-00013|DESKTOP-TEST123",
|
||||
agent_id=seq("asdkj3h4234-1234hg3h4g34-234jjh34|DESKTOP-TEST123"),
|
||||
)
|
||||
|
||||
server_agent = agent.extend(
|
||||
|
||||
@@ -724,34 +724,32 @@ class Agent(BaseAuditModel):
|
||||
# called when agent is back online
|
||||
if checkin:
|
||||
if Alert.objects.filter(agent=self, resolved=False).exists():
|
||||
|
||||
|
||||
# resolve alert if exists
|
||||
alert = Alert.objects.get(agent=self, resolved=False)
|
||||
alert.resolve()
|
||||
|
||||
# check if a resolved notification should be emailed
|
||||
if (
|
||||
not alert.resolved_email_sent
|
||||
and alert_template
|
||||
alert_template
|
||||
and alert_template.agent_email_on_resolved
|
||||
or self.overdue_email_alert
|
||||
and not alert.resolved_email_sent
|
||||
):
|
||||
agent_recovery_email_task.delay(pk=alert.pk)
|
||||
|
||||
# check if a resolved notification should be texted
|
||||
if (
|
||||
not alert.resolved_sms_sent
|
||||
and alert_template
|
||||
alert_template
|
||||
and alert_template.agent_text_on_resolved
|
||||
or self.overdue_text_alert
|
||||
and not alert.resolved_sms_sent
|
||||
):
|
||||
agent_recovery_sms_task.delay(pk=alert.pk)
|
||||
|
||||
# check if any scripts should be run
|
||||
if (
|
||||
not alert.resolved_action_run
|
||||
and alert_template
|
||||
and alert_template.resolved_action
|
||||
and (alert_template
|
||||
and alert_template.resolved_action)
|
||||
):
|
||||
r = self.run_script(
|
||||
scriptpk=alert_template.resolved_action.pk,
|
||||
@@ -809,37 +807,35 @@ class Agent(BaseAuditModel):
|
||||
|
||||
# create dashboard alert if enabled
|
||||
if (
|
||||
alert_template
|
||||
and alert_template.agent_always_alert
|
||||
or self.overdue_dashboard_alert
|
||||
self.overdue_dashboard_alert
|
||||
or (alert_template
|
||||
and alert_template.agent_always_alert)
|
||||
):
|
||||
alert.hidden = False
|
||||
alert.save()
|
||||
|
||||
# send email alert if enabled
|
||||
if (
|
||||
not alert.email_sent
|
||||
and alert_template
|
||||
and alert_template.agent_always_email
|
||||
or self.overdue_email_alert
|
||||
self.overdue_email_alert
|
||||
or (alert_template
|
||||
and alert_template.agent_always_email)
|
||||
):
|
||||
agent_outage_email_task.delay(
|
||||
pk=alert.pk,
|
||||
alert_interval=alert_template.check_periodic_alert_days
|
||||
alert_interval=alert_template.agent_periodic_alert_days
|
||||
if alert_template
|
||||
else None,
|
||||
)
|
||||
|
||||
# send text message if enabled
|
||||
if (
|
||||
not alert.sms_sent
|
||||
and alert_template
|
||||
and alert_template.agent_always_text
|
||||
or self.overdue_text_alert
|
||||
self.overdue_text_alert
|
||||
or (alert_template
|
||||
and alert_template.agent_always_text)
|
||||
):
|
||||
agent_outage_sms_task.delay(
|
||||
pk=alert.pk,
|
||||
alert_interval=alert_template.check_periodic_alert_days
|
||||
alert_interval=alert_template.agent_periodic_alert_days
|
||||
if alert_template
|
||||
else None,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from unittest.mock import patch
|
||||
from django.utils import timezone as djangotime
|
||||
from model_bakery import baker, seq
|
||||
from django.conf import settings
|
||||
|
||||
from core.models import CoreSettings
|
||||
from tacticalrmm.test import TacticalTestCase
|
||||
@@ -346,7 +347,15 @@ class TestAlertsViews(TacticalTestCase):
|
||||
|
||||
class TestAlertTasks(TacticalTestCase):
|
||||
def setUp(self):
|
||||
self.authenticate()
|
||||
self.setup_coresettings()
|
||||
core = CoreSettings.objects.first()
|
||||
core.twilio_account_sid = "test"
|
||||
core.twilio_auth_token = "test"
|
||||
core.text_recipients = ["+12314567890"]
|
||||
core.email_recipients = ["test@example.com"]
|
||||
core.twilio_number = "+12314567890"
|
||||
core.save()
|
||||
|
||||
def test_unsnooze_alert_task(self):
|
||||
from alerts.tasks import unsnooze_alerts
|
||||
@@ -484,27 +493,222 @@ class TestAlertTasks(TacticalTestCase):
|
||||
self.assertEquals(workstation.get_alert_template().pk, alert_templates[1].pk)
|
||||
self.assertEquals(server.get_alert_template().pk, alert_templates[2].pk)
|
||||
|
||||
def test_handle_agent_offline_alerts(self):
|
||||
from agents.tasks import agent_outages_task
|
||||
@patch("agents.tasks.sleep")
|
||||
@patch("smtplib.SMTP")
|
||||
@patch("core.models.TwClient")
|
||||
@patch("agents.tasks.agent_outage_sms_task.delay")
|
||||
@patch("agents.tasks.agent_outage_email_task.delay")
|
||||
@patch("agents.tasks.agent_recovery_email_task.delay")
|
||||
@patch("agents.tasks.agent_recovery_sms_task.delay")
|
||||
def test_handle_agent_offline_alerts(
|
||||
self, recovery_sms, recovery_email, outage_email, outage_sms, TwClient, SMTP, sleep
|
||||
):
|
||||
from agents.tasks import (
|
||||
agent_outages_task,
|
||||
agent_outage_sms_task,
|
||||
agent_outage_email_task,
|
||||
agent_recovery_sms_task,
|
||||
agent_recovery_email_task,
|
||||
)
|
||||
from alerts.models import Alert
|
||||
|
||||
agent = baker.make_recipe("agents.overdue_agent")
|
||||
# setup sms and email mock objects
|
||||
TwClient.messages.create.return_value.sid = "SomeRandomText"
|
||||
SMTP.return_value = True
|
||||
|
||||
agent_dashboard_alert = baker.make_recipe("agents.overdue_agent")
|
||||
|
||||
# call outages task and no alert should be created
|
||||
agent_outages_task()
|
||||
|
||||
self.assertFalse(Alert.objects.filter(agent=agent).exists())
|
||||
self.assertEquals(Alert.objects.count(), 0)
|
||||
|
||||
# set overdue_dashboard_alert and alert should be created
|
||||
agent.overdue_dashboard_alert = True
|
||||
agent.save()
|
||||
agent_dashboard_alert.overdue_dashboard_alert = True
|
||||
agent_dashboard_alert.save()
|
||||
|
||||
# create other agents with various alert settings
|
||||
alert_template_always_alert = baker.make(
|
||||
"alerts.AlertTemplate", is_active=True, agent_always_alert=True
|
||||
)
|
||||
alert_template_always_text = baker.make(
|
||||
"alerts.AlertTemplate", is_active=True, agent_always_text=True, agent_periodic_alert_days=5
|
||||
)
|
||||
alert_template_always_email = baker.make(
|
||||
"alerts.AlertTemplate", is_active=True, agent_always_email=True, agent_periodic_alert_days=5
|
||||
)
|
||||
|
||||
alert_template_blank = baker.make("alerts.AlertTemplate", is_active=True)
|
||||
|
||||
agent_template_email = baker.make_recipe("agents.overdue_agent")
|
||||
agent_template_dashboard = baker.make_recipe("agents.overdue_agent")
|
||||
agent_template_text = baker.make_recipe("agents.overdue_agent")
|
||||
agent_template_blank = baker.make_recipe("agents.overdue_agent")
|
||||
|
||||
# assign alert templates to agent's clients
|
||||
agent_template_email.client.alert_template = alert_template_always_email
|
||||
agent_template_email.client.save()
|
||||
agent_template_dashboard.client.alert_template = alert_template_always_alert
|
||||
agent_template_dashboard.client.save()
|
||||
agent_template_text.client.alert_template = alert_template_always_text
|
||||
agent_template_text.client.save()
|
||||
agent_template_blank.client.alert_template = alert_template_blank
|
||||
agent_template_blank.client.save()
|
||||
|
||||
agent_text_alert = baker.make_recipe(
|
||||
"agents.overdue_agent", overdue_text_alert=True
|
||||
)
|
||||
agent_email_alert = baker.make_recipe(
|
||||
"agents.overdue_agent", overdue_email_alert=True
|
||||
)
|
||||
agent_outages_task()
|
||||
|
||||
# should have created 6 alerts
|
||||
self.assertEquals(Alert.objects.count(), 6)
|
||||
|
||||
# other specific agents should have created alerts
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_dashboard_alert).count(), 1)
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_text_alert).count(), 1)
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_email_alert).count(), 1)
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_template_email).count(), 1)
|
||||
self.assertEquals(
|
||||
Alert.objects.filter(agent=agent_template_dashboard).count(), 1
|
||||
)
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_template_text).count(), 1)
|
||||
self.assertEquals(Alert.objects.filter(agent=agent_template_blank).count(), 0)
|
||||
|
||||
# check if email and text tasks were called
|
||||
self.assertEquals(outage_email.call_count, 2)
|
||||
self.assertEquals(outage_sms.call_count, 2)
|
||||
|
||||
outage_sms.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_text_alert).pk, alert_interval=None
|
||||
)
|
||||
outage_sms.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_template_text).pk, alert_interval=5
|
||||
)
|
||||
outage_email.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_email_alert).pk, alert_interval=None
|
||||
)
|
||||
outage_email.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_template_email).pk, alert_interval=5
|
||||
)
|
||||
|
||||
# call the email/sms outage tasks synchronously
|
||||
agent_outage_sms_task(
|
||||
pk=Alert.objects.get(agent=agent_text_alert).pk, alert_interval=None
|
||||
)
|
||||
agent_outage_email_task(
|
||||
pk=Alert.objects.get(agent=agent_email_alert).pk, alert_interval=None
|
||||
)
|
||||
agent_outage_sms_task(
|
||||
pk=Alert.objects.get(agent=agent_template_text).pk, alert_interval=5
|
||||
)
|
||||
agent_outage_email_task(
|
||||
pk=Alert.objects.get(agent=agent_template_email).pk, alert_interval=5
|
||||
)
|
||||
|
||||
# check if email/text sent was set
|
||||
self.assertTrue(Alert.objects.get(agent=agent_text_alert).sms_sent)
|
||||
self.assertFalse(Alert.objects.get(agent=agent_text_alert).email_sent)
|
||||
self.assertTrue(Alert.objects.get(agent=agent_email_alert).email_sent)
|
||||
self.assertFalse(Alert.objects.get(agent=agent_email_alert).sms_sent)
|
||||
self.assertTrue(Alert.objects.get(agent=agent_template_text).sms_sent)
|
||||
self.assertTrue(Alert.objects.get(agent=agent_template_email).email_sent)
|
||||
self.assertFalse(Alert.objects.get(agent=agent_dashboard_alert).email_sent)
|
||||
self.assertFalse(Alert.objects.get(agent=agent_dashboard_alert).sms_sent)
|
||||
|
||||
SMTP.reset_mock()
|
||||
TwClient.reset_mock()
|
||||
|
||||
# calling agent outage task again shouldn't create duplicate alerts and won't send alerts
|
||||
agent_outages_task()
|
||||
self.assertEquals(Alert.objects.count(), 6)
|
||||
|
||||
SMTP.assert_not_called()
|
||||
TwClient.assert_not_called()
|
||||
|
||||
# test periodic notification
|
||||
|
||||
# change email/text sent to sometime in the past
|
||||
alert_text = Alert.objects.get(agent=agent_template_text)
|
||||
alert_text.sms_sent = djangotime.now() - djangotime.timedelta(days=20)
|
||||
alert_text.save()
|
||||
alert_email = Alert.objects.get(agent=agent_template_email)
|
||||
alert_email.email_sent = djangotime.now() - djangotime.timedelta(days=20)
|
||||
alert_email.save()
|
||||
|
||||
agent_outages_task()
|
||||
|
||||
self.assertTrue(Alert.objects.filter(agent=agent).exists())
|
||||
print(outage_sms.call_count)
|
||||
print(outage_email.call_count)
|
||||
|
||||
outage_sms.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_template_text).pk, alert_interval=5
|
||||
)
|
||||
outage_email.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_template_email).pk, alert_interval=5
|
||||
)
|
||||
|
||||
agent_outage_sms_task(
|
||||
pk=Alert.objects.get(agent=agent_template_text).pk, alert_interval=5
|
||||
)
|
||||
agent_outage_email_task(
|
||||
pk=Alert.objects.get(agent=agent_template_email).pk, alert_interval=5
|
||||
)
|
||||
|
||||
self.assertEquals(SMTP.call_count, 1)
|
||||
self.assertEquals(TwClient.call_count, 1)
|
||||
|
||||
# test resolved alerts
|
||||
# alter the alert template to email and test on resolved
|
||||
alert_template_always_email.agent_email_on_resolved = True
|
||||
alert_template_always_email.save()
|
||||
alert_template_always_text.agent_text_on_resolved = True
|
||||
alert_template_always_text.save()
|
||||
|
||||
# have the two agents checkin
|
||||
url = "/api/v3/checkin/"
|
||||
|
||||
agent_template_text.version = settings.LATEST_AGENT_VER
|
||||
agent_template_text.save()
|
||||
agent_template_email.version = settings.LATEST_AGENT_VER
|
||||
agent_template_email.save()
|
||||
|
||||
data = {
|
||||
"agent_id": agent_template_text.agent_id,
|
||||
"version": settings.LATEST_AGENT_VER
|
||||
}
|
||||
|
||||
resp = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
data = {
|
||||
"agent_id": agent_template_email.agent_id,
|
||||
"version": settings.LATEST_AGENT_VER
|
||||
}
|
||||
|
||||
resp = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
recovery_sms.assert_called_with(
|
||||
pk=Alert.objects.get(agent=agent_template_text).pk
|
||||
)
|
||||
recovery_email.assert_any_call(
|
||||
pk=Alert.objects.get(agent=agent_template_email).pk
|
||||
)
|
||||
|
||||
agent_recovery_sms_task(pk=Alert.objects.get(agent=agent_template_text).pk)
|
||||
agent_recovery_email_task(pk=Alert.objects.get(agent=agent_template_email).pk)
|
||||
|
||||
self.assertTrue(Alert.objects.get(agent=agent_template_text).resolved_sms_sent)
|
||||
self.assertTrue(Alert.objects.get(agent=agent_template_email).resolved_email_sent)
|
||||
|
||||
def test_handle_check_alerts(self):
|
||||
pass
|
||||
|
||||
def test_handle_task_alerts(self):
|
||||
pass
|
||||
|
||||
def test_override_email_settings(self):
|
||||
pass
|
||||
|
||||
@@ -249,27 +249,25 @@ class AutomatedTask(BaseAuditModel):
|
||||
|
||||
# check if resolved email should be send
|
||||
if (
|
||||
not alert.resolved_email_sent
|
||||
and self.email_alert
|
||||
or alert_template
|
||||
and alert_template.task_email_on_resolved
|
||||
(alert_template
|
||||
and alert_template.task_email_on_resolved)
|
||||
and not alert.resolved_email_sent
|
||||
):
|
||||
handle_resolved_task_email_alert.delay(pk=alert.pk)
|
||||
|
||||
# check if resolved text should be sent
|
||||
if (
|
||||
not alert.resolved_sms_sent
|
||||
and self.text_alert
|
||||
or alert_template
|
||||
and alert_template.task_text_on_resolved
|
||||
(alert_template
|
||||
and alert_template.task_text_on_resolved)
|
||||
and not alert.resolved_sms_sent
|
||||
):
|
||||
handle_resolved_task_sms_alert.delay(pk=alert.pk)
|
||||
|
||||
# check if resolved script should be run
|
||||
if (
|
||||
alert_template
|
||||
and alert_template.resolved_action
|
||||
and not alert.resolved_action_run
|
||||
not alert.resolved_action_run
|
||||
and (alert_template
|
||||
and alert_template.resolved_action)
|
||||
):
|
||||
|
||||
r = self.agent.run_script(
|
||||
@@ -328,38 +326,37 @@ class AutomatedTask(BaseAuditModel):
|
||||
# create alert in dashboard if enabled
|
||||
if (
|
||||
self.dashboard_alert
|
||||
or alert_template
|
||||
and alert_template.task_always_alert
|
||||
or (alert_template
|
||||
and self.alert_severity in alert_template.task_dashboard_alert_severity
|
||||
and alert_template.task_always_alert)
|
||||
):
|
||||
alert.hidden = False
|
||||
alert.save()
|
||||
|
||||
# send email if enabled
|
||||
if (
|
||||
not alert.email_sent
|
||||
and self.email_alert
|
||||
or alert_template
|
||||
self.email_alert
|
||||
or (alert_template
|
||||
and self.alert_severity in alert_template.task_email_alert_severity
|
||||
and alert_template.check_always_email
|
||||
and alert_template.task_always_email)
|
||||
):
|
||||
handle_task_email_alert.delay(
|
||||
pk=alert.pk,
|
||||
alert_template=alert_template.check_periodic_alert_days
|
||||
alert_template=alert_template.task_periodic_alert_days
|
||||
if alert_template
|
||||
else None,
|
||||
)
|
||||
|
||||
# send text if enabled
|
||||
if (
|
||||
not alert.sms_sent
|
||||
and self.text_alert
|
||||
or alert_template
|
||||
self.text_alert
|
||||
or (alert_template
|
||||
and self.alert_severity in alert_template.task_text_alert_severity
|
||||
and alert_template.check_always_text
|
||||
and alert_template.task_always_text)
|
||||
):
|
||||
handle_task_sms_alert.delay(
|
||||
pk=alert.pk,
|
||||
alert_template=alert_template.check_periodic_alert_days
|
||||
alert_template=alert_template.task_periodic_alert_days
|
||||
if alert_template
|
||||
else None,
|
||||
)
|
||||
|
||||
@@ -360,9 +360,9 @@ class Check(BaseAuditModel):
|
||||
# create alert in dashboard if enabled
|
||||
if (
|
||||
self.dashboard_alert
|
||||
or alert_template
|
||||
or (alert_template
|
||||
and self.alert_severity in alert_template.check_dashboard_alert_severity
|
||||
and alert_template.check_always_alert
|
||||
and alert_template.check_always_alert)
|
||||
):
|
||||
alert.hidden = False
|
||||
alert.save()
|
||||
@@ -384,11 +384,10 @@ class Check(BaseAuditModel):
|
||||
|
||||
# send text if enabled
|
||||
if (
|
||||
not alert.sms_sent
|
||||
and self.text_alert
|
||||
or alert_template
|
||||
self.text_alert
|
||||
or (alert_template
|
||||
and self.alert_severity in alert_template.check_text_alert_severity
|
||||
and alert_template.check_always_text
|
||||
and alert_template.check_always_text)
|
||||
):
|
||||
handle_check_sms_alert_task.delay(
|
||||
pk=alert.pk,
|
||||
|
||||
Reference in New Issue
Block a user