Skip to content
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): remove from*Name() methods and replace with from*Attributes() #11266

Merged
merged 11 commits into from
Nov 6, 2020
29 changes: 29 additions & 0 deletions packages/@aws-cdk/aws-appmesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,32 @@ gateway.addGatewayRoute('gateway-route-grpc', {
}),
});
```

## Importing Resources

Each mesh resource comes with two static methods for importing a reference to an existing App Mesh resource.
These imported resources can be used as references for other resources in your mesh.
There are two static methods, `from<Resource>Arn` and `from<Resource>Attributes` where the `<Resource>` is replaced with the resource name.

```typescript
const arn = "arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh/virtualNode/testNode";
appmesh.VirtualNode.fromVirtualNodeArn(stack, 'importedVirtualNode', arn);
```

```typescript
appmesh.VirtualNode.fromVirtualNodeAttributes(stack, 'imported-virtual-node', {
mesh: appmesh.Mesh.fromMeshName(stack, 'Mesh', 'testMesh'),
virtualNodeName: virtualNodeName,
});
```

To import a mesh, there are two static methods, `fromMeshArn` and `fromMeshName`.

```typescript
const arn = 'arn:aws:appmesh:us-east-1:123456789012:mesh/testMesh';
appmesh.Mesh.fromMeshArn(stack, 'imported-mesh', arn);
```

```typescript
appmesh.Mesh.fromMeshName(stack, 'imported-mesh', 'abc');
```
70 changes: 24 additions & 46 deletions packages/@aws-cdk/aws-appmesh/lib/gateway-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,26 @@ export class GatewayRoute extends cdk.Resource implements IGatewayRoute {
* Import an existing GatewayRoute given an ARN
*/
public static fromGatewayRouteArn(scope: Construct, id: string, gatewayRouteArn: string): IGatewayRoute {
return new ImportedGatewayRoute(scope, id, { gatewayRouteArn });
return new class extends cdk.Resource implements IGatewayRoute {
readonly gatewayRouteArn = gatewayRouteArn;
readonly gatewayRouteName = cdk.Fn.select(4, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(gatewayRouteArn).resourceName!));
readonly virtualGateway = VirtualGateway.fromVirtualGatewayArn(this, 'virtualGateway', gatewayRouteArn);
}(scope, id);
}

/**
* Import an existing GatewayRoute given attributes
*/
public static fromGatewayRouteAttributes(scope: Construct, id: string, attrs: GatewayRouteAttributes): IGatewayRoute {
return new class extends cdk.Resource implements IGatewayRoute {
readonly gatewayRouteName = attrs.gatewayRouteName;
readonly gatewayRouteArn = cdk.Stack.of(scope).formatArn({
service: 'appmesh',
resource: `mesh/${attrs.virtualGateway.mesh.meshName}/virtualGateway/${attrs.virtualGateway.virtualGatewayName}/gatewayRoute`,
resourceName: this.gatewayRouteName,
});
readonly virtualGateway = attrs.virtualGateway;
}(scope, id);
}

/**
Expand Down Expand Up @@ -114,55 +133,14 @@ export class GatewayRoute extends cdk.Resource implements IGatewayRoute {
/**
* Interface with properties necessary to import a reusable GatewayRoute
*/
interface GatewayRouteAttributes {
export interface GatewayRouteAttributes {
/**
* The name of the GatewayRoute
*/
readonly gatewayRouteName?: string;
readonly gatewayRouteName: string;

/**
* The Amazon Resource Name (ARN) for the GatewayRoute
* The VirtualGateway this GatewayRoute is associated with.
*/
readonly gatewayRouteArn?: string;

/**
* The name of the mesh this GatewayRoute is associated with
*/
readonly meshName?: string;

/**
* The name of the Virtual Gateway this GatewayRoute is associated with
*/
readonly virtualGateway?: IVirtualGateway;
}

/**
* Represents an imported IGatewayRoute
*/
class ImportedGatewayRoute extends cdk.Resource implements IGatewayRoute {
/**
* The name of the GatewayRoute
*/
public gatewayRouteName: string;

/**
* The Amazon Resource Name (ARN) for the GatewayRoute
*/
public gatewayRouteArn: string;

/**
* The VirtualGateway the GatewayRoute belongs to
*/
public virtualGateway: IVirtualGateway;

constructor(scope: Construct, id: string, props: GatewayRouteAttributes) {
super(scope, id);
if (props.gatewayRouteArn) {
this.gatewayRouteArn = props.gatewayRouteArn;
this.gatewayRouteName = cdk.Fn.select(4, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(props.gatewayRouteArn).resourceName!));
this.virtualGateway = VirtualGateway.fromVirtualGatewayArn(this, 'virtualGateway', props.gatewayRouteArn);
} else {
throw new Error('Need gatewayRouteArn');
}
}
readonly virtualGateway: IVirtualGateway;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In EKS, for example we actually only take ARNs here and not strongly-typed objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skinny85 asked for these to be strongly typed. An ARN would work for this, but this using the constructs is more explicit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we always use the strongly-typed properties for these, surprised EKS does something different.

}
88 changes: 31 additions & 57 deletions packages/@aws-cdk/aws-appmesh/lib/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Construct } from 'constructs';
import { CfnRoute } from './appmesh.generated';
import { IMesh } from './mesh';
import { IVirtualNode } from './virtual-node';
import { IVirtualRouter } from './virtual-router';
import { IVirtualRouter, VirtualRouter } from './virtual-router';

/**
* Interface for which all Route based classes MUST implement
Expand All @@ -22,6 +22,11 @@ export interface IRoute extends cdk.IResource {
* @attribute
*/
readonly routeArn: string;

/**
* The VirtualRouter the Route belongs to
*/
readonly virtualRouter: IVirtualRouter;
}

/**
Expand Down Expand Up @@ -99,7 +104,7 @@ export interface RouteProps extends RouteBaseProps {
readonly mesh: IMesh;

/**
* The virtual router in which to define the route
* The VirtualRouter the Route belongs to
*/
readonly virtualRouter: IVirtualRouter;
}
Expand All @@ -111,21 +116,33 @@ export interface RouteProps extends RouteBaseProps {
*/
export class Route extends cdk.Resource implements IRoute {
/**
* Import an existing route given an ARN
* Import an existing Route given an ARN
*/
public static fromRouteArn(scope: Construct, id: string, routeArn: string): IRoute {
return new ImportedRoute(scope, id, { routeArn });
return new class extends cdk.Resource implements IRoute {
readonly routeArn = routeArn;
readonly virtualRouter = VirtualRouter.fromVirtualRouterArn(this, 'VirtualRouter', routeArn);
readonly routeName = cdk.Fn.select(4, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(routeArn).resourceName!));
}(scope, id);
dfezzie marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Import an existing route given its name
* Import an existing Route given attributes
*/
public static fromRouteName(scope: Construct, id: string, meshName: string, virtualRouterName: string, routeName: string): IRoute {
return new ImportedRoute(scope, id, { meshName, virtualRouterName, routeName });
public static fromRouteAttributes(scope: Construct, id: string, attrs: RouteAttributes): IRoute {
return new class extends cdk.Resource implements IRoute {
readonly routeName = attrs.routeName;
readonly virtualRouter = attrs.virtualRouter;
readonly routeArn = cdk.Stack.of(this).formatArn({
service: 'appmesh',
resource: `mesh/${attrs.virtualRouter.mesh.meshName}/virtualRouter/${attrs.virtualRouter.virtualRouterName}/route`,
resourceName: this.routeName,
});
}(scope, id);
}

/**
* The name of the route
* The name of the Route
*/
public readonly routeName: string;

Expand All @@ -135,7 +152,7 @@ export class Route extends cdk.Resource implements IRoute {
public readonly routeArn: string;

/**
* The virtual router this route is a part of
* The VirtualRouter the Route belongs to
*/
public readonly virtualRouter: IVirtualRouter;

Expand Down Expand Up @@ -215,57 +232,14 @@ export class Route extends cdk.Resource implements IRoute {
/**
* Interface with properties ncecessary to import a reusable Route
*/
interface RouteAttributes {
/**
* The name of the route
*/
readonly routeName?: string;

/**
* The Amazon Resource Name (ARN) for the route
*/
readonly routeArn?: string;

/**
* The name of the mesh this route is associated with
*/
readonly meshName?: string;

/**
* The name of the virtual router this route is associated with
*/
readonly virtualRouterName?: string;
}

/**
* Represents and imported IRoute
*/
class ImportedRoute extends cdk.Resource implements IRoute {
export interface RouteAttributes {
/**
* The name of the route
* The name of the Route
*/
public readonly routeName: string;
readonly routeName: string;

/**
* The Amazon Resource Name (ARN) for the route
* The VirtualRouter the Route belongs to
*/
public readonly routeArn: string;

constructor(scope: Construct, id: string, props: RouteAttributes) {
super(scope, id);

if (props.routeArn) {
this.routeArn = props.routeArn;
this.routeName = cdk.Fn.select(4, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(props.routeArn).resourceName!));
} else if (props.routeName && props.meshName && props.virtualRouterName) {
this.routeName = props.routeName;
this.routeArn = cdk.Stack.of(this).formatArn({
service: 'appmesh',
resource: `mesh/${props.meshName}/virtualRouter/${props.virtualRouterName}/route`,
resourceName: this.routeName,
});
} else {
throw new Error('Need either arn or three names');
}
}
readonly virtualRouter: IVirtualRouter;
}
76 changes: 27 additions & 49 deletions packages/@aws-cdk/aws-appmesh/lib/virtual-gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface IVirtualGateway extends cdk.IResource {
readonly virtualGatewayArn: string;

/**
* The mesh which the VirtualGateway belongs to
* The Mesh which the VirtualGateway belongs to
*/
readonly mesh: IMesh;

Expand Down Expand Up @@ -67,7 +67,7 @@ export interface VirtualGatewayBaseProps {
*/
export interface VirtualGatewayProps extends VirtualGatewayBaseProps {
/**
* The mesh which the VirtualGateway belongs to
* The Mesh which the VirtualGateway belongs to
*/
readonly mesh: IMesh;
}
Expand All @@ -84,7 +84,7 @@ abstract class VirtualGatewayBase extends cdk.Resource implements IVirtualGatewa
public abstract readonly virtualGatewayArn: string;

/**
* The name of the mesh which the VirtualGateway belongs to
* The Mesh which the VirtualGateway belongs to
*/
public abstract readonly mesh: IMesh;

Expand Down Expand Up @@ -112,7 +112,27 @@ export class VirtualGateway extends VirtualGatewayBase {
* Import an existing VirtualGateway given an ARN
*/
public static fromVirtualGatewayArn(scope: Construct, id: string, virtualGatewayArn: string): IVirtualGateway {
return new ImportedVirtualGateway(scope, id, { virtualGatewayArn });
return new class extends VirtualGatewayBase {
private readonly parsedArn = cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(virtualGatewayArn).resourceName!);
readonly mesh = Mesh.fromMeshName(this, 'Mesh', cdk.Fn.select(0, this.parsedArn));
readonly virtualGatewayArn = virtualGatewayArn;
readonly virtualGatewayName = cdk.Fn.select(2, this.parsedArn);
}(scope, id);
}

/**
* Import an existing VirtualGateway given its attributes
*/
public static fromVirtualGatewayAttributes(scope: Construct, id: string, attrs: VirtualGatewayAttributes): IVirtualGateway {
return new class extends VirtualGatewayBase {
readonly mesh = attrs.mesh;
readonly virtualGatewayName = attrs.virtualGatewayName;
readonly virtualGatewayArn = cdk.Stack.of(this).formatArn({
service: 'appmesh',
resource: `mesh/${attrs.mesh.meshName}/virtualGateway`,
resourceName: this.virtualGatewayName,
});
}(scope, id);
}

/**
Expand Down Expand Up @@ -171,56 +191,14 @@ export class VirtualGateway extends VirtualGatewayBase {
/**
* Unterface with properties necessary to import a reusable VirtualGateway
*/
interface VirtualGatewayAttributes {
/**
* The name of the VirtualGateway
*/
readonly virtualGatewayName?: string;

/**
* The Amazon Resource Name (ARN) belonging to the VirtualGateway
*/
readonly virtualGatewayArn?: string;

/**
* The Mesh that the VirtualGateway belongs to
*/
readonly mesh?: IMesh;

/**
* The name of the mesh that the VirtualGateway belongs to
*/
readonly meshName?: string;
}

/**
* Used to import a VirtualGateway and read its properties
*/
class ImportedVirtualGateway extends VirtualGatewayBase {
export interface VirtualGatewayAttributes {
/**
* The name of the VirtualGateway
*/
public readonly virtualGatewayName: string;

/**
* The Amazon Resource Name (ARN) belonging to the VirtualGateway
*/
public readonly virtualGatewayArn: string;
readonly virtualGatewayName: string;

/**
* The Mesh that the VirtualGateway belongs to
*/
public readonly mesh: IMesh;

constructor(scope: Construct, id: string, props: VirtualGatewayAttributes) {
super(scope, id);
if (props.virtualGatewayArn) {
const meshName = cdk.Fn.select(0, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(props.virtualGatewayArn).resourceName!));
this.mesh = Mesh.fromMeshName(this, 'Mesh', meshName);
this.virtualGatewayArn = props.virtualGatewayArn;
this.virtualGatewayName = cdk.Fn.select(2, cdk.Fn.split('/', cdk.Stack.of(scope).parseArn(props.virtualGatewayArn).resourceName!));
} else {
throw new Error('Need virtualGatewayArn');
}
}
readonly mesh: IMesh;
}
Loading