Skip to content

Commit

Permalink
feat: pass AWS clients into handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
sshelomentsev committed Feb 26, 2024
1 parent 02fea3e commit 1aa3dc8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 41 deletions.
45 changes: 13 additions & 32 deletions mgmt-lambda/app.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { APIGatewayProxyEventV2WithRequestContext, APIGatewayEventRequestContextV2 } from 'aws-lambda'
import { SecretsManagerClient, GetSecretValueCommand, GetSecretValueResponse } from '@aws-sdk/client-secrets-manager'
import type { AuthSettings } from './model/AuthSettings'
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager'
import { getAuthSettings } from './auth'
import type { DeploymentSettings } from './model/DeploymentSettings'
import { handleNoAthentication, handleWrongConfiguration, handleNotFound } from './handlers/errorHandlers'
import { defaults } from './DefaultSettings'
import { handleStatus } from './handlers/statusHandler'
import { handleUpdate } from './handlers/updateHandler'
import { LambdaClient } from '@aws-sdk/client-lambda'
import { CloudFrontClient } from '@aws-sdk/client-cloudfront'

export async function handler(event: APIGatewayProxyEventV2WithRequestContext<APIGatewayEventRequestContextV2>) {
console.info(JSON.stringify(event))

const authSettings = await getAuthSettings()
const secretManagerClient = new SecretsManagerClient({ region: defaults.AWS_REGION })
const authSettings = await getAuthSettings(secretManagerClient)
console.info(authSettings)

const authorization = event.headers['authorization']
Expand All @@ -26,42 +30,19 @@ export async function handler(event: APIGatewayProxyEventV2WithRequestContext<AP

const path = event.rawPath
console.info(`path = ${path}`)

const lambdaClient = new LambdaClient({ region: defaults.AWS_REGION })
const cloudFrontClient = new CloudFrontClient({ region: defaults.AWS_REGION })

if (path.startsWith('/update')) {
return handleUpdate(deploymentSettings)
return handleUpdate(lambdaClient, cloudFrontClient, deploymentSettings)
} else if (path.startsWith('/status')) {
return handleStatus(deploymentSettings)
return handleStatus(lambdaClient, deploymentSettings)
} else {
return handleNotFound()
}
}

async function getAuthSettings(): Promise<AuthSettings> {
console.info(JSON.stringify(process.env))
const secretName = process.env.SettingsSecretName
if (!secretName) {
throw new Error('Unable to get secret name. ')
}

try {
const client = new SecretsManagerClient({
region: 'us-east-1',
})
const command = new GetSecretValueCommand({
SecretId: secretName,
})

const response: GetSecretValueResponse = await client.send(command)

if (!response.SecretString) {
throw new Error('Secret is empty')
}

return JSON.parse(response.SecretString)
} catch (error) {
throw new Error(`Unable to retrieve secret, ${error}`)
}
}

function loadDeploymentSettings(): DeploymentSettings {
const cfDistributionId = process.env.CFDistributionId
if (!cfDistributionId) {
Expand Down
27 changes: 27 additions & 0 deletions mgmt-lambda/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { AuthSettings } from './model/AuthSettings'
import { SecretsManagerClient, GetSecretValueCommand, GetSecretValueResponse } from '@aws-sdk/client-secrets-manager'

export async function getAuthSettings(secretManagerClient: SecretsManagerClient): Promise<AuthSettings> {
const secretName = process.env.SettingsSecretName
if (!secretName) {
throw new Error('Unable to retrieve secret. Error: unable to get secret name')
}

try {
const command = new GetSecretValueCommand({
SecretId: secretName,
})

const response: GetSecretValueResponse = await secretManagerClient.send(command)

if (response.SecretBinary) {
return JSON.parse(Buffer.from(response.SecretBinary).toString('utf8'))
} else if (response.SecretString) {
return JSON.parse(response.SecretString)
} else {
throw new Error('secret is empty')
}
} catch (error: any) {
throw new Error(`Unable to retrieve secret. ${error}`)
}
}
8 changes: 5 additions & 3 deletions mgmt-lambda/handlers/statusHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { APIGatewayProxyResult } from 'aws-lambda'
import type { DeploymentSettings } from '../model/DeploymentSettings'
import { LambdaClient, GetFunctionCommand } from '@aws-sdk/client-lambda'

export async function handleStatus(settings: DeploymentSettings): Promise<APIGatewayProxyResult> {
const client = new LambdaClient({})
export async function handleStatus(
lambdaClient: LambdaClient,
settings: DeploymentSettings,
): Promise<APIGatewayProxyResult> {
const command = new GetFunctionCommand({ FunctionName: settings.LambdaFunctionName })
const functionResult = await client.send(command)
const functionResult = await lambdaClient.send(command)

return {
statusCode: 200,
Expand Down
18 changes: 12 additions & 6 deletions mgmt-lambda/handlers/updateHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,38 @@ import {
UpdateFunctionCodeCommand,
} from '@aws-sdk/client-lambda'

export async function handleUpdate(settings: DeploymentSettings): Promise<APIGatewayProxyResult> {
export async function handleUpdate(
lambdaClient: LambdaClient,
cloudFrontClient: CloudFrontClient,
settings: DeploymentSettings,
): Promise<APIGatewayProxyResult> {
console.info(`Going to upgrade Fingerprint Pro function association at CloudFront distbution.`)
console.info(`Settings: ${settings}`)

const lambdaClient = new LambdaClient({ region: defaults.AWS_REGION })

const latestFunctionArn = await getLambdaLatestVersionArn(lambdaClient, settings.LambdaFunctionName)
if (!latestFunctionArn) {
return handleResult('No lambda version')
}

try {
const functionVersionArn = await updateLambdaFunctionCode(lambdaClient, settings.LambdaFunctionName)
return updateCloudFrontConfig(settings.CFDistributionId, settings.LambdaFunctionName, functionVersionArn)
return updateCloudFrontConfig(
cloudFrontClient,
settings.CFDistributionId,
settings.LambdaFunctionName,
functionVersionArn,
)
} catch (error) {
return handleResult(error)
}
}

async function updateCloudFrontConfig(
cloudFrontClient: CloudFrontClient,
cloudFrontDistributionId: string,
lambdaFunctionName: string,
latestFunctionArn: string,
) {
const cloudFrontClient = new CloudFrontClient({ region: defaults.AWS_REGION })

const configParams = {
Id: cloudFrontDistributionId,
}
Expand Down

0 comments on commit 1aa3dc8

Please sign in to comment.