Skip to content

Commit 2ce164e

Browse files
committed
Get production service to work
1 parent dc7f8bc commit 2ce164e

15 files changed

+228
-12
lines changed

automate/deploy_mdf_flow.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@
6767
]))
6868

6969
mdf_flow.save_flow(flow_info_file)
70-
print("scope = ", mdf_flow.get_scope_for_runAs_role('SubmittingUser')['scopes'][0]['id'])
70+
print("scope = ", mdf_flow.get_scope_id_for_runAs_role('SubmittingUser')['scopes'][0]['id'])
7171

7272
print("MDF Flow deployed", mdf_flow)
73-
submitting_user_scope_id = mdf_flow.get_scope_for_runAs_role('SubmittingUser')['scopes'][0]['id']
73+
submitting_user_scope_id = mdf_flow.get_scope_id_for_runAs_role('SubmittingUser')['scopes'][0]['id']
7474

7575
connect_scope_def = {
7676
"scope": {

aws/globus_automate_flow.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ def read_flow(self, path):
157157
self.flow_id = flow_info['flow_id']
158158
self.flow_scope = flow_info['flow_scope']
159159

160-
def get_scope_for_runAs_role(self, rolename):
161-
print("--->RunAsScopes ", self.runAsScopes[rolename])
160+
def get_scope_id_for_runAs_role(self, rolename):
162161
return self.globus_auth.scope_id_from_uri(self.runAsScopes[rolename])
162+
163+
def get_scope_uri_for_runAs_role(self, rolename):
164+
return self.runAsScopes[rolename]

infra/mdf/modules/lambdas/main.tf

+45-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11

2+
#### Create lambda functions for MDF Connect
3+
#### These functions are deployed as container images
4+
#### The container images are built and pushed to ECR by the GitHub Action
5+
#### We explicitly create the log groups so we can tag them and set the retention period
6+
locals {
7+
auth_function_name = "${var.namespace}-auth-${var.env}"
8+
submit_function_name = "${var.namespace}-submit-${var.env}"
9+
status_function_name = "${var.namespace}-status-${var.env}"
10+
submissions_function_name = "${var.namespace}-submissions-${var.env}"
11+
}
12+
213
resource "aws_lambda_function" "mdf-connect-auth" {
3-
function_name = "${var.namespace}-auth-${var.env}"
14+
function_name = local.auth_function_name
415
description = "GlobusAuth Authorizer for MDF Connect"
516
image_uri = "${var.ecr_repos["auth"]}:${var.env}"
617
package_type = "Image"
@@ -10,11 +21,19 @@ resource "aws_lambda_function" "mdf-connect-auth" {
1021
environment {
1122
variables = var.env_vars
1223
}
24+
depends_on = [aws_cloudwatch_log_group.auth_log_group]
25+
tags = var.resource_tags
1326
}
1427

1528

29+
resource "aws_cloudwatch_log_group" "auth_log_group" {
30+
name = "/aws/lambda/${local.auth_function_name}"
31+
retention_in_days = 5
32+
tags = var.resource_tags
33+
}
34+
1635
resource "aws_lambda_function" "mdf-connect-submit" {
17-
function_name = "${var.namespace}-submit-${var.env}"
36+
function_name = local.submit_function_name
1837
description = "Submit Datasets via MDF Connect"
1938
image_uri = "${var.ecr_repos["submit"]}:${var.env}"
2039
package_type = "Image"
@@ -24,10 +43,18 @@ resource "aws_lambda_function" "mdf-connect-submit" {
2443
environment {
2544
variables = var.env_vars
2645
}
46+
depends_on = [aws_cloudwatch_log_group.submit_log_group]
47+
tags = var.resource_tags
48+
}
49+
50+
resource "aws_cloudwatch_log_group" "submit_log_group" {
51+
name = "/aws/lambda/${local.submit_function_name}"
52+
retention_in_days = 5
53+
tags = var.resource_tags
2754
}
2855

2956
resource "aws_lambda_function" "mdf-connect-status" {
30-
function_name = "${var.namespace}-status-${var.env}"
57+
function_name = local.status_function_name
3158
description = "Retrieve submit status via MDF Connect"
3259
image_uri = "${var.ecr_repos["status"]}:${var.env}"
3360
package_type = "Image"
@@ -37,11 +64,18 @@ resource "aws_lambda_function" "mdf-connect-status" {
3764
environment {
3865
variables = var.env_vars
3966
}
67+
depends_on = [aws_cloudwatch_log_group.status_log_group]
68+
tags = var.resource_tags
4069
}
4170

71+
resource "aws_cloudwatch_log_group" "status_log_group" {
72+
name = "/aws/lambda/${local.status_function_name}"
73+
retention_in_days = 5
74+
tags = var.resource_tags
75+
}
4276

4377
resource "aws_lambda_function" "mdf-connect-submissions" {
44-
function_name = "${var.namespace}-submissions-${var.env}"
78+
function_name = local.submissions_function_name
4579
description = "Retrieve history of submissions via MDF Connect"
4680

4781
image_uri = "${var.ecr_repos["submissions"]}:${var.env}"
@@ -53,5 +87,12 @@ resource "aws_lambda_function" "mdf-connect-submissions" {
5387
environment {
5488
variables = var.env_vars
5589
}
90+
depends_on = [aws_cloudwatch_log_group.submissions_log_group]
91+
tags = var.resource_tags
5692
}
5793

94+
resource "aws_cloudwatch_log_group" "submissions_log_group" {
95+
name = "/aws/lambda/${local.submissions_function_name}"
96+
retention_in_days = 5
97+
tags = var.resource_tags
98+
}

infra/mdf/modules/lambdas/variables.tf

+6-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ variable "env_vars" {
2121
variable "ecr_repos" {
2222
description = "Map of lambda function to ECR repo holding the images."
2323
type = map(string)
24-
}
24+
}
25+
26+
variable "resource_tags" {
27+
description = "Tags to apply to all resources."
28+
type = map(string)
29+
}

infra/mdf/modules/permissions/main.tf

+16-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,23 @@ resource "aws_iam_role" "lambda_execution_role" {
1616
}
1717

1818

19-
resource "aws_iam_role_policy_attachment" "AWSLambdaBasicExecutionRole" {
19+
# role
20+
data "aws_iam_policy_document" "lambda_logging_role_policy" {
21+
statement {
22+
actions = [
23+
"logs:CreateLogStream",
24+
"logs:PutLogEvents"
25+
]
26+
resources = [
27+
"arn:aws:logs:*:*:*"
28+
]
29+
}
30+
}
31+
32+
33+
resource "aws_iam_role_policy" "lambda_logging_role" {
2034
role = aws_iam_role.lambda_execution_role.id
21-
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
35+
policy = data.aws_iam_policy_document.lambda_logging_role_policy.json
2236
}
2337

2438
resource "aws_iam_policy" "allow_mdf_secrets_access_policy" {

infra/mdf/prod/main.tf

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ module "lambdas" {
3636
namespace = var.namespace
3737
lambda_execution_role_arn = module.permissions.submit_lambda_invoke_arn
3838
ecr_repos = var.ecr_repos
39+
resource_tags = var.resource_tags
3940
}
4041

4142
module "dynamodb" {

infra/mdf/prod/variables.tf

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ variable "env_vars" {
3030
MANAGE_FLOWS_SCOPE="https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/manage_flows"
3131
MONITOR_BY_GROUP="urn:globus:groups:id:5fc63928-3752-11e8-9c6f-0e00fd09bf20"
3232
PORTAL_URL="https://acdc.alcf.anl.gov/mdf/detail/"
33-
RUN_AS_SCOPE="aa5f9e85-5305-4f9e-9679-95c158e5aa47"
33+
RUN_AS_SCOPE="c096e223-59e8-42fe-85ea-956208b0f878"
3434
SEARCH_INDEX_UUID="1a57bbe5-5272-477f-9d31-343b8258b7a5"
3535
TEST_DATA_DESTINATION="globus://f10a69a9-338c-4e5b-baa1-0dc92359ab47/mdf_testing/"
3636
TEST_SEARCH_INDEX_UUID="5acded0c-a534-45af-84be-dcf042e36412"
@@ -47,4 +47,13 @@ variable "ecr_repos" {
4747
"status" = "557062710055.dkr.ecr.us-east-1.amazonaws.com/mdf-lambdas/status"
4848
"auth" = "557062710055.dkr.ecr.us-east-1.amazonaws.com/mdf-lambdas/auth"
4949
}
50+
}
51+
52+
variable "resource_tags" {
53+
type = map(string)
54+
default = {
55+
"Owner" = "MDF"
56+
"Environment" = "Production"
57+
"Project" = "MDF Connect"
58+
}
5059
}

scripts/get_mdf_token.py

+2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@
99
print("Usage: python get_mdf_token.py <MDF Application URL>")
1010
sys.exit(1)
1111

12+
mdfcc = MDFConnectClient(service_instance=sys.argv[1])
13+
mdfcc.logout()
1214
mdfcc = MDFConnectClient(service_instance=sys.argv[1])
1315
print(mdfcc._MDFConnectClient__authorizer.access_token)

scripts/get_submissions.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from mdf_connect_client import MDFConnectClient
2+
mdfcc = MDFConnectClient(service_instance="dev")
3+
4+
print(mdfcc.check_all_submissions(newer_than_date=(2023, 10, 1)))

scripts/get_token.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import json
2+
import os
3+
import sys
4+
5+
import globus_sdk
6+
7+
if "API_CLIENT_ID" in os.environ:
8+
globus_secrets = {
9+
"API_CLIENT_ID": os.environ["API_CLIENT_ID"],
10+
"API_CLIENT_SECRET": os.environ["API_CLIENT_SECRET"],
11+
"smtp_hostname": os.environ["SMTP_HOSTNAME"],
12+
"smtp_user": os.environ["SMTP_USER"],
13+
"smtp_pass": os.environ["SMTP_PASS"]
14+
}
15+
else:
16+
if len(sys.argv) == 2:
17+
secret_file = f"../automate/.mdfsecrets.{sys.argv[1]}"
18+
else:
19+
secret_file = "../automate/.mdfsecretsCCC"
20+
21+
with open(secret_file, 'r') as f:
22+
globus_secrets = json.load(f)
23+
24+
client = globus_sdk.ConfidentialAppAuthClient(globus_secrets['API_CLIENT_ID'], globus_secrets['API_CLIENT_SECRET'])
25+
scopes = "urn:globus:auth:scope:groups.api.globus.org:all openid email profile " "urn:globus:auth:scope:transfer.api.globus.org:all"
26+
token_response = client.oauth2_client_credentials_tokens(requested_scopes=scopes)
27+
print(token_response)
28+
tokens = token_response.by_resource_server["groups.api.globus.org"]
29+
GROUP_TOKEN = tokens["access_token"]
30+
print("Token ",GROUP_TOKEN)
31+
print(tokens)

scripts/globus_auth_busybox.py

Whitespace-only changes.

scripts/join_mdf_group.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import globus_sdk
2+
CLIENT_ID = 'c296acd8-f454-4ad7-b582-51a48685e775'
3+
CLIENT_SECRET = 'IgkdmTz8cE+7hS/uo8JPmXE7xtsIJ1xg+2AC2AlHF5g='
4+
client = globus_sdk.ConfidentialAppAuthClient(CLIENT_ID, CLIENT_SECRET)
5+
scopes = "urn:globus:auth:scope:groups.api.globus.org:all openid email profile " "urn:globus:auth:scope:transfer.api.globus.org:all"
6+
token_response = client.oauth2_client_credentials_tokens(requested_scopes=scopes)
7+
tokens = token_response.by_resource_server["groups.api.globus.org"]
8+
GROUP_TOKEN = tokens["access_token"]
9+
print("Token ",GROUP_TOKEN)
10+
a = globus_sdk.AccessTokenAuthorizer(GROUP_TOKEN)
11+
groups_client = globus_sdk.GroupsClient(authorizer=a)
12+
batch = globus_sdk.BatchMembershipActions()
13+
batch.join("c296acd8-f454-4ad7-b582-51a48685e775")
14+
groups_client.batch_membership_action("cc192dca-3751-11e8-90c1-0a7c735d220a", batch)
15+
print(groups_client.get_my_groups())
16+

scripts/schemas

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../data-schemas

scripts/status_versions.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import json
2+
import re
3+
import sys
4+
from decimal import Decimal
5+
6+
import boto3
7+
from boto3.dynamodb.conditions import Key
8+
from aws.dynamo_manager import DynamoManager
9+
10+
dynamo_manager = DynamoManager()
11+
v = dynamo_manager.get_current_version('_test_v1')
12+
print(v)
13+
sys.exit(0)
14+
15+
response = dest_table.query(
16+
KeyConditionExpression=
17+
Key('source_name').eq("_test_v1"),
18+
ScanIndexForward=False
19+
)
20+
21+
versions = {str(x['version']): x for x in response['Items']}
22+
print(sorted(versions.keys(), key=lambda x:[int(i) if i.isdigit() else i for i in x.split('.')]))
23+
24+

scripts/update_dynamo.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import json
2+
import re
3+
from decimal import Decimal
4+
from time import sleep
5+
6+
import boto3
7+
from boto3.dynamodb.conditions import Key
8+
from botocore.exceptions import ClientError
9+
10+
RETRY_EXCEPTIONS = ('ProvisionedThroughputExceededException',
11+
'ThrottlingException')
12+
13+
dynamodb = boto3.resource('dynamodb')
14+
table = dynamodb.Table('prod-status-alpha-1')
15+
dest_table = dynamodb.Table('dev-status-0.4')
16+
print(table)
17+
scan_kwargs = {}
18+
19+
done = False
20+
start_key = None
21+
i = 0
22+
version_re = re.compile("(.+)_(v[0-9].*$)")
23+
while not done:
24+
if i > 10:
25+
break
26+
i = i + 1
27+
if start_key:
28+
scan_kwargs['ExclusiveStartKey'] = start_key
29+
response = table.scan(**scan_kwargs)
30+
items = response.get('Items', [])
31+
for item in items:
32+
match = version_re.match(item['source_id'])
33+
if not match:
34+
print("--------->", item['source_id'])
35+
else:
36+
source_name = match.group(1)
37+
version = match.group(2).replace("-", ".")
38+
if "." not in version:
39+
version = version + ".0"
40+
41+
# Remove the leading v
42+
version = version[1:]
43+
print(item['source_id'], f"[{version}] ({source_name})")
44+
new_rec = item.copy()
45+
new_rec['version'] = version
46+
original_submission = json.loads(item['original_submission'])
47+
new_rec['source_id'] = original_submission.get('source_name', source_name)
48+
49+
retries = 0
50+
success = False
51+
while not success:
52+
try:
53+
dest_table.put_item(Item=new_rec)
54+
retries = 0
55+
success = True
56+
except ClientError as err:
57+
if err.response['Error']['Code'] not in RETRY_EXCEPTIONS:
58+
raise
59+
print('WHOA, too fast, slow it down retries={}'.format(retries))
60+
sleep(2 ** retries)
61+
retries += 1 # TODO max limit
62+
63+
start_key = response.get('LastEvaluatedKey', None)
64+
done = start_key is None
65+
66+

0 commit comments

Comments
 (0)