Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production Deploy 3/6/2024 #834

Merged
merged 107 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
6d4064e
make sure original_file_name is stored as part of job (notify-admin-1…
Feb 28, 2024
689d822
fix tests
Feb 28, 2024
820ee5a
Cleaning up a lot of things, getting Enums used everywhere.
xlorepdarkhelm Feb 28, 2024
43f18ee
More changes for enums.
xlorepdarkhelm Feb 28, 2024
df866e4
More Enum goodness.
xlorepdarkhelm Jan 18, 2024
df10c46
Formatting goodness.
xlorepdarkhelm Jan 18, 2024
908d695
More cleanup.
xlorepdarkhelm Jan 10, 2024
ac9591e
More tweaks, trying to get tests to be clean.
xlorepdarkhelm Jan 10, 2024
3982f06
Made enums.py for all the enums to avoid cyclic imports.
xlorepdarkhelm Jan 10, 2024
985ad27
Getting imports right to use app.enums
xlorepdarkhelm Jan 10, 2024
f120641
Getting permission types configured.
xlorepdarkhelm Jan 12, 2024
661904e
More fixes for enums.
xlorepdarkhelm Jan 12, 2024
a177042
Formatting cleanup for models.py
xlorepdarkhelm Jan 12, 2024
69a9acc
Getting NotificationStatus implemented everywhere.
xlorepdarkhelm Jan 18, 2024
db37616
Job Status changed.
xlorepdarkhelm Jan 15, 2024
7416de2
KeyType implemented.
xlorepdarkhelm Jan 18, 2024
ab7387a
All string "constants" in app.models converted to app.enums.
xlorepdarkhelm Jan 15, 2024
9523cc1
Cleaning up with black, isort, flake8.
xlorepdarkhelm Jan 16, 2024
8c6046b
Cleaning up tests.
xlorepdarkhelm Jan 16, 2024
26bc619
Cleaning up tests.
xlorepdarkhelm Jan 16, 2024
bd705ed
More cleanup.
xlorepdarkhelm Jan 16, 2024
e0b9ac0
Even more cleanup.
xlorepdarkhelm Jan 16, 2024
95ee8b7
Cleaning things up, trying to get tests to work.
xlorepdarkhelm Jan 17, 2024
d7e8228
Making the migration.
xlorepdarkhelm Jan 18, 2024
f4c8c3e
Making the migration, part 2.
xlorepdarkhelm Jan 18, 2024
655a57c
Adding some documentation to the helper function.
xlorepdarkhelm Jan 18, 2024
22c4866
MOre cleanup of helper function.
xlorepdarkhelm Jan 18, 2024
a89d025
Removing migration file, will rebuild soon.
xlorepdarkhelm Jan 18, 2024
ecf7b71
Cleaning up models.py to have consistant enum definitions.
xlorepdarkhelm Jan 18, 2024
f6297a3
Making migration (better!)
xlorepdarkhelm Jan 18, 2024
8c50f39
More stuff is being done to get the migration to work.
xlorepdarkhelm Jan 19, 2024
d7ad4ed
More cleanup of migration.
xlorepdarkhelm Jan 19, 2024
cbf73ff
Migration file organized. Need a few more things.
xlorepdarkhelm Jan 20, 2024
0fbe67b
Migration is set up, need to test.
xlorepdarkhelm Jan 23, 2024
6a8f7ff
More migration fun.
xlorepdarkhelm Jan 25, 2024
ced386b
Another thing needs an enum.
xlorepdarkhelm Jan 25, 2024
5d02f22
Migration worked without errors now.
xlorepdarkhelm Jan 25, 2024
b3223f8
Downgrade works now too.
xlorepdarkhelm Jan 25, 2024
8907edc
Got tests to use OrganizationType everywhere now.
xlorepdarkhelm Jan 25, 2024
e64e500
Debugging things is fun.
xlorepdarkhelm Jan 29, 2024
77bc5fb
Trying to get the Auth Types to work right.
xlorepdarkhelm Jan 29, 2024
0790e5f
TRying to fix defaults.
xlorepdarkhelm Jan 30, 2024
1160785
Switching to using StrEnum, which is in an external lib until 3.11.
xlorepdarkhelm Jan 30, 2024
fe69042
Adding note.
xlorepdarkhelm Jan 30, 2024
b1a53c7
More cleanup.
xlorepdarkhelm Jan 30, 2024
544bf35
Adding another set of columns to the migration.
xlorepdarkhelm Jan 31, 2024
689ff10
Latest and greatest.
xlorepdarkhelm Feb 2, 2024
c6136bb
Minor fixes.
xlorepdarkhelm Feb 2, 2024
6717729
Casting columns to TEXT type seems to resolve some bugs with UNION
xlorepdarkhelm Feb 6, 2024
2655dc6
Stuff was done.
xlorepdarkhelm Feb 6, 2024
2a67846
Fixed more stuff.
xlorepdarkhelm Feb 7, 2024
1d580df
More fixes, only 47 tests left to get right.
xlorepdarkhelm Feb 7, 2024
f43ad68
More fixes for everyone.
xlorepdarkhelm Feb 8, 2024
b5c2a8e
Fixin' bugs.
xlorepdarkhelm Feb 8, 2024
cd081ef
Down to 11 errors left to fix for tests.
xlorepdarkhelm Feb 8, 2024
dcf7885
Only 6 fails left to go.
xlorepdarkhelm Feb 9, 2024
9cc3f1c
Cleanup.
xlorepdarkhelm Feb 9, 2024
262bd89
More cleanup.
xlorepdarkhelm Feb 9, 2024
f279648
More cleanup.
xlorepdarkhelm Feb 9, 2024
acecf97
Even more cleanup of tests.
xlorepdarkhelm Feb 9, 2024
63aa12e
More cleanup.
xlorepdarkhelm Feb 13, 2024
3624cd8
Stuff was done.
xlorepdarkhelm Feb 13, 2024
64adb09
More stuff done.
xlorepdarkhelm Feb 13, 2024
cf1db4d
Cleaning house a bit.
xlorepdarkhelm Feb 13, 2024
287dcd6
More cleanup happening.
xlorepdarkhelm Feb 16, 2024
8e8749a
More fixes.
xlorepdarkhelm Feb 16, 2024
f0e7374
Done some stuff.
xlorepdarkhelm Feb 20, 2024
a26cc54
Another changed string format.
xlorepdarkhelm Feb 20, 2024
12658fe
Even more format strings changed.
xlorepdarkhelm Feb 20, 2024
74ac09a
Even more cleanup.
xlorepdarkhelm Feb 20, 2024
4429e48
More changes are done.
xlorepdarkhelm Feb 20, 2024
9fde1f3
"sms" entries cleaned up.
xlorepdarkhelm Feb 21, 2024
6f5f5fb
Cleaning up "email" from code.
xlorepdarkhelm Feb 21, 2024
15eeac6
Reformatting.
xlorepdarkhelm Feb 21, 2024
43a8b65
More fixes, removing literal "created" from code.
xlorepdarkhelm Feb 21, 2024
afc1de6
Even more cleanup.
xlorepdarkhelm Feb 21, 2024
a118b16
Replaced "delivered".
xlorepdarkhelm Feb 21, 2024
e9f9a3c
Lots more cleanup.
xlorepdarkhelm Feb 21, 2024
7083db9
Even more cleanup.
xlorepdarkhelm Feb 21, 2024
06d1e02
String cleanup complete.
xlorepdarkhelm Feb 21, 2024
9d17d3a
Fixing tests, fixing tests...
xlorepdarkhelm Feb 22, 2024
b5dac89
Debugging.
xlorepdarkhelm Feb 22, 2024
75cec3a
Almost all tests are working. Only 3 left to fix.
xlorepdarkhelm Feb 27, 2024
c407d61
Cleaning & debugging
xlorepdarkhelm Feb 27, 2024
a8cf49e
Fixed another error.
xlorepdarkhelm Feb 28, 2024
c47501c
Fixed test.
xlorepdarkhelm Feb 28, 2024
5bab443
Final test fix
xlorepdarkhelm Feb 28, 2024
c49e1fa
Updated and fixed poetry.lock.
xlorepdarkhelm Feb 28, 2024
11992be
Fixing things is fun.
xlorepdarkhelm Feb 28, 2024
18dddf4
Merge pull request #745 from GSA/API-414_Set_Up_Enums
ccostino Mar 1, 2024
611a8c8
Add E2E configuration information to docs
ccostino Mar 1, 2024
08fe6be
Added commands to add test data to DB
anagradova Mar 1, 2024
b13d3ed
Merge branch 'main' into 800-flask-command-for-test
anagradova Mar 1, 2024
eb52cdf
New lock file
anagradova Mar 1, 2024
c0e3a68
Added faker to poetry lock file
anagradova Mar 1, 2024
980e32c
Swapped random for secrets
anagradova Mar 1, 2024
0d856f0
Removed gov.uk text from org invite
Mar 4, 2024
3db6462
Merge pull request #822 from GSA/notify-admin-1148
ccostino Mar 4, 2024
aecf543
Merge pull request #826 from GSA/update-e2e-info
ccostino Mar 4, 2024
e0fb52c
Merge pull request #829 from GSA/org-invite-uk-bug
ccostino Mar 4, 2024
ee6dfac
Standardized command names and updated
anagradova Mar 4, 2024
6cf9c81
Update app/commands.py
anagradova Mar 4, 2024
117ac98
moved faker to under imports according to PEP-8
anagradova Mar 4, 2024
f9f26a2
Merge branch '800-flask-command-for-test' of https://github.com/GSA/n…
anagradova Mar 4, 2024
8e44e4d
Corrected flake spacing
anagradova Mar 5, 2024
7035002
Updated doucmentation in README and all.md
anagradova Mar 5, 2024
df9ee47
Merge pull request #828 from GSA/800-flask-command-for-test
ccostino Mar 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,36 @@ brew services start postgresql@15
brew services start redis
```

### Final environment setup

There's one final thing to adjust in the newly created `.env` file. This
project has support for end-to-end (E2E) tests and has some additional checks
for the presence of an E2E test user so that it can be authenticated properly.

In the `.env` file, you should see this section:

```
#############################################################

# E2E Testing

NOTIFY_E2E_TEST_EMAIL=example@fake.gov
NOTIFY_E2E_TEST_PASSWORD="don't write secrets to the sample file"
```

You can leave the email address alone or change it to something else to your
liking.

**You should absolutely change the `NOTIFY_E2E_TEST_PASSWORD` environment
variable to something else, preferably a lengthy passphrase.**

With those two environment variable set, the database migrations will run
properly and an E2E test user will be ready to go for use in the admin project.

_Note: Whatever you set these two environment variables to, you'll need to
match their values on the admin side. Please see the admin README and
documentation for more details._

## Running the Project and Routine Maintenance

The first time you run the project you'll need to run the project setup from the
Expand Down Expand Up @@ -410,6 +440,7 @@ instructions above for more details.
- [CI testing](./docs/all.md#ci-testing)
- [Manual testing](./docs/all.md#manual-testing)
- [To run a local OWASP scan](./docs/all.md#to-run-a-local-owasp-scan)
- [End-to-end testing](./docs/all.md#end-to-end-testing)
- [Deploying](./docs/all.md#deploying)
- [Egress Proxy](./docs/all.md#egress-proxy)
- [Managing environment variables](./docs/all.md#managing-environment-variables)
Expand All @@ -421,6 +452,7 @@ instructions above for more details.
- [Migrations](./docs/all.md#migrations)
- [Purging user data](./docs/all.md#purging-user-data)
- [One-off tasks](./docs/all.md#one-off-tasks)
- [Test Loading Commands](./docs/all.md#commands-for-test-loading-the-local-dev-database)
- [How messages are queued and sent](./docs/all.md#how-messages-are-queued-and-sent)
- [Writing public APIs](./docs/all.md#writing-public-apis)
- [Overview](./docs/all.md#overview)
Expand Down
4 changes: 3 additions & 1 deletion app/billing/billing_schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from datetime import datetime

from app.enums import NotificationType

create_or_update_free_sms_fragment_limit_schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "POST annual billing schema",
Expand All @@ -25,7 +27,7 @@ def serialize_ft_billing_remove_emails(rows):
"charged_units": row.charged_units,
}
for row in rows
if row.notification_type != "email"
if row.notification_type != NotificationType.EMAIL
]


Expand Down
9 changes: 5 additions & 4 deletions app/celery/nightly_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
from app.dao.service_data_retention_dao import (
fetch_service_data_retention_for_all_services_by_notification_type,
)
from app.models import EMAIL_TYPE, SMS_TYPE, FactProcessingTime
from app.enums import NotificationType
from app.models import FactProcessingTime
from app.utils import get_midnight_in_utc


@notify_celery.task(name="remove_sms_email_jobs")
@cronitor("remove_sms_email_jobs")
def remove_sms_email_csv_files():
_remove_csv_files([EMAIL_TYPE, SMS_TYPE])
_remove_csv_files([NotificationType.EMAIL, NotificationType.SMS])


def _remove_csv_files(job_types):
Expand Down Expand Up @@ -69,13 +70,13 @@ def delete_notifications_older_than_retention():
@notify_celery.task(name="delete-sms-notifications")
@cronitor("delete-sms-notifications")
def delete_sms_notifications_older_than_retention():
_delete_notifications_older_than_retention_by_type("sms")
_delete_notifications_older_than_retention_by_type(NotificationType.SMS)


@notify_celery.task(name="delete-email-notifications")
@cronitor("delete-email-notifications")
def delete_email_notifications_older_than_retention():
_delete_notifications_older_than_retention_by_type("email")
_delete_notifications_older_than_retention_by_type(NotificationType.EMAIL)


def _delete_notifications_older_than_retention_by_type(notification_type):
Expand Down
20 changes: 12 additions & 8 deletions app/celery/process_ses_receipts_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
get_service_complaint_callback_api_for_service,
get_service_delivery_status_callback_api_for_service,
)
from app.models import NOTIFICATION_PENDING, NOTIFICATION_SENDING, Complaint
from app.enums import CallbackType, NotificationStatus
from app.models import Complaint


@notify_celery.task(
Expand Down Expand Up @@ -76,7 +77,10 @@ def process_ses_results(self, response):
f"SES bounce for notification ID {notification.id}: {bounce_message}"
)

if notification.status not in {NOTIFICATION_SENDING, NOTIFICATION_PENDING}:
if notification.status not in {
NotificationStatus.SENDING,
NotificationStatus.PENDING,
}:
notifications_dao._duplicate_update_warning(
notification, notification_status
)
Expand Down Expand Up @@ -166,22 +170,22 @@ def get_aws_responses(ses_message):
"Permanent": {
"message": "Hard bounced",
"success": False,
"notification_status": "permanent-failure",
"notification_status": NotificationStatus.PERMANENT_FAILURE,
},
"Temporary": {
"message": "Soft bounced",
"success": False,
"notification_status": "temporary-failure",
"notification_status": NotificationStatus.TEMPORARY_FAILURE,
},
"Delivery": {
"message": "Delivered",
"success": True,
"notification_status": "delivered",
"notification_status": NotificationStatus.DELIVERED,
},
"Complaint": {
"message": "Complaint",
"success": True,
"notification_status": "delivered",
"notification_status": NotificationStatus.DELIVERED,
},
}[status]

Expand All @@ -205,7 +209,7 @@ def handle_complaint(ses_message):
)
return
notification = dao_get_notification_history_by_reference(reference)
ses_complaint = ses_message.get("complaint", None)
ses_complaint = ses_message.get(CallbackType.COMPLAINT, None)

complaint = Complaint(
notification_id=notification.id,
Expand Down Expand Up @@ -237,7 +241,7 @@ def remove_emails_from_bounce(bounce_dict):

def remove_emails_from_complaint(complaint_dict):
remove_mail_headers(complaint_dict)
complaint_dict["complaint"].pop("complainedRecipients")
complaint_dict[CallbackType.COMPLAINT].pop("complainedRecipients")
return complaint_dict["mail"].pop("destination")


Expand Down
22 changes: 10 additions & 12 deletions app/celery/provider_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@
update_notification_status_by_id,
)
from app.delivery import send_to_providers
from app.enums import NotificationStatus
from app.exceptions import NotificationTechnicalFailureException
from app.models import (
NOTIFICATION_DELIVERED,
NOTIFICATION_FAILED,
NOTIFICATION_TECHNICAL_FAILURE,
NOTIFICATION_TEMPORARY_FAILURE,
)

# This is the amount of time to wait after sending an sms message before we check the aws logs and look for delivery
# receipts
Expand Down Expand Up @@ -67,12 +62,12 @@ def check_sms_delivery_receipt(self, message_id, notification_id, sent_at):
raise self.retry(exc=ntfe)

if status == "success":
status = NOTIFICATION_DELIVERED
status = NotificationStatus.DELIVERED
elif status == "failure":
status = NOTIFICATION_FAILED
status = NotificationStatus.FAILED
# if status is not success or failure the client raised an exception and this method will retry

if status == NOTIFICATION_DELIVERED:
if status == NotificationStatus.DELIVERED:
sanitize_successful_notification_by_id(
notification_id, carrier=carrier, provider_response=provider_response
)
Expand Down Expand Up @@ -126,7 +121,8 @@ def deliver_sms(self, notification_id):
)
except Exception as e:
update_notification_status_by_id(
notification_id, NOTIFICATION_TEMPORARY_FAILURE
notification_id,
NotificationStatus.TEMPORARY_FAILURE,
)
if isinstance(e, SmsClientResponseException):
current_app.logger.warning(
Expand All @@ -151,7 +147,8 @@ def deliver_sms(self, notification_id):
)
)
update_notification_status_by_id(
notification_id, NOTIFICATION_TECHNICAL_FAILURE
notification_id,
NotificationStatus.TECHNICAL_FAILURE,
)
raise NotificationTechnicalFailureException(message)

Expand Down Expand Up @@ -194,6 +191,7 @@ def deliver_email(self, notification_id):
)
)
update_notification_status_by_id(
notification_id, NOTIFICATION_TECHNICAL_FAILURE
notification_id,
NotificationStatus.TECHNICAL_FAILURE,
)
raise NotificationTechnicalFailureException(message)
4 changes: 2 additions & 2 deletions app/celery/reporting_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from app.dao.fact_billing_dao import fetch_billing_data_for_day, update_fact_billing
from app.dao.fact_notification_status_dao import update_fact_notification_status
from app.dao.notifications_dao import get_service_ids_with_notifications_on_date
from app.models import EMAIL_TYPE, SMS_TYPE
from app.enums import NotificationType


@notify_celery.task(name="create-nightly-billing")
Expand Down Expand Up @@ -80,7 +80,7 @@ def create_nightly_notification_status():

yesterday = datetime.utcnow().date() - timedelta(days=1)

for notification_type in [SMS_TYPE, EMAIL_TYPE]:
for notification_type in (NotificationType.SMS, NotificationType.EMAIL):
days = 4

for i in range(days):
Expand Down
4 changes: 2 additions & 2 deletions app/celery/research_mode_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from app.celery.process_ses_receipts_tasks import process_ses_results
from app.config import QueueNames
from app.dao.notifications_dao import get_notification_by_id
from app.models import SMS_TYPE
from app.enums import NotificationType

temp_fail = "2028675303"
perm_fail = "2028675302"
Expand All @@ -21,7 +21,7 @@ def send_sms_response(provider, reference):
body = sns_callback(reference)
headers = {"Content-type": "application/json"}

make_request(SMS_TYPE, provider, body, headers)
make_request(NotificationType.SMS, provider, body, headers)


def send_email_response(reference, to):
Expand Down
20 changes: 7 additions & 13 deletions app/celery/scheduled_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,8 @@
)
from app.dao.users_dao import delete_codes_older_created_more_than_a_day_ago
from app.delivery.send_to_providers import provider_to_use
from app.models import (
EMAIL_TYPE,
JOB_STATUS_ERROR,
JOB_STATUS_IN_PROGRESS,
JOB_STATUS_PENDING,
SMS_TYPE,
Job,
)
from app.enums import JobStatus, NotificationType
from app.models import Job
from app.notifications.process_notifications import send_notification_to_queue

MAX_NOTIFICATION_FAILS = 10000
Expand Down Expand Up @@ -160,7 +154,7 @@ def check_db_notification_fails():
)
# suppress any spam coming from development tier
if message and curr_env != "development":
provider = provider_to_use(EMAIL_TYPE, False)
provider = provider_to_use(NotificationType.EMAIL, False)
from_address = '"{}" <{}@{}>'.format(
"Failed Notification Count Alert",
"test_sender",
Expand Down Expand Up @@ -192,11 +186,11 @@ def check_job_status():
thirty_five_minutes_ago = datetime.utcnow() - timedelta(minutes=35)

incomplete_in_progress_jobs = Job.query.filter(
Job.job_status == JOB_STATUS_IN_PROGRESS,
Job.job_status == JobStatus.IN_PROGRESS,
between(Job.processing_started, thirty_five_minutes_ago, thirty_minutes_ago),
)
incomplete_pending_jobs = Job.query.filter(
Job.job_status == JOB_STATUS_PENDING,
Job.job_status == JobStatus.PENDING,
Job.scheduled_for.isnot(None),
between(Job.scheduled_for, thirty_five_minutes_ago, thirty_minutes_ago),
)
Expand All @@ -211,7 +205,7 @@ def check_job_status():
# if they haven't been re-processed in time.
job_ids = []
for job in jobs_not_complete_after_30_minutes:
job.job_status = JOB_STATUS_ERROR
job.job_status = JobStatus.ERROR
dao_update_job(job)
job_ids.append(str(job.id))

Expand All @@ -224,7 +218,7 @@ def check_job_status():
def replay_created_notifications():
# if the notification has not be send after 1 hour, then try to resend.
resend_created_notifications_older_than = 60 * 60
for notification_type in (EMAIL_TYPE, SMS_TYPE):
for notification_type in (NotificationType.EMAIL, NotificationType.SMS):
notifications_to_resend = notifications_not_yet_sent(
resend_created_notifications_older_than, notification_type
)
Expand Down
Loading
Loading