Skip to content

Commit

Permalink
fix(servicecatalog): incorrect objectkey produced from asset relative… (
Browse files Browse the repository at this point in the history
#23580)

Currently when assets are nested in a directory, ProductStack is unable to parse the fileName and produces an incorrect template.
Since `asset.fileName` is the relative to the root of the cloud assembly, in which this asset source resides, 
we need to call `path.basename` in order to get the actual name of the file before parsing it to generate the `s3Filename`

More details found in #23560 


----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
wanjacki authored Jan 12, 2023
1 parent 7cbe8ac commit b4a6120
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as path from 'path';
import { CfnBucket, IBucket } from '@aws-cdk/aws-s3';
import { BucketDeployment, Source } from '@aws-cdk/aws-s3-deployment';
import * as cdk from '@aws-cdk/core';
Expand Down Expand Up @@ -42,7 +43,11 @@ export class ProductStackSynthesizer extends cdk.StackSynthesizer {
const physicalName = this.physicalNameOfBucket(this.assetBucket);

const bucketName = physicalName;
const s3Filename = asset.fileName?.split('.')[1] + '.zip';
if (!asset.fileName) {
throw new Error('Asset file name is undefined');
}
const assetFileBaseName = path.basename(asset.fileName);
const s3Filename = assetFileBaseName.split('.')[1] + '.zip';
const objectKey = `${s3Filename}`;
const s3ObjectUrl = `s3://${bucketName}/${objectKey}`;
const httpUrl = `https://s3.${bucketName}/${objectKey}`;
Expand Down
64 changes: 61 additions & 3 deletions packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { Template } from '@aws-cdk/assertions';
import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import * as s3_assets from '@aws-cdk/aws-s3-assets';
import * as sns from '@aws-cdk/aws-sns';
Expand Down Expand Up @@ -32,13 +34,69 @@ describe('ProductStack', () => {
assetBucket: testAssetBucket,
});

// WHEN
new s3_assets.Asset(productStack, 'testAsset', {
path: path.join(__dirname, 'assets'),
new lambda.Function(productStack, 'HelloHandler', {
runtime: lambda.Runtime.PYTHON_3_9,
code: lambda.Code.fromAsset(path.join(__dirname, 'assets')),
handler: 'index.handler',
});

// WHEN
const assembly = app.synth();

// THEN
expect(productStack._getAssetBucket()).toBeDefined();
const template = JSON.parse(fs.readFileSync(path.join(assembly.directory, productStack.templateFile), 'utf-8'));
Template.fromJSON(template).hasResourceProperties('AWS::Lambda::Function', {
Code: {
S3Bucket: 'test-asset-bucket',
S3Key: 'd3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip',
},
});
});

test('Used defined Asset bucket in product stack with nested assets', () => {
// GIVEN
const app = new cdk.App(
{ outdir: 'cdk.out' },
);
const mainStack = new cdk.Stack(app, 'MyStack');
let templateFileUrl = '';
class PortfolioStage extends cdk.Stage {
constructor(scope: Construct, id: string) {
super(scope, id);

const portfolioStack: cdk.Stack = new cdk.Stack(this, 'NestedStack');

const testAssetBucket = new s3.Bucket(portfolioStack, 'TestAssetBucket', {
bucketName: 'test-asset-bucket',
});
const productStack = new servicecatalog.ProductStack(portfolioStack, 'MyProductStack', {
assetBucket: testAssetBucket,
});

new lambda.Function(productStack, 'HelloHandler', {
runtime: lambda.Runtime.PYTHON_3_9,
code: lambda.Code.fromAsset(path.join(__dirname, 'assets')),
handler: 'index.handler',
});

expect(productStack._getAssetBucket()).toBeDefined();
templateFileUrl = productStack.templateFile;
}
}
const portfolioStage = new PortfolioStage(mainStack, 'PortfolioStage');

// WHEN
app.synth();

//THEN
const template = JSON.parse(fs.readFileSync(path.join(portfolioStage.outdir, templateFileUrl), 'utf-8'));
Template.fromJSON(template).hasResourceProperties('AWS::Lambda::Function', {
Code: {
S3Bucket: 'test-asset-bucket',
S3Key: 'd3833f63e813b3a96ea04c8c50ca98209330867f5f6ac358efca11f85a3476c2.zip',
},
});
});

test('fails if bucketName is not specified in product stack with assets', () => {
Expand Down

0 comments on commit b4a6120

Please sign in to comment.