From 403680cf76058fbfa75ad38619466fc2fcf2d522 Mon Sep 17 00:00:00 2001 From: Sergey Shelomentsev Date: Wed, 20 Dec 2023 00:52:13 +0200 Subject: [PATCH] feat: update lambda existence check --- mgmt-lambda/handlers/updateHandler.ts | 32 ++++++------- .../test/handlers/handleUpdate.test.ts | 45 +++++++------------ 2 files changed, 31 insertions(+), 46 deletions(-) diff --git a/mgmt-lambda/handlers/updateHandler.ts b/mgmt-lambda/handlers/updateHandler.ts index 90996f5c..b40e6495 100644 --- a/mgmt-lambda/handlers/updateHandler.ts +++ b/mgmt-lambda/handlers/updateHandler.ts @@ -12,10 +12,10 @@ import { } from '@aws-sdk/client-cloudfront' import { LambdaClient, - ListVersionsByFunctionCommand, - ListVersionsByFunctionCommandInput, - ListVersionsByFunctionCommandOutput, + GetFunctionCommand, UpdateFunctionCodeCommand, + GetFunctionCommandInput, + GetFunctionCommandOutput, } from '@aws-sdk/client-lambda' export async function handleUpdate( @@ -26,9 +26,9 @@ export async function handleUpdate( console.info(`Going to upgrade Fingerprint Pro function association at CloudFront distbution.`) console.info(`Settings: ${settings}`) - const latestFunctionArn = await getLambdaLatestVersionArn(lambdaClient, settings.LambdaFunctionName) - if (!latestFunctionArn) { - return handleFailure('No lambda version') + const isLambdaFunctionExist = await checkLambdaFunctionExistance(lambdaClient, settings.LambdaFunctionName) + if (!isLambdaFunctionExist) { + return handleFailure(`Lambda function with name ${settings.LambdaFunctionName} not found`) } try { @@ -67,7 +67,7 @@ async function updateCloudFrontConfig( } const cacheBehavior = fpCbs[0] const lambdas = cacheBehavior.LambdaFunctionAssociations?.Items?.filter( - (it) => it && it.EventType === 'origin-request' && it.LambdaFunctionARN?.includes(lambdaFunctionName), + (it) => it && it.EventType === 'origin-request' && it.LambdaFunctionARN?.includes(`${lambdaFunctionName}:`), ) if (!lambdas || lambdas?.length === 0) { return handleFailure('Lambda function association not found') @@ -130,20 +130,16 @@ async function updateLambdaFunctionCode(lambdaClient: LambdaClient, functionName return result.FunctionArn } -async function getLambdaLatestVersionArn(client: LambdaClient, functionName: string): Promise { - const params: ListVersionsByFunctionCommandInput = { +async function checkLambdaFunctionExistance(client: LambdaClient, functionName: string): Promise { + const params: GetFunctionCommandInput = { FunctionName: functionName, } - const command = new ListVersionsByFunctionCommand(params) - const result: ListVersionsByFunctionCommandOutput = await client.send(command) - if (!result.Versions || result.Versions?.length === 0) { - return Promise.resolve(undefined) + const command = new GetFunctionCommand(params) + const result: GetFunctionCommandOutput = await client.send(command) + if (!result.Configuration?.FunctionArn) { + return false } - - const latest = result.Versions.filter((it) => it.Version && Number.isFinite(Number.parseInt(it.Version))).sort( - (a, b) => Number.parseInt(b.Version!!) - Number.parseInt(a.Version!!), - )[0] - return Promise.resolve(latest.FunctionArn) + return true } async function handleFailure(message?: any): Promise { diff --git a/mgmt-lambda/test/handlers/handleUpdate.test.ts b/mgmt-lambda/test/handlers/handleUpdate.test.ts index 91a3b38c..810f9e7c 100644 --- a/mgmt-lambda/test/handlers/handleUpdate.test.ts +++ b/mgmt-lambda/test/handlers/handleUpdate.test.ts @@ -3,8 +3,6 @@ import { LambdaClient, GetFunctionCommand, GetFunctionResponse, - ListVersionsByFunctionCommand, - ListVersionsByFunctionResponse, UpdateFunctionCodeCommand, } from '@aws-sdk/client-lambda' import { @@ -30,19 +28,10 @@ const settings: DeploymentSettings = { LambdaFunctionName: 'fingerprint-pro-lambda-function', } -const existingLambdaVersions: ListVersionsByFunctionResponse = { - Versions: [ - { - FunctionName: 'fingerprint-pro-lambda-function', - FunctionArn: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function:2', - Version: '2', - }, - { - FunctionName: 'fingerprint-pro-lambda-function', - FunctionArn: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function:1', - Version: '1', - }, - ], +const existingLambda: GetFunctionResponse = { + Configuration: { + FunctionArn: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function', + }, } const functionInfo: GetFunctionResponse = { @@ -81,7 +70,7 @@ const cloudFrontConfigBeforeUpdate: GetDistributionConfigResult = { Quantity: 1, Items: [ { - LambdaFunctionARN: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function', + LambdaFunctionARN: 'arn:aws:lambda:us-east-1:1234567890:function:fingerprint-pro-lambda-function:1', EventType: 'origin-request', IncludeBody: true, }, @@ -158,10 +147,10 @@ describe('Handle mgmt-update', () => { it('basic test', async () => { lambdaMock - .on(ListVersionsByFunctionCommand, { + .on(GetFunctionCommand, { FunctionName: settings.LambdaFunctionName, }) - .resolves(existingLambdaVersions) + .resolves(existingLambda) lambdaMock .on(GetFunctionCommand, { @@ -189,7 +178,7 @@ describe('Handle mgmt-update', () => { const result = await handleUpdate(lambdaClient, cloudFrontClient, settings) expect(result.statusCode).toBe(200) - expect(lambdaMock).toHaveReceivedCommandTimes(ListVersionsByFunctionCommand, 1) + expect(lambdaMock).toHaveReceivedCommandTimes(GetFunctionCommand, 1) expect(lambdaMock).toHaveReceivedCommandTimes(UpdateFunctionCodeCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(GetDistributionConfigCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(UpdateDistributionCommand, 1) @@ -198,7 +187,7 @@ describe('Handle mgmt-update', () => { it('No lambda version', async () => { lambdaMock - .on(ListVersionsByFunctionCommand, { + .on(GetFunctionCommand, { FunctionName: settings.LambdaFunctionName, }) .resolves({}) @@ -206,9 +195,9 @@ describe('Handle mgmt-update', () => { const result = await handleUpdate(lambdaClient, cloudFrontClient, settings) expect(result.statusCode).toBe(500) const error = JSON.parse(result.body)['error'] - expect(error).toBe('No lambda version') + expect(error).toBe('Lambda function with name fingerprint-pro-lambda-function not found') - expect(lambdaMock).toHaveReceivedCommandTimes(ListVersionsByFunctionCommand, 1) + expect(lambdaMock).toHaveReceivedCommandTimes(GetFunctionCommand, 1) expect(lambdaMock).toHaveReceivedCommandTimes(UpdateFunctionCodeCommand, 0) expect(cloudFrontMock).toHaveReceivedCommandTimes(GetDistributionConfigCommand, 0) expect(cloudFrontMock).toHaveReceivedCommandTimes(UpdateDistributionCommand, 0) @@ -217,10 +206,10 @@ describe('Handle mgmt-update', () => { it('CloudFront has no fpjs cache behavior', async () => { lambdaMock - .on(ListVersionsByFunctionCommand, { + .on(GetFunctionCommand, { FunctionName: settings.LambdaFunctionName, }) - .resolves(existingLambdaVersions) + .resolves(existingLambda) lambdaMock .on(GetFunctionCommand, { @@ -286,7 +275,7 @@ describe('Handle mgmt-update', () => { const error = JSON.parse(result.body)['error'] expect(error).toBe('Cache behavior not found') - expect(lambdaMock).toHaveReceivedCommandTimes(ListVersionsByFunctionCommand, 1) + expect(lambdaMock).toHaveReceivedCommandTimes(GetFunctionCommand, 1) expect(lambdaMock).toHaveReceivedCommandTimes(UpdateFunctionCodeCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(GetDistributionConfigCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(UpdateDistributionCommand, 0) @@ -295,10 +284,10 @@ describe('Handle mgmt-update', () => { it('CloudFront cache behavior without lambda association', async () => { lambdaMock - .on(ListVersionsByFunctionCommand, { + .on(GetFunctionCommand, { FunctionName: settings.LambdaFunctionName, }) - .resolves(existingLambdaVersions) + .resolves(existingLambda) lambdaMock .on(GetFunctionCommand, { @@ -354,7 +343,7 @@ describe('Handle mgmt-update', () => { const error = JSON.parse(result.body)['error'] expect(error).toBe('Lambda function association not found') - expect(lambdaMock).toHaveReceivedCommandTimes(ListVersionsByFunctionCommand, 1) + expect(lambdaMock).toHaveReceivedCommandTimes(GetFunctionCommand, 1) expect(lambdaMock).toHaveReceivedCommandTimes(UpdateFunctionCodeCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(GetDistributionConfigCommand, 1) expect(cloudFrontMock).toHaveReceivedCommandTimes(UpdateDistributionCommand, 0)