diff --git a/packages/@aws-cdk/aws-ec2-alpha/README.md b/packages/@aws-cdk/aws-ec2-alpha/README.md index 515f739ce1fd2..4c5eb7165306b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/README.md +++ b/packages/@aws-cdk/aws-ec2-alpha/README.md @@ -369,19 +369,20 @@ myVpc.addInternetGateway({ ## Importing an existing VPC -You can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attributes()` and `SubnetV2.fromSubnetV2Attributes()` methods. This is useful when you want to use existing resources in your CDK stack. +You can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attributes()` and `SubnetV2.fromSubnetV2Attributes()` methods. ### Importing a VPC -To import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, CIDR block, and information about the subnets. This method allows you to integrate existing AWS resources into your CDK stack. +To import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, primary CIDR block, and information about the subnets. You can import secondary address as well created through IPAM, BYOIP(IPv4) or enabled through Amazon Provided IPv6. -Here's a comprehensive example of how to import a VPC with multiple CIDR blocks, IPv6 support, and different subnet types: +Here's an example of how to import a VPC with multiple CIDR blocks, IPv6 support, and different subnet types: In this example, we're importing a VPC with: - A primary CIDR block (10.1.0.0/16) - - Two secondary IPv4 CIDR blocks (10.2.0.0/16 and 10.3.0.0/16) - - An Amazon-provided IPv6 CIDR block + - One secondary IPv4 CIDR blocks (10.2.0.0/16) + - Two secondary address using IPAM pool (IPv4 and IPv6) + - VPC has Amazon-provided IPv6 CIDR enabled - An isolated subnet in us-west-2a - A public subnet in us-west-2b @@ -390,7 +391,7 @@ In this example, we're importing a VPC with: const stack = new Stack(); const importedVpc = VpcV2.fromVpcV2Attributes(this, 'ImportedVPC', { - vpcId: 'vpc-08193db3ccc4f909f', + vpcId: 'vpc-XXX', vpcCidrBlock: '10.1.0.0/16', secondaryCidrBlocks: [ { @@ -398,8 +399,14 @@ const importedVpc = VpcV2.fromVpcV2Attributes(this, 'ImportedVPC', { cidrBlockName: 'ImportedBlock1', }, { - cidrBlock: '10.3.0.0/16', - cidrBlockName: 'ImportedBlock2', + ipv6IpamPoolId: 'ipam-pool-XXX', + ipv6NetmaskLength: 52, + cidrBlockName: 'ImportedIpamIpv6', + }, + { + ipv4IpamPoolId: 'ipam-pool-XXX', + ipv4IpamProvisionedCidrs: ['10.2.0.0/16'], + cidrBlockName: 'ImportedIpamIpv4', }, { amazonProvidedIpv6CidrBlock: true, diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/ipam.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/ipam.ts index 0d41d98f2cb5e..1fd931cbd73a5 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/ipam.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/ipam.ts @@ -92,7 +92,7 @@ export enum IpamScopeType { * * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html */ -export interface PoolOptions{ +export interface PoolOptions { /** * addressFamily - The address family of the pool (ipv4 or ipv6). @@ -180,7 +180,7 @@ export interface IpamPoolCidrProvisioningOptions { /** * Definition used to add or create a new IPAM pool */ -export interface IIpamPool{ +export interface IIpamPool { /** * Pool ID to be passed to the VPC construct * @attribute IpamPoolId @@ -193,7 +193,8 @@ export interface IIpamPool{ readonly ipamCidrs: CfnIPAMPoolCidr[]; /** - * Pool CIDR for IPv4 to be provisioned + * Pool CIDR for IPv4 to be provisioned using IPAM + * Required to check for subnet IP range is within the VPC range */ readonly ipamIpv4Cidrs?: string[]; @@ -321,7 +322,8 @@ class IpamPool extends Resource implements IIpamPool { public readonly ipamCidrs: CfnIPAMPoolCidr[] = [] /** - * Pool CIDR for IPv4 to be provisioned + * Pool CIDR for IPv4 to be provisioned using IPAM + * Required to check for subnet IP range is within the VPC range */ public readonly ipamIpv4Cidrs: string[] = [] @@ -350,6 +352,8 @@ class IpamPool extends Resource implements IIpamPool { awsService: props.awsService, }); this.ipamPoolId = this._ipamPool.attrIpamPoolId; + + // Populating to check for subnet range against all IPv4 ranges assigned to VPC including IPAM props.ipv4ProvisionedCidrs?.map(cidr => (this.ipamIpv4Cidrs.push(cidr))); this.node.defaultChild = this._ipamPool; } diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/subnet-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/subnet-v2.ts index 6aa404a89e61c..79d5f4ad7605b 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/subnet-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/subnet-v2.ts @@ -288,47 +288,48 @@ export class SubnetV2 extends Resource implements ISubnetV2 { */ export interface SubnetV2Attributes { /** - * The Availability Zone the subnet is located in + * The Availability Zone this subnet is located in * * @default - No AZ information, cannot use AZ selection features */ readonly availabilityZone: string; /** - * The IPv4 CIDR block associated with the subnet - * - * @default - No CIDR information, cannot use CIDR filter features - */ + * The IPv4 CIDR block associated with the subnet + * + * @default - No CIDR information, cannot use CIDR filter features + */ readonly ipv4CidrBlock: string; /** - * The IPv4 CIDR block associated with the subnet - * - * @default - No CIDR information, cannot use CIDR filter features - */ + * The IPv4 CIDR block associated with the subnet + * + * @default - No CIDR information, cannot use CIDR filter features + */ readonly ipv6CidrBlock?: string; /** - * The ID of the route table for this particular subnet - * - * @default - No route table information, cannot create VPC endpoints - */ + * The ID of the route table for this particular subnet + * + * @default - No route table information, cannot create VPC endpoints + */ readonly routeTableId?: string; /** - * The subnetId for this particular subnet - */ + * The subnetId for this particular subnet + */ readonly subnetId: string; /** - * The type of subnet (public or private) that this subnet represents. - */ + * The type of subnet (public or private) that this subnet represents. + */ readonly subnetType: SubnetType; /** - * The type of subnet (public or private) that this subnet represents. - * @default - no subnet name - */ + * Name of the given subnet + * + * @default - no subnet name + */ readonly subnetName?: string; } @@ -339,28 +340,29 @@ export interface SubnetV2Attributes { export interface ImportedSubnetV2Props extends SubnetV2Attributes {} /** - * Class to define an import for existing subnet + * Class to define an import for an existing subnet * @resource AWS::EC2::Subnet */ export class ImportedSubnetV2 extends Resource implements ISubnetV2 { /** - * The IPv6 CIDR Block for this subnet + * The IPv6 CIDR Block assigned to this subnet */ public readonly ipv6CidrBlock?: string; /** - * The type of subnet (public or private) that this subnet represents. + * The type of subnet (eg. public or private) that this subnet represents. */ public readonly subnetType?: SubnetType; /** - * The Availability Zone the subnet is located in + * The Availability Zone in which subnet is located */ public readonly availabilityZone: string; /** * The subnetId for this particular subnet + * Refers to the physical ID created */ public readonly subnetId: string; @@ -370,12 +372,12 @@ export class ImportedSubnetV2 extends Resource implements ISubnetV2 { public readonly internetConnectivityEstablished: IDependable = new DependencyGroup(); /** - * The IPv4 CIDR block for this subnet + * The IPv4 CIDR block assigned to this subnet */ public readonly ipv4CidrBlock: string; /** - * The route table for this subnet + * Current route table associated with this subnet */ public readonly routeTable: IRouteTable; @@ -392,7 +394,6 @@ export class ImportedSubnetV2 extends Resource implements ISubnetV2 { this.ipv6CidrBlock = props.ipv6CidrBlock; this.subnetId = props.subnetId; this.routeTable = { - //if not given should we fallback routeTableId: props.routeTableId!, }; } @@ -456,7 +457,6 @@ function storeSubnetToVpcByType(vpc: IVpcV2, subnet: SubnetV2, type: SubnetType) * @internal */ function validateSupportIpv6(vpc: IVpcV2) { - if (vpc.secondaryCidrBlock) { if (vpc.secondaryCidrBlock.some((secondaryAddress) => secondaryAddress.amazonProvidedIpv6CidrBlock === true || secondaryAddress.ipv6IpamPoolId != undefined)) { @@ -475,36 +475,12 @@ function validateSupportIpv6(vpc: IVpcV2) { * @returns True if the CIDR range falls within the VPC's IP address ranges, false otherwise. * @internal */ -// function checkCidrRanges(vpc: IVpcV2, cidrRange: string) { - -// const vpcCidrBlock = [vpc.ipv4CidrBlock]; - -// if (vpc.secondaryCidrBlock) { -// for (const ipAddress of vpc.secondaryCidrBlock) { -// if (ipAddress.cidrBlock) { -// vpcCidrBlock.push(ipAddress.cidrBlock); -// } -// } -// const cidrs = vpcCidrBlock.map(cidr => new CidrBlock(cidr)); - -// const subnetCidrBlock = new CidrBlock(cidrRange); - -// return cidrs.some(c => c.containsCidr(subnetCidrBlock)); -// } -// if (vpc.ipv4ProvisionedCidrs) { - -// const cidrs = vpc.ipv4ProvisionedCidrs.map(cidr => new CidrBlock(cidr)); - -// const subnetCidrBlock = new CidrBlock(cidrRange); - -// return cidrs.some(c => c.containsCidr(subnetCidrBlock)); -// } else {throw error('No secondary IP address attached to VPC');} -// } function checkCidrRanges(vpc: IVpcV2, cidrRange: string) { - const vpcCidrBlock = [vpc.ipv4CidrBlock]; + const subnetCidrBlock = new CidrBlock(cidrRange); const allCidrs: CidrBlock[] = []; + // Secondary IP addresses assoicated using user defined IPv4 range if (vpc.secondaryCidrBlock) { for (const ipAddress of vpc.secondaryCidrBlock) { if (ipAddress.cidrBlock) { @@ -515,17 +491,17 @@ function checkCidrRanges(vpc: IVpcV2, cidrRange: string) { allCidrs.push(...cidrs); } - if (vpc.ipv4ProvisionedCidrs) { - - const cidrs = vpc.ipv4ProvisionedCidrs.map(cidr => new CidrBlock(cidr)); + // Secondary IP addresses assoicated using IPAM IPv4 range + if (vpc.ipv4IpamProvisionedCidrs) { + const cidrs = vpc.ipv4IpamProvisionedCidrs.map(cidr => new CidrBlock(cidr)); allCidrs.push(...cidrs); } + + // If no IPv4 is assigned as secondary address if (allCidrs.length === 0) { throw new Error('No secondary IP address attached to VPC'); } - const subnetCidrBlock = new CidrBlock(cidrRange); - return allCidrs.some(c => c.containsCidr(subnetCidrBlock)); } diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts index 15904a30e61aa..2b0757f29f3f4 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2-base.ts @@ -102,7 +102,7 @@ export interface IVpcV2 extends IVpc { * Required to check for overlapping CIDRs after provisioning * is complete under IPAM pool */ - readonly ipv4ProvisionedCidrs?: string[]; + readonly ipv4IpamProvisionedCidrs?: string[]; /** * Add an Egress only Internet Gateway to current VPC. @@ -353,7 +353,6 @@ export abstract class VpcV2Base extends Resource implements IVpcV2 { }); let useIpv6; - if (this.secondaryCidrBlock) { useIpv6 = (this.secondaryCidrBlock.some((secondaryAddress) => secondaryAddress.amazonProvidedIpv6CidrBlock === true || secondaryAddress.ipv6IpamPoolId != undefined)); diff --git a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts index 2b0bfffc5c4ba..c1b0c3218b095 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/lib/vpc-v2.ts @@ -119,7 +119,7 @@ export interface VpcCidrOptions { * is complete under IPAM pool * @default - no IPAM IPv4 CIDR range is provisioned using IPAM */ - readonly ipv4ProvisionedCidrs?: string[]; + readonly ipv4IpamProvisionedCidrs?: string[]; } /** @@ -192,7 +192,7 @@ export interface VpcV2Props { } /** - * Options to import a VPC created outside of CDK + * Options to import a VPC created outside of CDK stack */ export interface VpcV2Attributes { @@ -204,6 +204,7 @@ export interface VpcV2Attributes { /** * The VPC ID + * Refers to physical Id of the resource */ readonly vpcId: string; @@ -242,7 +243,6 @@ export interface VpcV2Attributes { * @default - No secondary IP address */ readonly secondaryCidrBlocks?: VPCCidrBlockattributes[]; - } /** @@ -328,11 +328,11 @@ export class VpcV2 extends VpcV2Base { public readonly secondaryCidrBlock?: IVPCCidrBlock[] = new Array; /** - * IPv4 CIDR provisioned under pool + * IPv4 CIDR provisioned using IPAM pool * Required to check for overlapping CIDRs after provisioning - * is complete under IPAM pool + * is complete under IPAM */ - public readonly ipv4ProvisionedCidrs?: string[]; + public readonly ipv4IpamProvisionedCidrs?: string[]; /** * For validation to define IPv6 subnets, set to true in case of @@ -400,10 +400,10 @@ export class VpcV2 extends VpcV2Base { throw new Error('CIDR block should be in the same RFC 1918 range in the VPC'); } } - if (secondaryVpcOptions.ipv4ProvisionedCidrs!) { - this.ipv4ProvisionedCidrs?.push(...secondaryVpcOptions.ipv4ProvisionedCidrs); + if (secondaryVpcOptions.ipv4IpamProvisionedCidrs!) { + this.ipv4IpamProvisionedCidrs?.push(...secondaryVpcOptions.ipv4IpamProvisionedCidrs); } - const cfnVpcCidrBlock = new VPCCidrBlock(this, secondaryVpcOptions.cidrBlockName, { + const vpcCidrBlock = new VPCCidrBlock(this, secondaryVpcOptions.cidrBlockName, { vpcId: this.vpcId, cidrBlock: secondaryVpcOptions.ipv4CidrBlock, ipv4IpamPoolId: secondaryVpcOptions.ipv4IpamPool?.ipamPoolId, @@ -414,11 +414,11 @@ export class VpcV2 extends VpcV2Base { }); if (secondaryVpcOptions.dependencies) { for (const dep of secondaryVpcOptions.dependencies) { - cfnVpcCidrBlock.node.addDependency(dep); + vpcCidrBlock.node.addDependency(dep); } } //Create secondary blocks for Ipv4 and Ipv6 - this.secondaryCidrBlock?.push(cfnVpcCidrBlock); + this.secondaryCidrBlock?.push(vpcCidrBlock); } } @@ -519,7 +519,7 @@ class IpamIpv4 implements IIpAddresses { ipv4NetmaskLength: this.props.netmaskLength, ipv4IpamPool: this.props.ipamPool, cidrBlockName: this.props?.cidrBlockName, - ipv4ProvisionedCidrs: this.props.ipamPool?.ipamIpv4Cidrs, + ipv4IpamProvisionedCidrs: this.props.ipamPool?.ipamIpv4Cidrs, }; } } @@ -535,17 +535,21 @@ class ImportedVpcV2 extends VpcV2Base { public readonly privateSubnets: ISubnetV2[] = []; public readonly isolatedSubnets: ISubnetV2[] = []; public readonly internetConnectivityEstablished: IDependable = new DependencyGroup(); - - //Added in IVPCv2 public readonly ipv4CidrBlock: string; - //Added in IVPCv2 + /* + * Reference to all secondary blocks attached + */ public readonly secondaryCidrBlock?: IVPCCidrBlock[]; + /** + * Refers to actual VPC Resource attribute in non-imported VPC + * Required to implement here due to extension from Base class + */ public readonly vpcCidrBlock: string; - // required to do CIDR range test on imported VPCs to create new subnets - public readonly ipv4ProvisionedCidrs: string[] = []; + // Required to do CIDR range test on imported VPCs to create new subnets + public readonly ipv4IpamProvisionedCidrs: string[] = []; constructor(scope: Construct, id: string, props: VpcV2Attributes) { super(scope, id, { @@ -558,8 +562,10 @@ class ImportedVpcV2 extends VpcV2Base { resourceName: this.vpcId, }, Stack.of(this)); this.vpcCidrBlock = props.vpcCidrBlock; + // Required for subnet range related checks this.ipv4CidrBlock = props.vpcCidrBlock; - this._vpnGatewayId = props.vpnGatewayId; //TODO if we need it for other gateways + this._vpnGatewayId = props.vpnGatewayId; + if (props.publicSubnets) { this.publicSubnets = props.publicSubnets.map(subnet => new ImportedSubnetV2(scope, subnet.subnetName?? 'ImportedPublicSubnet', subnet)); } @@ -571,98 +577,95 @@ class ImportedVpcV2 extends VpcV2Base { } this.secondaryCidrBlock = props.secondaryCidrBlocks?.map(cidrBlock => VPCCidrBlock.fromVPCCidrBlockattributes(scope, cidrBlock.cidrBlockName ?? 'ImportedSecondaryCidrBlock', { ...cidrBlock })); if (props.secondaryCidrBlocks) { - for (const cidr of props.secondaryCidrBlocks) { - if (cidr.ipv4ProvisionedCidrs) { - this.ipv4ProvisionedCidrs.push(...cidr.ipv4ProvisionedCidrs); + for (const cidrBlock of props.secondaryCidrBlocks) { + if (cidrBlock.ipv4IpamProvisionedCidrs) { + this.ipv4IpamProvisionedCidrs.push(...cidrBlock.ipv4IpamProvisionedCidrs); } } } } } -//@internal First two Octet to verify RFC 1918 -interface IPaddressConfig { - octet1: number; - octet2: number; -} - /** - * Validates whether a secondary IPv4 address is within the same private IP address range as the primary IPv4 address. - * - * @param cidr1 The secondary IPv4 CIDR block to be validated. - * @param cidr2 The primary IPv4 CIDR block to validate against. - * @returns True if the secondary IPv4 CIDR block is within the same private IP address range as the primary IPv4 CIDR block, false otherwise. - * @internal - * The private IP address ranges are defined by RFC 1918 as 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. + * Interface to create L2 for VPC Cidr Block */ -function validateIpv4address(cidr1?: string, cidr2?: string): boolean { - if (!cidr1 || !cidr2) { - return false; // Handle cases where CIDR ranges are not provided - } - - const octetsCidr1: number[] = cidr1.split('.').map(octet => parseInt(octet, 10)); - const octetsCidr2: number[] = cidr2.split('.').map(octet => parseInt(octet, 10)); - - if (octetsCidr1.length !== 4 || octetsCidr2.length !== 4) { - return false; // Handle invalid CIDR ranges - } +export interface IVPCCidrBlock { + /** + * Amazon Provided Ipv6 + */ + readonly amazonProvidedIpv6CidrBlock? : boolean; - const ip1: IPaddressConfig = { - octet1: octetsCidr1[0], - octet2: octetsCidr1[1], - }; + /** + * The secondary IPv4 CIDR Block + * + * @default - no CIDR block provided + */ + readonly cidrBlock?: string; - const ip2: IPaddressConfig = { - octet1: octetsCidr2[0], - octet2: octetsCidr2[1], - }; + /** + * IPAM pool for IPv6 address type + */ + readonly ipv6IpamPoolId ?: string; - return (ip1.octet1 === 10 && ip2.octet1 === 10) || - (ip1.octet1 === 192 && ip1.octet2 === 168 && ip2.octet1 === 192 && ip2.octet2 === 168) || - (ip1.octet1 === 172 && ip1.octet2 === 16 && ip2.octet1 === 172 && ip2.octet2 === 16); // CIDR ranges belong to same private IP address ranges + /** + * IPAM pool for IPv4 address type + */ + readonly ipv4IpamPoolId ?: string; } /** - * Attributes for VPCCidrBlock used for defining a new VPCCIDRBlock - * and also importing an existing VPCCIDRBlock + * Attributes for VPCCidrBlock used for defining a new CIDR Block + * and also for importing an existing CIDR */ export interface VPCCidrBlockattributes { + /** + * Amazon Provided Ipv6 + * + * @default false + */ + readonly amazonProvidedIpv6CidrBlock? : boolean; /** * The secondary IPv4 CIDR Block + * * @default - no CIDR block provided */ readonly cidrBlock?: string; /** - * CIDR Block Name - * @default - no CIDR Block name generated, this field is required while importing CIDR block for VPC - */ + * The secondary IPv4 CIDR Block + * + * @default - no CIDR block provided + */ readonly cidrBlockName?: string; /** - * Opt for amazonProvided Ipv6 CIDR address - * @default false - */ - readonly amazonProvidedIpv6CidrBlock?: boolean; + * Net mask length for IPv6 address type + * + * @default - no Net mask length configured for IPv6 + */ + readonly ipv6NetmaskLength?: number; /** - * IPAM pool Id for IPv6 address type - * @default - no IPAM pool Id provided - */ - readonly ipv6IpamPoolId?: string; + * Net mask length for IPv4 address type + * + * @default - no Net mask length configured for IPv4 + */ + readonly ipv4NetmaskLength?: number; /** - * IPAM pool Id for IPv4 address type - * @default - no IPAM pool Id provided - */ - readonly ipv4IpamPoolId?: string; + * IPAM pool for IPv6 address type + * + * @default - no IPAM pool Id provided for IPv6 + */ + readonly ipv6IpamPoolId ?: string; /** - * Net mask length for IPv4 address type - * @default - no Net mask length configured and it would fail the deployment - */ - readonly ipv4NetmaskLength?: number; + * IPAM pool for IPv4 address type + * + * @default - no IPAM pool Id provided for IPv4 + */ + readonly ipv4IpamPoolId ?: string; /** * IPv4 CIDR provisioned under pool @@ -670,14 +673,7 @@ export interface VPCCidrBlockattributes { * is complete under IPAM pool * @default - no IPAM IPv4 CIDR range is provisioned using IPAM */ - readonly ipv4ProvisionedCidrs?: string[]; - - /** - * Net mask length for IPv6 address type - * @default - no Net mask length configured and it would fail the deployment - */ - readonly ipv6NetmaskLength?: number; - + readonly ipv4IpamProvisionedCidrs?: string[]; } /** @@ -685,23 +681,26 @@ export interface VPCCidrBlockattributes { */ interface VPCCidrBlockProps extends VPCCidrBlockattributes { /** - * The VPC Id + * The VPC Id for associating CIDR Block as a secondary address */ readonly vpcId: string; - } /** - * Internal L2 for VPC Cidr Block + * Internal L2 to define a new VPC CIDR Block * @internal */ class VPCCidrBlock extends Resource implements IVPCCidrBlock { + /** + * Import an existing VPC CIDR Block + */ public static fromVPCCidrBlockattributes(scope: Construct, id: string, props: VPCCidrBlockattributes) : IVPCCidrBlock { class Import extends Resource implements IVPCCidrBlock { public readonly cidrBlock = props.cidrBlock; public readonly amazonProvidedIpv6CidrBlock ?: boolean = props.amazonProvidedIpv6CidrBlock;; public readonly ipv6IpamPoolId ?: string = props.ipv6IpamPoolId; + public readonly ipv4IpamPoolId ?: string = props.ipv4IpamPoolId; } return new Import(scope, id); } @@ -719,35 +718,52 @@ class VPCCidrBlock extends Resource implements IVPCCidrBlock { constructor(scope: Construct, id: string, props: VPCCidrBlockProps) { super(scope, id); this.resource = new CfnVPCCidrBlock(this, id, props); + this.node.defaultChild = this.resource; this.cidrBlock = props.cidrBlock; this.ipv6IpamPoolId = props.ipv6IpamPoolId; this.ipv4IpamPoolId = props.ipv4IpamPoolId; this.amazonProvidedIpv6CidrBlock = props.amazonProvidedIpv6CidrBlock; } +} +//@internal First two Octet to verify RFC 1918 +interface IPaddressConfig { + octet1: number; + octet2: number; } /** - * Interface to create L2 for VPC Cidr Block + * Validates whether a secondary IPv4 address is within the same private IP address range as the primary IPv4 address. + * + * @param cidr1 The secondary IPv4 CIDR block to be validated. + * @param cidr2 The primary IPv4 CIDR block to validate against. + * @returns True if the secondary IPv4 CIDR block is within the same private IP address range as the primary IPv4 CIDR block, false otherwise. + * @internal + * The private IP address ranges are defined by RFC 1918 as 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. */ -export interface IVPCCidrBlock { - /** - * The CIDR block - */ - readonly cidrBlock?: string; +function validateIpv4address(cidr1?: string, cidr2?: string): boolean { + if (!cidr1 || !cidr2) { + return false; // Handle cases where CIDR ranges are not provided + } - /** - * Amazon Provided Ipv6 - */ - readonly amazonProvidedIpv6CidrBlock? : boolean; + const octetsCidr1: number[] = cidr1.split('.').map(octet => parseInt(octet, 10)); + const octetsCidr2: number[] = cidr2.split('.').map(octet => parseInt(octet, 10)); - /** - * IPAM pool for IPv6 address type - */ - readonly ipv6IpamPoolId ?: string; + if (octetsCidr1.length !== 4 || octetsCidr2.length !== 4) { + return false; // Handle invalid CIDR ranges + } - /** - * IPAM pool for IPv4 address type - */ - readonly ipv4IpamPoolId ?: string; + const ip1: IPaddressConfig = { + octet1: octetsCidr1[0], + octet2: octetsCidr1[1], + }; + + const ip2: IPaddressConfig = { + octet1: octetsCidr2[0], + octet2: octetsCidr2[1], + }; + + return (ip1.octet1 === 10 && ip2.octet1 === 10) || + (ip1.octet1 === 192 && ip1.octet2 === 168 && ip2.octet1 === 192 && ip2.octet2 === 168) || + (ip1.octet1 === 172 && ip1.octet2 === 16 && ip2.octet1 === 172 && ip2.octet2 === 16); // CIDR ranges belong to same private IP address ranges } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.ts b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.ts index 9b6e250397c08..ea9da7f48a6db 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/integ.test-import.ts @@ -97,7 +97,7 @@ const ipamvpc = VpcV2.VpcV2.fromVpcV2Attributes(stack, 'ImportedIPAMVPC', { }, { ipv4IpamPoolId: 'ipam-pool-0d53ae29b3b8ca8de', - ipv4ProvisionedCidrs: ['10.2.0.0/16'], + ipv4IpamProvisionedCidrs: ['10.2.0.0/16'], cidrBlockName: 'ImportedIpamIpv4', }], }); diff --git a/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts b/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts index c90f846ce7458..abfd0f22e2408 100644 --- a/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts +++ b/packages/@aws-cdk/aws-ec2-alpha/test/vpcv2-import.test.ts @@ -120,7 +120,7 @@ describe('Vpc V2 with full control', () => { vpcCidrBlock: '10.0.0.0/16', secondaryCidrBlocks: [{ ipv4IpamPoolId: 'ipam-pool-0d53ae29b3b8ca8de', - ipv4ProvisionedCidrs: ['10.2.0.0/16'], + ipv4IpamProvisionedCidrs: ['10.2.0.0/16'], cidrBlockName: 'ImportedIpamIpv4', }], });