-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(backup): Send relocation started email
Once we have decent confidence that a relocation is not obviously invalid, we send the owner (and creator, if they are different people) an email indicating that their relocation has started. Issue: getsentry/team-ospo#203
- Loading branch information
1 parent
2b2ba06
commit 2145474
Showing
8 changed files
with
112 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/sentry/templates/sentry/emails/relocation_started.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "sentry/emails/base.html" %} | ||
|
||
{% load i18n %} | ||
|
||
{% block main %} | ||
<h3>Relocation Accepted</h3> | ||
<p>Your relocation request has been accepted. You requested that the following organizations be migrating to sentry.io:</p> | ||
<ul> | ||
{% for org in orgs %} | ||
<li> | ||
<a>{{ org }}</a> | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
<p>Relocations usually complete in 24 hours or less. If you do not hear from us in that time frame, please <a href="https://help.sentry.io">contact support</a>.</p> | ||
<p><small><i>ID: {{ uuid }}</i></small></p> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Your relocation request has been accepted. You requested that the following organizations be migrating to sentry.io: | ||
|
||
{% for org in orgs %} | ||
* {{ org }} | ||
{% endfor %} | ||
|
||
Relocations usually complete in 24 hours or less. If you do not hear from us in that time frame, please contact support at https://help.sentry.io. | ||
|
||
ID: {{ uuid }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,10 +86,10 @@ class RelocationTaskTestCase(TestCase): | |
def setUp(self): | ||
super().setUp() | ||
self.owner = self.create_user( | ||
email="owner", is_superuser=False, is_staff=False, is_active=True | ||
email="owner@example.com", is_superuser=False, is_staff=False, is_active=True | ||
) | ||
self.superuser = self.create_user( | ||
"superuser", is_superuser=True, is_staff=True, is_active=True | ||
email="superuser@example.com", is_superuser=True, is_staff=True, is_active=True | ||
) | ||
self.login_as(user=self.superuser, superuser=True) | ||
self.relocation: Relocation = Relocation.objects.create( | ||
|
@@ -231,8 +231,10 @@ def setUp(self): | |
self.relocation.latest_task = "UPLOADING_COMPLETE" | ||
self.relocation.save() | ||
|
||
def test_success( | ||
@patch("sentry.utils.email.MessageBuilder.send_async") | ||
def test_success_admin_assisted_relocation( | ||
self, | ||
send_async_mock: Mock, | ||
preprocessing_baseline_config_mock: Mock, | ||
fake_kms_client: FakeKeyManagementServiceClient, | ||
): | ||
|
@@ -243,6 +245,26 @@ def test_success( | |
assert fake_kms_client.asymmetric_decrypt.call_count == 1 | ||
assert fake_kms_client.get_public_key.call_count == 0 | ||
assert preprocessing_baseline_config_mock.call_count == 1 | ||
send_async_mock.assert_called_once_with(to=[self.owner.email, self.superuser.email]) | ||
assert Relocation.objects.get(uuid=self.uuid).want_usernames == ["[email protected]"] | ||
|
||
@patch("sentry.utils.email.MessageBuilder.send_async") | ||
def test_success_self_service_relocation( | ||
self, | ||
send_async_mock: Mock, | ||
preprocessing_baseline_config_mock: Mock, | ||
fake_kms_client: FakeKeyManagementServiceClient, | ||
): | ||
self.mock_kms_client(fake_kms_client) | ||
self.relocation.creator_id = self.relocation.owner_id | ||
self.relocation.save() | ||
|
||
preprocessing_scan(self.uuid) | ||
|
||
assert fake_kms_client.asymmetric_decrypt.call_count == 1 | ||
assert fake_kms_client.get_public_key.call_count == 0 | ||
assert preprocessing_baseline_config_mock.call_count == 1 | ||
send_async_mock.assert_called_once_with(to=[self.owner.email]) | ||
assert Relocation.objects.get(uuid=self.uuid).want_usernames == ["[email protected]"] | ||
|
||
def test_retry_if_attempts_left( | ||
|
@@ -462,7 +484,7 @@ def test_success( | |
# Only user `superuser` is an admin, so only they should be exported. | ||
for json_model in json_models: | ||
if NormalizedModelName(json_model["model"]) == get_model_name(User): | ||
assert json_model["fields"]["username"] in "superuser" | ||
assert json_model["fields"]["username"] in "superuser@example.com" | ||
|
||
def test_retry_if_attempts_left( | ||
self, | ||
|
@@ -1227,6 +1249,7 @@ def test_fail_if_no_attempts_left(self, completed_mock: Mock): | |
"sentry.tasks.relocation.CloudBuildClient", | ||
new_callable=lambda: FakeCloudBuildClient, | ||
) | ||
@patch("sentry.utils.email.MessageBuilder.send_async") | ||
@region_silo_test | ||
class EndToEndTest(RelocationTaskTestCase, TransactionTestCase): | ||
def setUp(self): | ||
|
@@ -1252,6 +1275,7 @@ def setUp(self): | |
|
||
def test_valid_no_retries( | ||
self, | ||
send_async_mock: Mock, | ||
fake_cloudbuild_client: FakeCloudBuildClient, | ||
fake_kms_client: FakeKeyManagementServiceClient, | ||
): | ||
|
@@ -1287,8 +1311,11 @@ def test_valid_no_retries( | |
"sentry.useremail", | ||
] | ||
|
||
assert send_async_mock.call_count == 1 | ||
|
||
def test_invalid_no_retries( | ||
self, | ||
send_async_mock: Mock, | ||
fake_cloudbuild_client: FakeCloudBuildClient, | ||
fake_kms_client: FakeKeyManagementServiceClient, | ||
): | ||
|
@@ -1305,6 +1332,8 @@ def test_invalid_no_retries( | |
assert relocation.failure_reason | ||
assert Organization.objects.filter(slug__startswith="testing").count() == org_count | ||
|
||
assert send_async_mock.call_count == 1 | ||
|
||
# TODO(getsentry/team-ospo#190): We should add "max retry" tests as well, but these are quite | ||
# hard to mock in celery at the moment. We may need to use the mock sync celery test scheduler, | ||
# rather than the "self.tasks()" approach above, to accomplish this. |