Skip to content

Commit f43a36b

Browse files
committed
feat: support IPAM Manager for VPC creation
1 parent 2891a57 commit f43a36b

27 files changed

+262
-14
lines changed

api/v1beta1/awscluster_conversion.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
5454
dst.Status.Network.SecurityGroups[role] = sg
5555
}
5656

57+
if restored.Spec.NetworkSpec.VPC.IPAMPool != nil {
58+
if dst.Spec.NetworkSpec.VPC.IPAMPool == nil {
59+
dst.Spec.NetworkSpec.VPC.IPAMPool = &infrav2.IPAMPool{}
60+
}
61+
62+
restoreIPAMPool(restored.Spec.NetworkSpec.VPC.IPAMPool, dst.Spec.NetworkSpec.VPC.IPAMPool)
63+
}
64+
5765
return nil
5866
}
5967

@@ -66,6 +74,14 @@ func restoreControlPlaneLoadBalancerStatus(restored, dst *infrav2.LoadBalancer)
6674
dst.ELBListeners = restored.ELBListeners
6775
}
6876

77+
// restoreIPAMPool manually restores the ipam pool data.
78+
// Assumes restored and dst are non-nil.
79+
func restoreIPAMPool(restored, dst *infrav2.IPAMPool) {
80+
dst.ID = restored.ID
81+
dst.Name = restored.Name
82+
dst.NetmaskLength = restored.NetmaskLength
83+
}
84+
6985
// restoreControlPlaneLoadBalancer manually restores the control plane loadbalancer data.
7086
// Assumes restored and dst are non-nil.
7187
func restoreControlPlaneLoadBalancer(restored, dst *infrav2.AWSLoadBalancerSpec) {

api/v1beta1/conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,7 @@ func Convert_v1beta2_LoadBalancer_To_v1beta1_ClassicELB(in *v1beta2.LoadBalancer
8282
func Convert_v1beta2_IngressRule_To_v1beta1_IngressRule(in *v1beta2.IngressRule, out *IngressRule, s conversion.Scope) error {
8383
return autoConvert_v1beta2_IngressRule_To_v1beta1_IngressRule(in, out, s)
8484
}
85+
86+
func Convert_v1beta2_VPCSpec_To_v1beta1_VPCSpec(in *v1beta2.VPCSpec, out *VPCSpec, s conversion.Scope) error {
87+
return autoConvert_v1beta2_VPCSpec_To_v1beta1_VPCSpec(in, out, s)
88+
}

api/v1beta1/zz_generated.conversion.go

Lines changed: 6 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta2/awscluster_webhook.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@ func (r *AWSCluster) validateNetwork() field.ErrorList {
189189
allErrs = append(allErrs, field.Invalid(field.NewPath("subnets"), r.Spec.NetworkSpec.Subnets, "IPv6 cannot be used with unmanaged clusters at this time."))
190190
}
191191
}
192+
193+
if r.Spec.NetworkSpec.VPC.CidrBlock != "" && r.Spec.NetworkSpec.VPC.IPAMPool != nil {
194+
allErrs = append(allErrs, field.Invalid(field.NewPath("cidrBlock"), r.Spec.NetworkSpec.VPC.CidrBlock, "cidrBlock and ipamPool cannot be used together"))
195+
}
196+
197+
if r.Spec.NetworkSpec.VPC.IPAMPool != nil && r.Spec.NetworkSpec.VPC.IPAMPool.ID == "" && r.Spec.NetworkSpec.VPC.IPAMPool.Name == "" {
198+
allErrs = append(allErrs, field.Invalid(field.NewPath("ipamPool"), r.Spec.NetworkSpec.VPC.IPAMPool, "ipamPool must have either id or name"))
199+
}
200+
192201
return allErrs
193202
}
194203

api/v1beta2/awscluster_webhook_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,33 @@ func TestAWSClusterValidateCreate(t *testing.T) {
335335
},
336336
wantErr: false,
337337
},
338+
{
339+
name: "rejects cidrBlock and ipamPool if set together",
340+
cluster: &AWSCluster{
341+
Spec: AWSClusterSpec{
342+
NetworkSpec: NetworkSpec{
343+
VPC: VPCSpec{
344+
CidrBlock: "10.0.0.0/16",
345+
IPAMPool: &IPAMPool{},
346+
},
347+
},
348+
},
349+
},
350+
wantErr: true,
351+
},
352+
{
353+
name: "rejects ipamPool if id or name not set",
354+
cluster: &AWSCluster{
355+
Spec: AWSClusterSpec{
356+
NetworkSpec: NetworkSpec{
357+
VPC: VPCSpec{
358+
IPAMPool: &IPAMPool{},
359+
},
360+
},
361+
},
362+
},
363+
wantErr: true,
364+
},
338365
}
339366
for _, tt := range tests {
340367
t.Run(tt.name, func(t *testing.T) {

api/v1beta2/network_types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,18 @@ type IPv6 struct {
245245
EgressOnlyInternetGatewayID *string `json:"egressOnlyInternetGatewayId,omitempty"`
246246
}
247247

248+
// IPAMPool defines the IPAM pool to be used for VPC.
249+
type IPAMPool struct {
250+
// ID is the ID of the IPAM pool this provider should use to create VPC.
251+
ID string `json:"id,omitempty"`
252+
// Name is the name of the IPAM pool this provider should use to create VPC.
253+
Name string `json:"name,omitempty"`
254+
// The netmask length of the IPv4 CIDR you want to allocate to VPC from
255+
// an Amazon VPC IP Address Manager (IPAM) pool.
256+
// Defaults to /16 for IPv4 if not specified.
257+
NetmaskLength int64 `json:"netmaskLength,omitempty"`
258+
}
259+
248260
// VPCSpec configures an AWS VPC.
249261
type VPCSpec struct {
250262
// ID is the vpc-id of the VPC this provider should use to create resources.
@@ -254,6 +266,9 @@ type VPCSpec struct {
254266
// Defaults to 10.0.0.0/16.
255267
CidrBlock string `json:"cidrBlock,omitempty"`
256268

269+
// IPAMPool defines the IPAM pool to be used for VPC.
270+
IPAMPool *IPAMPool `json:"ipamPool,omitempty"`
271+
257272
// IPv6 contains ipv6 specific settings for the network. Supported only in managed clusters.
258273
// This field cannot be set on AWSCluster object.
259274
// +optional

api/v1beta2/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/clusterawsadm/cloudformation/bootstrap/cluster_api_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ func (t Template) ControllersPolicy() *iamv1.PolicyDocument {
8181
Effect: iamv1.EffectAllow,
8282
Resource: iamv1.Resources{iamv1.Any},
8383
Action: iamv1.Actions{
84+
"ec2:DescribeIpamPools",
85+
"ec2:AllocateIpamPoolCidr",
8486
"ec2:AttachNetworkInterface",
8587
"ec2:DetachNetworkInterface",
8688
"ec2:AllocateAddress",

cmd/clusterawsadm/cloudformation/bootstrap/fixtures/customsuffix.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ Resources:
140140
PolicyDocument:
141141
Statement:
142142
- Action:
143+
- ec2:DescribeIpamPools
144+
- ec2:AllocateIpamPoolCidr
143145
- ec2:AttachNetworkInterface
144146
- ec2:DetachNetworkInterface
145147
- ec2:AllocateAddress

cmd/clusterawsadm/cloudformation/bootstrap/fixtures/default.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ Resources:
140140
PolicyDocument:
141141
Statement:
142142
- Action:
143+
- ec2:DescribeIpamPools
144+
- ec2:AllocateIpamPoolCidr
143145
- ec2:AttachNetworkInterface
144146
- ec2:DetachNetworkInterface
145147
- ec2:AllocateAddress

0 commit comments

Comments
 (0)