-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
329 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
packages/@aws-cdk/aws-cloudwatch/lib/alarm-status-widget.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { IAlarm } from './alarm-base'; | ||
import { ConcreteWidget } from './widget'; | ||
|
||
/** | ||
* Properties for an Alarm Status Widget | ||
*/ | ||
export interface AlarmStatusWidgetProps { | ||
/** | ||
* CloudWatch Alarms to show in widget | ||
*/ | ||
readonly alarms: IAlarm[]; | ||
/** | ||
* The title of the widget | ||
* | ||
* @default 'Alarm Status' | ||
*/ | ||
readonly title?: string; | ||
/** | ||
* Width of the widget, in a grid of 24 units wide | ||
* | ||
* @default 6 | ||
*/ | ||
readonly width?: number; | ||
/** | ||
* Height of the widget | ||
* | ||
* @default 3 | ||
*/ | ||
readonly height?: number; | ||
} | ||
|
||
/** | ||
* A dashboard widget that displays alarms in a grid view | ||
*/ | ||
export class AlarmStatusWidget extends ConcreteWidget { | ||
private readonly props: AlarmStatusWidgetProps; | ||
|
||
constructor(props: AlarmStatusWidgetProps) { | ||
super(props.width || 6, props.height || 3); | ||
this.props = props; | ||
} | ||
|
||
public position(x: number, y: number): void { | ||
this.x = x; | ||
this.y = y; | ||
} | ||
|
||
public toJson(): any[] { | ||
return [ | ||
{ | ||
type: 'alarm', | ||
width: this.width, | ||
height: this.height, | ||
x: this.x, | ||
y: this.y, | ||
properties: { | ||
title: this.props.title ? this.props.title : 'Alarm Status', | ||
alarms: this.props.alarms.map((alarm) => alarm.alarmArn), | ||
}, | ||
}, | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
packages/@aws-cdk/aws-cloudwatch/test/test.alarm-status-widget.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Stack } from '@aws-cdk/core'; | ||
import { Test } from 'nodeunit'; | ||
import { Metric, Alarm, AlarmStatusWidget } from '../lib'; | ||
export = { | ||
'alarm status widget'(test: Test) { | ||
// GIVEN | ||
const stack = new Stack(); | ||
const metric = new Metric({ namespace: 'CDK', metricName: 'Test' }); | ||
const alarm = new Alarm(stack, 'Alarm', { | ||
metric, | ||
threshold: 1, | ||
evaluationPeriods: 1, | ||
}); | ||
|
||
// WHEN | ||
const widget = new AlarmStatusWidget({ | ||
alarms: [alarm], | ||
}); | ||
|
||
// THEN | ||
test.deepEqual(stack.resolve(widget.toJson()), [ | ||
{ | ||
type: 'alarm', | ||
width: 6, | ||
height: 3, | ||
properties: { | ||
title: 'Alarm Status', | ||
alarms: [{ 'Fn::GetAtt': ['Alarm7103F465', 'Arn'] }], | ||
}, | ||
}, | ||
]); | ||
|
||
test.done(); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
packages/@aws-cdk/aws-globalaccelerator/lib/accelerator-security-group.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { ISecurityGroup, SecurityGroup, IVpc } from '@aws-cdk/aws-ec2'; | ||
import { Construct } from '@aws-cdk/core'; | ||
import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId} from '@aws-cdk/custom-resources'; | ||
import { EndpointGroup } from '../lib'; | ||
|
||
/** | ||
* The security group used by a Global Accelerator to send traffic to resources in a VPC. | ||
*/ | ||
export class AcceleratorSecurityGroup { | ||
/** | ||
* Lookup the Global Accelerator security group at CloudFormation deployment time. | ||
* | ||
* As of this writing, Global Accelerators (AGA) create a single security group per VPC. AGA security groups are shared | ||
* by all AGAs in an account. Additionally, there is no CloudFormation mechanism to reference the AGA security groups. | ||
* | ||
* This makes creating security group rules which allow traffic from an AGA complicated in CDK. This lookup will identify | ||
* the AGA security group for a given VPC at CloudFormation deployment time, and lets you create rules for traffic from AGA | ||
* to other resources created by CDK. | ||
*/ | ||
public static fromVpc(scope: Construct, id: string, vpc: IVpc, endpointGroup: EndpointGroup): ISecurityGroup { | ||
|
||
// The security group name is always 'GlobalAccelerator' | ||
const globalAcceleratorSGName = 'GlobalAccelerator'; | ||
|
||
// How to reference the security group name in the response from EC2 | ||
const ec2ResponseSGIdField = 'SecurityGroups.0.GroupId'; | ||
|
||
// The AWS Custom Resource that make a call to EC2 to get the security group ID, for the given VPC | ||
const lookupAcceleratorSGCustomResource = new AwsCustomResource(scope, id + 'CustomResource', { | ||
onCreate: { | ||
service: 'EC2', | ||
action: 'describeSecurityGroups', | ||
parameters: { | ||
Filters: [ | ||
{ | ||
Name: 'group-name', | ||
Values: [ | ||
globalAcceleratorSGName, | ||
], | ||
}, | ||
{ | ||
Name: 'vpc-id', | ||
Values: [ | ||
vpc.vpcId, | ||
], | ||
}, | ||
], | ||
}, | ||
// We get back a list of responses, but the list should be of length 0 or 1 | ||
// Getting no response means no resources have been linked to the AGA | ||
physicalResourceId: PhysicalResourceId.fromResponse(ec2ResponseSGIdField), | ||
}, | ||
policy: AwsCustomResourcePolicy.fromSdkCalls({ | ||
resources: AwsCustomResourcePolicy.ANY_RESOURCE, | ||
}), | ||
}); | ||
|
||
// Look up the security group ID | ||
const sg = SecurityGroup.fromSecurityGroupId(scope, | ||
id, | ||
lookupAcceleratorSGCustomResource.getResponseField(ec2ResponseSGIdField)); | ||
// We add a dependency on the endpoint group, guaranteeing that CloudFormation won't | ||
// try and look up the SG before AGA creates it. The SG is created when a VPC resource | ||
// is associated with an AGA | ||
lookupAcceleratorSGCustomResource.node.addDependency(endpointGroup); | ||
return sg; | ||
} | ||
|
||
private constructor() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
// AWS::GlobalAccelerator CloudFormation Resources: | ||
export * from './globalaccelerator.generated'; | ||
export * from './accelerator'; | ||
export * from './accelerator-security-group'; | ||
export * from './listener'; | ||
export * from './endpoint-group'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
packages/@aws-cdk/aws-globalaccelerator/test/globalaccelerator-security-group.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { expect, haveResource, ResourcePart } from '@aws-cdk/assert'; | ||
import { Port } from '@aws-cdk/aws-ec2'; | ||
import * as ga from '../lib'; | ||
import { testFixture, testFixtureAlb } from './util'; | ||
|
||
test('custom resource exists', () => { | ||
// GIVEN | ||
const { stack, vpc } = testFixture(); | ||
const accelerator = new ga.Accelerator(stack, 'Accelerator'); | ||
const listener = new ga.Listener(stack, 'Listener', { | ||
accelerator, | ||
portRanges: [ | ||
{ | ||
fromPort: 443, | ||
toPort: 443, | ||
}, | ||
], | ||
}); | ||
const endpointGroup = new ga.EndpointGroup(stack, 'Group', { listener }); | ||
|
||
// WHEN | ||
ga.AcceleratorSecurityGroup.fromVpc(stack, 'GlobalAcceleratorSG', vpc, endpointGroup); | ||
|
||
// THEN | ||
expect(stack).to(haveResource('Custom::AWS', { | ||
Properties: { | ||
ServiceToken: { | ||
'Fn::GetAtt': [ | ||
'AWS679f53fac002430cb0da5b7982bd22872D164C4C', | ||
'Arn', | ||
], | ||
}, | ||
Create: { | ||
action: 'describeSecurityGroups', | ||
service: 'EC2', | ||
parameters: { | ||
Filters: [ | ||
{ | ||
Name: 'group-name', | ||
Values: [ | ||
'GlobalAccelerator', | ||
], | ||
}, | ||
{ | ||
Name: 'vpc-id', | ||
Values: [ | ||
{ | ||
Ref: 'VPCB9E5F0B4', | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
physicalResourceId: { | ||
responsePath: 'SecurityGroups.0.GroupId', | ||
}, | ||
}, | ||
}, | ||
DependsOn: [ | ||
'GroupC77FDACD', | ||
], | ||
}, ResourcePart.CompleteDefinition)); | ||
}); | ||
|
||
test('can create security group rule', () => { | ||
// GIVEN | ||
const { stack, alb, vpc } = testFixtureAlb(); | ||
const accelerator = new ga.Accelerator(stack, 'Accelerator'); | ||
const listener = new ga.Listener(stack, 'Listener', { | ||
accelerator, | ||
portRanges: [ | ||
{ | ||
fromPort: 443, | ||
toPort: 443, | ||
}, | ||
], | ||
}); | ||
const endpointGroup = new ga.EndpointGroup(stack, 'Group', { listener }); | ||
endpointGroup.addLoadBalancer('endpoint', alb); | ||
|
||
// WHEN | ||
const sg = ga.AcceleratorSecurityGroup.fromVpc(stack, 'GlobalAcceleratorSG', vpc, endpointGroup); | ||
alb.connections.allowFrom(sg, Port.tcp(443)); | ||
|
||
// THEN | ||
expect(stack).to(haveResource('AWS::EC2::SecurityGroupIngress', { | ||
IpProtocol: 'tcp', | ||
FromPort: 443, | ||
GroupId: { | ||
'Fn::GetAtt': [ | ||
'ALBSecurityGroup8B8624F8', | ||
'GroupId', | ||
], | ||
}, | ||
SourceSecurityGroupId: { | ||
'Fn::GetAtt': [ | ||
'GlobalAcceleratorSGCustomResourceC1DB5287', | ||
'SecurityGroups.0.GroupId', | ||
], | ||
}, | ||
ToPort: 443, | ||
})); | ||
}); |
Oops, something went wrong.