Skip to content

Commit 8ae5868

Browse files
authored
Merge pull request #1666 from GSA/main
04/24/2025 Production Deploy
2 parents c497c28 + 6689214 commit 8ae5868

File tree

13 files changed

+2073
-1481
lines changed

13 files changed

+2073
-1481
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ too-complex:
6464
poetry run radon cc ./app -a -nc
6565

6666
.PHONY: run-flask
67-
run-flask: ## Run flask
67+
run-flask:
6868
poetry run newrelic-admin run-program flask run -p 6011 --host=0.0.0.0
6969

7070
.PHONY: run-celery

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ instructions above for more details.
507507
- [Deploying to Production](./docs/all.md#-deploying-to-production)
508508
- [Smoke-testing the App](./docs/all.md#-smoke-testing-the-app)
509509
- [Configuration Management](./docs/all.md#-configuration-management)
510-
- [DNS Changes](./docs/all.md#-dns-changes)
510+
- [DNS and Domain Changes](./docs/all.md#-dns-and-domain-changes)
511511
- [Exporting test results for compliance monitoring](./docs/all.md#exporting-test-results-for-compliance-monitoring)
512512
- [Known Gotchas](./docs/all.md#-known-gotchas)
513513
- [User Account Management](./docs/all.md#-user-account-management)

app/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from flask.ctx import has_app_context
1414
from flask_marshmallow import Marshmallow
1515
from flask_migrate import Migrate
16+
from flask_socketio import SocketIO
1617
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
1718
from sqlalchemy import event
1819
from werkzeug.exceptions import HTTPException as WerkzeugHTTPException
@@ -94,6 +95,14 @@ def apply_driver_hacks(self, app, info, options):
9495
redis_store = RedisClient()
9596
document_download_client = DocumentDownloadClient()
9697

98+
socketio = SocketIO(
99+
cors_allowed_origins=[
100+
config.Config.ADMIN_BASE_URL,
101+
],
102+
message_queue=config.Config.REDIS_URL,
103+
logger=True,
104+
engineio_logger=True,
105+
)
97106

98107
notification_provider_clients = NotificationProviderClients()
99108

@@ -111,6 +120,11 @@ def create_app(application):
111120
application.config["NOTIFY_APP_NAME"] = application.name
112121
init_app(application)
113122

123+
socketio.init_app(application)
124+
125+
from app.socket_handlers import register_socket_handlers
126+
127+
register_socket_handlers(socketio)
114128
request_helper.init_app(application)
115129
db.init_app(application)
116130
migrate.init_app(application, db=db)

app/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class Config(object):
179179
S3_RESOURCE = session.resource("s3", config=AWS_CLIENT_CONFIG)
180180

181181
CELERY = {
182+
"broker_connection_retry_on_startup": True,
182183
"worker_max_tasks_per_child": 500,
183184
"task_ignore_result": True,
184185
"result_persistent": False,

app/dao/notifications_dao.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
from app import create_uuid, db
2727
from app.dao.dao_utils import autocommit
2828
from app.dao.inbound_sms_dao import Pagination
29+
from app.dao.jobs_dao import dao_get_job_by_id
2930
from app.enums import KeyType, NotificationStatus, NotificationType
3031
from app.models import FactNotificationStatus, Notification, NotificationHistory
3132
from app.utils import (
33+
emit_job_update_summary,
3234
escape_special_characters,
3335
get_midnight_in_utc,
3436
midnight_n_days_ago,
@@ -895,6 +897,19 @@ def dao_update_delivery_receipts(receipts, delivered):
895897
f"#loadtestperformance batch update query time: \
896898
updated {len(receipts)} notification in {elapsed_time} ms"
897899
)
900+
job_ids = (
901+
db.session.execute(
902+
select(Notification.job_id).where(
903+
Notification.message_id.in_(id_to_carrier.keys())
904+
)
905+
)
906+
.scalars()
907+
.all()
908+
)
909+
910+
for job_id in set(job_ids):
911+
job = dao_get_job_by_id(job_id)
912+
emit_job_update_summary(job)
898913

899914

900915
def dao_close_out_delivery_receipts():

app/socket_handlers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from flask import current_app, request
2+
from flask_socketio import join_room, leave_room
3+
4+
5+
def register_socket_handlers(socketio):
6+
@socketio.on("join")
7+
def on_join(data): # noqa: F401
8+
room = data.get("room")
9+
join_room(room)
10+
current_app.logger.info(f"Socket {request.sid} joined room {room}")
11+
12+
@socketio.on("leave")
13+
def on_leave(data): # noqa: F401
14+
room = data.get("room")
15+
leave_room(room)
16+
current_app.logger.info(f"Socket {request.sid} left room {room}")

app/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,18 @@ def utc_now():
131131
def debug_not_production(msg):
132132
if os.getenv("NOTIFY_ENVIRONMENT") not in ["production"]:
133133
current_app.logger.info(msg)
134+
135+
136+
def emit_job_update_summary(job):
137+
from app import socketio
138+
139+
current_app.logger.info(f"Emitting summary for job {job.id}")
140+
socketio.emit(
141+
"job_updated",
142+
{
143+
"job_id": str(job.id),
144+
"job_status": job.job_status,
145+
"notification_count": job.notification_count,
146+
},
147+
room=f"job-{job.id}",
148+
)

docs/all.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
- [Smoke-testing the App](#-smoke-testing-the-app)
5454
- [Simulated bulk send testing](#-simulated-bulk-send-testing)
5555
- [Configuration Management](#-configuration-management)
56-
- [DNS Changes](#-dns-changes)
56+
- [DNS and Domain Changes](#-dns-and-domain-changes)
5757
- [Exporting test results for compliance monitoring](#exporting-test-results-for-compliance-monitoring)
5858
- [Known Gotchas](#-known-gotchas)
5959
- [User Account Management](#-user-account-management)
@@ -1068,7 +1068,7 @@ that the security of the system is maintained.
10681068
1. [Smoke-testing the App](#smoke-testing)
10691069
1. [Simulated bulk send testing](#simulated-bulk-send-testing)
10701070
1. [Configuration Management](#cm)
1071-
1. [DNS Changes](#dns)
1071+
1. [DNS and Domain Changes](#dns)
10721072
1. [Known Gotchas](#gotcha)
10731073
1. [User Account Management](#ac)
10741074
1. [SMS Phone Number Management](#phone-numbers)
@@ -1239,15 +1239,41 @@ US_Notify Administrators are responsible for ensuring that remediations for vuln
12391239
- Low - 180 days
12401240
- Informational - 365 days (depending on the analysis of the issue)
12411241

1242-
## <a name="dns"></a> DNS Changes
1242+
## <a name="dns"></a> DNS and Domain Changes
12431243

1244-
Notify.gov DNS records are maintained within [the 18f/dns repository](https://github.com/18F/dns/blob/main/terraform/notify.gov.tf). To create new DNS records for notify.gov or any subdomains:
1244+
Notify.gov DNS records are maintained within [the GSA-TTS/dns repository](https://github.com/GSA-TTS/dns/blob/main/terraform/notify.gov.tf), and the domains and routes are managed directly in our Cloud.gov production space.
12451245

1246-
1. Update the `notify.gov.tf` terraform to update oƒr create the new records within Route53 and push the branch to the 18f/dns repository.
1247-
1. Open a PR.
1248-
1. Verify that the plan output within circleci creates the records that you expect.
1249-
1. Request a PR review from the 18F/tts-tech-portfolio team
1250-
1. Once the PR is approved and merged, verify that the apply step happened correctly within [CircleCI](https://app.circleci.com/pipelines/github/18F/dns)
1246+
**Step 1: Make changes to the DNS records**
1247+
1248+
1. If you haven't already, clone a local copy of [the GSA-TTS/dns repository](https://github.com/GSA-TTS/dns).
1249+
1. Create a new branch and update the [`notify.gov.tf`]((https://github.com/GSA-TTS/dns/blob/main/terraform/notify.gov.tf)) Terraform file to update, create, or remove DNS records within AWS Route 53.
1250+
1. Open a PR in the repository and verify that the plan output within CircleCI makes the changes that you expect.
1251+
1. Request a PR review from the `@tts-tech-operations` team within the GSA-TTS GitHub org.
1252+
1. Once the PR is approved and merged, verify that the apply step happened correctly within [CircleCI](https://app.circleci.com/pipelines/github/GSA-TTS/dns).
1253+
1254+
**Step 2: Make changes to the domains and routes in Cloud.gov**
1255+
1256+
The domains and routes are managed via the [external domain service](https://www.cloud.gov/docs/services/external-domain-service/) within Cloud.gov.
1257+
1258+
If you're creating new domains:
1259+
1260+
1. Sign in to the `cf` CLI in your terminal and target the `notify-production` space.
1261+
1. Create the new domain(s) with [`cf create-private-domain`](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#private-domains).
1262+
1. Map the routes needed to the new domain(s) with [`cf map-route`](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#map-route).
1263+
1. Update the service to account for the new domain(s): `cf update-service notify-admin-domain-production -c '{"domains": "example.gov,www.example.gov,..."}'` (make sure to list *all* domains that need to be accounted for, including any existing ones that you want to keep!).
1264+
1265+
If you're removing existing domains:
1266+
1267+
1. Sign in to the `cf` CLI in your terminal and target the `notify-production` space.
1268+
1. Unmap the routes to the existing domain(s) with [`cf unmap-route`](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#unmap-route).
1269+
1. Delete the existing domain(s) with [`cf delete-private-domain`](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#private-domains).
1270+
1. Update the service to account for the deleted domain(s): `cf update-service notify-admin-domain-production -c '{"domains": "example.gov,www.example.gov,..."}'` (make sure to list *all* domains that need to be accounted for, including any existing ones that you want to keep!).
1271+
1272+
**Step 3: Redeploy or restage the Admin app:**
1273+
1274+
Restage or redeploy the `notify-admin-production` app. To restage, you can trigger the action in GitHub or run the command directly: `cf restage notify-admin-production --strategy rolling`.
1275+
1276+
Test that the changes took effect properly by going to the domain(s) that were adjusted and seeing if they resolve correctly and/or no longer resolve as expected. Note that this may take up to 72 hours, depending on how long it takes for the DNS changes to propogate.
12511277
12521278
## Exporting test results for compliance monitoring
12531279
@@ -1507,3 +1533,19 @@ Note: better to search on space 'notify-production' rather than specifically for
15071533
#notify-admin-1505 (general login issues)
15081534
#notify-admin-1701 (wrong sender phone number)
15091535
#notify-admin-1859 (job is created with created_at being the wrong time)
1536+
1537+
### refreshing the login.gov certificate
1538+
1539+
1. generate certificate: `openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.crt -nodes`
1540+
2. update the github secrets for staging, demo, production (contents of key.pem go in LOGIN_PEM and contents of cert.crt in LOGIN_PUB).
1541+
DO NOT RESTAGE YET.
1542+
3. use the same certificate for staging, demo, and production
1543+
4. login to the login.gov partner app (https://portal.int.identitysandbox.gov)
1544+
5. add the new certificate to the production version of Notify in the partner app (our partner app account has sandbox and production)
1545+
6. Make a Zendesk support request for login.gov to push the new version of Notify (https://zendesk.login.gov)
1546+
7. Do not delete the old certificate, because you need things to keep working until you complete the transition.
1547+
8. When you receive an email from login.gov that the app has been pushed successfully, restage notify on the staging tier
1548+
9. If staging works, you can restage demo and production
1549+
10. Delete the old certificate in the partner app, send another zendesk request to push again. This is best practice but a lower
1550+
priority, because certificates eventually expire anyway and we have changed the certificate in github secrets, so the old cert is
1551+
no longer relevant.

package-lock.json

Lines changed: 120 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"socket.io-client": "^4.8.1"
4+
}
5+
}

0 commit comments

Comments
 (0)