Skip to content

Commit 810bbf4

Browse files
authored
Merge pull request #4900 from mtulio/CORS-3214-refact-rtb
🌱 refactor route discover/creation flow
2 parents a7673e1 + 4634da0 commit 810bbf4

File tree

2 files changed

+301
-45
lines changed

2 files changed

+301
-45
lines changed

pkg/cloud/services/network/routetables.go

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -60,30 +60,10 @@ func (s *Service) reconcileRouteTables() error {
6060
for i := range subnets {
6161
sn := &subnets[i]
6262
// We need to compile the minimum routes for this subnet first, so we can compare it or create them.
63-
var routes []*ec2.Route
64-
if sn.IsPublic {
65-
if s.scope.VPC().InternetGatewayID == nil {
66-
return errors.Errorf("failed to create routing tables: internet gateway for %q is nil", s.scope.VPC().ID)
67-
}
68-
routes = append(routes, s.getGatewayPublicRoute())
69-
if sn.IsIPv6 {
70-
routes = append(routes, s.getGatewayPublicIPv6Route())
71-
}
72-
} else {
73-
natGatewayID, err := s.getNatGatewayForSubnet(sn)
74-
if err != nil {
75-
return err
76-
}
77-
routes = append(routes, s.getNatGatewayPrivateRoute(natGatewayID))
78-
if sn.IsIPv6 {
79-
if !s.scope.VPC().IsIPv6Enabled() {
80-
// Safety net because EgressOnlyInternetGateway needs the ID from the ipv6 block.
81-
// if, for whatever reason by this point that is not available, we don't want to
82-
// panic because of a nil pointer access. This should never occur. Famous last words though.
83-
return errors.Errorf("ipv6 block missing for ipv6 enabled subnet, can't create egress only internet gateway")
84-
}
85-
routes = append(routes, s.getEgressOnlyInternetGateway())
86-
}
63+
routes, err := s.getRoutesForSubnet(sn)
64+
if err != nil {
65+
record.Warnf(s.scope.InfraCluster(), "FailedRouteTableRoutes", "Failed to get routes for managed RouteTable for subnet %s: %v", sn.ID, err)
66+
return errors.Wrapf(err, "failed to discover routes on route table %s", sn.ID)
8767
}
8868

8969
if rt, ok := subnetRouteMap[sn.GetResourceID()]; ok {
@@ -145,7 +125,7 @@ func (s *Service) reconcileRouteTables() error {
145125
return nil
146126
}
147127

148-
func (s *Service) fixMismatchedRouting(specRoute *ec2.Route, currentRoute *ec2.Route, rt *ec2.RouteTable) error {
128+
func (s *Service) fixMismatchedRouting(specRoute *ec2.CreateRouteInput, currentRoute *ec2.Route, rt *ec2.RouteTable) error {
149129
var input *ec2.ReplaceRouteInput
150130
if specRoute.DestinationCidrBlock != nil {
151131
if (currentRoute.DestinationCidrBlock != nil &&
@@ -280,7 +260,7 @@ func (s *Service) describeVpcRouteTables() ([]*ec2.RouteTable, error) {
280260
return out.RouteTables, nil
281261
}
282262

283-
func (s *Service) createRouteTableWithRoutes(routes []*ec2.Route, isPublic bool, zone string) (*infrav1.RouteTable, error) {
263+
func (s *Service) createRouteTableWithRoutes(routes []*ec2.CreateRouteInput, isPublic bool, zone string) (*infrav1.RouteTable, error) {
284264
out, err := s.EC2Client.CreateRouteTableWithContext(context.TODO(), &ec2.CreateRouteTableInput{
285265
VpcId: aws.String(s.scope.VPC().ID),
286266
TagSpecifications: []*ec2.TagSpecification{
@@ -296,17 +276,8 @@ func (s *Service) createRouteTableWithRoutes(routes []*ec2.Route, isPublic bool,
296276
for i := range routes {
297277
route := routes[i]
298278
if err := wait.WaitForWithRetryable(wait.NewBackoff(), func() (bool, error) {
299-
if _, err := s.EC2Client.CreateRouteWithContext(context.TODO(), &ec2.CreateRouteInput{
300-
RouteTableId: out.RouteTable.RouteTableId,
301-
DestinationCidrBlock: route.DestinationCidrBlock,
302-
DestinationIpv6CidrBlock: route.DestinationIpv6CidrBlock,
303-
EgressOnlyInternetGatewayId: route.EgressOnlyInternetGatewayId,
304-
GatewayId: route.GatewayId,
305-
InstanceId: route.InstanceId,
306-
NatGatewayId: route.NatGatewayId,
307-
NetworkInterfaceId: route.NetworkInterfaceId,
308-
VpcPeeringConnectionId: route.VpcPeeringConnectionId,
309-
}); err != nil {
279+
route.RouteTableId = out.RouteTable.RouteTableId
280+
if _, err := s.EC2Client.CreateRouteWithContext(context.TODO(), route); err != nil {
310281
return false, err
311282
}
312283
return true, nil
@@ -341,29 +312,29 @@ func (s *Service) associateRouteTable(rt *infrav1.RouteTable, subnetID string) e
341312
return nil
342313
}
343314

344-
func (s *Service) getNatGatewayPrivateRoute(natGatewayID string) *ec2.Route {
345-
return &ec2.Route{
315+
func (s *Service) getNatGatewayPrivateRoute(natGatewayID string) *ec2.CreateRouteInput {
316+
return &ec2.CreateRouteInput{
346317
NatGatewayId: aws.String(natGatewayID),
347318
DestinationCidrBlock: aws.String(services.AnyIPv4CidrBlock),
348319
}
349320
}
350321

351-
func (s *Service) getEgressOnlyInternetGateway() *ec2.Route {
352-
return &ec2.Route{
322+
func (s *Service) getEgressOnlyInternetGateway() *ec2.CreateRouteInput {
323+
return &ec2.CreateRouteInput{
353324
DestinationIpv6CidrBlock: aws.String(services.AnyIPv6CidrBlock),
354325
EgressOnlyInternetGatewayId: s.scope.VPC().IPv6.EgressOnlyInternetGatewayID,
355326
}
356327
}
357328

358-
func (s *Service) getGatewayPublicRoute() *ec2.Route {
359-
return &ec2.Route{
329+
func (s *Service) getGatewayPublicRoute() *ec2.CreateRouteInput {
330+
return &ec2.CreateRouteInput{
360331
DestinationCidrBlock: aws.String(services.AnyIPv4CidrBlock),
361332
GatewayId: aws.String(*s.scope.VPC().InternetGatewayID),
362333
}
363334
}
364335

365-
func (s *Service) getGatewayPublicIPv6Route() *ec2.Route {
366-
return &ec2.Route{
336+
func (s *Service) getGatewayPublicIPv6Route() *ec2.CreateRouteInput {
337+
return &ec2.CreateRouteInput{
367338
DestinationIpv6CidrBlock: aws.String(services.AnyIPv6CidrBlock),
368339
GatewayId: aws.String(*s.scope.VPC().InternetGatewayID),
369340
}
@@ -394,3 +365,45 @@ func (s *Service) getRouteTableTagParams(id string, public bool, zone string) in
394365
Additional: additionalTags,
395366
}
396367
}
368+
369+
func (s *Service) getRoutesToPublicSubnet(sn *infrav1.SubnetSpec) ([]*ec2.CreateRouteInput, error) {
370+
var routes []*ec2.CreateRouteInput
371+
372+
if s.scope.VPC().InternetGatewayID == nil {
373+
return routes, errors.Errorf("failed to create routing tables: internet gateway for %q is nil", s.scope.VPC().ID)
374+
}
375+
376+
routes = append(routes, s.getGatewayPublicRoute())
377+
if sn.IsIPv6 {
378+
routes = append(routes, s.getGatewayPublicIPv6Route())
379+
}
380+
381+
return routes, nil
382+
}
383+
384+
func (s *Service) getRoutesToPrivateSubnet(sn *infrav1.SubnetSpec) (routes []*ec2.CreateRouteInput, err error) {
385+
natGatewayID, err := s.getNatGatewayForSubnet(sn)
386+
if err != nil {
387+
return routes, err
388+
}
389+
390+
routes = append(routes, s.getNatGatewayPrivateRoute(natGatewayID))
391+
if sn.IsIPv6 {
392+
if !s.scope.VPC().IsIPv6Enabled() {
393+
// Safety net because EgressOnlyInternetGateway needs the ID from the ipv6 block.
394+
// if, for whatever reason by this point that is not available, we don't want to
395+
// panic because of a nil pointer access. This should never occur. Famous last words though.
396+
return routes, errors.Errorf("ipv6 block missing for ipv6 enabled subnet, can't create route for egress only internet gateway")
397+
}
398+
routes = append(routes, s.getEgressOnlyInternetGateway())
399+
}
400+
401+
return routes, nil
402+
}
403+
404+
func (s *Service) getRoutesForSubnet(sn *infrav1.SubnetSpec) ([]*ec2.CreateRouteInput, error) {
405+
if sn.IsPublic {
406+
return s.getRoutesToPublicSubnet(sn)
407+
}
408+
return s.getRoutesToPrivateSubnet(sn)
409+
}

0 commit comments

Comments
 (0)