mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-2692 Assigning LB rule for vm nic secondary ips
Conflicts: setup/db/db/schema-430to440.sql
This commit is contained in:
parent
c1085ed94b
commit
14a4dd116f
|
|
@ -94,7 +94,7 @@ public interface LoadBalancingRulesService {
|
|||
/**
|
||||
* Assign a virtual machine, or list of virtual machines, to a load balancer.
|
||||
*/
|
||||
boolean assignToLoadBalancer(long lbRuleId, List<Long> vmIds);
|
||||
boolean assignToLoadBalancer(long lbRuleId, List<Long> vmIds, Map<Long, List<String>> vmIdIpMap);
|
||||
|
||||
boolean assignSSLCertToLoadBalancerRule(Long lbRuleId, String certName, String publicCert, String privateKey);
|
||||
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ public class ApiConstants {
|
|||
public static final String VALUE = "value";
|
||||
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
|
||||
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
|
||||
public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
|
||||
|
||||
public static final String VLAN = "vlan";
|
||||
public static final String VLAN_RANGE = "vlanrange";
|
||||
public static final String REMOVE_VLAN = "removevlan";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.loadbalancer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -62,10 +67,12 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "the list of IDs of the virtual machine that are being assigned to the load balancer rule(i.e. virtualMachineIds=1,2,3)")
|
||||
private List<Long> virtualMachineIds;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID_IP, type = CommandType.MAP, description = "VM ID and IP map, vmidipmap[0].vmid=1 vmidipmap[0].ip=10.1.1.75")
|
||||
private Map vmIdIpMap;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -78,6 +85,10 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
return virtualMachineIds;
|
||||
}
|
||||
|
||||
public Map<Long, String> getVmIdIpMap() {
|
||||
return vmIdIpMap;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -106,10 +117,42 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd {
|
|||
return "applying instances for load balancer: " + getLoadBalancerId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")";
|
||||
}
|
||||
|
||||
|
||||
public Map<Long, List<String>> getVmIdIpListMap() {
|
||||
Map<Long, List<String>> vmIdIpsMap = null;
|
||||
if (vmIdIpMap != null && !vmIdIpMap.isEmpty()) {
|
||||
vmIdIpsMap = new HashMap<Long, List<String>>();
|
||||
Collection idIpsCollection = vmIdIpMap.values();
|
||||
Iterator iter = idIpsCollection.iterator();
|
||||
while (iter.hasNext()) {
|
||||
HashMap<String, String> idIpsMap = (HashMap<String, String>)iter.next();
|
||||
String vmId = idIpsMap.get("vmid");
|
||||
String vmIp = idIpsMap.get("vmip");
|
||||
|
||||
Long longVmId = new Long(vmId);
|
||||
|
||||
List<String> ipsList = null;
|
||||
if (vmIdIpsMap.containsKey(longVmId)) {
|
||||
ipsList = vmIdIpsMap.get(longVmId);
|
||||
} else {
|
||||
ipsList = new ArrayList<String>();
|
||||
}
|
||||
ipsList.add(vmIp);
|
||||
vmIdIpsMap.put(longVmId, ipsList);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vmIdIpsMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Load balancer Id: " + getLoadBalancerId() + " VmIds: " + StringUtils.join(getVirtualMachineIds(), ","));
|
||||
boolean result = _lbService.assignToLoadBalancer(getLoadBalancerId(), virtualMachineIds);
|
||||
|
||||
Map<Long, List<String>> vmIdIpsMap = getVmIdIpListMap();
|
||||
|
||||
boolean result = _lbService.assignToLoadBalancer(getLoadBalancerId(), virtualMachineIds, vmIdIpsMap);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -34,4 +34,6 @@ public interface LoadBalancerVMMapDao extends GenericDao<LoadBalancerVMMapVO, Lo
|
|||
LoadBalancerVMMapVO findByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId);
|
||||
|
||||
boolean isVmAttachedToLoadBalancer(long loadBalancerId);
|
||||
|
||||
List<LoadBalancerVMMapVO> listByInstanceIp(String instanceIp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase<LoadBalancerVMMapVO
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoadBalancerVMMapVO> listByInstanceIp(String instanceIp) {
|
||||
SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
|
||||
sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoadBalancerVMMapVO> listByLoadBalancerId(long loadBalancerId) {
|
||||
SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ public class LoadBalancerVMMapVO implements InternalIdentity {
|
|||
@Column(name = "instance_id")
|
||||
private long instanceId;
|
||||
|
||||
@Column(name = "instance_ip")
|
||||
private String instanceIp;
|
||||
|
||||
@Column(name = "revoke")
|
||||
private boolean revoke = false;
|
||||
|
||||
|
|
@ -59,6 +62,13 @@ public class LoadBalancerVMMapVO implements InternalIdentity {
|
|||
this.revoke = revoke;
|
||||
}
|
||||
|
||||
public LoadBalancerVMMapVO(long loadBalancerId, long instanceId, String vmIp, boolean revoke) {
|
||||
this.loadBalancerId = loadBalancerId;
|
||||
this.instanceId = instanceId;
|
||||
this.instanceIp = vmIp;
|
||||
this.revoke = revoke;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
|
|
@ -87,4 +97,13 @@ public class LoadBalancerVMMapVO implements InternalIdentity {
|
|||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getInstanceIp() {
|
||||
return instanceIp;
|
||||
}
|
||||
|
||||
public void setInstanceIp(String instanceIp) {
|
||||
this.instanceIp = instanceIp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,10 +113,12 @@ import com.cloud.network.dao.NetworkVO;
|
|||
import com.cloud.network.dao.OvsProviderDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapVO;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.OvsProviderVO;
|
||||
import com.cloud.network.element.VirtualRouterElement;
|
||||
|
|
@ -307,6 +309,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
IpAddressManager _ipAddrMgr;
|
||||
@Inject
|
||||
EntityManager _entityMgr;
|
||||
@Inject
|
||||
LoadBalancerVMMapDao _lbVmMapDao;
|
||||
|
||||
int _cidrLimit;
|
||||
boolean _allowSubdomainNetworkAccess;
|
||||
|
|
@ -806,7 +810,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
|
||||
throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
|
||||
}
|
||||
} else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
|
||||
|
||||
List<LoadBalancerVMMapVO> lbVmMap = _lbVmMapDao.listByInstanceIp(secondaryIp);
|
||||
if (lbVmMap != null && lbVmMap.size() != 0) {
|
||||
s_logger.debug("VM nic IP " + secondaryIp + " is mapped to load balancing rule");
|
||||
throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is mapped to load balancing rule");
|
||||
|
||||
}
|
||||
|
||||
} else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
|
||||
final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address());
|
||||
if (ip != null) {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
|
|
@ -3819,12 +3831,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
|||
PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId);
|
||||
DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId());
|
||||
if (dvo.getNetworkType() == NetworkType.Basic) {
|
||||
|
||||
Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider");
|
||||
if (provider == null) {
|
||||
|
||||
Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider");
|
||||
if (provider == null) {
|
||||
// baremetal is not loaded
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalDhcpProvider", null, null);
|
||||
addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
|
||||
|
|
|
|||
|
|
@ -1414,7 +1414,7 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
|
|||
}
|
||||
}
|
||||
lstVmId.add(new Long(vmId));
|
||||
return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId);
|
||||
return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId, null);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.Set;
|
|||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
|
||||
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
|
||||
|
|
@ -258,6 +259,9 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
@Inject
|
||||
LoadBalancerCertMapDao _lbCertMapDao;
|
||||
|
||||
@Inject
|
||||
NicSecondaryIpDao _nicSecondaryIpDao;
|
||||
|
||||
// Will return a string. For LB Stickiness this will be a json, for
|
||||
// autoscale this will be "," separated values
|
||||
@Override
|
||||
|
|
@ -923,7 +927,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true)
|
||||
public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds) {
|
||||
public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds, Map<Long, List<String>> vmIdIpMap) {
|
||||
CallContext ctx = CallContext.current();
|
||||
Account caller = ctx.getCallingAccount();
|
||||
|
||||
|
|
@ -932,22 +936,68 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found.");
|
||||
}
|
||||
|
||||
|
||||
if (instanceIds == null && vmIdIpMap == null) {
|
||||
throw new InvalidParameterValueException("Both instanceids and vmidipmap can't be null");
|
||||
}
|
||||
|
||||
// instanceIds and vmIdipmap is passed
|
||||
if (instanceIds != null && vmIdIpMap != null) {
|
||||
for(long instanceId: instanceIds) {
|
||||
if (!vmIdIpMap.containsKey(instanceId)) {
|
||||
vmIdIpMap.put(instanceId, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//only instanceids list passed
|
||||
if (instanceIds != null && vmIdIpMap == null){
|
||||
vmIdIpMap = new HashMap<Long, List<String>>();
|
||||
for (long instanceId: instanceIds){
|
||||
vmIdIpMap.put(instanceId, null);
|
||||
}
|
||||
}
|
||||
|
||||
List<LoadBalancerVMMapVO> mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false);
|
||||
Set<Long> mappedInstanceIds = new HashSet<Long>();
|
||||
for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
|
||||
mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId()));
|
||||
}
|
||||
|
||||
final List<UserVm> vmsToAdd = new ArrayList<UserVm>();
|
||||
Map<Long, List<String>> existingVmIdIps = new HashMap<Long, List<String>>();
|
||||
// now get the ips of vm and add it to map
|
||||
for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
|
||||
|
||||
if (instanceIds == null || instanceIds.isEmpty()) {
|
||||
s_logger.warn("List of vms to assign to the lb, is empty");
|
||||
return false;
|
||||
List<String> ipsList = null;
|
||||
if (existingVmIdIps.containsKey(mappedInstance.getInstanceId())) {
|
||||
ipsList = existingVmIdIps.get(mappedInstance.getInstanceId());
|
||||
} else {
|
||||
ipsList = new ArrayList<String>();
|
||||
}
|
||||
ipsList.add(mappedInstance.getInstanceIp());
|
||||
existingVmIdIps.put(mappedInstance.getInstanceId(), ipsList);
|
||||
}
|
||||
|
||||
for (Long instanceId : instanceIds) {
|
||||
if (mappedInstanceIds.contains(instanceId)) {
|
||||
throw new InvalidParameterValueException("VM " + instanceId + " is already mapped to load balancer.");
|
||||
|
||||
|
||||
|
||||
final List<UserVm> vmsToAdd = new ArrayList<UserVm>();
|
||||
|
||||
// check for conflict
|
||||
Set<Long> passedInstanceIds = vmIdIpMap.keySet();
|
||||
for (Long instanceId : passedInstanceIds) {
|
||||
if (existingVmIdIps.containsKey(instanceId)) {
|
||||
// now check for ip address
|
||||
List<String> mappedIps = existingVmIdIps.get(instanceId);
|
||||
List<String> newIps = vmIdIpMap.get(instanceId);
|
||||
|
||||
if (newIps != null) {
|
||||
for (String newIp: newIps) {
|
||||
if (mappedIps.contains(newIp)) {
|
||||
throw new InvalidParameterValueException("VM " + instanceId + " with " + newIp +" is already mapped to load balancer.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UserVm vm = _vmDao.findById(instanceId);
|
||||
|
|
@ -985,18 +1035,43 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
throw ex;
|
||||
}
|
||||
|
||||
String priIp = nicInSameNetwork.getIp4Address();
|
||||
List<String> vmIpsList = vmIdIpMap.get(instanceId);
|
||||
String vmLbIp = null;
|
||||
|
||||
if (vmIpsList == null) {
|
||||
vmIpsList = new ArrayList<String>();
|
||||
vmIpsList.add(priIp);
|
||||
vmIdIpMap.put(instanceId, vmIpsList);
|
||||
} else {
|
||||
//check if the ips belongs to nic secondary ip
|
||||
for (String ip: vmIpsList) {
|
||||
if(_nicSecondaryIpDao.findByIp4AddressAndNicId(ip,nicInSameNetwork.getId()) == null) {
|
||||
throw new InvalidParameterValueException("VM ip specified " + ip + " is not belongs to nic in network " + nicInSameNetwork.getNetworkId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Adding " + vm + " to the load balancer pool");
|
||||
}
|
||||
vmsToAdd.add(vm);
|
||||
}
|
||||
|
||||
final Set<Long> vmIds = vmIdIpMap.keySet();
|
||||
final Map<Long, List<String>> newMap = vmIdIpMap;
|
||||
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
for (UserVm vm : vmsToAdd) {
|
||||
LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false);
|
||||
|
||||
for (Long vmId : vmIds) {
|
||||
final List<String> lbVmIps = newMap.get(vmId);
|
||||
for (String vmIp: lbVmIps) {
|
||||
LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vmId, vmIp, false);
|
||||
map = _lb2VmMapDao.persist(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1020,8 +1095,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
for (UserVm vm : vmsToAdd) {
|
||||
vmInstanceIds.add(vm.getId());
|
||||
for (Long vmId : vmIds) {
|
||||
vmInstanceIds.add(vmId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1875,7 +1950,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
|
||||
UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
|
||||
Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId());
|
||||
dstIp = nic.getIp4Address();
|
||||
dstIp = lbVmMap.getInstanceIp() == null ? nic.getIp4Address(): lbVmMap.getInstanceIp();
|
||||
LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke());
|
||||
dstList.add(lbDst);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,3 +748,5 @@ ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_region_level_vpc boolean
|
|||
ALTER TABLE `cloud`.`network_offerings` ADD COLUMN supports_streched_l2 boolean default false;
|
||||
ALTER TABLE `cloud`.`networks` ADD COLUMN streched_l2 boolean default false;
|
||||
ALTER TABLE `cloud`.`vpc` ADD COLUMN region_level_vpc boolean default false;
|
||||
ALTER TABLE `cloud`.`load_balancer_vm_map` ADD COLUMN instance_ip VARCHAR(40);
|
||||
ALTER TABLE `cloud`.`load_balancer_vm_map` DROP KEY `load_balancer_id`, ADD UNIQUE KEY load_balancer_id (`load_balancer_id`, `instance_id`, `instance_ip`);
|
||||
Loading…
Reference in New Issue