fb0fd99a38
- narrowing error handling in aws sdk usage - updating dto to authorize null descriptions
154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import fs from 'fs';
|
|
|
|
import {
|
|
CreateFunctionCommand,
|
|
Lambda,
|
|
LambdaClientConfig,
|
|
InvokeCommand,
|
|
GetFunctionCommand,
|
|
UpdateFunctionCodeCommand,
|
|
DeleteFunctionCommand,
|
|
ResourceNotFoundException,
|
|
} from '@aws-sdk/client-lambda';
|
|
import { CreateFunctionCommandInput } from '@aws-sdk/client-lambda/dist-types/commands/CreateFunctionCommand';
|
|
import { UpdateFunctionCodeCommandInput } from '@aws-sdk/client-lambda/dist-types/commands/UpdateFunctionCodeCommand';
|
|
|
|
import { ServerlessDriver } from 'src/engine/integrations/serverless/drivers/interfaces/serverless-driver.interface';
|
|
|
|
import { createZipFile } from 'src/engine/integrations/serverless/drivers/utils/create-zip-file';
|
|
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
|
import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service';
|
|
import { BaseServerlessDriver } from 'src/engine/integrations/serverless/drivers/base-serverless.driver';
|
|
import { BuildDirectoryManagerService } from 'src/engine/integrations/serverless/drivers/services/build-directory-manager.service';
|
|
|
|
export interface LambdaDriverOptions extends LambdaClientConfig {
|
|
fileStorageService: FileStorageService;
|
|
buildDirectoryManagerService: BuildDirectoryManagerService;
|
|
region: string;
|
|
role: string;
|
|
}
|
|
|
|
export class LambdaDriver
|
|
extends BaseServerlessDriver
|
|
implements ServerlessDriver
|
|
{
|
|
private readonly lambdaClient: Lambda;
|
|
private readonly lambdaRole: string;
|
|
private readonly fileStorageService: FileStorageService;
|
|
private readonly buildDirectoryManagerService: BuildDirectoryManagerService;
|
|
|
|
constructor(options: LambdaDriverOptions) {
|
|
super();
|
|
const { region, role, ...lambdaOptions } = options;
|
|
|
|
this.lambdaClient = new Lambda({ ...lambdaOptions, region });
|
|
this.lambdaRole = role;
|
|
this.fileStorageService = options.fileStorageService;
|
|
this.buildDirectoryManagerService = options.buildDirectoryManagerService;
|
|
}
|
|
|
|
private async checkFunctionExists(
|
|
serverlessFunctionId: string,
|
|
): Promise<boolean> {
|
|
try {
|
|
const getFunctionCommand = new GetFunctionCommand({
|
|
FunctionName: serverlessFunctionId,
|
|
});
|
|
|
|
await this.lambdaClient.send(getFunctionCommand);
|
|
|
|
return true;
|
|
} catch (error) {
|
|
if (error instanceof ResourceNotFoundException) {
|
|
return false;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async delete(serverlessFunction: ServerlessFunctionEntity) {
|
|
const functionExists = await this.checkFunctionExists(
|
|
serverlessFunction.id,
|
|
);
|
|
|
|
if (functionExists) {
|
|
const deleteFunctionCommand = new DeleteFunctionCommand({
|
|
FunctionName: serverlessFunction.id,
|
|
});
|
|
|
|
await this.lambdaClient.send(deleteFunctionCommand);
|
|
}
|
|
}
|
|
|
|
async build(serverlessFunction: ServerlessFunctionEntity) {
|
|
const javascriptCode = await this.getCompiledCode(
|
|
serverlessFunction,
|
|
this.fileStorageService,
|
|
);
|
|
|
|
const {
|
|
sourceTemporaryDir,
|
|
lambdaZipPath,
|
|
javascriptFilePath,
|
|
lambdaHandler,
|
|
} = await this.buildDirectoryManagerService.init();
|
|
|
|
await fs.promises.writeFile(javascriptFilePath, javascriptCode);
|
|
|
|
await createZipFile(sourceTemporaryDir, lambdaZipPath);
|
|
|
|
const functionExists = await this.checkFunctionExists(
|
|
serverlessFunction.id,
|
|
);
|
|
|
|
if (!functionExists) {
|
|
const params: CreateFunctionCommandInput = {
|
|
Code: {
|
|
ZipFile: await fs.promises.readFile(lambdaZipPath),
|
|
},
|
|
FunctionName: serverlessFunction.id,
|
|
Handler: lambdaHandler,
|
|
Role: this.lambdaRole,
|
|
Runtime: serverlessFunction.runtime,
|
|
Description: 'Lambda function to run user script',
|
|
Timeout: 900,
|
|
};
|
|
|
|
const command = new CreateFunctionCommand(params);
|
|
|
|
await this.lambdaClient.send(command);
|
|
} else {
|
|
const params: UpdateFunctionCodeCommandInput = {
|
|
ZipFile: await fs.promises.readFile(lambdaZipPath),
|
|
FunctionName: serverlessFunction.id,
|
|
};
|
|
|
|
const command = new UpdateFunctionCodeCommand(params);
|
|
|
|
await this.lambdaClient.send(command);
|
|
}
|
|
|
|
await this.buildDirectoryManagerService.clean();
|
|
}
|
|
|
|
async execute(
|
|
functionToExecute: ServerlessFunctionEntity,
|
|
payload: object | undefined = undefined,
|
|
): Promise<object> {
|
|
const params = {
|
|
FunctionName: functionToExecute.id,
|
|
Payload: JSON.stringify(payload),
|
|
};
|
|
|
|
const command = new InvokeCommand(params);
|
|
|
|
const result = await this.lambdaClient.send(command);
|
|
|
|
if (!result.Payload) {
|
|
return {};
|
|
}
|
|
|
|
return JSON.parse(result.Payload.transformToString());
|
|
}
|
|
}
|