Skip to content

refactor: provider-cloudformation and amplify-category-storage #14238

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

Draft
wants to merge 14 commits into
base: dev
Choose a base branch
from
Draft
3 changes: 2 additions & 1 deletion packages/amplify-category-storage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
"@aws-amplify/amplify-prompts": "2.8.7",
"@aws-amplify/amplify-util-import": "2.8.3",
"@aws-amplify/cli-extensibility-helper": "3.0.39",
"@aws-sdk/client-dynamodb": "^3.515.0",
"@aws-sdk/client-s3": "^3.515.0",
"amplify-headless-interface": "1.17.8",
"amplify-util-headless-input": "1.9.19",
"aws-cdk-lib": "~2.189.1",
"aws-sdk": "^2.1464.0",
"chalk": "^4.1.1",
"constructs": "^10.0.5",
"enquirer": "^2.3.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '@aws-amplify/amplify-cli-core';
import { printer } from '@aws-amplify/amplify-prompts';
import { IS3Service } from '@aws-amplify/amplify-util-import';
import { Bucket } from 'aws-sdk/clients/s3';
import { Bucket } from '@aws-sdk/client-s3';
import Enquirer from 'enquirer';
import _ from 'lodash';
import { v4 as uuid } from 'uuid';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { $TSContext, $TSObject } from '@aws-amplify/amplify-cli-core';
import { IDynamoDBService, IS3Service } from '@aws-amplify/amplify-util-import';
import { Bucket } from 'aws-sdk/clients/s3';
import { TableDescription } from 'aws-sdk/clients/dynamodb';
import { Bucket } from '@aws-sdk/client-s3';
import { TableDescription } from '@aws-sdk/client-dynamodb';

// parameters.json
export type S3ResourceParameters = {
Expand Down
18 changes: 18 additions & 0 deletions packages/amplify-provider-awscloudformation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@
"@aws-amplify/cli-extensibility-helper": "3.0.39",
"@aws-amplify/graphql-transformer-core": "^2.11.1",
"@aws-amplify/graphql-transformer-interfaces": "^3.12.0",
"@aws-sdk/client-api-gateway": "^3.624.0",
"@aws-sdk/client-cloudformation": "^3.624.0",
"@aws-sdk/client-cognito-identity": "^3.624.0",
"@aws-sdk/client-cognito-identity-provider": "^3.624.0",
"@aws-sdk/client-dynamodb": "^3.624.0",
"@aws-sdk/client-ecr": "^3.624.0",
"@aws-sdk/client-iam": "^3.624.0",
"@aws-sdk/client-lambda": "^3.624.0",
"@aws-sdk/client-location": "^3.624.0",
"@aws-sdk/client-s3": "^3.624.0",
"@aws-sdk/client-ssm": "^3.624.0",
"@aws-sdk/client-sts": "^3.624.0",
"@aws-sdk/credential-provider-node": "^3.624.0",
"@aws-sdk/credential-providers": "^3.624.0",
"@aws-sdk/lib-dynamodb": "^3.624.0",
"@aws-sdk/s3-request-presigner": "^3.624.0",
"@aws-sdk/types": "^3.624.0",
"@smithy/node-http-handler": "^4.1.0",
"amplify-codegen": "^4.10.3",
"archiver": "^7.0.1",
"aws-cdk-lib": "~2.189.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { $TSAny, $TSContext } from '@aws-amplify/amplify-cli-core';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { IDynamoDBService } from '@aws-amplify/amplify-util-import';
import DynamoDB, { ListTablesInput, ListTablesOutput, TableDescription, TableName } from 'aws-sdk/clients/dynamodb';
import {
DynamoDBClient,
ListTablesCommand,
ListTablesCommandInput,
ListTablesCommandOutput,
DescribeTableCommand,
TableDescription,
} from '@aws-sdk/client-dynamodb';
import { loadConfiguration } from '../configuration-manager';
import { pagedAWSCall } from './paged-call';

Expand All @@ -13,26 +21,28 @@
// could not load credentials
}

const dynamoDB = new DynamoDB({ ...credentials, ...options });
const dynamoDBClient = new DynamoDBClient({
...credentials,
...options,
});

return new DynamoDBService(dynamoDB);
return new DynamoDBService(dynamoDBClient);
};

export class DynamoDBService implements IDynamoDBService {
private cachedTableList: string[] = [];

public constructor(private dynamoDB: DynamoDB) {}
public constructor(private dynamoDBClient: DynamoDBClient) {}

public async listTables(): Promise<TableName[]> {
public async listTables(): Promise<string[]> {
if (this.cachedTableList.length === 0) {
const result = await pagedAWSCall<ListTablesOutput, TableName, TableName>(
async (params: ListTablesInput, nextToken: TableName) => {
return await this.dynamoDB
.listTables({
...params,
ExclusiveStartTableName: nextToken,
})
.promise();
const result = await pagedAWSCall<ListTablesCommandOutput, string, string>(
async (params: ListTablesCommandInput, nextToken: string) => {
const command = new ListTablesCommand({
...params,
ExclusiveStartTableName: nextToken,
});
return await this.dynamoDBClient.send(command);
},
{
Limit: 100,
Expand All @@ -48,11 +58,10 @@
}

public async getTableDetails(tableName: string): Promise<TableDescription> {
const response = await this.dynamoDB
.describeTable({
TableName: tableName,
})
.promise();
const command = new DescribeTableCommand({
TableName: tableName,
});
const response = await this.dynamoDBClient.send(command);

return response.Table;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import { $TSContext, AmplifyFault } from '@aws-amplify/amplify-cli-core';
import { IS3Service } from '@aws-amplify/amplify-util-import';
import { S3 } from 'aws-sdk';
import { Bucket } from 'aws-sdk/clients/s3';
import { S3Client, ListBucketsCommand, HeadBucketCommand, GetBucketLocationCommand, Bucket } from '@aws-sdk/client-s3';
import { AwsSecrets, loadConfiguration } from '../configuration-manager';

export const createS3Service = async (context: $TSContext): Promise<S3Service> => {
const credentials = await tryGetCredentials(context);
const s3 = new S3({ ...credentials });
const s3Client = new S3Client({
...credentials,
});

return new S3Service(s3);
return new S3Service(s3Client);
};

export class S3Service implements IS3Service {
private cachedBucketList: Bucket[] = [];

public constructor(private s3: S3) {}
public constructor(private s3Client: S3Client) {}

public async listBuckets(): Promise<Bucket[]> {
if (this.cachedBucketList.length === 0) {
const response = await this.s3.listBuckets().promise();
const command = new ListBucketsCommand({});
const response = await this.s3Client.send(command);

if (response.Buckets) {
this.cachedBucketList.push(...response.Buckets);
Expand All @@ -28,16 +30,21 @@
return this.cachedBucketList;
}

private async checkIfBucketExists(bucketName: string, s3?: S3): Promise<boolean> {
const s3Client = s3 ?? this.s3;
private async checkIfBucketExists(bucketName: string, s3Client?: S3Client): Promise<boolean> {
const client = s3Client ?? this.s3Client;
try {
const response = await s3Client.headBucket({ Bucket: bucketName }).promise();
const command = new HeadBucketCommand({ Bucket: bucketName });
const response = await client.send(command);
// If the return object has no keys then it means successful empty object was returned.
return Object.keys(response).length === 0;
} catch (error) {
// workaround for S3 service bug causing headBucket for a opt-in region bucket to respond with BadRequest if s3 client is initialized with a different region
if (error.region !== s3Client.config.region && error.code === 'BadRequest') {
return this.checkIfBucketExists(bucketName, new S3({ ...s3Client.config?.credentials, region: error.region }));
if (error.region !== client.config.region && error.name === 'BadRequest') {
const newClient = new S3Client({
...client.config?.credentials,
region: error.region,
});
return this.checkIfBucketExists(bucketName, newClient);
}

return handleS3Error(error);
Expand All @@ -49,15 +56,17 @@
}

public async getBucketLocation(bucketName: string): Promise<string> {
const response = await this.s3
.getBucketLocation({
Bucket: bucketName,
})
.promise();
const command = new GetBucketLocationCommand({
Bucket: bucketName,
});
const response = await this.s3Client.send(command);

// For us-east-1 buckets the LocationConstraint is always empty, we have to return a
// region in every case.
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html
if (response.LocationConstraint === undefined || response.LocationConstraint === '' || response.LocationConstraint === null) {
if (
(response.LocationConstraint === undefined || response.LocationConstraint, toString() === '' || response.LocationConstraint === null)
) {
return 'us-east-1';
}
return response.LocationConstraint;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import aws from './aws.js';
import { APIGateway as APIGW } from 'aws-sdk';
import { APIGatewayClient, APIGatewayClientConfig } from '@aws-sdk/client-api-gateway';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { loadConfiguration } from '../configuration-manager';
import { proxyAgent } from './aws-globals';

export class APIGateway {
private static instance: APIGateway;
private readonly context: $TSContext;
public readonly apigw: APIGW;
public readonly apigw: APIGatewayClient;

static async getInstance(context: $TSContext, options = {}): Promise<APIGateway> {
if (!APIGateway.instance) {
Expand All @@ -25,12 +25,16 @@ export class APIGateway {

constructor(context: $TSContext, creds, options = {}) {
this.context = context;
this.apigw = new aws.APIGateway({

const clientConfig: APIGatewayClientConfig = {
...creds,
...options,
httpOptions: {
agent: proxyAgent(),
},
});
requestHandler: new NodeHttpHandler({
httpAgent: proxyAgent(),
httpsAgent: proxyAgent(),
}),
};

this.apigw = new APIGatewayClient(clientConfig);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import AWS from 'aws-sdk';
import aws from './aws';
import { ECRClient } from '@aws-sdk/client-ecr';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { loadConfiguration } from '../configuration-manager';
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import { proxyAgent } from './aws-globals';

class ECR {
public ecr: AWS.ECR;
public ecr: ECRClient;

constructor(private readonly context: $TSContext, options = {}) {
const instancePromise = (async () => {
Expand All @@ -15,12 +16,13 @@ class ECR {
// ignore missing config
}

this.ecr = new (aws as typeof AWS).ECR({
this.ecr = new ECRClient({
...cred,
...options,
httpOptions: {
agent: proxyAgent(),
},
requestHandler: new NodeHttpHandler({
httpAgent: proxyAgent(),
httpsAgent: proxyAgent(),
}),
});

return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import * as AWS from 'aws-sdk';
import { LocationClient } from '@aws-sdk/client-location';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { AwsSecrets, loadConfiguration } from '../configuration-manager';
import aws from './aws.js';
import { proxyAgent } from './aws-globals';

export class LocationService {
private static instance: LocationService;
readonly client: AWS.Location;
readonly client: LocationClient;

static async getInstance(context: $TSContext, options = {}): Promise<LocationService> {
if (!LocationService.instance) {
Expand All @@ -22,12 +22,13 @@ export class LocationService {
}

private constructor(cred: AwsSecrets, options = {}) {
this.client = new aws.Location({
this.client = new LocationClient({
...cred,
...options,
httpOptions: {
agent: proxyAgent(),
},
requestHandler: new NodeHttpHandler({
httpAgent: proxyAgent(),
httpsAgent: proxyAgent(),
}),
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { printer } from '@aws-amplify/amplify-prompts';
import * as fs from 'fs-extra';
import sequential from 'promise-sequential';
import { APIGateway } from './aws-utils/aws-apigw';
import { GetSdkCommand } from '@aws-sdk/client-api-gateway';

/**
* Download API models from API Gateway
Expand Down Expand Up @@ -41,7 +42,7 @@ const extractAPIModel = async (context: $TSContext, resource: $TSObject, framewo

const apiName = resource.output.ApiName;

const data = await apigw.apigw.getSdk(apigwParams).promise();
const data = await apigw.apigw.send(new GetSdkCommand(apigwParams));

const backendDir = pathManager.getBackendDirPath();

Expand Down
Loading
Loading