Skip to content

Commit

Permalink
Remove SGs from non-existent nodes ports on Update
Browse files Browse the repository at this point in the history
  • Loading branch information
EmilienM committed Oct 21, 2024
1 parent 04bd8e1 commit 4b17c5b
Showing 1 changed file with 52 additions and 24 deletions.
76 changes: 52 additions & 24 deletions pkg/openstack/loadbalancer_sg.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func applyNodeSecurityGroupIDForLB(network *gophercloud.ServiceClient, svcConf *
continue
}

listOpts := neutronports.ListOpts{DeviceID: serverID}
listOpts := neutronports.ListOpts{}
allPorts, err := openstackutil.GetPorts[PortWithPortSecurity](network, listOpts)
if err != nil {
return err
Expand All @@ -75,6 +75,23 @@ func applyNodeSecurityGroupIDForLB(network *gophercloud.ServiceClient, svcConf *
continue
}

if port.DeviceID != serverID {
sgFound := false
for _, portSG := range port.SecurityGroups {
if portSG == sg {
sgFound = true
break
}
}
if sgFound {
err := removeSecurityGroupFromPort(network, port.Port, sg)
if err != nil {
return err
}
continue
}
}

// If the Security Group is already present on the port, skip it.
if slices.Contains(port.SecurityGroups, sg) {
continue
Expand All @@ -97,6 +114,7 @@ func applyNodeSecurityGroupIDForLB(network *gophercloud.ServiceClient, svcConf *
return fmt.Errorf("failed to update security group for port %s: %v", port.ID, res.Err)
}
}

}

return nil
Expand All @@ -113,31 +131,41 @@ func disassociateSecurityGroupForLB(network *gophercloud.ServiceClient, sg strin

// Disassocate security group and remove the tag.
for _, port := range allPorts {
existingSGs := sets.NewString()
for _, sgID := range port.SecurityGroups {
existingSGs.Insert(sgID)
}
existingSGs.Delete(sg)

// Update port security groups
newSGs := existingSGs.List()
// TODO(dulek): This should be done using Neutron's revision_number to make sure
// we don't trigger a lost update issue.
updateOpts := neutronports.UpdateOpts{SecurityGroups: &newSGs}
mc := metrics.NewMetricContext("port", "update")
res := neutronports.Update(context.TODO(), network, port.ID, updateOpts)
if mc.ObserveRequest(res.Err) != nil {
return fmt.Errorf("failed to update security group for port %s: %v", port.ID, res.Err)
err := removeSecurityGroupFromPort(network, port, sg)
if err != nil {
return err
}
}

// Remove the security group ID tag from the port. Please note we don't tag ports with SG IDs anymore,
// so this stays for backward compatibility. It's reasonable to delete it in the future. 404s are ignored.
if slices.Contains(port.Tags, sg) {
mc = metrics.NewMetricContext("port_tag", "delete")
err := neutrontags.Delete(context.TODO(), network, "ports", port.ID, sg).ExtractErr()
if mc.ObserveRequest(err) != nil {
return fmt.Errorf("failed to remove tag %s to port %s: %v", sg, port.ID, res.Err)
}
return nil
}

// removeSecurityGroupFromPort removes the given security group from the port
func removeSecurityGroupFromPort(network *gophercloud.ServiceClient, port neutronports.Port, sg string) error {
existingSGs := sets.NewString()
for _, sgID := range port.SecurityGroups {
existingSGs.Insert(sgID)
}
existingSGs.Delete(sg)

// Update port security groups
newSGs := existingSGs.List()
// TODO(dulek): This should be done using Neutron's revision_number to make sure
// we don't trigger a lost update issue.
updateOpts := neutronports.UpdateOpts{SecurityGroups: &newSGs}
mc := metrics.NewMetricContext("port", "update")
res := neutronports.Update(context.TODO(), network, port.ID, updateOpts)
if mc.ObserveRequest(res.Err) != nil {
return fmt.Errorf("failed to update security group for port %s: %v", port.ID, res.Err)
}

// Remove the security group ID tag from the port. Please note we don't tag ports with SG IDs anymore,
// so this stays for backward compatibility. It's reasonable to delete it in the future. 404s are ignored.
if slices.Contains(port.Tags, sg) {
mc = metrics.NewMetricContext("port_tag", "delete")
err := neutrontags.Delete(context.TODO(), network, "ports", port.ID, sg).ExtractErr()
if mc.ObserveRequest(err) != nil {
return fmt.Errorf("failed to remove tag %s to port %s: %v", sg, port.ID, res.Err)
}
}

Expand Down

0 comments on commit 4b17c5b

Please sign in to comment.