Skip to content

Commit

Permalink
Merge pull request #580 from magieno/add-cloudformation-client
Browse files Browse the repository at this point in the history
Create cloudformation client
  • Loading branch information
mathieugh authored Sep 20, 2023
2 parents 9c0f5bc + f8ee7fe commit 78b1b58
Show file tree
Hide file tree
Showing 8 changed files with 4,384 additions and 198 deletions.
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

0 comments on commit 78b1b58

Please sign in to comment.