-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(appmesh): add Virtual Gateways and Gateway Routes #10879
Merged
Merged
Changes from 6 commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
5cab38c
Initial VGW commit
71ac7dd
Update with upstream changes
0cf538a
Add initial round of tests
1849af9
Fixes a bug with default paths on health checks
4e26790
Implements Gateway Routes
9c7dc48
Adds routeType to GatewayRouteBaseProps
0d47976
Update packages/@aws-cdk/aws-appmesh/lib/virtual-node.ts
dfezzie 463f507
Reworks Gateway Routes to use bind classes for protocol spec variants
860a40a
Merge branch 'master' into gateway
d2c59bb
Adds addListener to VGW
4976d8f
Adds gateway listener protocol variant classes
ce2f325
Adds addListener method to IVirtualGateway
45690a9
Merge branch 'master' into gateway
2939e5c
Fixes some build issues
a242bfd
adds utility method to add multiple gateway routes to a VirtualGateway
a97a5c5
adds more tests to gateway routes
0016549
adds integ tests for gateway routes
5a54ab5
Updates README and adds tests for adding multiple gateway routes
2b36223
Merge branch 'master' into gateway
ca1d0b3
Apply suggestions from code review
dfezzie 92dd147
refactor gateway route spec related code into a separate file
4c9a69c
add a newline between properties
214177c
do not export gateway listeners
93ded0e
removes fromResourceName methods and replaces it with fromResourceAtt…
b737de6
makes error message more specific for prefixPath
2689cc0
Merge branch 'master' into gateway
48900ef
Apply suggestions from code review
dfezzie 1df5158
Merge branch 'master' into gateway
dfezzie bcd5425
Revert "removes fromResourceName methods and replaces it with fromRes…
94e79a8
Update README with requested changes
9cd6eb6
Addresses PR comments
14df61e
bind method for gateway listeners no longer returns raw cfn spec
b30faaf
uses inheritance for http2 gateway listener and removes fromName() me…
a86c57b
add protocol variant tests for gateway routes
4e432c2
addresses smaller changes from review
e550d53
moves gateway listener classes to separate file and adds health check…
7813bbc
removes addListener() methods from virtual gateways
8670dbd
removes the ListenerBase interface
c01eb4c
Merge branch 'master' into gateway
5efc195
remove validation for only having 1 listener on virtual gateways
1eda686
Merge branch 'master' into gateway
519fc23
Merge branch 'master' into gateway
skinny85 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,364 @@ | ||
import * as cdk from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { CfnGatewayRoute } from './appmesh.generated'; | ||
import { Protocol } from './shared-interfaces'; | ||
import { IVirtualGateway } from './virtual-gateway'; | ||
import { IVirtualService } from './virtual-service'; | ||
|
||
/** | ||
* Interface for which all Gateway Route based classes MUST implement | ||
*/ | ||
export interface IGatewayRoute extends cdk.IResource { | ||
/** | ||
* The name of the Gateway Route | ||
* | ||
* @attribute | ||
*/ | ||
readonly gatewayRouteName: string, | ||
|
||
/** | ||
* The Amazon Resource Name (ARN) for the Gateway Route | ||
* | ||
* @attribute | ||
*/ | ||
readonly gatewayRouteArn: string; | ||
} | ||
|
||
interface GatewayRouteBaseProps { | ||
/** | ||
* The name of the Gateway Route | ||
* | ||
* @default - an automatically generated name | ||
*/ | ||
readonly gatewayRouteName?: string; | ||
|
||
/** | ||
* The VirtualService this Gateway Route directs traffic to | ||
*/ | ||
readonly routeTarget: IVirtualService; | ||
|
||
/** | ||
* What protocol the route uses | ||
*/ | ||
readonly routeType: Protocol.GRPC | Protocol.HTTP | Protocol.HTTP2; | ||
} | ||
|
||
/** | ||
* Base interface for HTTP Based Gateway Routes | ||
*/ | ||
export interface GatewayHttpRouteBaseProps extends GatewayRouteBaseProps { | ||
/** | ||
* The criterion for determining a request match for this Gateway Route. | ||
* | ||
* @default - prefix match on "/" | ||
*/ | ||
readonly match?: GatewayHttpRouteMatch; | ||
/** | ||
* HTTP Procol | ||
*/ | ||
readonly routeType: Protocol.HTTP; | ||
} | ||
|
||
/** | ||
* Interface for HTTP Based Gateway Routes | ||
*/ | ||
export interface GatewayHttpRouteProps extends GatewayHttpRouteBaseProps { | ||
/** | ||
* The Virtual Gateway this Gateway Route is associated with | ||
*/ | ||
readonly virtualGateway: IVirtualGateway; | ||
} | ||
|
||
/** | ||
* Base interface for HTTP2 Based Gateway Routes | ||
*/ | ||
export interface GatewayHttp2RouteBaseProps extends GatewayRouteBaseProps { | ||
/** | ||
* The criterion for determining a request match for this Gateway Route. | ||
* | ||
* @default - prefix match on "/" | ||
*/ | ||
readonly match?: GatewayHttp2RouteMatch; | ||
dfezzie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* HTTP2 Procol | ||
*/ | ||
readonly routeType: Protocol.HTTP2; | ||
} | ||
|
||
/** | ||
* Interface for HTTP2 Based Gateway Routes | ||
*/ | ||
export interface GatewayHttp2RouteProps extends GatewayHttp2RouteBaseProps { | ||
/** | ||
* The Virtual Gateway this Gateway Route is associated with | ||
*/ | ||
readonly virtualGateway: IVirtualGateway; | ||
} | ||
|
||
/** | ||
* Base interface for GRPC Based Gateway Routes | ||
*/ | ||
export interface GatewayGrpcRouteBaseProps extends GatewayRouteBaseProps { | ||
/** | ||
* The criterion for determining a request match for this Gateway Route. | ||
* | ||
* @default - no default | ||
*/ | ||
readonly match: GatewayGrpcRouteMatch; | ||
/** | ||
* GRPC Protocol | ||
*/ | ||
readonly routeType: Protocol.GRPC; | ||
} | ||
|
||
/** | ||
* Interface for GRPC Based Gateway Routes | ||
*/ | ||
export interface GatewayGrpcRouteProps extends GatewayGrpcRouteBaseProps { | ||
/** | ||
* The Virtual Gateway this Gateway Route is associated with | ||
*/ | ||
readonly virtualGateway: IVirtualGateway; | ||
} | ||
|
||
interface GatewayHttpSharedRouteMatch { | ||
/** | ||
* Specifies the path to match requests with. | ||
* This parameter must always start with /, which by itself matches all requests to the virtual service name. | ||
* You can also match for path-based routing of requests. For example, if your virtual service name is my-service.local | ||
* and you want the route to match requests to my-service.local/metrics, your prefix should be /metrics. | ||
* | ||
*/ | ||
readonly prefixPath: string; | ||
} | ||
|
||
/** | ||
* The criterion for determining a request match for this Gateway Route | ||
*/ | ||
export interface GatewayHttpRouteMatch extends GatewayHttpSharedRouteMatch {} | ||
|
||
/** | ||
* The criterion for determining a request match for this Gateway Route | ||
*/ | ||
export interface GatewayHttp2RouteMatch extends GatewayHttpSharedRouteMatch {} | ||
|
||
/** | ||
* The criterion for determining a request match for this Gateway Route | ||
*/ | ||
export interface GatewayGrpcRouteMatch { | ||
/** | ||
* The fully qualified domain name for the service to match from the request | ||
*/ | ||
readonly serviceName: string; | ||
} | ||
|
||
/** | ||
* Properties to define new Gateway Routes | ||
*/ | ||
export interface GatewayRouteProps extends GatewayRouteBaseProps { | ||
/** | ||
* The Virtual Gateway this Gateway Route is associated with | ||
*/ | ||
readonly virtualGateway: IVirtualGateway; | ||
} | ||
|
||
/** | ||
* Gateway Route represents a new or existing gateway route attached to a VirtualGateway and Mesh | ||
* | ||
* @see https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html | ||
*/ | ||
export class GatewayRoute extends cdk.Resource implements IGatewayRoute { | ||
skinny85 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Import an existing Gateway Route given an ARN | ||
*/ | ||
public static fromGatewayRouteArn(scope: Construct, id: string, gatewayRouteArn: string): IGatewayRoute { | ||
return new ImportedGatewayRoute(scope, id, { gatewayRouteArn }); | ||
} | ||
|
||
/** | ||
* Import an existing Gateway Route given its name | ||
*/ | ||
public static fromGatewayRouteName( | ||
dfezzie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
scope: Construct, id: string, meshName: string, virtualGatewayName: string, gatewayRouteName: string): IGatewayRoute { | ||
return new ImportedGatewayRoute(scope, id, { meshName, virtualGatewayName, gatewayRouteName }); | ||
} | ||
|
||
/** | ||
* The name of the Gateway Route | ||
*/ | ||
public readonly gatewayRouteName: string; | ||
|
||
/** | ||
* The Amazon Resource Name (ARN) for the Gateway Route | ||
*/ | ||
public readonly gatewayRouteArn: string; | ||
|
||
/** | ||
* The VirtualGateway this GatewayRoute is a part of | ||
*/ | ||
public readonly virtualGateway: IVirtualGateway; | ||
|
||
private readonly httpRoute?: CfnGatewayRoute.HttpGatewayRouteProperty; | ||
private readonly http2Route?: CfnGatewayRoute.HttpGatewayRouteProperty; | ||
private readonly grpcRoute?: CfnGatewayRoute.GrpcGatewayRouteProperty; | ||
|
||
constructor(scope: Construct, id: string, props: GatewayHttpRouteProps | GatewayHttp2RouteProps | GatewayGrpcRouteProps) { | ||
super(scope, id, { | ||
physicalName: props.gatewayRouteName || cdk.Lazy.stringValue({ produce: () => this.node.uniqueId }), | ||
}); | ||
|
||
this.virtualGateway = props.virtualGateway; | ||
|
||
if (props.routeType === Protocol.HTTP) { | ||
this.httpRoute = this.renderHttpRoute(props); | ||
} | ||
if (props.routeType === Protocol.HTTP2) { | ||
this.http2Route = this.renderHttpRoute(props); | ||
} | ||
if (props.routeType === Protocol.GRPC) { | ||
this.grpcRoute = this.renderGrpcRoute(props); | ||
} | ||
|
||
const gatewayRoute = new CfnGatewayRoute(this, 'Resource', { | ||
gatewayRouteName: this.physicalName, | ||
meshName: props.virtualGateway.mesh.meshName, | ||
spec: { | ||
httpRoute: this.httpRoute, | ||
http2Route: this.http2Route, | ||
grpcRoute: this.grpcRoute, | ||
}, | ||
virtualGatewayName: this.virtualGateway.virtualGatewayName, | ||
}); | ||
|
||
this.gatewayRouteName = this.getResourceNameAttribute(gatewayRoute.attrGatewayRouteName); | ||
this.gatewayRouteArn = this.getResourceArnAttribute(gatewayRoute.ref, { | ||
service: 'appmesh', | ||
resource: `mesh/${props.virtualGateway.mesh.meshName}/virtualRouter/${this.virtualGateway.virtualGatewayName}/gatewayRoute`, | ||
resourceName: this.physicalName, | ||
}); | ||
} | ||
|
||
private renderHttpRoute(props: GatewayHttpRouteProps | GatewayHttp2RouteProps): CfnGatewayRoute.HttpGatewayRouteProperty { | ||
const prefixPath = props.match ? props.match.prefixPath : '/'; | ||
if (prefixPath[0] != '/') { | ||
throw new Error('Prefix Path must start with \'/\''); | ||
} | ||
return { | ||
action: { | ||
target: { | ||
virtualService: { | ||
virtualServiceName: props.routeTarget.virtualServiceName, | ||
}, | ||
}, | ||
}, | ||
match: { | ||
prefix: prefixPath, | ||
}, | ||
}; | ||
} | ||
|
||
private renderGrpcRoute(props: GatewayGrpcRouteProps): CfnGatewayRoute.GrpcGatewayRouteProperty { | ||
return { | ||
action: { | ||
target: { | ||
virtualService: { | ||
virtualServiceName: props.routeTarget.virtualServiceName, | ||
}, | ||
}, | ||
}, | ||
match: { | ||
serviceName: props.match.serviceName, | ||
}, | ||
}; | ||
} | ||
} | ||
|
||
/** | ||
* HTTP Gateway Route attached to a VirtualGateway and Mesh | ||
* | ||
* @see https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html | ||
*/ | ||
export class GatewayHttpRoute extends GatewayRoute { | ||
constructor(scope: Construct, id: string, props: GatewayHttpRouteProps) { | ||
super(scope, id, props); | ||
} | ||
} | ||
|
||
/** | ||
* HTTP2 Gateway Route attached to a VirtualGateway and Mesh | ||
* | ||
* @see https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html | ||
*/ | ||
export class GatewayHttp2Route extends GatewayRoute { | ||
constructor(scope: Construct, id: string, props: GatewayHttp2RouteProps) { | ||
super(scope, id, props); | ||
} | ||
} | ||
|
||
/** | ||
* GRPC Gateway Route attached to a VirtualGateway and Mesh | ||
* | ||
* @see https://docs.aws.amazon.com/app-mesh/latest/userguide/gateway-routes.html | ||
*/ | ||
export class GatewayGrpcRoute extends GatewayRoute { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fact that these are empty suggests to me the modeling is not quite right here 🙂 |
||
constructor(scope: Construct, id: string, props: GatewayGrpcRouteProps) { | ||
super(scope, id, props); | ||
} | ||
} | ||
|
||
/** | ||
* Interface with properties necessary to import a reusable Gateway Route | ||
*/ | ||
interface GatewayRouteAttributes { | ||
/** | ||
* The name of the Gateway Route | ||
*/ | ||
readonly gatewayRouteName?: string; | ||
|
||
/** | ||
* The Amazon Resource Name (ARN) for the Gateway Route | ||
*/ | ||
readonly gatewayRouteArn?: string; | ||
skinny85 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The name of the mesh this Gateway Route is associated with | ||
*/ | ||
readonly meshName?: string; | ||
dfezzie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The name of the Virtual Gateway this Gateway Route is associated with | ||
*/ | ||
readonly virtualGatewayName?: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
} | ||
|
||
/** | ||
* Represents an imported IGatewayRoute | ||
*/ | ||
class ImportedGatewayRoute extends cdk.Resource implements IGatewayRoute { | ||
/** | ||
* The name of the Gateway Route | ||
*/ | ||
public gatewayRouteName: string; | ||
|
||
/** | ||
* The Amazon Resource Name (ARN) for the Gateway Route | ||
*/ | ||
public gatewayRouteArn: string; | ||
|
||
constructor(scope: Construct, id: string, props: GatewayRouteAttributes) { | ||
super(scope, id); | ||
if (props.gatewayRouteArn) { | ||
dfezzie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.gatewayRouteArn = props.gatewayRouteArn; | ||
this.gatewayRouteName = cdk.Fn.select(4, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(props.gatewayRouteArn).resourceName!)); | ||
} else if (props.gatewayRouteName && props.meshName && props.virtualGatewayName) { | ||
this.gatewayRouteName = props.gatewayRouteName; | ||
this.gatewayRouteArn = cdk.Stack.of(this).formatArn({ | ||
service: 'appmesh', | ||
resource: `mesh/${props.meshName}/virtualGateway/${props.virtualGatewayName}/gatewayRoute`, | ||
resourceName: this.gatewayRouteName, | ||
}); | ||
} else { | ||
throw new Error('Need either arn or three names'); | ||
} | ||
} | ||
} |
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder - is the reason the type is not simply
Protocol
because there's noTCP
Gateway?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I wanted to reuse
Protocol
for this, but scope it down to not include TCP. Would you suggest creating a separate enum?