@@ -25,13 +25,15 @@ import (
2525 "github.com/golang/glog"
2626 "github.com/gophercloud/gophercloud"
2727 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions"
28+ "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external"
2829 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
2930 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners"
3031 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers"
3132 v2monitors "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors"
3233 v2pools "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools"
3334 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
3435 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
36+ "github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
3537 neutronports "github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
3638 "github.com/gophercloud/gophercloud/pagination"
3739
@@ -566,6 +568,52 @@ func getNodeSecurityGroupIDForLB(compute *gophercloud.ServiceClient, nodes []*v1
566568 return nodeSecurityGroupIDs .List (), nil
567569}
568570
571+ // getFloatingNetworkIdForLB returns a floating-network-id for cluster.
572+ func getFloatingNetworkIdForLB (client * gophercloud.ServiceClient ) (string , error ) {
573+ var floatingNetworkIds []string
574+
575+ type NetworkWithExternalExt struct {
576+ networks.Network
577+ external.NetworkExternalExt
578+ }
579+
580+ err := networks .List (client , networks.ListOpts {}).EachPage (func (page pagination.Page ) (bool , error ) {
581+ var externalNetwork []NetworkWithExternalExt
582+ err := networks .ExtractNetworksInto (page , & externalNetwork )
583+ if err != nil {
584+ return false , err
585+ }
586+
587+ for _ , externalNet := range externalNetwork {
588+ if externalNet .External {
589+ floatingNetworkIds = append (floatingNetworkIds , externalNet .ID )
590+ }
591+ }
592+
593+ if len (floatingNetworkIds ) > 1 {
594+ return false , ErrMultipleResults
595+ }
596+ return true , nil
597+ })
598+ if err != nil {
599+ if isNotFound (err ) {
600+ return "" , ErrNotFound
601+ }
602+
603+ if err == ErrMultipleResults {
604+ glog .V (4 ).Infof ("find multiple external networks, pick the first one when there are no explicit configuration." )
605+ return floatingNetworkIds [0 ], nil
606+ }
607+ return "" , err
608+ }
609+
610+ if len (floatingNetworkIds ) == 0 {
611+ return "" , ErrNotFound
612+ }
613+
614+ return floatingNetworkIds [0 ], nil
615+ }
616+
569617// TODO: This code currently ignores 'region' and always creates a
570618// loadbalancer in only the current OpenStack region. We should take
571619// a list of regions (from config) and query/create loadbalancers in
@@ -596,7 +644,13 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
596644 }
597645
598646 floatingPool := getStringFromServiceAnnotation (apiService , ServiceAnnotationLoadBalancerFloatingNetworkId , lbaas .opts .FloatingNetworkId )
599- glog .V (4 ).Infof ("EnsureLoadBalancer using floatingPool: %v" , floatingPool )
647+ if len (floatingPool ) == 0 {
648+ var err error
649+ floatingPool , err = getFloatingNetworkIdForLB (lbaas .network )
650+ if err != nil {
651+ glog .Warningf ("Failed to find floating-network-id for loadbalancer service %s/%s: %v" , apiService .Namespace , apiService .Name , err )
652+ }
653+ }
600654
601655 var internalAnnotation bool
602656 internal := getStringFromServiceAnnotation (apiService , ServiceAnnotationLoadBalancerInternal , "false" )
@@ -606,7 +660,7 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
606660 internalAnnotation = true
607661 case "false" :
608662 if len (floatingPool ) != 0 {
609- glog .V (4 ).Infof ("Ensure an external loadbalancer service." )
663+ glog .V (4 ).Infof ("Ensure an external loadbalancer service, using floatingPool: %v" , floatingPool )
610664 internalAnnotation = false
611665 } else {
612666 return nil , fmt .Errorf ("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when ensuring an external loadbalancer service" )
0 commit comments