@@ -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
@@ -560,6 +562,52 @@ func getNodeSecurityGroupIDForLB(compute *gophercloud.ServiceClient, nodes []*v1
560562 return nodeSecurityGroupIDs .List (), nil
561563}
562564
565+ // getFloatingNetworkIdForLB returns a floating-network-id for cluster.
566+ func getFloatingNetworkIdForLB (client * gophercloud.ServiceClient ) (string , error ) {
567+ var floatingNetworkIds []string
568+
569+ type NetworkWithExternalExt struct {
570+ networks.Network
571+ external.NetworkExternalExt
572+ }
573+
574+ err := networks .List (client , networks.ListOpts {}).EachPage (func (page pagination.Page ) (bool , error ) {
575+ var externalNetwork []NetworkWithExternalExt
576+ err := networks .ExtractNetworksInto (page , & externalNetwork )
577+ if err != nil {
578+ return false , err
579+ }
580+
581+ for _ , externalNet := range externalNetwork {
582+ if externalNet .External {
583+ floatingNetworkIds = append (floatingNetworkIds , externalNet .ID )
584+ }
585+ }
586+
587+ if len (floatingNetworkIds ) > 1 {
588+ return false , ErrMultipleResults
589+ }
590+ return true , nil
591+ })
592+ if err != nil {
593+ if isNotFound (err ) {
594+ return "" , ErrNotFound
595+ }
596+
597+ if err == ErrMultipleResults {
598+ glog .V (4 ).Infof ("find multiple external networks, pick the first one when there are no explicit configuration." )
599+ return floatingNetworkIds [0 ], nil
600+ }
601+ return "" , err
602+ }
603+
604+ if len (floatingNetworkIds ) == 0 {
605+ return "" , ErrNotFound
606+ }
607+
608+ return floatingNetworkIds [0 ], nil
609+ }
610+
563611// TODO: This code currently ignores 'region' and always creates a
564612// loadbalancer in only the current OpenStack region. We should take
565613// a list of regions (from config) and query/create loadbalancers in
@@ -590,7 +638,13 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
590638 }
591639
592640 floatingPool := getStringFromServiceAnnotation (apiService , ServiceAnnotationLoadBalancerFloatingNetworkId , lbaas .opts .FloatingNetworkId )
593- glog .V (4 ).Infof ("EnsureLoadBalancer using floatingPool: %v" , floatingPool )
641+ if len (floatingPool ) == 0 {
642+ var err error
643+ floatingPool , err = getFloatingNetworkIdForLB (lbaas .network )
644+ if err != nil {
645+ glog .Warningf ("Failed to find floating-network-id for loadbalancer service %s/%s: %v" , apiService .Namespace , apiService .Name , err )
646+ }
647+ }
594648
595649 var internalAnnotation bool
596650 internal := getStringFromServiceAnnotation (apiService , ServiceAnnotationLoadBalancerInternal , "false" )
@@ -600,7 +654,7 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
600654 internalAnnotation = true
601655 case "false" :
602656 if len (floatingPool ) != 0 {
603- glog .V (4 ).Infof ("Ensure an external loadbalancer service." )
657+ glog .V (4 ).Infof ("Ensure an external loadbalancer service, using floatingPool: %v" , floatingPool )
604658 internalAnnotation = false
605659 } else {
606660 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