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

Merge from master to 2.2.8 branch

Conflicts:

	api/src/com/cloud/api/ApiConstants.java
	server/src/com/cloud/network/NetworkManager.java
	server/src/com/cloud/network/NetworkManagerImpl.java
	server/src/com/cloud/network/guru/GuestNetworkGuru.java
	server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
	server/src/com/cloud/vm/UserVmManagerImpl.java
This commit is contained in:
alena 2011-07-15 14:20:52 -07:00
parent 06ea7338a8
commit 0d2787e2db
14 changed files with 184 additions and 45 deletions

View File

@ -245,5 +245,6 @@ public class ApiConstants {
public static final String VOLUME_NAME = "volumename";
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;
@ -80,7 +84,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
@ -110,6 +114,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 ///////////////////////
@ -188,6 +195,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;
}
@ -202,6 +219,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///////////////////
@ -330,18 +368,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;
@ -144,10 +145,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
@ -170,7 +167,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
@ -182,7 +183,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;
/**
@ -198,10 +199,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
@ -224,7 +221,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
@ -236,7 +237,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;
/**
@ -250,10 +251,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
@ -276,7 +273,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
@ -288,7 +289,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

@ -61,10 +61,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.
@ -200,4 +201,6 @@ public interface NetworkManager extends NetworkService {
List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestIpType guestType, Boolean isDefault);
IPAddressVO markIpAsUnavailable(long addrId);
public String acquireGuestIpAddress(Network network, String requestedIp);
}

View File

@ -28,7 +28,9 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -232,25 +234,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);
@ -258,8 +264,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);
@ -267,8 +280,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);
}
@ -373,7 +388,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);
@ -586,7 +601,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);
@ -2941,4 +2956,54 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
Random _rand = new Random(System.currentTimeMillis());
@Override
@DB
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) {
allPossibleIps.removeAll(usedIps);
}
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)]);
} while (result.split("\\.")[3].equals("1"));
return result;
}
}

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

@ -188,7 +188,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setIsolationUri(network.getBroadcastUri());
nic.setGateway(network.getGateway());
String guestIp = 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());
}
@ -199,7 +199,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

@ -739,6 +739,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
defaultNic.setDeviceId(2);
networks.add(new Pair<NetworkVO, NicProfile>(publicNetworks.get(0), defaultNic));
NicProfile gatewayNic = new NicProfile();
gatewayNic.setIp4Address(guestNetwork.getGateway());
gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri());
gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType());

View File

@ -2030,7 +2030,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();
@ -2082,13 +2082,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();
@ -2193,12 +2193,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();
@ -2317,12 +2317,12 @@ 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);
}
@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();
@ -2443,6 +2443,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
s_logger.debug("Allocating in the DB for vm");
List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
@ -2453,7 +2454,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;
}
}