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

Save Nat Gateways IPs to status on every reconciliation #4508

Merged
merged 1 commit into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions pkg/cloud/services/network/natgateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func (s *Service) reconcileNatGateways() error {
return err
}

natGatewaysIPs := []string{}
subnetIDs := []string{}

for _, sn := range s.scope.Subnets().FilterPublic() {
Expand All @@ -77,6 +78,9 @@ func (s *Service) reconcileNatGateways() error {
}

if ngw, ok := existing[sn.ID]; ok {
if len(ngw.NatGatewayAddresses) > 0 && ngw.NatGatewayAddresses[0].PublicIp != nil {
natGatewaysIPs = append(natGatewaysIPs, *ngw.NatGatewayAddresses[0].PublicIp)
}
// Make sure tags are up to date.
if err := wait.WaitForWithRetryable(wait.NewBackoff(), func() (bool, error) {
buildParams := s.getNatGatewayTagParams(*ngw.NatGatewayId)
Expand All @@ -96,6 +100,8 @@ func (s *Service) reconcileNatGateways() error {
subnetIDs = append(subnetIDs, sn.ID)
}

s.scope.SetNatGatewaysIPs(natGatewaysIPs)

// Batch the creation of NAT gateways
if len(subnetIDs) > 0 {
// set NatGatewayCreationStarted if the condition has never been set before
Expand All @@ -106,18 +112,12 @@ func (s *Service) reconcileNatGateways() error {
}
}
ngws, err := s.createNatGateways(subnetIDs)
var natGatewaysIPs []string

for _, ng := range ngws {
subnet := s.scope.Subnets().FindByID(*ng.SubnetId)
subnet.NatGatewayID = ng.NatGatewayId
if len(ng.NatGatewayAddresses) > 0 && ng.NatGatewayAddresses[0].PublicIp != nil {
natGatewaysIPs = append(natGatewaysIPs, *ng.NatGatewayAddresses[0].PublicIp)
}
}

s.scope.SetNatGatewaysIPs(natGatewaysIPs)

if err != nil {
return err
}
Expand Down
91 changes: 45 additions & 46 deletions pkg/cloud/services/securitygroup/securitygroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,68 +728,63 @@ func ingressRuleToSDKType(scope scope.SGScope, i *infrav1.IngressRule) (res *ec2
}

func ingressRulesFromSDKType(v *ec2.IpPermission) (res infrav1.IngressRules) {
for _, ec2range := range v.IpRanges {
rule := ingressRuleFromSDKProtocol(v)
if ec2range.Description != nil && *ec2range.Description != "" {
rule.Description = *ec2range.Description
}

rule.CidrBlocks = []string{*ec2range.CidrIp}
res = append(res, rule)
}

for _, ec2range := range v.Ipv6Ranges {
rule := ingressRuleFromSDKProtocol(v)
if ec2range.Description != nil && *ec2range.Description != "" {
rule.Description = *ec2range.Description
}

rule.IPv6CidrBlocks = []string{*ec2range.CidrIpv6}
res = append(res, rule)
}

for _, pair := range v.UserIdGroupPairs {
rule := ingressRuleFromSDKProtocol(v)
if pair.GroupId == nil {
continue
}

if pair.Description != nil && *pair.Description != "" {
rule.Description = *pair.Description
}

rule.SourceSecurityGroupIDs = []string{*pair.GroupId}
res = append(res, rule)
}

return res
}

func ingressRuleFromSDKProtocol(v *ec2.IpPermission) infrav1.IngressRule {
// Ports are only well-defined for TCP and UDP protocols, but EC2 overloads the port range
// in the case of ICMP(v6) traffic to indicate which codes are allowed. For all other protocols,
// including the custom "-1" All Traffic protocol, FromPort and ToPort are omitted from the response.
// See: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_IpPermission.html
var ir infrav1.IngressRule
switch *v.IpProtocol {
case IPProtocolTCP,
IPProtocolUDP,
IPProtocolICMP,
IPProtocolICMPv6:
ir = infrav1.IngressRule{
return infrav1.IngressRule{
Protocol: infrav1.SecurityGroupProtocol(*v.IpProtocol),
FromPort: *v.FromPort,
ToPort: *v.ToPort,
}
default:
ir = infrav1.IngressRule{
return infrav1.IngressRule{
Protocol: infrav1.SecurityGroupProtocol(*v.IpProtocol),
}
}

if len(v.IpRanges) > 0 {
r1 := ir
for _, ec2range := range v.IpRanges {
if ec2range.Description != nil && *ec2range.Description != "" {
r1.Description = *ec2range.Description
}

r1.CidrBlocks = append(r1.CidrBlocks, *ec2range.CidrIp)
}
res = append(res, r1)
}

if len(v.Ipv6Ranges) > 0 {
r1 := ir
for _, ec2range := range v.Ipv6Ranges {
if ec2range.Description != nil && *ec2range.Description != "" {
r1.Description = *ec2range.Description
}

r1.IPv6CidrBlocks = append(r1.IPv6CidrBlocks, *ec2range.CidrIpv6)
}
res = append(res, r1)
}

if len(v.UserIdGroupPairs) > 0 {
r2 := ir
for _, pair := range v.UserIdGroupPairs {
if pair.GroupId == nil {
continue
}

if pair.Description != nil && *pair.Description != "" {
r2.Description = *pair.Description
}

r2.SourceSecurityGroupIDs = append(r2.SourceSecurityGroupIDs, *pair.GroupId)
}
res = append(res, r2)
}

return res
}

// getIngressRulesToAllowKubeletToAccessTheControlPlaneLB returns ingress rules required in the control plane LB.
Expand All @@ -800,15 +795,19 @@ func (s *Service) getIngressRulesToAllowKubeletToAccessTheControlPlaneLB() infra
return s.getIngressRuleToAllowVPCCidrInTheAPIServer()
}

natGatewaysCidrs := []string{}
natGatewaysIPs := s.scope.GetNatGatewaysIPs()
for _, ip := range natGatewaysIPs {
natGatewaysCidrs = append(natGatewaysCidrs, fmt.Sprintf("%s/32", ip))
}
if len(natGatewaysIPs) > 0 {
return infrav1.IngressRules{
{
Description: "Kubernetes API",
Protocol: infrav1.SecurityGroupProtocolTCP,
FromPort: int64(s.scope.APIServerPort()),
ToPort: int64(s.scope.APIServerPort()),
CidrBlocks: natGatewaysIPs,
CidrBlocks: natGatewaysCidrs,
},
}
}
Expand Down
47 changes: 44 additions & 3 deletions pkg/cloud/services/securitygroup/securitygroups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ func TestControlPlaneLoadBalancerIngressRules(t *testing.T) {
Protocol: infrav1.SecurityGroupProtocolTCP,
FromPort: 6443,
ToPort: 6443,
CidrBlocks: []string{"1.2.3.4"},
CidrBlocks: []string{"1.2.3.4/32"},
},
infrav1.IngressRule{
Description: "Kubernetes API",
Expand Down Expand Up @@ -915,7 +915,7 @@ func TestControlPlaneLoadBalancerIngressRules(t *testing.T) {
Protocol: infrav1.SecurityGroupProtocolTCP,
FromPort: 6443,
ToPort: 6443,
CidrBlocks: []string{"1.2.3.4"},
CidrBlocks: []string{"1.2.3.4/32"},
},
infrav1.IngressRule{
Description: "My custom ingress rule",
Expand Down Expand Up @@ -1250,6 +1250,40 @@ func TestIngressRulesFromSDKType(t *testing.T) {
input *ec2.IpPermission
expected infrav1.IngressRules
}{
{
name: "two ingress rules",
input: &ec2.IpPermission{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(6443),
ToPort: aws.Int64(6443),
IpRanges: []*ec2.IpRange{
{
CidrIp: aws.String("0.0.0.0/0"),
Description: aws.String("Kubernetes API"),
},
{
CidrIp: aws.String("192.168.1.1/32"),
Description: aws.String("My VPN"),
},
},
},
expected: infrav1.IngressRules{
{
Description: "Kubernetes API",
Protocol: "tcp",
FromPort: 6443,
ToPort: 6443,
CidrBlocks: []string{"0.0.0.0/0"},
},
{
Description: "My VPN",
Protocol: "tcp",
FromPort: 6443,
ToPort: 6443,
CidrBlocks: []string{"192.168.1.1/32"},
},
},
},
{
name: "Two group pairs",
input: &ec2.IpPermission{
Expand All @@ -1275,7 +1309,14 @@ func TestIngressRulesFromSDKType(t *testing.T) {
Protocol: "tcp",
FromPort: 10250,
ToPort: 10250,
SourceSecurityGroupIDs: []string{"sg-source-1", "sg-source-2"},
SourceSecurityGroupIDs: []string{"sg-source-1"},
},
{
Description: "Kubelet API",
Protocol: "tcp",
FromPort: 10250,
ToPort: 10250,
SourceSecurityGroupIDs: []string{"sg-source-2"},
},
},
},
Expand Down