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

Create cloudformation client #580

Merged
merged 2 commits into from
Sep 20, 2023
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
2,255 changes: 2,129 additions & 126 deletions package-lock.json

Large diffs are not rendered by default.

2,135 changes: 2,069 additions & 66 deletions packages/aws/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/aws/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@aws-sdk/client-ses": "^3.211.0",
"@aws-sdk/client-sqs": "^3.211.0",
"@aws-sdk/client-ssm": "^3.211.0",
"@aws-sdk/client-cloudformation": "^3.211.0",
"@aws-sdk/s3-request-presigner": "^3.211.0",
"@awslabs-community-fork/dynamodb-data-mapper": "^0.7.9",
"@awslabs-community-fork/dynamodb-data-marshaller": "^0.7.9",
Expand Down
1 change: 1 addition & 0 deletions packages/aws/src/clients/clients.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./cloudformation.client";
export * from "./dynamodb.client";
export * from "./event-bridge.client";
export * from "./s3.client";
Expand Down
127 changes: 127 additions & 0 deletions packages/aws/src/clients/cloudformation.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import {inject, injectable} from "tsyringe";
import {LogHandlerInterface} from "@pristine-ts/logging";
import {moduleScoped, tag} from "@pristine-ts/common";
import {AwsModuleKeyname} from "../aws.module.keyname";
import {
CloudFormationClient as AWSCloudformationClient,
CloudFormationClientConfig,
CreateStackCommand,
CreateStackCommandInput,
CreateStackCommandOutput, DeleteStackCommand, DeleteStackCommandInput, DeleteStackCommandOutput,
DescribeStacksCommand,
DescribeStacksCommandOutput,
Stack, UpdateStackCommand, UpdateStackCommandInput, UpdateStackCommandOutput
} from "@aws-sdk/client-cloudformation";
import {CloudformationClientInterface} from "../interfaces/cloudformation-client.interface";

/**
* The client to use to interact with AWS Cloudformation. It is a wrapper around the CloudformationClient of @aws-sdk/client-cloudformation.
* It is tagged so it can be injected using CloudformationClientInterface.
* AWS documentation https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cloudformation/
*/
@tag("CloudformationClientInterface")
@moduleScoped(AwsModuleKeyname)
@injectable()
export class CloudformationClient implements CloudformationClientInterface {

/**
* The instantiated client from the @aws-sdk/client-cloudformation library.
* @private
*/
private client: AWSCloudformationClient;

/**
* The client to use to interact with AWS Cloudformation. It is a wrapper around the CloudformationClient of @aws-sdk/client-cloudformation.
* @param logHandler The log handler used to output logs.
* @param region The aws region for which the client will be used.
*/
constructor(
@inject("LogHandlerInterface") private readonly logHandler: LogHandlerInterface,
@inject("%pristine.aws.region%") public region: string,
) {
}

/**
* Returns the instantiated CloudformationClient from the @aws-sdk/client-s3 cloudformation
*/
getClient(): AWSCloudformationClient {
return this.client = this.client ?? new AWSCloudformationClient({region: this.region});
}

/**
* Allows you to manually set the config if needed.
* @param config
*/
setClient(config: CloudFormationClientConfig) {
this.client = new AWSCloudformationClient(config);
}

/**
* Gets the description and all its details from a Cloudformation stack.
* @param stackName The stack name to get the.
*/
async getStackDescription(stackName: string): Promise<Stack> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Getting stack information", {stackName}, AwsModuleKeyname);
const command = new DescribeStacksCommand({
StackName: stackName,
})
try {
const response: DescribeStacksCommandOutput = await this.getClient().send(command);
if(!response.Stacks || response.Stacks.length < 1){
throw new Error("No stacks were returned from cloudformation");
}
if(response.Stacks.length > 1){
throw new Error("More than one stack was returned from cloudformation");
}
return response.Stacks[0];
} catch (e) {
this.logHandler.error("Error getting stack description from cloudformation", {error: e}, AwsModuleKeyname);
throw e;
}
}

/**
* Creates a new stack in Cloudformation.
* @param input The input to create the new stack.
*/
async createStack(input: CreateStackCommandInput): Promise<CreateStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Creating new stack", {input}, AwsModuleKeyname);
const command = new CreateStackCommand(input)
try {
return this.getClient().send(command);
} catch (e) {
this.logHandler.error("Error creating stack in cloudformation", {error: e}, AwsModuleKeyname);
throw e;
}
}

/**
* Updates a stack in Cloudformation.
* @param input The input to update the new stack.
*/
async updateStack(input: UpdateStackCommandInput): Promise<UpdateStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Updating stack", {input}, AwsModuleKeyname);
const command = new UpdateStackCommand(input)
try {
return this.getClient().send(command);
} catch (e) {
this.logHandler.error("Error updating stack in cloudformation", {error: e}, AwsModuleKeyname);
throw e;
}
}

/**
* Deletes a stack in Cloudformation.
* @param input The input to delete the new stack.
*/
async deleteStack(input: DeleteStackCommandInput): Promise<DeleteStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Deleting stack", {input}, AwsModuleKeyname);
const command = new DeleteStackCommand(input)
try {
return this.getClient().send(command);
} catch (e) {
this.logHandler.error("Error deleting stack in cloudformation", {error: e}, AwsModuleKeyname);
throw e;
}
}
}
51 changes: 51 additions & 0 deletions packages/aws/src/interfaces/cloudformation-client.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { S3PresignedOperationTypeEnum } from "../enums/s3-presigned-operation-type.enum";
import {GetObjectCommandOutput, S3Client as AWSS3Client, S3ClientConfig} from "@aws-sdk/client-s3";
import {CloudFormationClient as AWSCloudformationClient} from "@aws-sdk/client-cloudformation/dist-types/CloudFormationClient";
import {
CreateStackCommandInput,
CreateStackCommandOutput,
DeleteStackCommandInput, DeleteStackCommandOutput,
Stack, UpdateStackCommandInput, UpdateStackCommandOutput
} from "@aws-sdk/client-cloudformation";
import {CloudFormationClientConfig} from "@aws-sdk/client-cloudformation/dist-types/ts3.4";

/**
* The CloudformationClient Interface defines the methods that a Cloudformation client must implement.
* When injecting the Cloudformation client the 'CloudformationClientInterface' tag should be used.
*/
export interface CloudformationClientInterface {
/**
* Returns the instantiated CloudformationClient from the @aws-sdk/client-s3 cloudformation
*/
getClient(): AWSCloudformationClient;

/**
* Allows you to manually set the config if needed.
* @param config
*/
setClient(config: CloudFormationClientConfig);

/**
* Gets the description and all its details from a Cloudformation stack.
* @param stackName The stack name to get the.
*/
getStackDescription(stackName: string): Promise<Stack>;

/**
* Creates a new stack in Cloudformation.
* @param input The input to create the new stack.
*/
createStack(input: CreateStackCommandInput): Promise<CreateStackCommandOutput>;

/**
* Updates a stack in Cloudformation.
* @param input The input to update the new stack.
*/
updateStack(input: UpdateStackCommandInput): Promise<UpdateStackCommandOutput>;

/**
* Deletes a stack in Cloudformation.
* @param input The input to delete the new stack.
*/
deleteStack(input: DeleteStackCommandInput): Promise<DeleteStackCommandOutput>;
}
1 change: 1 addition & 0 deletions packages/aws/src/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./cloudformation-client.interface";
export * from "./dynamodb-client.interface";
export * from "./event-bridge-client.interface";
export * from "./s3-client.interface";
Expand Down
11 changes: 5 additions & 6 deletions packages/aws/src/interfaces/s3-client.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { S3PresignedOperationTypeEnum } from "../enums/s3-presigned-operation-type.enum";
import { GetObjectCommandOutput, S3Client as AWSS3Client } from "@aws-sdk/client-s3";
import {S3PresignedOperationTypeEnum} from "../enums/s3-presigned-operation-type.enum";
import {S3Client as AWSS3Client, S3ClientConfig} from "@aws-sdk/client-s3";

/**
* The S3Client Interface defines the methods that an S3 client must implement.
Expand All @@ -12,11 +12,10 @@ export interface S3ClientInterface {
getClient(): AWSS3Client;

/**
* Gets an object and all its details from S3.
* @param bucketName The bucket name where to get the object.
* @param key The key of the object.
* Allows you to manually set the config if needed.
* @param config
*/
get(bucketName: string, key: string): Promise<GetObjectCommandOutput>;
setClient(config: S3ClientConfig);

/**
* Gets an object's body as an array buffer from S3.
Expand Down