Skip to content

Commit 2cbca37

Browse files
author
Sheng Yang
committed
IPv6: Add support for IPv6 on DeployVMCmd
1 parent 5b92c57 commit 2cbca37

10 files changed

Lines changed: 121 additions & 44 deletions

File tree

api/src/com/cloud/network/Network.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,33 @@ private State(String description) {
252252
s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented);
253253
}
254254
}
255-
255+
256+
public class IpAddresses {
257+
private String ip4Address;
258+
private String ip6Address;
259+
260+
public IpAddresses(String ip4Address, String ip6Address) {
261+
this.setIp4Address(ip4Address);
262+
this.setIp6Address(ip6Address);
263+
}
264+
265+
public String getIp4Address() {
266+
return ip4Address;
267+
}
268+
269+
public void setIp4Address(String ip4Address) {
270+
this.ip4Address = ip4Address;
271+
}
272+
273+
public String getIp6Address() {
274+
return ip6Address;
275+
}
276+
277+
public void setIp6Address(String ip6Address) {
278+
this.ip6Address = ip6Address;
279+
}
280+
}
281+
256282
String getName();
257283

258284
Mode getMode();

api/src/com/cloud/vm/UserVmService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.cloud.exception.VirtualMachineMigrationException;
4747
import com.cloud.host.Host;
4848
import com.cloud.hypervisor.Hypervisor.HypervisorType;
49+
import com.cloud.network.Network.IpAddresses;
4950
import com.cloud.offering.ServiceOffering;
5051
import com.cloud.storage.StoragePool;
5152
import com.cloud.storage.Volume;
@@ -197,7 +198,7 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
197198
* @throws InsufficientResourcesException
198199
*/
199200
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner, String hostName,
200-
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps, String defaultIp, String keyboard)
201+
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, String keyboard)
201202
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
202203

203204
/**
@@ -244,7 +245,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
244245
* - name of the ssh key pair used to login to the virtual machine
245246
* @param requestedIps
246247
* TODO
247-
* @param defaultIp
248+
* @param defaultIps
248249
* TODO
249250
* @param accountName
250251
* - an optional account for the virtual machine. Must be used with domainId
@@ -262,8 +263,8 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
262263
* @throws InsufficientResourcesException
263264
*/
264265
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, List<Long> securityGroupIdList,
265-
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps,
266-
String defaultIp, String keyboard)
266+
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps,
267+
IpAddresses defaultIps, String keyboard)
267268
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
268269

269270
/**
@@ -308,8 +309,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
308309
* - name of the ssh key pair used to login to the virtual machine
309310
* @param requestedIps
310311
* TODO
311-
* @param defaultIp
312-
* TODO
312+
* @param defaultIps TODO
313313
* @param accountName
314314
* - an optional account for the virtual machine. Must be used with domainId
315315
* @param domainId
@@ -326,7 +326,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
326326
* @throws InsufficientResourcesException
327327
*/
328328
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner, String hostName,
329-
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps, String defaultIp, String keyboard)
329+
String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, String keyboard)
330330
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
331331

332332
/**

api/src/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class ApiConstants {
9393
public static final String INTERNAL_DNS2 = "internaldns2";
9494
public static final String INTERVAL_TYPE = "intervaltype";
9595
public static final String IP_ADDRESS = "ipaddress";
96+
public static final String IP6_ADDRESS = "ip6address";
9697
public static final String IP_ADDRESS_ID = "ipaddressid";
9798
public static final String IS_ASYNC = "isasync";
9899
public static final String IP_AVAILABLE = "ipavailable";

api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import com.cloud.hypervisor.Hypervisor.HypervisorType;
5252
import com.cloud.network.IpAddress;
5353
import com.cloud.network.Network;
54+
import com.cloud.network.Network.IpAddresses;
5455
import com.cloud.offering.DiskOffering;
5556
import com.cloud.offering.ServiceOffering;
5657
import com.cloud.template.VirtualMachineTemplate;
@@ -148,12 +149,15 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
148149

149150
@Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP,
150151
description = "ip to network mapping. Can't be specified with networkIds parameter." +
151-
" Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].networkid=uuid - requests to use ip 10.10.10.11 in network id=uuid")
152+
" Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid - requests to use ip 10.10.10.11 in network id=uuid")
152153
private Map ipToNetworkList;
153154

154155
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="the ip address for default vm's network")
155156
private String ipAddress;
156157

158+
@Parameter(name=ApiConstants.IP6_ADDRESS, type=CommandType.STRING, description="the ipv6 address for default vm's network")
159+
private String ip6Address;
160+
157161
@Parameter(name=ApiConstants.KEYBOARD, type=CommandType.STRING, description="an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us")
158162
private String keyboard;
159163

@@ -244,7 +248,7 @@ public Long getZoneId() {
244248

245249
public List<Long> getNetworkIds() {
246250
if (ipToNetworkList != null) {
247-
if (networkIds != null || ipAddress != null) {
251+
if (networkIds != null || ipAddress != null || ip6Address != null) {
248252
throw new InvalidParameterValueException("ipToNetworkMap can't be specified along with networkIds or ipAddress");
249253
} else {
250254
List<Long> networks = new ArrayList<Long>();
@@ -271,13 +275,13 @@ public boolean getStartVm() {
271275
return startVm == null ? true : startVm;
272276
}
273277

274-
private Map<Long, String> getIpToNetworkMap() {
275-
if ((networkIds != null || ipAddress != null) && ipToNetworkList != null) {
278+
private Map<Long, IpAddresses> getIpToNetworkMap() {
279+
if ((networkIds != null || ipAddress != null || ip6Address != null) && ipToNetworkList != null) {
276280
throw new InvalidParameterValueException("NetworkIds and ipAddress can't be specified along with ipToNetworkMap parameter");
277281
}
278-
LinkedHashMap<Long, String> ipToNetworkMap = null;
282+
LinkedHashMap<Long, IpAddresses> ipToNetworkMap = null;
279283
if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
280-
ipToNetworkMap = new LinkedHashMap<Long, String>();
284+
ipToNetworkMap = new LinkedHashMap<Long, IpAddresses>();
281285
Collection ipsCollection = ipToNetworkList.values();
282286
Iterator iter = ipsCollection.iterator();
283287
while (iter.hasNext()) {
@@ -294,7 +298,9 @@ private Map<Long, String> getIpToNetworkMap() {
294298
}
295299
}
296300
String requestedIp = (String) ips.get("ip");
297-
ipToNetworkMap.put(networkId, requestedIp);
301+
String requestedIpv6 = (String) ips.get("ipv6");
302+
IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6);
303+
ipToNetworkMap.put(networkId, addrs);
298304
}
299305
}
300306

@@ -428,23 +434,24 @@ public void create() throws ResourceAllocationException{
428434
if (getHypervisor() == HypervisorType.BareMetal) {
429435
vm = _bareMetalVmService.createVirtualMachine(this);
430436
} else {
437+
IpAddresses addrs = new IpAddresses(ipAddress, ip6Address);
431438
if (zone.getNetworkType() == NetworkType.Basic) {
432439
if (getNetworkIds() != null) {
433440
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
434441
} else {
435442
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
436-
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
443+
displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
437444
}
438445
} else {
439446
if (zone.isSecurityGroupEnabled()) {
440447
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
441-
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
448+
owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
442449
} else {
443450
if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
444451
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
445452
}
446453
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
447-
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
454+
diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), addrs, keyboard);
448455
}
449456
}
450457
}

server/src/com/cloud/network/NetworkManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,6 @@ Map<String, String> finalizeServicesAndProvidersForNetwork(NetworkOffering offer
329329
LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network);
330330

331331
PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, Account owner,
332-
VlanType type, Long networkId, String requestedIp, boolean isSystem)
332+
VlanType type, Long networkId, String requestedIp6, boolean isSystem)
333333
throws InsufficientAddressCapacityException;
334334
}

server/src/com/cloud/network/NetworkManagerImpl.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,17 +298,38 @@ public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, Vlan
298298
}
299299

300300
@Override
301-
public PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException {
301+
public PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp6, boolean isSystem) throws InsufficientAddressCapacityException {
302302
Vlan vlan = _networkModel.getVlanForNetwork(networkId);
303303
if (vlan == null) {
304304
s_logger.debug("Cannot find related vlan or too many vlan attached to network " + networkId);
305305
return null;
306306
}
307-
String ip = NetUtils.getIp6FromRange(vlan.getIp6Range());
308-
//Check for duplicate IP
309-
if (_ipv6Dao.findByDcIdAndIp(dcId, ip) != null) {
310-
//TODO regenerate ip
311-
throw new CloudRuntimeException("Fail to get unique ipv6 address");
307+
//TODO should check before this point
308+
if (!NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) {
309+
throw new CloudRuntimeException("Requested IPv6 is not in the predefined range!");
310+
}
311+
String ip = null;
312+
if (requestedIp6 == null) {
313+
int count = 0;
314+
while (ip == null || count >= 10) {
315+
ip = NetUtils.getIp6FromRange(vlan.getIp6Range());
316+
//Check for duplicate IP
317+
if (_ipv6Dao.findByDcIdAndIp(dcId, ip) == null) {
318+
break;
319+
} else {
320+
ip = null;
321+
}
322+
count ++;
323+
}
324+
if (ip == null) {
325+
throw new CloudRuntimeException("Fail to get unique ipv6 address after 10 times trying!");
326+
}
327+
} else {
328+
ip = requestedIp6;
329+
//TODO should check before this point
330+
if (_ipv6Dao.findByDcIdAndIp(dcId, ip) != null) {
331+
throw new CloudRuntimeException("The requested IP is already taken!");
332+
}
312333
}
313334
DataCenterVO dc = _dcDao.findById(dcId);
314335
Long mac = dc.getMacAddress();

server/src/com/cloud/network/PublicIpv6AddressVO.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public class PublicIpv6AddressVO implements PublicIpv6Address {
3939
@Column(name="id")
4040
long id;
4141

42-
@Id
4342
@Column(name="ip_address")
4443
@Enumerated(value=EnumType.STRING)
4544
private String address = null;

0 commit comments

Comments
 (0)