Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit 68bea98

Browse files
author
Kubernetes Submit Queue
authored
Merge pull request #50739 from FengyunPan/auto-get-subnet-id
Automatic merge from submit-queue (batch tested with PRs 50769, 50739) Support autoprobing subnet-id for openstack cloud provider Currently if user doesn't specify subnet-id or specify a unsafe subnet-id, openstack cloud provider can't create a correct LoadBalancer service. Actually we can get it automatically. This patch do a improvement. This is a part of #50726 **Special notes for your reviewer**: /assign @dims /assign @anguslees **Release note**: ```release-note NONE ```
2 parents f031be0 + eba5d22 commit 68bea98

2 files changed

Lines changed: 56 additions & 10 deletions

File tree

pkg/cloudprovider/providers/openstack/openstack.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ type LoadBalancer struct {
7777

7878
type LoadBalancerOpts struct {
7979
LBVersion string `gcfg:"lb-version"` // overrides autodetection. v1 or v2
80-
SubnetId string `gcfg:"subnet-id"` // required
80+
SubnetId string `gcfg:"subnet-id"` // overrides autodetection.
8181
FloatingNetworkId string `gcfg:"floating-network-id"` // If specified, will create floating ip for loadbalancer, or do not create floating ip.
8282
LBMethod string `gcfg:"lb-method"` // default to ROUND_ROBIN.
8383
CreateMonitor bool `gcfg:"create-monitor"`
@@ -221,12 +221,6 @@ func readInstanceID() (string, error) {
221221
func checkOpenStackOpts(openstackOpts *OpenStack) error {
222222
lbOpts := openstackOpts.lbOpts
223223

224-
// subnet-id is required
225-
if len(lbOpts.SubnetId) == 0 {
226-
glog.Warningf("subnet-id not set in cloud provider config. " +
227-
"OpenStack Load balancer will not work.")
228-
}
229-
230224
// if need to create health monitor for Neutron LB,
231225
// monitor-delay, monitor-timeout and monitor-max-retries should be set.
232226
emptyDuration := MyDuration{}

pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)