@@ -40,13 +40,13 @@ import (
4040 secgroups "github.com/gophercloud/utils/openstack/networking/v2/extensions/security/groups"
4141 "gopkg.in/godo.v2/glob"
4242 corev1 "k8s.io/api/core/v1"
43- "k8s.io/apimachinery/pkg/types"
4443 utilerrors "k8s.io/apimachinery/pkg/util/errors"
4544 "k8s.io/apimachinery/pkg/util/sets"
4645 "k8s.io/client-go/kubernetes"
4746 cloudprovider "k8s.io/cloud-provider"
4847 "k8s.io/klog/v2"
4948 netutils "k8s.io/utils/net"
49+ "k8s.io/utils/strings/slices"
5050
5151 "k8s.io/cloud-provider-openstack/pkg/metrics"
5252 cpoutil "k8s.io/cloud-provider-openstack/pkg/util"
@@ -721,48 +721,44 @@ func getSubnetIDForLB(network *gophercloud.ServiceClient, node corev1.Node, pref
721721}
722722
723723// applyNodeSecurityGroupIDForLB associates the security group with all the ports on the nodes.
724- func applyNodeSecurityGroupIDForLB (compute * gophercloud. ServiceClient , network * gophercloud.ServiceClient , nodes []* corev1.Node , sg string ) error {
724+ func applyNodeSecurityGroupIDForLB (network * gophercloud.ServiceClient , nodes []* corev1.Node , sg string ) error {
725725 for _ , node := range nodes {
726- nodeName := types .NodeName (node .Name )
727- srv , err := getServerByName (compute , nodeName )
726+ serverID , _ , err := instanceIDFromProviderID (node .Spec .ProviderID )
728727 if err != nil {
729- return err
728+ return fmt . Errorf ( "error getting server ID from the node: %w" , err )
730729 }
731-
732- listOpts := neutronports.ListOpts {DeviceID : srv .ID }
730+ listOpts := neutronports.ListOpts {DeviceID : serverID }
733731 allPorts , err := openstackutil .GetPorts (network , listOpts )
734732 if err != nil {
735733 return err
736734 }
737735
738736 for _ , port := range allPorts {
739737 // If the Security Group is already present on the port, skip it.
740- // As soon as this only supports Go 1.18, this can be replaces by
741- // slices.Contains.
742- if func () bool {
743- for _ , currentSG := range port .SecurityGroups {
744- if currentSG == sg {
745- return true
746- }
747- }
748- return false
749- }() {
738+ if slices .Contains (port .SecurityGroups , sg ) {
750739 continue
751740 }
752741
742+ // Add the security group ID as a tag to the port in order to find all these ports when removing the security group.
743+ // We're doing that before actually applying the SG as if tagging would fail we wouldn't be able to find the port
744+ // when deleting the SG and operation would be stuck forever. It's better to find more ports than not all of them.
745+ mc := metrics .NewMetricContext ("port_tag" , "add" )
746+ err := neutrontags .Add (network , "ports" , port .ID , sg ).ExtractErr ()
747+ if mc .ObserveRequest (err ) != nil {
748+ return fmt .Errorf ("failed to add tag %s to port %s: %v" , sg , port .ID , err )
749+ }
750+
751+ // Add the SG to the port
752+ // TODO(dulek): This isn't an atomic operation. In order to protect from lost update issues we should use
753+ // `revision_number` handling to make sure our update to `security_groups` field wasn't preceded
754+ // by a different one. Same applies to a removal of the SG.
753755 newSGs := append (port .SecurityGroups , sg )
754756 updateOpts := neutronports.UpdateOpts {SecurityGroups : & newSGs }
755- mc : = metrics .NewMetricContext ("port" , "update" )
757+ mc = metrics .NewMetricContext ("port" , "update" )
756758 res := neutronports .Update (network , port .ID , updateOpts )
757759 if mc .ObserveRequest (res .Err ) != nil {
758760 return fmt .Errorf ("failed to update security group for port %s: %v" , port .ID , res .Err )
759761 }
760- // Add the security group ID as a tag to the port in order to find all these ports when removing the security group.
761- mc = metrics .NewMetricContext ("port_tag" , "add" )
762- err := neutrontags .Add (network , "ports" , port .ID , sg ).ExtractErr ()
763- if mc .ObserveRequest (err ) != nil {
764- return fmt .Errorf ("failed to add tag %s to port %s: %v" , sg , port .ID , err )
765- }
766762 }
767763 }
768764
@@ -2325,7 +2321,7 @@ func (lbaas *LbaasV2) ensureAndUpdateOctaviaSecurityGroup(clusterName string, ap
23252321 }
23262322 }
23272323
2328- if err := applyNodeSecurityGroupIDForLB (lbaas .compute , lbaas . network , nodes , lbSecGroupID ); err != nil {
2324+ if err := applyNodeSecurityGroupIDForLB (lbaas .network , nodes , lbSecGroupID ); err != nil {
23292325 return err
23302326 }
23312327 return nil
0 commit comments