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

Use Node 18 #22

Merged
merged 1 commit into from
May 15, 2024
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 changes: 1 addition & 1 deletion .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v1
with:
node-version: '16.x'
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm run compile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:

strategy:
matrix:
node-version: [16.x]
node-version: [18.x]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16
v18
2 changes: 1 addition & 1 deletion cdkv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class AuroraSnapshotCopier extends Construct {

const handler = new lambda.Function(this, 'Handler', {
code: lambda.Code.fromAsset(pathlib.join(__dirname, 'handler')),
runtime: lambda.Runtime.NODEJS_16_X,
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'main.handler',
timeout: props.handlerTimeout ?? cdk.Duration.minutes(1),
environment: allToEnv(simplifiedProps),
Expand Down
67 changes: 32 additions & 35 deletions handler/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as AWS from 'aws-sdk';
import * as KMS from '@aws-sdk/client-kms';
import * as RDS from '@aws-sdk/client-rds';

import { allFromEnv, AuroraSnapshotSourceSelector, AuroraSnapshotSourceAggregation, AuroraSnapshotTarget, AuroraSnapshotDeletionPolicy } from './shared';
import { fromAwsTags, kmsKeyIdOrArnToId, hasKey, PickRequired } from './utils';

type RequiredSnapshotKeys = 'DBClusterSnapshotIdentifier' | 'DBClusterIdentifier' | 'DBClusterSnapshotArn' | 'SnapshotCreateTime';
type UsableSnapshot = PickRequired<AWS.RDS.Types.DBClusterSnapshot, RequiredSnapshotKeys>;
type UsableSnapshot = PickRequired<RDS.DBClusterSnapshot, RequiredSnapshotKeys>;

export const isUsableSnapshot = (snapshot: AWS.RDS.Types.DBClusterSnapshot): snapshot is UsableSnapshot => {
export const isUsableSnapshot = (snapshot: RDS.DBClusterSnapshot): snapshot is UsableSnapshot => {
return (
typeof snapshot.DBClusterSnapshotIdentifier !== 'undefined' &&
typeof snapshot.DBClusterIdentifier !== 'undefined' &&
Expand Down Expand Up @@ -37,7 +38,7 @@ interface SnapshotForDeletion extends Snapshot {
justRemoveTag: boolean;
}

export const snapshotFromApiMatchesSource = (source: AuroraSnapshotSourceSelector, snapshot: AWS.RDS.Types.DBClusterSnapshot): boolean => {
export const snapshotFromApiMatchesSource = (source: AuroraSnapshotSourceSelector, snapshot: RDS.DBClusterSnapshot): boolean => {
// logger('Checking snapshot against source', { snapshot, source });
// This ought to be handled by the filtering passed to the API, but this ensures no surprises.
if (source.dbClusterIdentifier && source.dbClusterIdentifier !== snapshot.DBClusterIdentifier) {
Expand Down Expand Up @@ -103,9 +104,9 @@ export const snapshotFromApiMatchesSource = (source: AuroraSnapshotSourceSelecto
};

export const listSnapshotsMatchingSource = async (source: AuroraSnapshotSourceSelector): Promise<Array<Snapshot>> => {
const rds = new AWS.RDS();
const rdsClient = new RDS.RDSClient();

const apiParams: AWS.RDS.Types.DescribeDBClusterSnapshotsMessage = {};
const apiParams: RDS.DescribeDBClusterSnapshotsCommandInput = {};

if (source.dbClusterIdentifier) {
apiParams.DBClusterIdentifier = source.dbClusterIdentifier;
Expand All @@ -114,7 +115,7 @@ export const listSnapshotsMatchingSource = async (source: AuroraSnapshotSourceSe
apiParams.SnapshotType = source.snapshotType;
}

const response = await rds.describeDBClusterSnapshots(apiParams).promise();
const response = await rdsClient.send(new RDS.DescribeDBClusterSnapshotsCommand(apiParams));

const snapshots: Array<Snapshot> = [];
for (const snapshot of response.DBClusterSnapshots || []) {
Expand Down Expand Up @@ -190,7 +191,7 @@ export const copySnapshotToRegion = async (props: CopySnapshotToRegionProps): Pr
targetRegionKmsKeyToUse: targetRegionKmsKeyToUse ?? '(none)',
});

const rds = new AWS.RDS({
const rdsClient = new RDS.RDSClient({
region: targetRegion,
});

Expand All @@ -204,8 +205,8 @@ export const copySnapshotToRegion = async (props: CopySnapshotToRegionProps): Pr
const targetSnapshotIdentifier = snapshot.identifier.replace(/^rds:/, '');

try {
await rds
.copyDBClusterSnapshot({
await rdsClient.send(
new RDS.CopyDBClusterSnapshotCommand({
SourceDBClusterSnapshotIdentifier: snapshot.arn,
TargetDBClusterSnapshotIdentifier: targetSnapshotIdentifier,
CopyTags: true,
Expand All @@ -232,21 +233,17 @@ export const copySnapshotToRegion = async (props: CopySnapshotToRegionProps): Pr
KmsKeyId: targetRegionKmsKeyToUse,
}
: {}),
SourceRegion: sourceRegion,
})
.promise();
// SourceRegion: sourceRegion,
}),
);
} catch (err) {
if (hasKey(err, 'code') && err.code === 'DBClusterSnapshotAlreadyExistsFault') {
logger('Snapshot already exists in the target region', {
targetSnapshotIdentifier,
snapshot,
});

const existingTargetSnapshotResponse = await rds
.describeDBClusterSnapshots({
DBClusterSnapshotIdentifier: targetSnapshotIdentifier,
})
.promise();
const existingTargetSnapshotResponse = await rdsClient.send(new RDS.DescribeDBClusterSnapshotsCommand({ DBClusterSnapshotIdentifier: targetSnapshotIdentifier }));

const snapshotInTargetRegion = (existingTargetSnapshotResponse.DBClusterSnapshots ?? [])[0];

Expand All @@ -268,17 +265,17 @@ export const copySnapshotToRegion = async (props: CopySnapshotToRegionProps): Pr
return;
}

await rds
.addTagsToResource({
await rdsClient.send(
new RDS.AddTagsToResourceCommand({
ResourceName: snapshotArnInTargetRegion,
Tags: [
{
Key: `aurora-snapshot-copier-cdk/CopiedBy/${instanceIdentifier}`,
Value: 'aurora-snapshot-copier-cdk',
},
],
})
.promise();
}),
);
return;
} else {
throw err;
Expand All @@ -294,11 +291,11 @@ export const copySnapshotToRegion = async (props: CopySnapshotToRegionProps): Pr
};

export const getDefaultRdsKmsKeyIdForRegion = async (region: string): Promise<string | undefined> => {
const kms = new AWS.KMS({
const kmsClient = new KMS.KMSClient({
region,
});

const aliasesResponse = await kms.listAliases({}).promise();
const aliasesResponse = await kmsClient.send(new KMS.ListAliasesCommand({}));

for (const alias of aliasesResponse.Aliases || []) {
if (alias.AliasName === 'alias/aws/rds') {
Expand Down Expand Up @@ -452,13 +449,13 @@ export const handleSnapshotDeletion = async (deletionPolicy: AuroraSnapshotDelet
region,
});

const rds = new AWS.RDS({
const rdsClient = new RDS.RDSClient({
region,
});

const snapshots: Array<SnapshotForDeletion> = [];

const response = await rds.describeDBClusterSnapshots({}).promise();
const response = await rdsClient.send(new RDS.DescribeDBClusterSnapshotsCommand({}));

for (const snapshot of response.DBClusterSnapshots || []) {
if (!isUsableSnapshot(snapshot)) {
Expand Down Expand Up @@ -502,12 +499,12 @@ export const handleSnapshotDeletion = async (deletionPolicy: AuroraSnapshotDelet
DBClusterSnapshotIdentifier: snapshot.identifier,
};
if (snapshot.justRemoveTag) {
await rds
.removeTagsFromResource({
await rdsClient.send(
new RDS.RemoveTagsFromResourceCommand({
ResourceName: snapshot.arn,
TagKeys: [`aurora-snapshot-copier-cdk/CopiedBy/${instanceIdentifier}`],
})
.promise();
}),
);
return;
}
if (deletionPolicy.apply) {
Expand All @@ -517,7 +514,7 @@ export const handleSnapshotDeletion = async (deletionPolicy: AuroraSnapshotDelet
apiCall: 'rds.deleteDBClusterSnapshot',
params: deleteParams,
});
await rds.deleteDBClusterSnapshot(deleteParams).promise();
await rdsClient.send(new RDS.DeleteDBClusterSnapshotCommand(deleteParams));
} else {
logger('Dry-run, marking snapshot as would-have-deleted', {
region,
Expand All @@ -527,17 +524,17 @@ export const handleSnapshotDeletion = async (deletionPolicy: AuroraSnapshotDelet
params: deleteParams,
},
});
await rds
.addTagsToResource({
await rdsClient.send(
new RDS.AddTagsToResourceCommand({
ResourceName: snapshot.arn,
Tags: [
{
Key: 'aurora-snapshot-copier-cdk/DryRunDeletedAt',
Value: new Date().toISOString(),
},
],
})
.promise();
}),
);
}
};

Expand Down
4 changes: 3 additions & 1 deletion handler/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as RDS from '@aws-sdk/client-rds';

export type PickRequired<T, Keys extends keyof T> = Required<Pick<T, Keys>> & Omit<T, Keys>;
export type PickPartial<T, Keys extends keyof T> = Partial<Pick<T, Keys>> & Omit<T, Keys>;

export const fromAwsTags = (awsTags: AWS.RDS.Types.TagList | undefined): Record<string, string> => {
export const fromAwsTags = (awsTags: RDS.Tag[] | undefined): Record<string, string> => {
const tags: Record<string, string> = {};
for (const awsTag of awsTags || []) {
if (typeof awsTag.Key === 'string' && typeof awsTag.Value === 'string') {
Expand Down
Loading
Loading