From de7c96ad3c3048bca4c262b0b617b1ea3b559326 Mon Sep 17 00:00:00 2001 From: FengyunPan Date: Wed, 22 Nov 2017 09:14:50 +0800 Subject: [PATCH] Support autoprobing floating-network-id for openstack cloud provider --- pkg/cloudprovider/providers/openstack/BUILD | 2 + .../openstack/openstack_loadbalancer.go | 58 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/pkg/cloudprovider/providers/openstack/BUILD b/pkg/cloudprovider/providers/openstack/BUILD index d08ecb4553..5598768d37 100644 --- a/pkg/cloudprovider/providers/openstack/BUILD +++ b/pkg/cloudprovider/providers/openstack/BUILD @@ -39,6 +39,7 @@ go_library( "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions:go_default_library", + "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners:go_default_library", @@ -47,6 +48,7 @@ go_library( "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules:go_default_library", + "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports:go_default_library", "//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library", "//vendor/github.com/mitchellh/mapstructure:go_default_library", diff --git a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go index 98b5b44ed7..a99f6e19c1 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go +++ b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go @@ -25,6 +25,7 @@ import ( "github.com/golang/glog" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers" @@ -32,6 +33,7 @@ import ( v2pools "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules" + "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" neutronports "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" "github.com/gophercloud/gophercloud/pagination" @@ -560,6 +562,52 @@ func getNodeSecurityGroupIDForLB(compute *gophercloud.ServiceClient, nodes []*v1 return nodeSecurityGroupIDs.List(), nil } +// getFloatingNetworkIdForLB returns a floating-network-id for cluster. +func getFloatingNetworkIdForLB(client *gophercloud.ServiceClient) (string, error) { + var floatingNetworkIds []string + + type NetworkWithExternalExt struct { + networks.Network + external.NetworkExternalExt + } + + err := networks.List(client, networks.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { + var externalNetwork []NetworkWithExternalExt + err := networks.ExtractNetworksInto(page, &externalNetwork) + if err != nil { + return false, err + } + + for _, externalNet := range externalNetwork { + if externalNet.External { + floatingNetworkIds = append(floatingNetworkIds, externalNet.ID) + } + } + + if len(floatingNetworkIds) > 1 { + return false, ErrMultipleResults + } + return true, nil + }) + if err != nil { + if isNotFound(err) { + return "", ErrNotFound + } + + if err == ErrMultipleResults { + glog.V(4).Infof("find multiple external networks, pick the first one when there are no explicit configuration.") + return floatingNetworkIds[0], nil + } + return "", err + } + + if len(floatingNetworkIds) == 0 { + return "", ErrNotFound + } + + return floatingNetworkIds[0], nil +} + // TODO: This code currently ignores 'region' and always creates a // loadbalancer in only the current OpenStack region. We should take // a list of regions (from config) and query/create loadbalancers in @@ -590,7 +638,13 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv } floatingPool := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerFloatingNetworkId, lbaas.opts.FloatingNetworkId) - glog.V(4).Infof("EnsureLoadBalancer using floatingPool: %v", floatingPool) + if len(floatingPool) == 0 { + var err error + floatingPool, err = getFloatingNetworkIdForLB(lbaas.network) + if err != nil { + glog.Warningf("Failed to find floating-network-id for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err) + } + } var internalAnnotation bool internal := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerInternal, "false") @@ -600,7 +654,7 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv internalAnnotation = true case "false": if len(floatingPool) != 0 { - glog.V(4).Infof("Ensure an external loadbalancer service.") + glog.V(4).Infof("Ensure an external loadbalancer service, using floatingPool: %v", floatingPool) internalAnnotation = false } else { return nil, fmt.Errorf("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when ensuring an external loadbalancer service")