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

feat: update all cache behavior that has Fingerprint pro association #186

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
3 changes: 2 additions & 1 deletion mgmt-lambda/DefaultSettings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const defaults = {
AWS_REGION: 'us-east-1',
LAMBDA_DISTRIBUTION_BUCKET: 'fingerprint-pro-cloudfront-integration-lambda-function',
LAMBDA_DISTRIBUTION_BUCKET_KEY: 'release/lambda_latest.zip',
LAMBDA_DISTRIBUTION_BUCKET_KEY: 'releaseV2/lambda_latest.zip',
LAMBDA_HANDLER_NAME: 'fingerprintjs-pro-cloudfront-lambda-function.handler',
FP_CDN_URL: 'fpcdn.io',
}
1 change: 1 addition & 0 deletions mgmt-lambda/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export async function handler(
try {
return await handleUpdate(lambdaClient, cloudFrontClient, deploymentSettings)
} catch (e: any) {
console.error(e)
return handleError(e)
}
}
Expand Down
92 changes: 70 additions & 22 deletions mgmt-lambda/handlers/updateHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
settings: DeploymentSettings,
): Promise<APIGatewayProxyResult> {
console.info(`Going to upgrade Fingerprint Pro function association at CloudFront distribution.`)
console.info(`Settings: ${settings}`)
console.info(`Settings: ${JSON.stringify(settings)}`)

const isLambdaFunctionExist = await checkIfLambdaFunctionWithNameExists(lambdaClient, settings.LambdaFunctionName)
if (!isLambdaFunctionExist) {
Expand Down Expand Up @@ -71,20 +71,67 @@
throw new ApiException(ErrorCode.CloudFrontDistributionNotFound)
}

const cacheBehaviors = cfConfig.DistributionConfig.CacheBehaviors
const fpCbs = cacheBehaviors?.Items?.filter((it) => it.TargetOriginId === 'fpcdn.io')
if (!fpCbs || fpCbs?.length === 0) {
const distributionConfig = cfConfig.DistributionConfig

let fpCacheBehaviorsFound = 0
let fpCacheBehaviorsUpdated = 0
const pathPatterns = []

if (distributionConfig.DefaultCacheBehavior?.TargetOriginId === defaults.FP_CDN_URL) {
fpCacheBehaviorsFound++
const lambdas = distributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations?.Items?.filter(
(it) => it && it.EventType === 'origin-request' && it.LambdaFunctionARN?.includes(`${lambdaFunctionName}:`),

Check warning on line 83 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 83 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

Check warning on line 83 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

Check warning on line 83 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

Check warning on line 83 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
)
if (lambdas?.length === 1) {
lambdas[0].LambdaFunctionARN = latestFunctionArn

Check warning on line 86 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
fpCacheBehaviorsUpdated++

Check warning on line 87 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
pathPatterns.push('/*')

Check warning on line 88 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
console.info('Updated Fingerprint Pro Lambda@Edge function association in the default cache behavior')

Check warning on line 89 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
} else {
console.info(
'The default cache behavior has targeted to FP CDN, but has no Fingerprint Pro Lambda@Edge association',
)
}

Check warning on line 94 in mgmt-lambda/handlers/updateHandler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
}

const fpCbs = distributionConfig.CacheBehaviors?.Items?.filter((it) => it.TargetOriginId === defaults.FP_CDN_URL)
if (fpCbs && fpCbs?.length > 0) {
fpCacheBehaviorsFound += fpCbs.length
fpCbs.forEach((cacheBehavior) => {
const lambdas = cacheBehavior.LambdaFunctionAssociations?.Items?.filter(
(it) => it && it.EventType === 'origin-request' && it.LambdaFunctionARN?.includes(`${lambdaFunctionName}:`),
)
if (lambdas?.length === 1) {
lambdas[0].LambdaFunctionARN = latestFunctionArn
fpCacheBehaviorsUpdated++
if (cacheBehavior.PathPattern) {
let pathPattern = cacheBehavior.PathPattern
if (!cacheBehavior.PathPattern.startsWith('/')) {
pathPattern = '/' + pathPattern
}
pathPatterns.push(pathPattern)
} else {
console.error(`Path pattern is not defined for cache behavior ${JSON.stringify(cacheBehavior)}`)
}
} else {
console.info(
`Cache behavior ${JSON.stringify(
cacheBehavior,
)} has targeted to FP CDN, but has no Fingerprint Pro Lambda@Edge association`,
)
}
})
}

if (fpCacheBehaviorsFound === 0) {
throw new ApiException(ErrorCode.CacheBehaviorNotFound)
}
const cacheBehavior = fpCbs[0]
const lambdas = cacheBehavior.LambdaFunctionAssociations?.Items?.filter(
(it) => it && it.EventType === 'origin-request' && it.LambdaFunctionARN?.includes(`${lambdaFunctionName}:`),
)
if (!lambdas || lambdas?.length === 0) {
if (fpCacheBehaviorsUpdated === 0) {
throw new ApiException(ErrorCode.LambdaFunctionAssociationNotFound)
}
const lambda = lambdas[0]
lambda.LambdaFunctionARN = latestFunctionArn
if (pathPatterns.length === 0) {
throw new ApiException(ErrorCode.CacheBehaviorPatternNotDefined)
}

const updateParams: UpdateDistributionCommandInput = {
DistributionConfig: cfConfig.DistributionConfig,
Expand All @@ -97,21 +144,20 @@
console.info(`CloudFront update has finished, ${JSON.stringify(updateCFResult)}`)

console.info('Going to invalidate routes for upgraded cache behavior')
if (!cacheBehavior.PathPattern) {
throw new ApiException(ErrorCode.CacheBehaviorPatternNotDefined)
}

let pathPattern = cacheBehavior.PathPattern
if (!pathPattern.startsWith('/')) {
pathPattern = '/' + pathPattern
}
invalidateFingerprintIntegrationCache(cloudFrontClient, cloudFrontDistributionId, pathPatterns)
}

async function invalidateFingerprintIntegrationCache(
cloudFrontClient: CloudFrontClient,
distributionId: string,
pathPatterns: string[],
) {
const invalidationParams: CreateInvalidationCommandInput = {
DistributionId: cloudFrontDistributionId,
DistributionId: distributionId,
InvalidationBatch: {
Paths: {
Quantity: 1,
Items: [pathPattern],
Items: pathPatterns,
},
CallerReference: 'fingerprint-pro-management-lambda-function',
},
Expand All @@ -133,9 +179,11 @@
FunctionName: functionName,
Publish: true,
})
console.info('Sending update command to Lambda runtime')
console.info(`Sending update command to Lambda runtime with data ${JSON.stringify(command)}`)
const result = await lambdaClient.send(command)

console.info(`Got update command result: ${JSON.stringify(result)}`)

if (!result) {
throw new ApiException(ErrorCode.LambdaFunctionARNNotFound)
}
Expand Down
10 changes: 5 additions & 5 deletions mgmt-lambda/test/app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ describe('Update endpoint', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -363,7 +363,7 @@ describe('Update endpoint', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'incorrect',
Publish: true,
})
Expand Down Expand Up @@ -444,7 +444,7 @@ describe('Update endpoint', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -486,7 +486,7 @@ describe('Update endpoint', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -554,7 +554,7 @@ describe('Update endpoint', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down
12 changes: 6 additions & 6 deletions mgmt-lambda/test/handlers/handleUpdate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -224,7 +224,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -303,7 +303,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -400,7 +400,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -433,7 +433,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down Expand Up @@ -496,7 +496,7 @@ describe('Handle mgmt-update', () => {
lambdaMock
.on(UpdateFunctionCodeCommand, {
S3Bucket: 'fingerprint-pro-cloudfront-integration-lambda-function',
S3Key: 'release/lambda_latest.zip',
S3Key: 'releaseV2/lambda_latest.zip',
FunctionName: 'fingerprint-pro-lambda-function',
Publish: true,
})
Expand Down
Loading