bug 4706: allow to specify which ip address from the network to take when do vm deployment. The model is supported for multiple network case as well.

status 4706: resolved fixed
This commit is contained in:
alena 2011-06-21 16:11:56 -07:00
parent 2ed1afa14e
commit 4fcb406f2b
14 changed files with 157 additions and 48 deletions

View File

@ -246,4 +246,5 @@ public class ApiConstants {
public static final String SNAPSHOT_POLICY = "snapshotpolicy";
public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
public static final String REDUNDANT_ROUTER = "redundantrouter";
public static final String IP_NETWORK_LIST = "iptonetworklist";
}

View File

@ -19,7 +19,11 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
@ -79,7 +83,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
private Long domainId;
//Network information
@Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids used by virtual machine")
@Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
private List<Long> networkIds;
//DataDisk information
@ -109,6 +113,9 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
@Parameter(name=ApiConstants.SECURITY_GROUP_NAMES, type=CommandType.LIST, collectionType=CommandType.STRING, description="comma separated list of security groups names that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupids parameter")
private List<String> securityGroupNameList;
@Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP, description = "ip to network mapping. Can't be specified with networkIds parameter. Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].networkid=204 - requests to use ip 10.10.10.11 in network id=204")
private Map ipToNetworkList;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -187,6 +194,16 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
}
public List<Long> getNetworkIds() {
if (ipToNetworkList != null ) {
if (networkIds != null) {
throw new InvalidParameterValueException("NetworkIds can't be specified along with ipToNetworkMap");
} else {
List<Long> networks = new ArrayList<Long>();
networks.addAll(getIpToNetworkMap().keySet());
return networks;
}
}
return networkIds;
}
@ -201,6 +218,27 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
public Long getHostId() {
return hostId;
}
private Map<Long, String> getIpToNetworkMap() {
if (networkIds != null && ipToNetworkList != null) {
throw new InvalidParameterValueException("NetworkIds can't be specified along with ipToNetworkMap");
}
Map<Long, String> ipToNetworkMap = null;
if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
ipToNetworkMap = new HashMap<Long, String>();
Collection ipsCollection = ipToNetworkList.values();
Iterator iter = ipsCollection.iterator();
while (iter.hasNext()) {
HashMap<String, String> ips = (HashMap<String, String>) iter.next();
Long networkId = Long.valueOf(ips.get("networkid"));
String requestedIp = (String) ips.get("ip");
ipToNetworkMap.put(networkId, requestedIp);
}
}
return ipToNetworkMap;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
@ -322,18 +360,18 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
} else {
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName);
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap());
}
} else {
if (zone.isSecurityGroupEnabled()) {
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName);
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap());
} else {
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
}
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName);
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap());
}
}
}

View File

@ -55,6 +55,7 @@ public class NicProfile {
Integer networkRate;
boolean isSecurityGroupEnabled;
List<String> tags;
String requestedIp;
public String getDns1() {
return dns1;
@ -254,6 +255,10 @@ public class NicProfile {
this.netmask = netmask;
this.strategy = strategy;
}
public NicProfile(String requestedIp) {
this.requestedIp = requestedIp;
}
public NicProfile() {
}
@ -278,6 +283,10 @@ public class NicProfile {
this.isSecurityGroupEnabled = enabled;
}
public String getRequestedIp() {
return requestedIp;
}
public void deallocate() {
this.gateway = null;
this.mode = null;

View File

@ -18,6 +18,7 @@
package com.cloud.vm;
import java.util.List;
import java.util.Map;
import javax.naming.InsufficientResourcesException;
@ -145,10 +146,6 @@ public interface UserVmService {
* - the template for the virtual machine
* @param securityGroupIdList
* - comma separated list of security groups id that going to be applied to the virtual machine
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @param hostName
* - host name for the virtual machine
* @param displayName
@ -171,7 +168,11 @@ public interface UserVmService {
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
*
* @param requestedIps TODO
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
@ -183,7 +184,7 @@ public interface UserVmService {
* @throws InsufficientResourcesException
*/
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
@ -199,10 +200,6 @@ public interface UserVmService {
* - list of network ids used by virtual machine
* @param securityGroupIdList
* - comma separated list of security groups id that going to be applied to the virtual machine
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @param hostName
* - host name for the virtual machine
* @param displayName
@ -225,7 +222,11 @@ public interface UserVmService {
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
*
* @param requestedIps TODO
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
@ -237,7 +238,7 @@ public interface UserVmService {
* @throws InsufficientResourcesException
*/
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, List<Long> securityGroupIdList,
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair)
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
@ -251,10 +252,6 @@ public interface UserVmService {
* - the template for the virtual machine
* @param networkIdList
* - list of network ids used by virtual machine
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @param hostName
* - host name for the virtual machine
* @param displayName
@ -277,7 +274,11 @@ public interface UserVmService {
* GET (via querystring), you can send up to 2KB of data after base64 encoding
* @param sshKeyPair
* - name of the ssh key pair used to login to the virtual machine
*
* @param requestedIps TODO
* @param accountName
* - an optional account for the virtual machine. Must be used with domainId
* @param domainId
* - an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used
* @return UserVm object if successful.
*
* @throws InsufficientCapacityException
@ -289,7 +290,7 @@ public interface UserVmService {
* @throws InsufficientResourcesException
*/
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**

View File

@ -62,10 +62,11 @@ public interface NetworkManager extends NetworkService {
* @param owner
* @param type
* @param networkId
* @param requestedIp TODO
* @return
* @throws InsufficientAddressCapacityException
*/
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException;
PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp) throws InsufficientAddressCapacityException;
/**
* assigns a source nat ip address to an account within a network.
@ -204,5 +205,5 @@ public interface NetworkManager extends NetworkService {
IPAddressVO markIpAsUnavailable(long addrId);
public String acquireGuestIpAddress(Network network);
public String acquireGuestIpAddress(Network network, String requestedIp);
}

View File

@ -239,25 +239,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
@Override
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException {
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true);
public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp) throws InsufficientAddressCapacityException {
return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp);
}
@DB
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign)
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign, String requestedIp)
throws InsufficientAddressCapacityException {
StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<IPAddressVO> sc = null;
if (podId != null) {
sc = AssignIpAddressFromPodVlanSearch.create();
sc.setJoinParameters("podVlanMapSB", "podId", podId);
errorMessage.append(" pod id=" + podId);
} else {
sc = AssignIpAddressSearch.create();
errorMessage.append(" zone id=" + dcId);
}
if (vlanDbId != null) {
sc.addAnd("vlanId", SearchCriteria.Op.EQ, vlanDbId);
errorMessage.append(", vlanId id=" + vlanDbId);
}
sc.setParameters("dc", dcId);
@ -265,8 +269,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
// for direct network take ip addresses only from the vlans belonging to the network
if (vlanUse == VlanType.DirectAttached) {
sc.setJoinParameters("vlan", "networkId", networkId);
errorMessage.append(", network id=" + networkId);
}
sc.setJoinParameters("vlan", "type", vlanUse);
if (requestedIp != null) {
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
errorMessage.append(": requested ip " + requestedIp + " is not available");
}
Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
@ -274,8 +285,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (addrs.size() == 0) {
if (podId != null) {
s_logger.warn(errorMessage.toString());
throw new InsufficientAddressCapacityException("Insufficient address capacity", HostPodDao.class, podId);
}
s_logger.warn(errorMessage.toString());
throw new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
}
@ -380,7 +393,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
vlanId = maps.get(0).getVlanDbId();
}
ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false);
ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false, null);
sourceNat = ip.ip();
markPublicIpAsAllocated(sourceNat);
@ -592,7 +605,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
ip = fetchNewPublicIp(zoneId, null, null, ipOwner, VlanType.VirtualNetwork, network.getId(), isSourceNat, false);
ip = fetchNewPublicIp(zoneId, null, null, ipOwner, VlanType.VirtualNetwork, network.getId(), isSourceNat, false, null);
if (ip == null) {
throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zoneId);
@ -2985,12 +2998,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
@DB
public String acquireGuestIpAddress(Network network) {
public String acquireGuestIpAddress(Network network, String requestedIp) {
List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
String[] cidr = network.getCidr().split("/");
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
Set<Long> usedIps = new TreeSet<Long>();
if (requestedIp != null && requestedIp.equals(network.getGateway())) {
s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network);
return null;
}
for (String ip : ips) {
if (requestedIp != null && requestedIp.equals(ip)) {
s_logger.warn("Requested ip address " + requestedIp + " is already in use in network " + network);
return null;
}
usedIps.add(NetUtils.ip2Long(ip));
}
if (usedIps.size() != 0) {
@ -2999,7 +3023,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (allPossibleIps.isEmpty()) {
return null;
}
Long[] array = allPossibleIps.toArray(new Long[allPossibleIps.size()]);
if (requestedIp != null) {
//check that requested ip has the same cidr
boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1]));
if (!isSameCidr) {
s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr");
return null;
} else {
return requestedIp;
}
}
String result;
do {
result = NetUtils.long2Ip(array[_rand.nextInt(array.length)]);

View File

@ -137,10 +137,10 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
super();
}
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network) throws InsufficientVirtualNetworkCapcityException,
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network, String requestedIp) throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId());
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIp);
nic.setIp4Address(ip.getAddress().toString());
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());
@ -183,7 +183,7 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setStrategy(ReservationStrategy.Create);
}
getIp(nic, dc, vm, network);
getIp(nic, dc, vm, network, nic.getRequestedIp());
nic.setStrategy(ReservationStrategy.Create);
return nic;
@ -193,7 +193,7 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
public void reserve(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
getIp(nic, dest.getDataCenter(), vm, network);
getIp(nic, dest.getDataCenter(), vm, network, null);
nic.setStrategy(ReservationStrategy.Create);
}
}

View File

@ -47,6 +47,7 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.utils.component.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
@ -95,6 +96,10 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
if (!canHandle(offering, dc)) {
return null;
}
if (nic != null && nic.getRequestedIp() != null) {
throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
}
if (nic == null) {
nic = new NicProfile(rsStrategy, null, null, null, null);
@ -127,7 +132,7 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
InsufficientAddressCapacityException, ConcurrentOperationException {
DataCenter dc = _dcDao.findById(pod.getDataCenterId());
if (nic.getIp4Address() == null) {
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId());
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null);
nic.setIp4Address(ip.getAddress().toString());
nic.setFormat(AddressFormat.Ip4);
nic.setGateway(ip.getGateway());

View File

@ -181,7 +181,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setIsolationUri(network.getBroadcastUri());
nic.setGateway(network.getGateway());
String guestIp = _networkMgr.acquireGuestIpAddress(network);
String guestIp = _networkMgr.acquireGuestIpAddress(network, nic.getRequestedIp());
if (guestIp == null) {
throw new InsufficientVirtualNetworkCapcityException("Unable to acquire guest IP address for network " + network, DataCenter.class, dc.getId());
}
@ -192,7 +192,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setDns1(dc.getDns1());
nic.setDns2(dc.getDns2());
}
}
nic.setStrategy(ReservationStrategy.Start);

View File

@ -46,6 +46,7 @@ import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicProfile;
@ -87,6 +88,9 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
assert (trafficType == TrafficType.Storage || trafficType == TrafficType.Management) : "Well, I can't take care of this config now can I? " + config;
if (nic != null) {
if (nic.getRequestedIp() != null) {
throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
}
nic.setStrategy(nic.getIp4Address() != null ? ReservationStrategy.Create : ReservationStrategy.Start);
} else {
nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);

View File

@ -53,6 +53,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
@ -106,7 +107,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network) throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null);
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null, null);
nic.setIp4Address(ip.getAddress().toString());
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());
@ -140,6 +141,10 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
if (!canHandle(offering, dc)) {
return null;
}
if (nic != null && nic.getRequestedIp() != null) {
throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
}
if (nic == null) {
nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);

View File

@ -846,7 +846,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
networks.add(new Pair<NetworkVO, NicProfile>(publicNetworks.get(0), defaultNic));
NicProfile gatewayNic = new NicProfile();
if (isRedundant) {
gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork));
gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null));
gatewayNic.setMacAddress(_networkMgr.getNextAvailableMacAddressInNetwork(guestNetwork.getId()));
} else {
gatewayNic.setIp4Address(guestNetwork.getGateway());

View File

@ -18,8 +18,10 @@
package com.cloud.vm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -2010,7 +2012,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
@Override
public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair)
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2060,13 +2062,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller);
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps);
}
@Override
public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
String sshKeyPair) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
String sshKeyPair, Map<Long, String> requestedIps) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2171,12 +2173,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller);
diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps);
}
@Override
public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair)
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
Account caller = UserContext.current().getCaller();
@ -2289,13 +2291,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller);
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, userData, sshKeyPair, hypervisor, caller, requestedIps);
}
@DB
@ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId,
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, String> requestedIps) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
_accountMgr.checkAccess(caller, owner);
long accountId = owner.getId();
@ -2413,7 +2415,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
short defaultNetworkNumber = 0;
for (NetworkVO network : networkList) {
@ -2426,7 +2428,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
defaultNetworkNumber++;
}
networks.add(new Pair<NetworkVO, NicProfile>(network, null));
NicProfile profile = null;
if (requestedIps != null && requestedIps.get(network.getId()) != null) {
profile = new NicProfile(requestedIps.get(network.getId()));
}
networks.add(new Pair<NetworkVO, NicProfile>(network, profile));
}
// Verify network information - network default network has to be set; and vm can't have more than one default network

View File

@ -233,4 +233,6 @@ public class VirtualMachineProfileImpl<T extends VMInstanceVO> implements Virtua
public void setServiceOffering(ServiceOfferingVO offering) {
_offering = offering;
}
}