Skip to content

Commit

Permalink
send an email on degraded event
Browse files Browse the repository at this point in the history
  • Loading branch information
meln1k committed Mar 8, 2024
1 parent 30bde8f commit 386fe00
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 8 deletions.
8 changes: 6 additions & 2 deletions fixbackend/cloud_accounts/service_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
WorkspaceId,
)
from fixbackend.logging_context import set_cloud_account_id, set_fix_cloud_account_id, set_workspace_id
from fixbackend.notification.email.email_messages import SecurityScanFinished
from fixbackend.notification.email import email_messages as email
from fixbackend.notification.notification_service import NotificationService
from fixbackend.sqs import SQSRawListener
from fixbackend.utils import uid
Expand Down Expand Up @@ -319,7 +319,7 @@ def compute_failed_scan_count(acc: CloudAccount) -> int:
await self.analytics_event_sender.send(AEFirstWorkspaceCollectFinished(user_id, event.tenant_id))
# inform workspace users about the first successful collect
await self.notification_service.send_message_to_workspace(
workspace_id=event.tenant_id, message=SecurityScanFinished()
workspace_id=event.tenant_id, message=email.SecurityScanFinished()
)
if first_account_collect:
await self.analytics_event_sender.send(AEFirstAccountCollectFinished(user_id, event.tenant_id))
Expand Down Expand Up @@ -351,6 +351,10 @@ def compute_failed_scan_count(acc: CloudAccount) -> int:

case AwsAccountDegraded.kind:
degraded_event = AwsAccountDegraded.from_json(message)
await self.notification_service.send_message_to_workspace(
workspace_id=degraded_event.tenant_id,
message=email.AccountDegraded(cloud_account_id=degraded_event.aws_account_id),
)
await send_pub_sub_message(degraded_event)

case _:
Expand Down
22 changes: 20 additions & 2 deletions fixbackend/notification/email/email_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from jinja2 import Environment, FileSystemLoader, StrictUndefined
from functools import lru_cache

from fixbackend.ids import CloudAccountId


@lru_cache(maxsize=1)
def get_env() -> Environment:
Expand Down Expand Up @@ -136,8 +138,24 @@ def html(self) -> str:
"security_scan_finished.html",
title=self.subject(),
fix_console_url="https://app.global.fixcloud.io/",
foo="foo",
)


EmailMessage = Union[Signup, Invite, VerifyEmail, SecurityScanFinished, PasswordReset]
@frozen(kw_only=True)
class AccountDegraded:
cloud_account_id: CloudAccountId

def subject(self) -> str:
return f"FIX: Account {self.cloud_account_id} Degraded"

def text(self) -> str:
return f"Account {self.cloud_account_id} can't be collected and now in degraded state. Please check that the account exists."

def html(self) -> str:
return render(
"account_degraded.html",
message=self,
)


EmailMessage = Union[Signup, Invite, VerifyEmail, SecurityScanFinished, PasswordReset, AccountDegraded]
18 changes: 18 additions & 0 deletions fixbackend/notification/email/templates/account_degraded.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% extends "base.html" %}

{% block content %}


<div class="f-fallback">
<h1 style="margin-top: 0; color: #333333; font-size: 22px; font-weight: bold; text-align: left;" align="left">
Account {{ message.cloud_account_id }} degraded!
</h1>

<p style="font-size: 16px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
One of your accounts can't be collected and is degraded now! Please check the account {{
message.cloud_account_id }} for issues.
</p>

</div>

{% endblock content %}
9 changes: 6 additions & 3 deletions fixbackend/notification/notification_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,12 @@ async def send_message_to_workspace(self, *, workspace_id: WorkspaceId, message:

emails = [user.email for user in await self.user_repository.get_by_ids(workspace.all_users())]
for email in emails:
await self.email_sender.send_email(
to=email, subject=message.subject(), text=message.text(), html=message.html()
)
try:
await self.email_sender.send_email(
to=email, subject=message.subject(), text=message.text(), html=message.html()
)
except Exception as e:
log.error(f"Failed to send message to workspace {workspace_id}: {e}")

async def list_notification_provider_configs(self, workspace_id: WorkspaceId) -> Dict[str, Json]:
configs = await self.provider_config_repo.all_messaging_configs_for_workspace(workspace_id)
Expand Down
16 changes: 15 additions & 1 deletion tests/fixbackend/notification/notification_service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
NodeId,
BenchmarkName,
)
from fixbackend.notification.email.email_messages import SecurityScanFinished
from fixbackend.notification.email.email_messages import AccountDegraded, SecurityScanFinished
from fixbackend.notification.model import (
WorkspaceAlert,
AlertingSetting,
Expand Down Expand Up @@ -274,3 +274,17 @@ async def test_send_test_alert(
# ensure that an alert was created
assert len(inventory_requests) == 1
assert str(inventory_requests[0].url) == "https://discord.com/webhook_example"


@pytest.mark.asyncio
async def test_send_degraded_message(
notification_service: NotificationService,
workspace: Workspace,
email_sender: InMemoryEmailSender,
) -> None:
message = AccountDegraded(cloud_account_id=CloudAccountId("12345"))
await notification_service.send_message_to_workspace(workspace_id=workspace.id, message=message)

assert len(email_sender.call_args) == 1
assert email_sender.call_args[0].subject == "FIX: Account 12345 Degraded"
assert "Account 12345 degraded!" in (email_sender.call_args[0].html or "")

0 comments on commit 386fe00

Please sign in to comment.