Skip to content

Commit 8a4f52d

Browse files
committed
Setup resource migration
1 parent 84ff056 commit 8a4f52d

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

onetime/uinHash-migration.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import json
2+
import boto3
3+
import logging
4+
from botocore.exceptions import ClientError
5+
6+
# --- Configuration ---
7+
SOURCE_TABLE_NAME = "infra-core-api-uin-mapping"
8+
DESTINATION_TABLE_NAME = "infra-core-api-user-info"
9+
DESTINATION_ID_SUFFIX = "@illinois.edu"
10+
11+
# --- Logging Setup ---
12+
logging.basicConfig(
13+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
14+
)
15+
16+
17+
def migrate_uin_hashes():
18+
"""
19+
Scans the source table for netId and uinHash mappings and updates
20+
the corresponding user records in the destination table.
21+
"""
22+
try:
23+
dynamodb = boto3.resource("dynamodb")
24+
destination_table = dynamodb.Table(DESTINATION_TABLE_NAME)
25+
26+
# A paginator is used to handle scanning tables of any size
27+
paginator = dynamodb.meta.client.get_paginator("scan")
28+
page_iterator = paginator.paginate(TableName=SOURCE_TABLE_NAME)
29+
30+
scanned_count = 0
31+
updated_count = 0
32+
logging.info(
33+
f"Starting migration from '{SOURCE_TABLE_NAME}' to '{DESTINATION_TABLE_NAME}'"
34+
)
35+
36+
for page in page_iterator:
37+
for item in page.get("Items", []):
38+
scanned_count += 1
39+
net_id = item.get("netId")
40+
uin_hash = item.get("uinHash")
41+
42+
# Validate that the necessary fields exist
43+
if not net_id or not uin_hash:
44+
logging.warning(
45+
f"Skipping item with missing 'netId' or 'uinHash': {item}"
46+
)
47+
continue
48+
49+
# Construct the primary key and update parameters for the destination table
50+
destination_pk_id = f"{net_id}{DESTINATION_ID_SUFFIX}"
51+
update_expression = "SET uinHash = :uh"
52+
expression_attribute_values = {":uh": uin_hash}
53+
54+
# Update the item in the destination DynamoDB table
55+
try:
56+
destination_table.update_item(
57+
Key={"id": destination_pk_id},
58+
UpdateExpression=update_expression,
59+
ExpressionAttributeValues=expression_attribute_values,
60+
)
61+
updated_count += 1
62+
if updated_count % 100 == 0:
63+
logging.info(
64+
f"Scanned {scanned_count} items, updated {updated_count} so far..."
65+
)
66+
except ClientError as e:
67+
logging.error(
68+
f"Failed to update item with id '{destination_pk_id}': {e}"
69+
)
70+
71+
logging.info("--- Script Finished ---")
72+
logging.info(f"Total items scanned from source: {scanned_count}")
73+
logging.info(f"Total items updated in destination: {updated_count}")
74+
75+
except ClientError as e:
76+
# This will catch errors like table not found, or credential issues
77+
logging.critical(f"A critical AWS error occurred: {e}")
78+
except Exception as e:
79+
logging.critical(f"An unexpected error occurred: {e}")
80+
81+
82+
if __name__ == "__main__":
83+
migrate_uin_hashes()

terraform/modules/dynamo/main.tf

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
resource "null_resource" "onetime_sl_expiration" {
2+
provisioner "local-exec" {
3+
command = <<-EOT
4+
set -e
5+
python uinHash-migration.py
6+
EOT
7+
interpreter = ["bash", "-c"]
8+
working_dir = "${path.module}/../../../onetime/"
9+
}
10+
}
11+
112
resource "aws_dynamodb_table" "app_audit_log" {
213
billing_mode = "PAY_PER_REQUEST"
314
name = "${var.ProjectId}-audit-log"
@@ -320,7 +331,7 @@ resource "aws_dynamodb_table" "cache" {
320331
resource "aws_dynamodb_table" "app_uin_records" {
321332
billing_mode = "PAY_PER_REQUEST"
322333
name = "${var.ProjectId}-uin-mapping"
323-
deletion_protection_enabled = true
334+
deletion_protection_enabled = false
324335
hash_key = "uinHash"
325336
point_in_time_recovery {
326337
enabled = true

terraform/modules/lambdas/main.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,16 @@ resource "aws_iam_policy" "shared_iam_policy" {
268268
]
269269
},
270270
{
271-
Sid = "DynamoDBUINAccess",
271+
Sid = "DynamoDBUserInfoAccess",
272272
Effect = "Allow",
273273
Action = [
274274
"dynamodb:PutItem",
275275
"dynamodb:DescribeTable",
276276
"dynamodb:Query",
277277
],
278278
Resource = [
279-
"arn:aws:dynamodb:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:table/infra-core-api-uin-mapping",
280-
"arn:aws:dynamodb:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:table/infra-core-api-uin-mapping/index/*",
279+
"arn:aws:dynamodb:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:table/infra-core-api-user-info",
280+
"arn:aws:dynamodb:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:table/infra-core-api-user-info/index/*",
281281
]
282282
},
283283
{

0 commit comments

Comments
 (0)