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: aws IP Ranges in routing #430

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
10 changes: 7 additions & 3 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 37 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint @typescript-eslint/no-require-imports: "off" */
import * as fs from 'fs';
import * as path from 'path';
import { Resource, RemovalPolicy, Duration, Tags, Annotations } from 'aws-cdk-lib';
Expand Down Expand Up @@ -89,6 +88,12 @@ export interface RouteProps {
* @default - false
*/
readonly excludeIPv6?: boolean;

/** mandatory for AWS regions */
readonly awsProps?:{
awsRegion:string;
awsService:string;
};
}

/**
Expand Down Expand Up @@ -287,6 +292,37 @@ export class SimpleNAT extends Resource {
return this;
}

/**
* Add AWS to route table
*/
public withAwsRoutes(props?: RouteProps): SimpleNAT {
const awsMeta = fetch('https://ip-ranges.amazonaws.com/ip-ranges.json').json();
const excludeIPv6 = props?.excludeIPv6 ?? false;
const ipv4fliteredPrefixList = awsMeta.prefixes.filter((value: { region: string | undefined; service: string | undefined })=>{
if (props?.awsProps?.awsRegion==value.region&&
props?.awsProps?.awsService==value.service) {return true;} else { return false;}
});
for (const cidr of ipv4fliteredPrefixList) {
for (const [routeId, subnets] of this._routeMappingSubnets) {
if (cidr.ip_prefix) {this._configureSubnet(routeId, subnets, cidr.ip_prefix);}
}
}
if (!excludeIPv6) {
const ipv6fliteredPrefixList = awsMeta.ipv6_prefixes.filter((value: { region: string | undefined; service: string | undefined })=>{
if (props?.awsProps?.awsRegion==value.region&&
props?.awsProps?.awsService==value.service) {return true;} else { return false;}
});

for (const cidr of ipv6fliteredPrefixList) {
for (const [routeId, subnets] of this._routeMappingSubnets) {
if (cidr.ipv6_prefix) {this._configureSubnet(routeId, subnets, undefined, cidr.ipv6_prefix);}
//if (cidr.ipv6Prefix && !excludeIPv6) {this._configureSubnet(routeId, subnets, undefined, cidr.ipv6Prefix);}
}
}
}
return this;
}

/**
* Add Cloudflare IPs to route table
*
Expand Down
47 changes: 47 additions & 0 deletions test/snat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,53 @@ describe('Simple NAT construct', () => {
})).toStrictEqual({});
});


test('create NAT instances for aws routes excluding IPv6 address', () => {

const stack = new Stack();
const vpc = new Vpc(stack, 'VPC-2');

new SimpleNAT(stack, 'nat', {
vpc,
}).withAwsRoutes({
excludeIPv6: true,
awsProps: {
awsRegion: 'ap-south-1',
awsService: 'AMAZON',
},
});

const awsMeta: {
syncToken: string;
createDate: string;
prefixes: [
{
ip_prefix:string;
region:string;
service:string;
network_border_group:string;
}
];
ipv6_prefixes: [
{
ipv6_prefix:string;
region:string;
service:string;
network_border_group:string;
}
];

} = fetch('https://ip-ranges.amazonaws.com/ip-ranges.json').json();
const ipV6 = awsMeta.ipv6_prefixes.filter(prefix => prefix.ipv6_prefix );
expect(ipV6.length).toBeGreaterThan(0);

expect(Template.fromStack(stack).findResources('AWS::EC2::Route', {
Properties: {
DestinationIpv6CidrBlock: Match.anyValue(),
},
})).toStrictEqual({});
});

test('create NAT instances for cloudflare routes', () => {

const stack = new Stack();
Expand Down
Loading