From 6aa7c47480525383d31bcef1d0498fe479972e2e Mon Sep 17 00:00:00 2001 From: FengyunPan Date: Tue, 8 Aug 2017 23:32:59 +0800 Subject: [PATCH] Fix conflict about getPortByIp Currently getPortByIp() get port of instance only based on IP. If there are two instances in diffent network and the CIDR of their subnet are same, getPortByIp() will be conflict. My PR gets port based on IP and Name of instance. --- .../openstack/openstack_loadbalancer.go | 28 ---------- .../providers/openstack/openstack_routes.go | 53 +++++++++++++++++-- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go index ca085890009..50948bb9809 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go +++ b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go @@ -100,34 +100,6 @@ func networkExtensions(client *gophercloud.ServiceClient) (map[string]bool, erro return seen, err } -func getPortByIP(client *gophercloud.ServiceClient, ipAddress string) (neutronports.Port, error) { - var targetPort neutronports.Port - var portFound = false - - err := neutronports.List(client, neutronports.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { - portList, err := neutronports.ExtractPorts(page) - if err != nil { - return false, err - } - - for _, port := range portList { - for _, ip := range port.FixedIPs { - if ip.IPAddress == ipAddress { - targetPort = port - portFound = true - return false, nil - } - } - } - - return true, nil - }) - if err == nil && !portFound { - err = ErrNotFound - } - return targetPort, err -} - func getFloatingIPByPortID(client *gophercloud.ServiceClient, portID string) (*floatingips.FloatingIP, error) { opts := floatingips.ListOpts{ PortID: portID, diff --git a/pkg/cloudprovider/providers/openstack/openstack_routes.go b/pkg/cloudprovider/providers/openstack/openstack_routes.go index 2cb0cd95ff0..e999f5eb5ae 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_routes.go +++ b/pkg/cloudprovider/providers/openstack/openstack_routes.go @@ -177,7 +177,12 @@ func (r *Routes) CreateRoute(clusterName string, nameHint string, route *cloudpr } defer onFailure.Call(unwind) - port, err := getPortByIP(r.network, addr) + // get the port of addr on target node. + portID, err := getPortIDByIP(r.compute, route.TargetNode, addr) + if err != nil { + return err + } + port, err := getPortByID(r.network, portID) if err != nil { return err } @@ -195,7 +200,7 @@ func (r *Routes) CreateRoute(clusterName string, nameHint string, route *cloudpr newPairs := append(port.AllowedAddressPairs, neutronports.AddressPair{ IPAddress: route.DestinationCIDR, }) - unwind, err := updateAllowedAddressPairs(r.network, &port, newPairs) + unwind, err := updateAllowedAddressPairs(r.network, port, newPairs) if err != nil { return err } @@ -246,7 +251,12 @@ func (r *Routes) DeleteRoute(clusterName string, route *cloudprovider.Route) err } defer onFailure.Call(unwind) - port, err := getPortByIP(r.network, addr) + // get the port of addr on target node. + portID, err := getPortIDByIP(r.compute, route.TargetNode, addr) + if err != nil { + return err + } + port, err := getPortByID(r.network, portID) if err != nil { return err } @@ -265,7 +275,7 @@ func (r *Routes) DeleteRoute(clusterName string, route *cloudprovider.Route) err addr_pairs[index] = addr_pairs[len(addr_pairs)-1] addr_pairs = addr_pairs[:len(addr_pairs)-1] - unwind, err := updateAllowedAddressPairs(r.network, &port, addr_pairs) + unwind, err := updateAllowedAddressPairs(r.network, port, addr_pairs) if err != nil { return err } @@ -276,3 +286,38 @@ func (r *Routes) DeleteRoute(clusterName string, route *cloudprovider.Route) err onFailure.Disarm() return nil } + +func getPortIDByIP(compute *gophercloud.ServiceClient, targetNode types.NodeName, ipAddress string) (string, error) { + srv, err := getServerByName(compute, targetNode) + if err != nil { + return "", err + } + + interfaces, err := getAttachedInterfacesByID(compute, srv.ID) + if err != nil { + return "", err + } + + for _, intf := range interfaces { + for _, fixedIP := range intf.FixedIPs { + if fixedIP.IPAddress == ipAddress { + return intf.PortID, nil + } + } + } + + return "", ErrNotFound +} + +func getPortByID(client *gophercloud.ServiceClient, portID string) (*neutronports.Port, error) { + targetPort, err := neutronports.Get(client, portID).Extract() + if err != nil { + return nil, err + } + + if targetPort == nil { + return nil, ErrNotFound + } + + return targetPort, nil +}