Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion templates/1-StartingBlocks-Main-Template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ Resources:
SNSTopicArn: !Ref SNSTopicArn
SlackWebhookUrl: !Ref SlackWebhookUrl
KmsKeyId: !GetAtt 'SharedResourcesStack.Outputs.KeyId'
DeploySwagger: !Ref 'DeploySwagger'

DatabaseStack:
Type: AWS::CloudFormation::Stack
Expand Down Expand Up @@ -725,12 +726,16 @@ Resources:
HostedZoneId: !Ref 'HostedZoneId'
S3SourceBucket: !Ref 'S3SourceBucket'
DomainName: !Ref 'DomainName'
SwaggerDefaultURL: !Sub 'https://swaggerui.${DomainName}/metadata/data/v3/resources/swagger.json'
SwaggerDefaultURL: !If
- UseDefaultWebApiZip
- !Sub 'https://api.ed-fi.org/v${EdFiApiVersion}/api/metadata/data/v3/resources/swagger.json'
- ''
CRHelperLambdaLayer: !GetAtt 'LambdaCoreStack.Outputs.CRHelperLambdaLayer'
Partner: !Ref 'Partner'
LambdaDefaultSGID: !GetAtt 'SharedResourcesStack.Outputs.LambdaDefaultSGID'
PrivateSubnet1Id: !Ref 'PrivateSubnet1Id'
PrivateSubnet2Id: !Ref 'PrivateSubnet2Id'
KmsKeyId: !GetAtt 'SharedResourcesStack.Outputs.KeyId'

StateMachineStack:
Type: AWS::CloudFormation::Stack
Expand Down
26 changes: 25 additions & 1 deletion templates/x-lambda-core-functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ Parameters:
KmsKeyId:
Description: The KMS Key ID used to encrypt resources in this deployment.
Type: String
DeploySwagger:
Type: String
Description: If enabled, Swagger UI will be deployed to swagger-ui.{DomainName}

Conditions:
UseAdminApi: !Equals [!Ref 'AdminInterface', "Ed-Fi Admin API"]
Expand Down Expand Up @@ -728,6 +731,11 @@ Resources:
- kms:Decrypt
Resource:
- !Sub 'arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${KmsKeyId}'
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${EnvLabel}-SwaggerUpdate'

TenantManagementFunction:
Type: AWS::Lambda::Function
Expand All @@ -753,6 +761,7 @@ Resources:
Variables:
ENVLABEL: !Ref EnvLabel
TENANCY_MODE: !Ref EdFiTenancyMode
DEPLOY_SWAGGER: !Ref 'DeploySwagger'
Code:
ZipFile: |
import json
Expand Down Expand Up @@ -1055,7 +1064,13 @@ Resources:
)

return response['Command']['Status']


def update_swagger(env_label):
lambda_client = boto3.client('lambda')
lambda_response = lambda_client.invoke(
FunctionName=f'{env_label}-SwaggerUpdate',
InvocationType='Event'
)

def lambda_handler(event, context):
conn = None
Expand All @@ -1069,6 +1084,7 @@ Resources:

env_label = os.environ['ENVLABEL']
secret_name = env_label + '-AuroraMasterSecret'
deploy_swagger = os.environ['DEPLOY_SWAGGER']

# Concatenate "-tenants" to env_label for the DynamoDB table name
table_name = env_label + '-tenants'
Expand Down Expand Up @@ -1110,6 +1126,10 @@ Resources:
# Add item to DynamoDB
response = add_item(table, tenant_name, allowed_ed_orgs)

# Update Swagger if needed
if deploy_swagger == 'True':
update_swagger(env_label)

print("Item added successfully, and template databases cloned")
return "Item added successfully, and template databases cloned"
elif action == 'Remove':
Expand All @@ -1131,6 +1151,10 @@ Resources:

# Delete tenant-specific databases
delete_tenant_databases(conn, tenant_name)

# Update Swagger if needed
if deploy_swagger == 'True':
update_swagger(env_label)

print("Item removed successfully, and tenant-specific databases deleted")
return "Item removed successfully, and tenant-specific databases deleted"
Expand Down
42 changes: 39 additions & 3 deletions templates/x-swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Parameters:
PrivateSubnet2Id:
Type: AWS::EC2::Subnet::Id
Description: ID of the private subnet 2 in Availability Zone 2 (e.g., subnet-a0246dcd)
KmsKeyId:
Description: The KMS Key ID used to encrypt dynamodb.
Type: String
Resources:
S3SwaggerFEBucket:
Type: AWS::S3::Bucket
Expand Down Expand Up @@ -388,6 +391,16 @@ Resources:
Resource:
- !Sub 'arn:${AWS::Partition}:s3:::${S3SwaggerFEBucket}'
- !Sub 'arn:${AWS::Partition}:s3:::${S3SwaggerFEBucket}/*'
- Effect: Allow
Action:
- dynamodb:Scan
Resource:
- !Sub 'arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${EnvLabel}-tenants*'
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- !Sub 'arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${KmsKeyId}*'
Roles:
- !Ref 'SwaggerLambdaRole'
SwaggerLambdaAWSCLILayer:
Expand Down Expand Up @@ -417,13 +430,16 @@ Resources:
- !Ref SwaggerLambdaAWSCLILayer
- !Ref 'CRHelperLambdaLayer'
ReservedConcurrentExecutions: 1
FunctionName: !Sub '${EnvLabel}-SwaggerUpdate'
Description: Updates and deploys Swagger UI in S3
Handler: index.lambda_handler
Environment:
Variables:
S3_BUCKET: !Ref S3SwaggerFEBucket
CF_DISTRIBUTION: !Ref CloudFront
DEFAULT_URL: !Ref SwaggerDefaultURL
DOMAIN_NAME: !Ref DomainName
ENV_LABEL: !Ref EnvLabel
Runtime: python3.11
MemorySize: 128
Role: !GetAtt 'SwaggerLambdaRole.Arn'
Expand All @@ -444,11 +460,15 @@ Resources:
import boto3
from zipfile import ZipFile
from crhelper import CfnResource

from datetime import datetime

helper = CfnResource()

def lambda_handler(event, context):
helper(event, context)
if "StackId" in event:
helper(event, context)
else:
create(event, context)

@helper.create
@helper.update
Expand All @@ -457,7 +477,23 @@ Resources:
the_bucket = os.environ['S3_BUCKET']
cf_dist = os.environ['CF_DISTRIBUTION']
swagger_url = os.environ['DEFAULT_URL']
domain_name = os.environ['DOMAIN_NAME']
env_label = os.environ['ENV_LABEL']
http = urllib3.PoolManager()

# Check dynamodb for tenants and replace swagger_url if one exists
ddb_table_name = env_label + '-tenants'
ddb = boto3.resource('dynamodb')
ddb_table = ddb.Table(ddb_table_name)
ddb_response = ddb_table.scan()
ddb_data = ddb_response['Items']
# Handle pagination for large tables.
while ddb_response.get('LastEvaluatedKey'):
ddb_response = ddb_table.scan(ExclusiveStartKey=ddb_response['LastEvaluatedKey'])
ddb_data.extend(ddb_response['Items'])
if len(ddb_data) > 0:
tenant = ddb_data[0]['Name']
swagger_url = f'https://swaggerui.{domain_name}/{tenant}/metadata/data/v3/resources/swagger.json'
print(swagger_url)

url = 'https://github.com/swagger-api/swagger-ui/releases/latest'
Expand Down Expand Up @@ -513,7 +549,7 @@ Resources:
'/*',
]
},
'CallerReference': v
'CallerReference': str(datetime.now())
}
)

Expand Down