@@ -570,6 +570,34 @@ func getStringFromServiceAnnotation(service *v1.Service, annotationKey string, d
570570 return defaultSetting
571571}
572572
573+ // getSubnetIDForLB returns subnet-id for a specific node
574+ func getSubnetIDForLB (compute * gophercloud.ServiceClient , node v1.Node ) (string , error ) {
575+ ipAddress , err := nodeAddressForLB (& node )
576+ if err != nil {
577+ return "" , err
578+ }
579+
580+ instanceID := node .Spec .ProviderID
581+ if ind := strings .LastIndex (instanceID , "/" ); ind >= 0 {
582+ instanceID = instanceID [(ind + 1 ):]
583+ }
584+
585+ interfaces , err := getAttachedInterfacesByID (compute , instanceID )
586+ if err != nil {
587+ return "" , err
588+ }
589+
590+ for _ , intf := range interfaces {
591+ for _ , fixedIP := range intf .FixedIPs {
592+ if fixedIP .IPAddress == ipAddress {
593+ return intf .NetID , nil
594+ }
595+ }
596+ }
597+
598+ return "" , ErrNotFound
599+ }
600+
573601// TODO: This code currently ignores 'region' and always creates a
574602// loadbalancer in only the current OpenStack region. We should take
575603// a list of regions (from config) and query/create loadbalancers in
@@ -579,7 +607,15 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv
579607 glog .V (4 ).Infof ("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)" , clusterName , apiService .Namespace , apiService .Name , apiService .Spec .LoadBalancerIP , apiService .Spec .Ports , nodes , apiService .Annotations )
580608
581609 if len (lbaas .opts .SubnetId ) == 0 {
582- return nil , fmt .Errorf ("subnet-id not set in cloud provider config" )
610+ // Get SubnetId automatically.
611+ // The LB needs to be configured with instance addresses on the same subnet, so get SubnetId by one node.
612+ subnetID , err := getSubnetIDForLB (lbaas .compute , * nodes [0 ])
613+ if err != nil {
614+ glog .Warningf ("Failed to find subnet-id for loadbalancer service %s/%s: %v" , apiService .Namespace , apiService .Name , err )
615+ return nil , fmt .Errorf ("No subnet-id for service %s/%s : subnet-id not set in cloud provider config, " +
616+ "and failed to find subnet-id from OpenStack: %v" , apiService .Namespace , apiService .Name , err )
617+ }
618+ lbaas .opts .SubnetId = subnetID
583619 }
584620
585621 ports := apiService .Spec .Ports
@@ -947,7 +983,15 @@ func (lbaas *LbaasV2) UpdateLoadBalancer(clusterName string, service *v1.Service
947983 glog .V (4 ).Infof ("UpdateLoadBalancer(%v, %v, %v)" , clusterName , loadBalancerName , nodes )
948984
949985 if len (lbaas .opts .SubnetId ) == 0 {
950- return fmt .Errorf ("subnet-id not set in cloud provider config" )
986+ // Get SubnetId automatically.
987+ // The LB needs to be configured with instance addresses on the same subnet, so get SubnetId by one node.
988+ subnetID , err := getSubnetIDForLB (lbaas .compute , * nodes [0 ])
989+ if err != nil {
990+ glog .Warningf ("Failed to find subnet-id for loadbalancer service %s/%s: %v" , service .Namespace , service .Name , err )
991+ return fmt .Errorf ("No subnet-id for service %s/%s : subnet-id not set in cloud provider config, " +
992+ "and failed to find subnet-id from OpenStack: %v" , service .Namespace , service .Name , err )
993+ }
994+ lbaas .opts .SubnetId = subnetID
951995 }
952996
953997 ports := service .Spec .Ports
@@ -1226,7 +1270,15 @@ func (lb *LbaasV1) EnsureLoadBalancer(clusterName string, apiService *v1.Service
12261270 glog .V (4 ).Infof ("EnsureLoadBalancer(%v, %v, %v, %v, %v, %v, %v)" , clusterName , apiService .Namespace , apiService .Name , apiService .Spec .LoadBalancerIP , apiService .Spec .Ports , nodes , apiService .Annotations )
12271271
12281272 if len (lb .opts .SubnetId ) == 0 {
1229- return nil , fmt .Errorf ("subnet-id not set in cloud provider config" )
1273+ // Get SubnetId automatically.
1274+ // The LB needs to be configured with instance addresses on the same subnet, so get SubnetId by one node.
1275+ subnetID , err := getSubnetIDForLB (lb .compute , * nodes [0 ])
1276+ if err != nil {
1277+ glog .Warningf ("Failed to find subnet-id for loadbalancer service %s/%s: %v" , apiService .Namespace , apiService .Name , err )
1278+ return nil , fmt .Errorf ("No subnet-id for service %s/%s : subnet-id not set in cloud provider config, " +
1279+ "and failed to find subnet-id from OpenStack: %v" , apiService .Namespace , apiService .Name , err )
1280+ }
1281+ lb .opts .SubnetId = subnetID
12301282 }
12311283
12321284 ports := apiService .Spec .Ports
0 commit comments