Skip to content

Commit

Permalink
Merge branch 'master' into chaimber/revert_temp_adam_issue_assign
Browse files Browse the repository at this point in the history
  • Loading branch information
BenChaimberg authored Aug 24, 2021
2 parents c4ea331 + eb54cd4 commit ac28d10
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 6 deletions.
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-sqs/lib/queue-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,13 @@ export interface QueueAttributes {
* @default - None
*/
readonly keyArn?: string;

/**
* Whether this queue is an Amazon SQS FIFO queue. If false, this is a standard queue.
*
* In case of a FIFO queue which is imported from a token, this value has to be explicitly set to true.
*
* @default - if fifo is not specified, the property will be determined based on the queue name (not possible for FIFO queues imported from a token)
*/
readonly fifo?: boolean;
}
25 changes: 22 additions & 3 deletions packages/@aws-cdk/aws-sqs/lib/queue.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as kms from '@aws-cdk/aws-kms';
import { Duration, RemovalPolicy, Stack, Token } from '@aws-cdk/core';
import { Duration, RemovalPolicy, Stack, Token, ArnFormat } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IQueue, QueueAttributes, QueueBase } from './queue-base';
import { CfnQueue } from './sqs.generated';
Expand Down Expand Up @@ -257,7 +257,7 @@ export class Queue extends QueueBase {
*/
public static fromQueueAttributes(scope: Construct, id: string, attrs: QueueAttributes): IQueue {
const stack = Stack.of(scope);
const parsedArn = stack.parseArn(attrs.queueArn);
const parsedArn = stack.splitArn(attrs.queueArn, ArnFormat.NO_RESOURCE_NAME);
const queueName = attrs.queueName || parsedArn.resource;
const queueUrl = attrs.queueUrl || `https://sqs.${parsedArn.region}.${stack.urlSuffix}/${parsedArn.account}/${queueName}`;

Expand All @@ -268,9 +268,28 @@ export class Queue extends QueueBase {
public readonly encryptionMasterKey = attrs.keyArn
? kms.Key.fromKeyArn(this, 'Key', attrs.keyArn)
: undefined;
public readonly fifo = queueName.endsWith('.fifo') ? true : false;
public readonly fifo: boolean = this.determineFifo();;

protected readonly autoCreatePolicy = false;

/**
* Determine fifo flag based on queueName and fifo attribute
*/
private determineFifo(): boolean {
if (Token.isUnresolved(this.queueArn)) {
return attrs.fifo || false;
} else {
if (typeof attrs.fifo !== 'undefined') {
if (attrs.fifo && !queueName.endsWith('.fifo')) {
throw new Error("FIFO queue names must end in '.fifo'");
}
if (!attrs.fifo && queueName.endsWith('.fifo')) {
throw new Error("Non-FIFO queue name may not end in '.fifo'");
}
}
return queueName.endsWith('.fifo') ? true : false;
}
}
}

return new Import(scope, id);
Expand Down
83 changes: 82 additions & 1 deletion packages/@aws-cdk/aws-sqs/test/test.sqs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, haveResource, ResourcePart } from '@aws-cdk/assert-internal';
import * as iam from '@aws-cdk/aws-iam';
import * as kms from '@aws-cdk/aws-kms';
import { CfnParameter, Duration, Stack, App } from '@aws-cdk/core';
import { CfnParameter, Duration, Stack, App, Token } from '@aws-cdk/core';
import { Test } from 'nodeunit';
import * as sqs from '../lib';

Expand Down Expand Up @@ -191,6 +191,87 @@ export = {
test.done();
},

'import queueArn from token, fifo and standard queues can be defined'(test: Test) {
// GIVEN
const stack = new Stack();

// WHEN
const stdQueue1 = sqs.Queue.fromQueueAttributes(stack, 'StdQueue1', {
queueArn: Token.asString({ Ref: 'ARN' }),
});
const stdQueue2 = sqs.Queue.fromQueueAttributes(stack, 'StdQueue2', {
queueArn: Token.asString({ Ref: 'ARN' }),
fifo: false,
});
const fifoQueue = sqs.Queue.fromQueueAttributes(stack, 'FifoQueue', {
queueArn: Token.asString({ Ref: 'ARN' }),
fifo: true,
});

// THEN
test.deepEqual(stdQueue1.fifo, false);
test.deepEqual(stdQueue2.fifo, false);
test.deepEqual(fifoQueue.fifo, true);
test.done();
},

'import queueArn from token, check attributes'(test: Test) {
// GIVEN
const stack = new Stack();

// WHEN
const stdQueue1 = sqs.Queue.fromQueueArn(stack, 'StdQueue', Token.asString({ Ref: 'ARN' }));

// THEN
test.deepEqual(stack.resolve(stdQueue1.queueArn), {
Ref: 'ARN',
});
test.deepEqual(stack.resolve(stdQueue1.queueName), {
'Fn::Select': [5, { 'Fn::Split': [':', { Ref: 'ARN' }] }],
});
test.deepEqual(stack.resolve(stdQueue1.queueUrl), {
'Fn::Join':
['',
['https://sqs.',
{ 'Fn::Select': [3, { 'Fn::Split': [':', { Ref: 'ARN' }] }] },
'.',
{ Ref: 'AWS::URLSuffix' },
'/',
{ 'Fn::Select': [4, { 'Fn::Split': [':', { Ref: 'ARN' }] }] },
'/',
{ 'Fn::Select': [5, { 'Fn::Split': [':', { Ref: 'ARN' }] }] }]],
});
test.deepEqual(stdQueue1.fifo, false);
test.done();
},

'fails if fifo flag is set for non fifo queue name'(test: Test) {
// GIVEN
const app = new App();
const stack = new Stack(app, 'my-stack');

// THEN
test.throws(() => sqs.Queue.fromQueueAttributes(stack, 'ImportedStdQueue', {
queueArn: 'arn:aws:sqs:us-west-2:123456789012:queue1',
fifo: true,
}), /FIFO queue names must end in '.fifo'/);
test.done();
},


'fails if fifo flag is false for fifo queue name'(test: Test) {
// GIVEN
const app = new App();
const stack = new Stack(app, 'my-stack');

// THEN
test.throws(() => sqs.Queue.fromQueueAttributes(stack, 'ImportedFifoQueue', {
queueArn: 'arn:aws:sqs:us-west-2:123456789012:queue1.fifo',
fifo: false,
}), /Non-FIFO queue name may not end in '.fifo'/);
test.done();
},

'importing works correctly for cross region queue'(test: Test) {
// GIVEN
const stack = new Stack(undefined, 'Stack', { env: { region: 'us-east-1' } });
Expand Down
5 changes: 3 additions & 2 deletions packages/@aws-cdk/aws-ssm/lib/parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import {
CfnDynamicReference, CfnDynamicReferenceService, CfnParameter,
Construct as CompatConstruct, ContextProvider, Fn, IResource, Resource, Stack, Token,
Tokenization,
} from '@aws-cdk/core';
import { Construct } from 'constructs';
import * as ssm from './ssm.generated';
Expand Down Expand Up @@ -324,7 +325,7 @@ export class StringParameter extends ParameterBase implements IStringParameter {
const type = attrs.type || ParameterType.STRING;

const stringValue = attrs.version
? new CfnDynamicReference(CfnDynamicReferenceService.SSM, `${attrs.parameterName}:${attrs.version}`).toString()
? new CfnDynamicReference(CfnDynamicReferenceService.SSM, `${attrs.parameterName}:${Tokenization.stringifyNumber(attrs.version)}`).toString()
: new CfnParameter(scope as CompatConstruct, `${id}.Parameter`, { type: `AWS::SSM::Parameter::Value<${type}>`, default: attrs.parameterName }).valueAsString;

class Import extends ParameterBase {
Expand All @@ -341,7 +342,7 @@ export class StringParameter extends ParameterBase implements IStringParameter {
* Imports a secure string parameter from the SSM parameter store.
*/
public static fromSecureStringParameterAttributes(scope: Construct, id: string, attrs: SecureStringParameterAttributes): IStringParameter {
const stringValue = new CfnDynamicReference(CfnDynamicReferenceService.SSM_SECURE, `${attrs.parameterName}:${attrs.version}`).toString();
const stringValue = new CfnDynamicReference(CfnDynamicReferenceService.SSM_SECURE, `${attrs.parameterName}:${Tokenization.stringifyNumber(attrs.version)}`).toString();

class Import extends ParameterBase {
public readonly parameterName = attrs.parameterName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
},
{
"Parameters": {
"MyParameterVersion": {
"Type": "Number",
"Default": 1
},
"MyValueParameter": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/My/Public/Parameter"
Expand All @@ -28,6 +32,20 @@
"Value": {
"Ref": "MyValueParameter"
}
},
"TheValueVersionFromToken": {
"Value": {
"Fn::Join": [
"",
[
"{{resolve:ssm:/My/Public/Parameter:",
{
"Ref": "MyParameterVersion"
},
"}}"
]
]
}
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,47 @@ class UsingStack extends cdk.Stack {
constructor(scope: cdk.App, id: string) {
super(scope, id);

// Parameter that contains version number, will be used to pass
// version value from token.
const parameterVersion = new cdk.CfnParameter(this, 'MyParameterVersion', {
type: 'Number',
default: 1,
}).valueAsNumber;

/// !show
// Retrieve the latest value of the non-secret parameter
// with name "/My/String/Parameter".
const stringValue = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValue', {
parameterName: '/My/Public/Parameter',
// 'version' can be specified but is optional.
}).stringValue;
const stringValueVersionFromToken = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValueVersionFromToken', {
parameterName: '/My/Public/Parameter',
// parameter version from token
version: parameterVersion,
}).stringValue;

// Retrieve a specific version of the secret (SecureString) parameter.
// 'version' is always required.
const secretValue = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValue', {
parameterName: '/My/Secret/Parameter',
version: 5,
});
const secretValueVersionFromToken = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValueVersionFromToken', {
parameterName: '/My/Secret/Parameter',
// parameter version from token
version: parameterVersion,
});

/// !hide

new cdk.CfnResource(this, 'Dummy', { type: 'AWS::SNS::Topic' });
new cdk.CfnOutput(this, 'TheValue', { value: stringValue });
new cdk.CfnOutput(this, 'TheValueVersionFromToken', { value: stringValueVersionFromToken });

// Cannot be provisioned so cannot be actually used
Array.isArray(secretValue);
Array.isArray(secretValueVersionFromToken);
}
}

Expand Down
68 changes: 68 additions & 0 deletions packages/@aws-cdk/aws-ssm/test/test.parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,40 @@ export = {
test.done();
},

'StringParameter.fromStringParameterAttributes with version from token'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
const param = ssm.StringParameter.fromStringParameterAttributes(stack, 'MyParamName', {
parameterName: 'MyParamName',
version: cdk.Token.asNumber({ Ref: 'version' }),
});

// THEN
test.deepEqual(stack.resolve(param.parameterArn), {
'Fn::Join': ['', [
'arn:',
{ Ref: 'AWS::Partition' },
':ssm:',
{ Ref: 'AWS::Region' },
':',
{ Ref: 'AWS::AccountId' },
':parameter/MyParamName',
]],
});
test.deepEqual(stack.resolve(param.parameterName), 'MyParamName');
test.deepEqual(stack.resolve(param.parameterType), 'String');
test.deepEqual(stack.resolve(param.stringValue), {
'Fn::Join': ['', [
'{{resolve:ssm:MyParamName:',
{ Ref: 'version' },
'}}',
]],
});
test.done();
},

'StringParameter.fromSecureStringParameterAttributes'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down Expand Up @@ -372,6 +406,40 @@ export = {
test.done();
},

'StringParameter.fromSecureStringParameterAttributes with version from token'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
const param = ssm.StringParameter.fromSecureStringParameterAttributes(stack, 'MyParamName', {
parameterName: 'MyParamName',
version: cdk.Token.asNumber({ Ref: 'version' }),
});

// THEN
test.deepEqual(stack.resolve(param.parameterArn), {
'Fn::Join': ['', [
'arn:',
{ Ref: 'AWS::Partition' },
':ssm:',
{ Ref: 'AWS::Region' },
':',
{ Ref: 'AWS::AccountId' },
':parameter/MyParamName',
]],
});
test.deepEqual(stack.resolve(param.parameterName), 'MyParamName');
test.deepEqual(stack.resolve(param.parameterType), 'SecureString');
test.deepEqual(stack.resolve(param.stringValue), {
'Fn::Join': ['', [
'{{resolve:ssm-secure:MyParamName:',
{ Ref: 'version' },
'}}',
]],
});
test.done();
},

'StringParameter.fromSecureStringParameterAttributes with encryption key creates the correct policy for grantRead'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit ac28d10

Please sign in to comment.