From aeb2c914a7743d4e3b666d4932a13e4a5cf5ae6b Mon Sep 17 00:00:00 2001 From: Jason Strese <431341+jstrese@users.noreply.github.com> Date: Sat, 3 Apr 2021 15:49:39 -0500 Subject: [PATCH] fix(aws-stepfunctions): allow tokens in state machine names Name validation for state machines was added in #13387. The validation did not take into consideration that the name may contain an unresolved token. This change skips name validation if there is an unresolved token as it does not make sense to attempt to validate something that is unknown. This change also allows a few more special characters as they are allowed through the AWS Console. fixes #13946 --- .../aws-stepfunctions/lib/state-machine.ts | 17 +++++----- .../test/state-machine.test.ts | 31 ++++++++++++++++++- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index fa97eccad71f4..d7e7a73efa3f0 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -1,7 +1,7 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; -import { Arn, Duration, IResource, Resource, Stack } from '@aws-cdk/core'; +import { Arn, Duration, IResource, Resource, Stack, Token } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { StateGraph } from './state-graph'; import { StatesMetrics } from './stepfunctions-canned-metrics.generated'; @@ -379,7 +379,7 @@ export class StateMachine extends StateMachineBase { physicalName: props.stateMachineName, }); - if (props.stateMachineName != undefined) { + if (props.stateMachineName !== undefined) { this.validateStateMachineName(props.stateMachineName); } @@ -431,11 +431,14 @@ export class StateMachine extends StateMachineBase { } private validateStateMachineName(stateMachineName: string) { - if (stateMachineName.length < 1 || stateMachineName.length > 80) { - throw new Error(`State Machine name must be between 1 and 80 characters. Received: ${stateMachineName}`); - } - if (!stateMachineName.match('^[0-9a-zA-Z+!@._-]+$')) { - throw new Error(`State Machine name must match "^[0-9a-zA-Z+!@._-]+$". Received: ${stateMachineName}`); + if (!Token.isUnresolved(stateMachineName)) { + if (stateMachineName.length < 1 || stateMachineName.length > 80) { + throw new Error(`State Machine name must be between 1 and 80 characters. Received: ${stateMachineName}`); + } + + if (!stateMachineName.match(/^[a-z0-9\+\!\@\.\(\)\-\=\_\']+$/i)) { + throw new Error(`State Machine name must match "^[a-z0-9+!@.()-=_']+$/i". Received: ${stateMachineName}`); + } } } diff --git a/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts index 1c26947659a54..0ded9c1512d4b 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts @@ -89,7 +89,36 @@ describe('State Machine', () => { expect(() => { createStateMachine(invalidCharactersName); - }).toThrow(`State Machine name must match "^[0-9a-zA-Z+!@._-]+$". Received: ${invalidCharactersName}`); + }).toThrow(`State Machine name must match "^[a-z0-9+!@.()-=_']+$/i". Received: ${invalidCharactersName}`); + }); + + test('State Machine with valid name', () => { + // GIVEN + const stack = new cdk.Stack(); + const newStateMachine = new stepfunctions.StateMachine(stack, 'dummyStateMachineToken', { + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'dummyStateMachineTokenPass')), + }); + + // WHEN + const nameContainingToken = newStateMachine.stateMachineName + '-Name'; + const validName = 'AWS-Stepfunctions_Name.Test(@aws-cdk+)!=\'1\''; + + // THEN + expect(() => { + new stepfunctions.StateMachine(stack, 'TokenTest-StateMachine', { + stateMachineName: nameContainingToken, + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'TokenTest-StateMachinePass')), + stateMachineType: stepfunctions.StateMachineType.EXPRESS, + }); + }).not.toThrow(); + + expect(() => { + new stepfunctions.StateMachine(stack, 'ValidNameTest-StateMachine', { + stateMachineName: validName, + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'ValidNameTest-StateMachinePass')), + stateMachineType: stepfunctions.StateMachineType.EXPRESS, + }); + }).not.toThrow(); }); test('log configuration', () => {