diff --git a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go index 722063bfe16..ca085890009 100644 --- a/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go +++ b/pkg/cloudprovider/providers/openstack/openstack_loadbalancer.go @@ -66,6 +66,8 @@ const ( activeStatus = "ACTIVE" errorStatus = "ERROR" + + ServiceAnnotationLoadBalancerFloatingNetworkId = "loadbalancer.openstack.org/floating-network-id" ) // LoadBalancer implementation for LBaaS v1 @@ -581,6 +583,21 @@ func nodeAddressForLB(node *v1.Node) (string, error) { return addrs[0].Address, nil } +//getStringFromServiceAnnotation searches a given v1.Service for a specific annotationKey and either returns the annotation's value or a specified defaultSetting +func getStringFromServiceAnnotation(service *v1.Service, annotationKey string, defaultSetting string) string { + glog.V(4).Infof("getStringFromServiceAnnotation(%v, %v, %v)", service, annotationKey, defaultSetting) + if annotationValue, ok := service.Annotations[annotationKey]; ok { + //if there is an annotation for this setting, set the "setting" var to it + // annotationValue can be empty, it is working as designed + // it makes possible for instance provisioning loadbalancer without floatingip + glog.V(4).Infof("Found a Service Annotation: %v = %v", annotationKey, annotationValue) + return annotationValue + } + //if there is no annotation, set "settings" var to the value from cloud config + glog.V(4).Infof("Could not find a Service Annotation; falling back on cloud-config setting: %v = %v", annotationKey, defaultSetting) + return defaultSetting +} + // 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 @@ -598,6 +615,9 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv return nil, fmt.Errorf("no ports provided to openstack load balancer") } + floatingPool := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerFloatingNetworkId, lbaas.opts.FloatingNetworkId) + glog.V(4).Infof("EnsureLoadBalancer using floatingPool: %v", floatingPool) + // Check for TCP protocol on each port // TODO: Convert all error messages to use an event recorder for _, port := range ports { @@ -827,10 +847,10 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(clusterName string, apiService *v1.Serv if err != nil && err != ErrNotFound { return nil, fmt.Errorf("Error getting floating ip for port %s: %v", portID, err) } - if floatIP == nil && lbaas.opts.FloatingNetworkId != "" { + if floatIP == nil && floatingPool != "" { glog.V(4).Infof("Creating floating ip for loadbalancer %s port %s", loadbalancer.ID, portID) floatIPOpts := floatingips.CreateOpts{ - FloatingNetworkID: lbaas.opts.FloatingNetworkId, + FloatingNetworkID: floatingPool, PortID: portID, } floatIP, err = floatingips.Create(lbaas.network, floatIPOpts).Extract()