Skip to content

Commit

Permalink
Merge branch 'master' into peterwoodworth/stacknamelimit
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Apr 2, 2022
2 parents 9a16a22 + 7e9a43d commit def2c14
Show file tree
Hide file tree
Showing 35 changed files with 1,812 additions and 268 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/issue-label-assign.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: "Set Issue Label and Assignee"
on:
issues:
types: [opened, edited]
pull_request:
types: [opened]
pull_request_target:
types: [opened]

Expand Down Expand Up @@ -48,7 +46,7 @@ jobs:
steps:
- uses: aws-github-ops/aws-issue-triage-manager@main
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
github-token: "${{ secrets.PROJEN_GITHUB_TOKEN }}"
target: "pull-requests"
area-is-keyword: true
default-area: >
Expand Down
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArnFormat, IResource, Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnApplication } from '../codedeploy.generated';
import { arnForApplication } from '../utils';
import { arnForApplication, validateName } from '../utils';

/**
* Represents a reference to a CodeDeploy Application deploying to Amazon ECS.
Expand Down Expand Up @@ -77,4 +77,8 @@ export class EcsApplication extends Resource implements IEcsApplication {
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
});
}

protected validate(): string[] {
return validateName('Application', this.physicalName);
}
}
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArnFormat, IResource, Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnApplication } from '../codedeploy.generated';
import { arnForApplication } from '../utils';
import { arnForApplication, validateName } from '../utils';

/**
* Represents a reference to a CodeDeploy Application deploying to AWS Lambda.
Expand Down Expand Up @@ -77,4 +77,8 @@ export class LambdaApplication extends Resource implements ILambdaApplication {
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
});
}

protected validate(): string[] {
return validateName('Application', this.physicalName);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Duration, Names, Resource } from '@aws-cdk/core';
import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '@aws-cdk/custom-resources';
import { Construct } from 'constructs';
import { arnForDeploymentConfig } from '../utils';
import { arnForDeploymentConfig, validateName } from '../utils';
import { ILambdaDeploymentConfig } from './deployment-config';

/**
Expand Down Expand Up @@ -143,6 +143,10 @@ export class CustomLambdaDeploymentConfig extends Resource implements ILambdaDep
});
}

protected validate(): string[] {
return validateName('Deployment config', this.deploymentConfigName);
}

// Validate the inputs. The percentage/interval limits come from CodeDeploy
private validateParameters(props: CustomLambdaDeploymentConfigProps): void {
if ( !(1 <= props.percentage && props.percentage <= 99) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnDeploymentGroup } from '../codedeploy.generated';
import { AutoRollbackConfig } from '../rollback-config';
import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../utils';
import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils';
import { ILambdaApplication, LambdaApplication } from './application';
import { ILambdaDeploymentConfig, LambdaDeploymentConfig } from './deployment-config';

Expand Down Expand Up @@ -254,6 +254,10 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy
actions: ['codedeploy:PutLifecycleEventHookExecutionStatus'],
});
}

protected validate(): string[] {
return validateName('Deployment group', this.physicalName);
}
}

/**
Expand Down
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/lib/server/application.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArnFormat, IResource, Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnApplication } from '../codedeploy.generated';
import { arnForApplication } from '../utils';
import { arnForApplication, validateName } from '../utils';

/**
* Represents a reference to a CodeDeploy Application deploying to EC2/on-premise instances.
Expand Down Expand Up @@ -78,4 +78,8 @@ export class ServerApplication extends Resource implements IServerApplication {
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
});
}

protected validate(): string[] {
return validateName('Application', this.physicalName);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnDeploymentConfig } from '../codedeploy.generated';
import { arnForDeploymentConfig } from '../utils';
import { arnForDeploymentConfig, validateName } from '../utils';

/**
* The Deployment Configuration of an EC2/on-premise Deployment Group.
Expand Down Expand Up @@ -119,6 +119,10 @@ export class ServerDeploymentConfig extends cdk.Resource implements IServerDeplo
this.deploymentConfigName = resource.ref;
this.deploymentConfigArn = arnForDeploymentConfig(this.deploymentConfigName);
}

protected validate(): string[] {
return validateName('Deployment config', this.physicalName);
}
}

function deploymentConfig(name: string): IServerDeploymentConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ArnFormat } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnDeploymentGroup } from '../codedeploy.generated';
import { AutoRollbackConfig } from '../rollback-config';
import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../utils';
import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils';
import { IServerApplication, ServerApplication } from './application';
import { IServerDeploymentConfig, ServerDeploymentConfig } from './deployment-config';
import { LoadBalancer, LoadBalancerGeneration } from './load-balancer';
Expand Down Expand Up @@ -341,6 +341,10 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {
return this._autoScalingGroups.slice();
}

protected validate(): string[] {
return validateName('Deployment group', this.physicalName);
}

private addCodeDeployAgentInstallUserData(asg: autoscaling.IAutoScalingGroup): void {
if (!this.installAgent) {
return;
Expand Down
17 changes: 16 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import { Aws } from '@aws-cdk/core';
import { Aws, Token } from '@aws-cdk/core';
import { CfnDeploymentGroup } from './codedeploy.generated';
import { AutoRollbackConfig } from './rollback-config';

Expand Down Expand Up @@ -65,3 +65,18 @@ CfnDeploymentGroup.AutoRollbackConfigurationProperty | undefined {
}
: undefined;
}

export function validateName(type: 'Application' | 'Deployment group' | 'Deployment config', name: string): string[] {
const ret = [];

if (!Token.isUnresolved(name) && name !== undefined) {
if (name.length > 100) {
ret.push(`${type} name: "${name}" can be a max of 100 characters.`);
}
if (!/^[a-z0-9._+=,@-]+$/i.test(name)) {
ret.push(`${type} name: "${name}" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).`);
}
}

return ret;
}
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/test/ecs/application.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,24 @@ describe('CodeDeploy ECS Application', () => {
ComputePlatform: 'ECS',
});
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.EcsApplication(stack, 'MyApp', {
applicationName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Application name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.EcsApplication(stack, 'MyApp', {
applicationName: 'my name',
});

expect(() => app.synth()).toThrow('Application name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});
});
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/test/lambda/application.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,24 @@ describe('CodeDeploy Lambda Application', () => {
ComputePlatform: 'Lambda',
});
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.LambdaApplication(stack, 'MyApp', {
applicationName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Application name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.LambdaApplication(stack, 'MyApp', {
applicationName: 'my name',
});

expect(() => app.synth()).toThrow('Application name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,32 @@ test('custom resource created with specific name', () => {
});
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stackWithApp = new cdk.Stack(app);
new codedeploy.CustomLambdaDeploymentConfig(stackWithApp, 'CustomConfig', {
type: codedeploy.CustomLambdaDeploymentConfigType.CANARY,
interval: cdk.Duration.minutes(1),
percentage: 5,
deploymentConfigName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Deployment config name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stackWithApp = new cdk.Stack(app);
new codedeploy.CustomLambdaDeploymentConfig(stackWithApp, 'CustomConfig', {
type: codedeploy.CustomLambdaDeploymentConfigType.CANARY,
interval: cdk.Duration.minutes(1),
percentage: 5,
deploymentConfigName: 'my name',
});

expect(() => app.synth()).toThrow('Deployment config name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});

test('can create linear custom config', () => {
// WHEN
const config = new codedeploy.CustomLambdaDeploymentConfig(stack, 'CustomConfig', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ describe('CodeDeploy Lambda DeploymentGroup', () => {
});
});


test('can be created with explicit name', () => {
const stack = new cdk.Stack();
const application = new codedeploy.LambdaApplication(stack, 'MyApp');
Expand All @@ -132,6 +131,30 @@ describe('CodeDeploy Lambda DeploymentGroup', () => {
});
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
const alias = mockAlias(stack);
new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', {
alias,
deploymentGroupName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Deployment group name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
const alias = mockAlias(stack);
new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', {
alias,
deploymentGroupName: 'my name',
});

expect(() => app.synth()).toThrow('Deployment group name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});

test('can be created with explicit role', () => {
const stack = new cdk.Stack();
const application = new codedeploy.LambdaApplication(stack, 'MyApp');
Expand Down Expand Up @@ -565,6 +588,32 @@ describe('CodeDeploy Lambda DeploymentGroup', () => {
},
});
});

test('uses the correct Service Principal in the us-isob-east-1 region', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'CodeDeployLambdaStack', {
env: { region: 'us-isob-east-1' },
});
const alias = mockAlias(stack);
new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', {
alias,
});

Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', {
AssumeRolePolicyDocument: {
Statement: [
{
Action: 'sts:AssumeRole',
Effect: 'Allow',
Principal: {
Service: 'codedeploy.amazonaws.com',
},
},
],
Version: '2012-10-17',
},
});
});
});

describe('imported with fromLambdaDeploymentGroupAttributes', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,26 @@ describe('CodeDeploy DeploymentConfig', () => {

expect(deploymentConfig).not.toEqual(undefined);
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.ServerDeploymentConfig(stack, 'DeploymentConfig', {
minimumHealthyHosts: codedeploy.MinimumHealthyHosts.percentage(75),
deploymentConfigName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Deployment config name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.ServerDeploymentConfig(stack, 'DeploymentConfig', {
minimumHealthyHosts: codedeploy.MinimumHealthyHosts.percentage(75),
deploymentConfigName: 'my name',
});

expect(() => app.synth()).toThrow('Deployment config name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -437,4 +437,25 @@ describe('CodeDeploy Server Deployment Group', () => {
});
});

test('fail with more than 100 characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.ServerDeploymentGroup(stack, 'MyDG', {
deploymentGroupName: 'a'.repeat(101),
});

expect(() => app.synth()).toThrow(`Deployment group name: "${'a'.repeat(101)}" can be a max of 100 characters.`);
});

test('fail with unallowed characters in name', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app);
new codedeploy.ServerDeploymentGroup(stack, 'MyDG', {

deploymentGroupName: 'my name',
});

expect(() => app.synth()).toThrow('Deployment group name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).');
});

});
Loading

0 comments on commit def2c14

Please sign in to comment.