diff --git a/pkg/openstack/instances.go b/pkg/openstack/instances.go index fbc1c7002b..73995113c5 100644 --- a/pkg/openstack/instances.go +++ b/pkg/openstack/instances.go @@ -27,9 +27,9 @@ import ( "strings" "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" "github.com/gophercloud/gophercloud/pagination" "github.com/mitchellh/mapstructure" v1 "k8s.io/api/core/v1" @@ -43,11 +43,13 @@ import ( "k8s.io/cloud-provider-openstack/pkg/util" "k8s.io/cloud-provider-openstack/pkg/util/errors" "k8s.io/cloud-provider-openstack/pkg/util/metadata" + "k8s.io/cloud-provider-openstack/pkg/util/openstack" ) // Instances encapsulates an implementation of Instances for OpenStack. type Instances struct { compute *gophercloud.ServiceClient + network *gophercloud.ServiceClient region string regionProviderID bool opts metadata.Opts @@ -148,6 +150,12 @@ func (os *OpenStack) instances() (*Instances, bool) { return nil, false } + network, err := client.NewNetworkV2(os.provider, os.epOpts) + if err != nil { + klog.Errorf("unable to access network v2 API : %v", err) + return nil, false + } + regionalProviderID := false if isRegionalProviderID := sysos.Getenv(RegionalProviderIDEnv); isRegionalProviderID == "true" { regionalProviderID = true @@ -155,6 +163,7 @@ func (os *OpenStack) instances() (*Instances, bool) { return &Instances{ compute: compute, + network: network, region: os.epOpts.Region, regionProviderID: regionalProviderID, opts: os.metadataOpts, @@ -226,12 +235,12 @@ func (i *Instances) NodeAddressesByProviderID(ctx context.Context, providerID st return []v1.NodeAddress{}, err } - interfaces, err := getAttachedInterfacesByID(i.compute, server.ID) + ports, err := getAttachedPorts(i.network, server.ID) if err != nil { return []v1.NodeAddress{}, err } - addresses, err := nodeAddresses(server, interfaces, i.networkingOpts) + addresses, err := nodeAddresses(server, ports, i.networkingOpts) if err != nil { return []v1.NodeAddress{}, err } @@ -332,11 +341,11 @@ func (i *Instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloud return nil, err } - interfaces, err := getAttachedInterfacesByID(i.compute, srv.ID) + ports, err := getAttachedPorts(i.network, srv.ID) if err != nil { return nil, err } - addresses, err := nodeAddresses(srv, interfaces, i.networkingOpts) + addresses, err := nodeAddresses(srv, ports, i.networkingOpts) if err != nil { return nil, err } @@ -564,13 +573,13 @@ func getServerByName(client *gophercloud.ServiceClient, name types.NodeName) (*S // * access IPs // * metadata hostname // * server object Addresses (floating type) -func nodeAddresses(srv *servers.Server, interfaces []attachinterfaces.Interface, networkingOpts NetworkingOpts) ([]v1.NodeAddress, error) { +func nodeAddresses(srv *servers.Server, ports []ports.Port, networkingOpts NetworkingOpts) ([]v1.NodeAddress, error) { addrs := []v1.NodeAddress{} // parse private IP addresses first in an ordered manner - for _, iface := range interfaces { - for _, fixedIP := range iface.FixedIPs { - if iface.PortState == "ACTIVE" { + for _, port := range ports { + for _, fixedIP := range port.FixedIPs { + if port.Status == "ACTIVE" { isIPv6 := net.ParseIP(fixedIP.IPAddress).To4() == nil if !(isIPv6 && networkingOpts.IPv6SupportDisabled) { AddToNodeAddresses(&addrs, @@ -683,31 +692,20 @@ func getAddressesByName(client *gophercloud.ServiceClient, name types.NodeName, return nil, err } - interfaces, err := getAttachedInterfacesByID(client, srv.ID) + ports, err := getAttachedPorts(client, srv.ID) if err != nil { return nil, err } - return nodeAddresses(&srv.Server, interfaces, networkingOpts) + return nodeAddresses(&srv.Server, ports, networkingOpts) } -// getAttachedInterfacesByID returns the node interfaces of the specified instance. -func getAttachedInterfacesByID(client *gophercloud.ServiceClient, serviceID string) ([]attachinterfaces.Interface, error) { - var interfaces []attachinterfaces.Interface - - mc := metrics.NewMetricContext("server_os_interface", "list") - pager := attachinterfaces.List(client, serviceID) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - s, err := attachinterfaces.ExtractInterfaces(page) - if err != nil { - return false, err - } - interfaces = append(interfaces, s...) - return true, nil - }) - if mc.ObserveRequest(err) != nil { - return interfaces, err +// getAttachedPorts returns a list of ports attached to a server. +func getAttachedPorts(client *gophercloud.ServiceClient, serverID string) ([]ports.Port, error) { + listOpts := ports.ListOpts{ + DeviceID: serverID, + DeviceOwner: "compute:nova", } - return interfaces, nil + return openstack.GetPorts(client, listOpts) } diff --git a/pkg/openstack/instancesv2.go b/pkg/openstack/instancesv2.go index e1f2c279cf..eea86dcc2b 100644 --- a/pkg/openstack/instancesv2.go +++ b/pkg/openstack/instancesv2.go @@ -34,6 +34,7 @@ import ( // InstancesV2 encapsulates an implementation of InstancesV2 for OpenStack. type InstancesV2 struct { compute *gophercloud.ServiceClient + network *gophercloud.ServiceClient region string regionProviderID bool networkingOpts NetworkingOpts @@ -56,6 +57,12 @@ func (os *OpenStack) instancesv2() (*InstancesV2, bool) { return nil, false } + network, err := client.NewNetworkV2(os.provider, os.epOpts) + if err != nil { + klog.Errorf("unable to access network v2 API : %v", err) + return nil, false + } + regionalProviderID := false if isRegionalProviderID := sysos.Getenv(RegionalProviderIDEnv); isRegionalProviderID == "true" { regionalProviderID = true @@ -63,6 +70,7 @@ func (os *OpenStack) instancesv2() (*InstancesV2, bool) { return &InstancesV2{ compute: compute, + network: network, region: os.epOpts.Region, regionProviderID: regionalProviderID, networkingOpts: os.networkingOpts, @@ -115,12 +123,12 @@ func (i *InstancesV2) InstanceMetadata(ctx context.Context, node *v1.Node) (*clo return nil, err } - interfaces, err := getAttachedInterfacesByID(i.compute, server.ID) + ports, err := getAttachedPorts(i.network, server.ID) if err != nil { return nil, err } - addresses, err := nodeAddresses(&server.Server, interfaces, i.networkingOpts) + addresses, err := nodeAddresses(&server.Server, ports, i.networkingOpts) if err != nil { return nil, err } diff --git a/pkg/openstack/loadbalancer.go b/pkg/openstack/loadbalancer.go index 9721821210..22fa65af7b 100644 --- a/pkg/openstack/loadbalancer.go +++ b/pkg/openstack/loadbalancer.go @@ -707,7 +707,7 @@ func getBoolFromServiceAnnotation(service *corev1.Service, annotationKey string, } // getSubnetIDForLB returns subnet-id for a specific node -func getSubnetIDForLB(compute *gophercloud.ServiceClient, node corev1.Node, preferredIPFamily corev1.IPFamily) (string, error) { +func getSubnetIDForLB(network *gophercloud.ServiceClient, node corev1.Node, preferredIPFamily corev1.IPFamily) (string, error) { ipAddress, err := nodeAddressForLB(&node, preferredIPFamily) if err != nil { return "", err @@ -718,13 +718,13 @@ func getSubnetIDForLB(compute *gophercloud.ServiceClient, node corev1.Node, pref instanceID = instanceID[(ind + 1):] } - interfaces, err := getAttachedInterfacesByID(compute, instanceID) + ports, err := getAttachedPorts(network, instanceID) if err != nil { return "", err } - for _, intf := range interfaces { - for _, fixedIP := range intf.FixedIPs { + for _, port := range ports { + for _, fixedIP := range port.FixedIPs { if fixedIP.IPAddress == ipAddress { return fixedIP.SubnetID, nil } @@ -1554,7 +1554,7 @@ func (lbaas *LbaasV2) checkServiceUpdate(service *corev1.Service, nodes []*corev } else { svcConf.lbMemberSubnetID = getStringFromServiceAnnotation(service, ServiceAnnotationLoadBalancerSubnetID, lbaas.opts.SubnetID) if len(svcConf.lbMemberSubnetID) == 0 && len(nodes) > 0 { - subnetID, err := getSubnetIDForLB(lbaas.compute, *nodes[0], svcConf.preferredIPFamily) + subnetID, err := getSubnetIDForLB(lbaas.network, *nodes[0], svcConf.preferredIPFamily) if err != nil { return fmt.Errorf("no subnet-id found for service %s: %v", serviceName, err) } @@ -1668,7 +1668,7 @@ func (lbaas *LbaasV2) checkService(service *corev1.Service, nodes []*corev1.Node svcConf.lbMemberSubnetID = svcConf.lbSubnetID } if len(svcConf.lbNetworkID) == 0 && len(svcConf.lbSubnetID) == 0 { - subnetID, err := getSubnetIDForLB(lbaas.compute, *nodes[0], svcConf.preferredIPFamily) + subnetID, err := getSubnetIDForLB(lbaas.network, *nodes[0], svcConf.preferredIPFamily) if err != nil { return fmt.Errorf("failed to get subnet to create load balancer for service %s: %v", serviceName, err) } diff --git a/pkg/openstack/openstack_test.go b/pkg/openstack/openstack_test.go index f7d98438ee..cd31f80c14 100644 --- a/pkg/openstack/openstack_test.go +++ b/pkg/openstack/openstack_test.go @@ -27,8 +27,8 @@ import ( "time" "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" "github.com/spf13/pflag" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -360,10 +360,10 @@ func TestNodeAddresses(t *testing.T) { PublicNetworkName: []string{"public"}, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -374,7 +374,7 @@ func TestNodeAddresses(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -439,10 +439,10 @@ func TestNodeAddressesCustomPublicNetwork(t *testing.T) { PublicNetworkName: []string{"pub-net"}, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -453,7 +453,7 @@ func TestNodeAddressesCustomPublicNetwork(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -512,10 +512,10 @@ func TestNodeAddressesCustomPublicNetworkWithIntersectingFixedIP(t *testing.T) { PublicNetworkName: []string{"pub-net"}, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -530,7 +530,7 @@ func TestNodeAddressesCustomPublicNetworkWithIntersectingFixedIP(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -600,10 +600,10 @@ func TestNodeAddressesMultipleCustomInternalNetworks(t *testing.T) { InternalNetworkName: []string{"private", "also-private"}, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -614,7 +614,7 @@ func TestNodeAddressesMultipleCustomInternalNetworks(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -684,10 +684,10 @@ func TestNodeAddressesOneInternalNetwork(t *testing.T) { InternalNetworkName: []string{"also-private"}, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -698,7 +698,7 @@ func TestNodeAddressesOneInternalNetwork(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -760,10 +760,10 @@ func TestNodeAddressesIPv6Disabled(t *testing.T) { IPv6SupportDisabled: true, } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -774,7 +774,7 @@ func TestNodeAddressesIPv6Disabled(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) } @@ -841,10 +841,10 @@ func TestNodeAddressesWithAddressSortOrderOptions(t *testing.T) { AddressSortOrder: "10.0.0.0/8, 50.56.176.0/24, 2001:4800::/32", } - interfaces := []attachinterfaces.Interface{ + ports := []ports.Port{ { - PortState: "ACTIVE", - FixedIPs: []attachinterfaces.FixedIP{ + Status: "ACTIVE", + FixedIPs: []ports.IP{ { IPAddress: "10.0.0.32", }, @@ -855,7 +855,7 @@ func TestNodeAddressesWithAddressSortOrderOptions(t *testing.T) { }, } - addrs, err := nodeAddresses(&srv, interfaces, networkingOpts) + addrs, err := nodeAddresses(&srv, ports, networkingOpts) if err != nil { t.Fatalf("nodeAddresses returned error: %v", err) }