in pkg/openstack/loadbalancer.go [573:662]
func (lbaas *LbaasV2) createFullyPopulatedOctaviaLoadBalancer(name, clusterName string, service *corev1.Service, nodes []*corev1.Node, svcConf *serviceConfig) (*loadbalancers.LoadBalancer, error) {
createOpts := loadbalancers.CreateOpts{
Name: name,
Description: fmt.Sprintf("Kubernetes external service %s/%s from cluster %s", service.Namespace, service.Name, clusterName),
Provider: lbaas.opts.LBProvider,
}
if svcConf.supportLBTags {
createOpts.Tags = []string{svcConf.lbName}
}
if svcConf.flavorID != "" {
createOpts.FlavorID = svcConf.flavorID
}
if svcConf.availabilityZone != "" {
createOpts.AvailabilityZone = svcConf.availabilityZone
}
vipPort := getStringFromServiceAnnotation(service, ServiceAnnotationLoadBalancerPortID, "")
lbClass := lbaas.opts.LBClasses[svcConf.configClassName]
if vipPort != "" {
createOpts.VipPortID = vipPort
} else {
if lbClass != nil && lbClass.SubnetID != "" {
createOpts.VipSubnetID = lbClass.SubnetID
} else {
createOpts.VipSubnetID = svcConf.lbSubnetID
}
if lbClass != nil && lbClass.NetworkID != "" {
createOpts.VipNetworkID = lbClass.NetworkID
} else if svcConf.lbNetworkID != "" {
createOpts.VipNetworkID = svcConf.lbNetworkID
} else {
klog.V(4).Infof("network-id parameter not passed, it will be inferred from subnet-id")
}
}
// For external load balancer, the LoadBalancerIP is a public IP address.
loadBalancerIP := service.Spec.LoadBalancerIP
if loadBalancerIP != "" && svcConf.internal {
createOpts.VipAddress = loadBalancerIP
}
for _, port := range service.Spec.Ports {
listenerCreateOpt := lbaas.buildListenerCreateOpt(port, svcConf)
members, newMembers, err := lbaas.buildBatchUpdateMemberOpts(port, nodes, svcConf)
if err != nil {
return nil, err
}
poolCreateOpt := lbaas.buildPoolCreateOpt(string(listenerCreateOpt.Protocol), service, svcConf)
poolCreateOpt.Members = members
// Pool name must be provided to create fully populated loadbalancer
poolCreateOpt.Name = fmt.Sprintf("%s_%d_pool", listenerCreateOpt.Protocol, int(port.Port))
var withHealthMonitor string
if svcConf.enableMonitor {
opts := lbaas.buildMonitorCreateOpts(svcConf, port)
poolCreateOpt.Monitor = &opts
withHealthMonitor = " with healthmonitor"
}
listenerCreateOpt.DefaultPool = &poolCreateOpt
createOpts.Listeners = append(createOpts.Listeners, listenerCreateOpt)
klog.V(2).Infof("Loadbalancer %s: adding pool%s using protocol %s with %d members", name, withHealthMonitor, poolCreateOpt.Protocol, len(newMembers))
}
mc := metrics.NewMetricContext("loadbalancer", "create")
loadbalancer, err := loadbalancers.Create(lbaas.lb, createOpts).Extract()
if mc.ObserveRequest(err) != nil {
var printObj interface{} = createOpts
if opts, err := json.Marshal(createOpts); err == nil {
printObj = string(opts)
}
return nil, fmt.Errorf("error creating loadbalancer %v: %v", printObj, err)
}
// In case subnet ID is not configured
if lbaas.opts.SubnetID == "" {
lbaas.opts.SubnetID = loadbalancer.VipSubnetID
svcConf.lbMemberSubnetID = loadbalancer.VipSubnetID
}
if err := openstackutil.WaitLoadbalancerActive(lbaas.lb, loadbalancer.ID); err != nil {
return nil, err
}
return loadbalancer, nil
}