Skip to content

Commit

Permalink
chore(deps): bumping jsii to 5.1.9 and node to 18
Browse files Browse the repository at this point in the history
Updated jsii and fixed issues that came up from that.

jsii requires at least Node.js 16. 16 is EOL soon, so change minimum
required version to 18.
  • Loading branch information
edwards-aws committed Aug 8, 2023
1 parent 638e820 commit 35d0f24
Show file tree
Hide file tree
Showing 24 changed files with 208 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

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

steps:
- uses: actions/checkout@v3
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and let us know if it's not up-to-date (even better, submit a PR with your corr
The RFDK is written in Typescript and converted, using [jsii](https://github.com/aws/jsii), into Python. Thus, the
minimal development environment must include:

- Node.js >= 14.19.3
- Node.js >= 18.0.0
- docker >= 18

We also recommend developing on a Linux system.
Expand All @@ -39,10 +39,10 @@ the [instructions](https://github.com/nvm-sh/nvm#installing-and-updating) to ins
then you can install a version of Node.js and set your shell to make it available when you login:

```bash
# For example, the latest version of Node.js 14.x
# For example, the latest version of Node.js 18.x

# Find out the version number for latest
LATEST_VERSION=$(nvm ls-remote | grep v14 | grep 'Latest' | awk '{print $1}')
LATEST_VERSION=$(nvm ls-remote | grep v18 | grep 'Latest' | awk '{print $1}')

# Install it
nvm install ${LATEST_VERSION}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ It offers high-level object-oriented abstractions to define render farm infrastr
using the power of Python and Typescript.

The RFDK is available in:
- Javascript, Typescript ([Node.js >= 14.19.3](https://nodejs.org/download/release/latest-v14.x/))
- Javascript, Typescript ([Node.js >= 18.0.0](https://nodejs.org/download/release/latest-v18.x/))
- We recommend using an [Active LTS Release](https://nodejs.org/en/about/releases/)
- Python ([Python >= 3.6](https://www.python.org/downloads/))

Expand Down
2 changes: 1 addition & 1 deletion integ/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@
"constructs": "^10.0.0"
},
"engines": {
"node": ">= 14.15.0"
"node": ">= 18.0.0"
}
}
2 changes: 1 addition & 1 deletion lambda-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"watch": "tsc -w"
},
"engines": {
"node": ">= 14.15.0"
"node": ">= 18.0.0"
},
"stability": "stable",
"maturity": "stable",
Expand Down
8 changes: 8 additions & 0 deletions packages/aws-rfdk/docs/upgrade/upgrading-1.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Upgrading to RFDK v1.3.x or Newer

## Updating Node.js

Node 14 is End of Life and RFDK >= 1.3.x no longer supports it. Node.js 18.0.0 is the minimum version
that RFDK now supports.

You can follow our [installation guide](CONTRIBUTING.md#installing-nodejs) for Node.js to upgrade to the latest version.
11 changes: 2 additions & 9 deletions packages/aws-rfdk/lib/deadline/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import {
/**
* Build arguments to supply to a Docker image build
*/
export interface BuildArgs {
readonly [name: string]: string;
}
export type BuildArgs = Record<string, string>;

/**
* Docker container image recipe
Expand Down Expand Up @@ -54,12 +52,7 @@ export interface Recipe {
/**
* A collection of Deadline Docker recipes
*/
export interface DeadlineDockerRecipes {
/**
* A mapping of name to recipe
*/
readonly [name: string]: Recipe;
}
export type DeadlineDockerRecipes = Record<string, Recipe>;

/**
* The manifest included with Deadline Docker image recipes
Expand Down
19 changes: 12 additions & 7 deletions packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

/* eslint-disable no-console */

import { types } from 'util';
// eslint-disable-next-line import/no-extraneous-dependencies
import {AutoScaling, EC2} from 'aws-sdk';
import {AutoScaling, EC2, AWSError} from 'aws-sdk';

/**
* Contents of the Message sent from Sns in response to a lifecycle event.
Expand Down Expand Up @@ -45,7 +46,7 @@ async function completeLifecycle(success: boolean, message: SnsLaunchInstanceMes
const response = await autoscaling.completeLifecycleAction(request).promise();
console.log('Got response: ' + JSON.stringify(response));
} catch (e) {
throw new Error(`Error sending completeLifecycleAction: ${e.code} -- ${e.message}`);
throw new Error(`Error sending completeLifecycleAction: ${(e as AWSError)?.code} -- ${(e as Error)?.message}`);
}
}

Expand All @@ -64,7 +65,7 @@ async function attachEniToInstance(instanceId: string, eniId: string): Promise<v
const response = await ec2.attachNetworkInterface(request).promise();
console.log('Got response: ' + JSON.stringify(response));
} catch (e) {
throw new Error(`Error attaching network interface to instance: ${e.code} -- ${e.message}`);
throw new Error(`Error attaching network interface to instance: ${(e as AWSError)?.code} -- ${(e as Error)?.message}`);
}
}

Expand All @@ -85,17 +86,21 @@ export async function handler(event: { [key: string]: any }): Promise<void> {
await attachEniToInstance(message.EC2InstanceId, eniId);
success = true;
} catch (e) {
console.error(e.toString());
console.error(e.stack);
console.error(String(e));
console.error((e as Error)?.stack);
} finally {
// Note: Instance stays in 'Pending: Wait' state unless this lambda signals a lifecycle transition, so we must **always** send one.
// https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html
await completeLifecycle(success, message);
}
}
} catch (e) {
console.error(e.toString());
console.error(e.stack);
if (types.isNativeError(e)) {
console.error(e.toString());
console.error(e.stack);
} else {
console.error(String(e));
}
}
}
}
46 changes: 46 additions & 0 deletions packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,49 @@ test('continues when complete lifecycle errors', async () => {
await expect(handler(event)).resolves.not.toThrow();
expect(console.error).toHaveBeenCalledTimes(4); // 4 = each of the two records printing two error messages
});

test('continues when complete lifecycle errors non-error thrown', async () => {
// GIVEN
const event = {
Records: [
{
Sns: {
Message: JSON.stringify({
LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING',
AutoScalingGroupName: 'ASG-Name-1',
LifecycleHookName: 'Hook-Name-1',
EC2InstanceId: 'i-0000000000',
LifecycleActionToken: 'Action-Token-1',
NotificationMetadata: JSON.stringify({
eniId: 'eni-000000000',
}),
}),
},
},
{
Sns: {
Message: JSON.stringify({
LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING',
AutoScalingGroupName: 'ASG-Name-1',
LifecycleHookName: 'Hook-Name-1',
EC2InstanceId: 'i-0000000000',
LifecycleActionToken: 'Action-Token-1',
NotificationMetadata: JSON.stringify({
eniId: 'eni-000000000',
}),
}),
},
},
],
};

attachSpy = jest.fn( (request) => successRequestMock(request) );
mock('EC2', 'attachNetworkInterface', attachSpy);

JSON.parse = jest.fn( () => {throw 47;} );

// THEN
// eslint-disable-next-line: no-floating-promises
await expect(handler(event)).resolves.not.toThrow();
expect(console.error).toHaveBeenCalledTimes(2); // 2 = each of the two records printing one error message.
});
2 changes: 1 addition & 1 deletion packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async function confirmTaskCompletion(taskId: string): Promise<void> {
} catch (e) {
// Retry 3 times before giving up
if (errorCount < 3) {
console.error(`${taskId}: Encountered failure #${errorCount} with message: ${e.message}`);
console.error(`${taskId}: Encountered failure #${errorCount} with message: ${(e as Error)?.message}`);
errorCount++;
} else {
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/* eslint-disable no-console */


import { types } from 'util';
import { LambdaContext } from '../aws-lambda';
import { calculateSha256Hash } from './hash';
import { CfnResponseStatus, sendCfnResponse } from './reply';
Expand Down Expand Up @@ -51,7 +52,7 @@ export abstract class SimpleCustomResource {
* @param resourceProperties The ResourceProperties given to the handler.
* @returns The Data to send back to CloudFormation as attributes of this CfnCustomResource
*/
public abstract async doCreate(physicalId: string, resourceProperties: object): Promise<object|undefined>;
public abstract doCreate(physicalId: string, resourceProperties: object): Promise<object|undefined>;

/**
* Called to perform the 'Delete' action. There are three locations in the state-diagram
Expand All @@ -64,7 +65,7 @@ export abstract class SimpleCustomResource {
* @param physicalId A stable hash value derived from the value of ResourceProperties
* @param resourceProperties The ResourceProperties given to the handler.
*/
public abstract async doDelete(physicalId: string, resourceProperties: object): Promise<void>;
public abstract doDelete(physicalId: string, resourceProperties: object): Promise<void>;

/**
* Handler/engine for the CustomResource state machine. Users of this class should
Expand Down Expand Up @@ -118,7 +119,11 @@ export abstract class SimpleCustomResource {
// failure to notify results in a stuck stack that takes at least an hour to
// timeout.
status = CfnResponseStatus.FAILED;
failReason = `${e.message}\n${e.stack}`;
if (types.isNativeError(e)) {
failReason = `${e.message}\n${e.stack}`;
} else {
failReason = String(e);
}
} finally {
// Always send a response to CloudFormation, signal success or
// failure based on whether or not we had an exception.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ export class DeadlineClient {
try {
return await this.performRequest(options, data);
} catch(exception) {
const { statusCode, statusMessage } = exception;
const statusCode = (exception as any)?.statusCode;
const statusMessage = (exception as any)?.statusMessage;
if (statusCode !== undefined && statusMessage !== undefined) {
if (statusCode >= 500 && retriesLeft > 0) {
console.log(`Request failed with ${statusCode}: ${statusMessage}. Will retry after ${retryDelayMs} ms.`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* eslint-disable no-console */

// eslint-disable-next-line import/no-extraneous-dependencies
import { DynamoDB } from 'aws-sdk';
import { DynamoDB, AWSError } from 'aws-sdk';

export class CompositeStringIndexTable {
public static readonly API_VERSION = '2012-08-10';
Expand Down Expand Up @@ -110,7 +110,7 @@ export class CompositeStringIndexTable {
);
return table;
} catch (e) {
throw new Error(`CreateTable '${args.name}': ${e.code} -- ${e.message}`);
throw new Error(`CreateTable '${args.name}': ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand Down Expand Up @@ -149,11 +149,11 @@ export class CompositeStringIndexTable {
this.tableName = undefined;

} catch (e) {
if (e.code === 'ResourceNotFoundException') {
if ((e as AWSError)?.code === 'ResourceNotFoundException') {
// Already gone. We're good.
this.tableName = undefined;
} else {
throw new Error(`DeleteTable '${this.tableName}': ${e.code} -- ${e.message}`);
throw new Error(`DeleteTable '${this.tableName}': ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}
}
Expand Down Expand Up @@ -207,11 +207,11 @@ export class CompositeStringIndexTable {
const response = await this.client.putItem(request).promise();
console.debug(`PutItem response: ${JSON.stringify(response)}`);
} catch (e) {
if (e.code === 'ConditionalCheckFailedException' && !props.allow_overwrite) {
if ((e as AWSError)?.code === 'ConditionalCheckFailedException' && !props.allow_overwrite) {
return false;
}
throw new Error(`PutItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
return true;
}
Expand Down Expand Up @@ -256,7 +256,7 @@ export class CompositeStringIndexTable {
return item;
} catch (e) {
throw new Error(`GetItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand Down Expand Up @@ -296,7 +296,7 @@ export class CompositeStringIndexTable {
return false;
} catch (e) {
throw new Error(`DeleteItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand Down Expand Up @@ -356,7 +356,7 @@ export class CompositeStringIndexTable {
} while (request.ExclusiveStartKey);
return items;
} catch (e) {
throw new Error(`Query '${primaryKeyValue}':" ${e.code} -- ${e.message}`);
throw new Error(`Query '${primaryKeyValue}':" ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

/* eslint-disable no-console */

import { isUint8Array } from 'util/types';
// eslint-disable-next-line import/no-extraneous-dependencies
import { SecretsManager } from 'aws-sdk';
import { SecretsManager, AWSError } from 'aws-sdk';

import { Key } from '../kms';
import { isArn } from './validation';
Expand Down Expand Up @@ -59,7 +60,7 @@ export class Secret {
return undefined;
} catch (e) {
throw new Error(`CreateSecret '${args.name}' failed in region '${args.client.config.region}': ` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand Down Expand Up @@ -94,7 +95,7 @@ export class Secret {
this.arn = undefined;
} catch (e) {
throw new Error(`DeleteSecret '${this.arn}' failed in region '${this.client.config.region}':` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand All @@ -121,7 +122,7 @@ export class Secret {
console.debug(`PutSecret response: ${JSON.stringify(response)}`);
} catch (e) {
throw new Error(`PutSecret '${this.arn}' failed in region '${this.client.config.region}':` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}

Expand All @@ -146,7 +147,7 @@ export class Secret {
return data;
} else if (typeof data === 'string') {
return Buffer.from(data, 'binary');
} else if (ArrayBuffer.isView(data)) {
} else if (isUint8Array(data)) {
return Buffer.from(data);
} else {
throw new Error('Unknown type for SecretBinary data');
Expand All @@ -155,7 +156,7 @@ export class Secret {
return response.SecretString;
} catch (e) {
throw new Error(`GetSecret '${this.arn}' failed in region '${this.client.config.region}':` +
`${e.code} -- ${e.message}`);
`${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`);
}
}
}
Loading

0 comments on commit 35d0f24

Please sign in to comment.