You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ap...@apache.org on 2013/04/17 06:50:28 UTC
git commit: updated refs/heads/master to 8b40e39
Updated Branches:
refs/heads/master 2057221f4 -> 8b40e393b
Cloudstack-701 Support for non contiguous vlan ranges.
Signed-off-by: Abhinandan Prateek <ap...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8b40e393
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8b40e393
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8b40e393
Branch: refs/heads/master
Commit: 8b40e393b845c4c3d7ca23c8e297dc43288f6863
Parents: 2057221
Author: Bharat Kumar <bh...@citrix.com>
Authored: Tue Apr 16 20:04:46 2013 +0530
Committer: Abhinandan Prateek <ap...@apache.org>
Committed: Wed Apr 17 10:14:42 2013 +0530
----------------------------------------------------------------------
api/src/com/cloud/network/NetworkService.java | 2 +-
api/src/com/cloud/network/PhysicalNetwork.java | 5 +-
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
.../admin/network/UpdatePhysicalNetworkCmd.java | 8 +-
server/src/com/cloud/api/ApiResponseHelper.java | 2 +-
.../configuration/ConfigurationManagerImpl.java | 2 +-
server/src/com/cloud/dc/dao/DataCenterVnetDao.java | 6 +
.../com/cloud/dc/dao/DataCenterVnetDaoImpl.java | 50 +++-
.../network/ExternalFirewallDeviceManagerImpl.java | 14 +-
.../src/com/cloud/network/NetworkServiceImpl.java | 289 +++++++++++----
.../com/cloud/network/dao/PhysicalNetworkVO.java | 20 +-
.../com/cloud/network/guru/GuestNetworkGuru.java | 14 +-
.../com/cloud/network/MockNetworkManagerImpl.java | 2 +-
.../cloud/network/UpdatePhysicalNetworkTest.java | 68 ++++
.../test/com/cloud/vpc/MockNetworkManagerImpl.java | 2 +-
test/integration/smoke/test_non_contigiousvlan.py | 125 +++++++
16 files changed, 512 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/api/src/com/cloud/network/NetworkService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java
index 066009b..5a6054d 100755
--- a/api/src/com/cloud/network/NetworkService.java
+++ b/api/src/com/cloud/network/NetworkService.java
@@ -79,7 +79,7 @@ public interface NetworkService {
Long startIndex, Long pageSize, String name);
PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags,
- String newVnetRangeString, String state);
+ String newVnetRangeString, String state, String removeVlan);
boolean deletePhysicalNetwork(Long id);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/api/src/com/cloud/network/PhysicalNetwork.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java
index a2044a6..c521dc4 100644
--- a/api/src/com/cloud/network/PhysicalNetwork.java
+++ b/api/src/com/cloud/network/PhysicalNetwork.java
@@ -18,6 +18,7 @@ package com.cloud.network;
import java.util.List;
+import com.cloud.utils.Pair;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
@@ -59,7 +60,9 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
Long getDomainId();
- String getVnet();
+ List<Pair<Integer,Integer>> getVnet();
+
+ String getVnetString();
String getSpeed();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index cb4d43e..8c32bb3 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -221,6 +221,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
public static final String VLAN = "vlan";
+ public static final String REMOVE_VLAN="removevlan";
public static final String VLAN_ID = "vlanid";
public static final String VM_AVAILABLE = "vmavailable";
public static final String VM_LIMIT = "vmlimit";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
index 06cf38d..6d37dd8 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
@@ -54,6 +54,8 @@ public class UpdatePhysicalNetworkCmd extends BaseAsyncCmd {
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the VLAN for the physical network")
private String vlan;
+ @Parameter(name=ApiConstants.REMOVE_VLAN, type = CommandType.STRING, description ="The vlan range we want to remove")
+ private String removevlan;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@@ -79,6 +81,10 @@ public class UpdatePhysicalNetworkCmd extends BaseAsyncCmd {
return vlan;
}
+ public String getRemoveVlan(){
+ return removevlan;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -95,7 +101,7 @@ public class UpdatePhysicalNetworkCmd extends BaseAsyncCmd {
@Override
public void execute(){
- PhysicalNetwork result = _networkService.updatePhysicalNetwork(getId(),getNetworkSpeed(), getTags(), getVlan(), getState());
+ PhysicalNetwork result = _networkService.updatePhysicalNetwork(getId(),getNetworkSpeed(), getTags(), getVlan(), getState(), getRemoveVlan());
PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index cfe0e00..b899fa1 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2667,7 +2667,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setZoneId(zone.getUuid());
}
response.setNetworkSpeed(result.getSpeed());
- response.setVlan(result.getVnet());
+ response.setVlan(result.getVnetString());
if (result.getDomainId() != null) {
Domain domain = ApiDBUtils.findDomainById(result.getDomainId());
if (domain != null) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 3551295..4fc2db7 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2633,7 +2633,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (vlan == null) {
throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
}
-
+
if (s_logger.isDebugEnabled()) {
s_logger.debug("lock vlan " + vlanDbId + " is acquired");
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/dc/dao/DataCenterVnetDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dc/dao/DataCenterVnetDao.java b/server/src/com/cloud/dc/dao/DataCenterVnetDao.java
index 79e91c4..7fb68dc 100644
--- a/server/src/com/cloud/dc/dao/DataCenterVnetDao.java
+++ b/server/src/com/cloud/dc/dao/DataCenterVnetDao.java
@@ -20,9 +20,11 @@ import java.util.List;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.Transaction;
public interface DataCenterVnetDao extends GenericDao<DataCenterVnetVO, Long> {
public List<DataCenterVnetVO> listAllocatedVnets(long physicalNetworkId);
+ public List<DataCenterVnetVO> listAllocatedVnetsInRange(long dcId, long physicalNetworkId, Integer start, Integer end);
public List<DataCenterVnetVO> findVnet(long dcId, String vnet);
public int countZoneVlans(long dcId, boolean onlyCountAllocated);
public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet);
@@ -31,6 +33,10 @@ public interface DataCenterVnetDao extends GenericDao<DataCenterVnetVO, Long> {
public void delete(long physicalNetworkId);
+ public void deleteRange(Transaction txn, long dcId, long physicalNetworkId, int start, int end);
+
+ public void lockRange(long dcId, long physicalNetworkId, Integer start, Integer end);
+
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId);
public void release(String vnet, long physicalNetworkId, long accountId, String reservationId);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
index 5ded0f4..2e04439 100755
--- a/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
+++ b/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
import java.util.Date;
import java.util.List;
+import com.cloud.exception.InvalidParameterValueException;
import org.springframework.stereotype.Component;
import com.cloud.dc.DataCenterVnetVO;
@@ -46,8 +47,10 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
private final SearchBuilder<DataCenterVnetVO> VnetDcSearch;
private final SearchBuilder<DataCenterVnetVO> VnetDcSearchAllocated;
private final SearchBuilder<DataCenterVnetVO> DcSearchAllocated;
+ private final SearchBuilder<DataCenterVnetVO> DcSearchAllocatedInRange;
private final GenericSearchBuilder<DataCenterVnetVO, Integer> countZoneVlans;
private final GenericSearchBuilder<DataCenterVnetVO, Integer> countAllocatedZoneVlans;
+ private final SearchBuilder<DataCenterVnetVO> SearchRange;
public List<DataCenterVnetVO> listAllocatedVnets(long physicalNetworkId) {
SearchCriteria<DataCenterVnetVO> sc = DcSearchAllocated.create();
@@ -55,6 +58,22 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
return listBy(sc);
}
+ public List<DataCenterVnetVO> listAllocatedVnetsInRange(long dcId, long physicalNetworkId, Integer start, Integer end) {
+ SearchCriteria<DataCenterVnetVO> sc = DcSearchAllocatedInRange.create();
+ sc.setParameters("dc",dcId);
+ sc.setParameters("physicalNetworkId", physicalNetworkId);
+ sc.setParameters("vnetRange", start.toString(), end.toString());
+ return listBy(sc);
+ }
+
+ public void lockRange(long dcId, long physicalNetworkId, Integer start, Integer end) {
+ SearchCriteria<DataCenterVnetVO> sc = SearchRange.create();
+ sc.setParameters("dc",dcId);
+ sc.setParameters("physicalNetworkId", physicalNetworkId);
+ sc.setParameters("vnetRange", start.toString(), end.toString());
+ lockRows(sc,null,true);
+ }
+
public List<DataCenterVnetVO> findVnet(long dcId, String vnet) {
SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();;
sc.setParameters("dc", dcId);
@@ -94,10 +113,27 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
stmt.executeBatch();
txn.commit();
} catch (SQLException e) {
+ if (!e.getMessage().contains("Duplicate")){
+ txn.rollback();
+ txn.close();
+ throw new CloudRuntimeException("Exception caught adding vnet ", e);
+ }
+ }
+ }
+
+ public void deleteRange(Transaction txn, long dcId, long physicalNetworkId, int start, int end) {
+ String deleteVnet = "DELETE FROM `cloud`.`op_dc_vnet_alloc` WHERE data_center_id=? AND physical_network_id=? AND taken IS NULL AND vnet BETWEEN ? AND ?";
+ try {
+ PreparedStatement stmt = txn.prepareAutoCloseStatement(deleteVnet);
+ stmt.setLong(1,dcId);
+ stmt.setLong(2,physicalNetworkId);
+ stmt.setString(3,((Integer)start).toString());
+ stmt.setString(4,((Integer)end).toString());
+ stmt.execute();
+ } catch (SQLException e) {
throw new CloudRuntimeException("Exception caught adding vnet ", e);
}
}
-
public void delete(long physicalNetworkId) {
SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
@@ -149,6 +185,18 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
DcSearchAllocated.and("physicalNetworkId", DcSearchAllocated.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
DcSearchAllocated.and("allocated", DcSearchAllocated.entity().getTakenAt(), SearchCriteria.Op.NNULL);
DcSearchAllocated.done();
+
+ DcSearchAllocatedInRange = createSearchBuilder();
+ DcSearchAllocatedInRange.and("dc",DcSearchAllocatedInRange.entity().getDataCenterId(), Op.EQ);
+ DcSearchAllocatedInRange.and("physicalNetworkId", DcSearchAllocatedInRange.entity().getPhysicalNetworkId(), Op.EQ);
+ DcSearchAllocatedInRange.and("allocated", DcSearchAllocatedInRange.entity().getTakenAt(), Op.NNULL);
+ DcSearchAllocatedInRange.and("vnetRange", DcSearchAllocatedInRange.entity().getVnet(), Op.BETWEEN);
+ DcSearchAllocatedInRange.done();
+
+ SearchRange = createSearchBuilder();
+ SearchRange.and("dc", SearchRange.entity().getDataCenterId(), Op.EQ);
+ SearchRange.and("physicalNetworkId", SearchRange.entity().getPhysicalNetworkId(), Op.EQ);
+ SearchRange.and("vnetRange", SearchRange.entity().getVnet(), Op.BETWEEN);
FreeVnetSearch = createSearchBuilder();
FreeVnetSearch.and("dc", FreeVnetSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
index c2038e5..ac00bc1 100644
--- a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
@@ -29,6 +29,7 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.ExternalFirewallResponse;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+import com.cloud.utils.Pair;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -715,8 +716,17 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl
if (pNetwork.getVnet() == null) {
throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
}
- String vlanRange[] = pNetwork.getVnet().split("-");
- int lowestVlanTag = Integer.valueOf(vlanRange[0]);
+ Integer lowestVlanTag = null;
+ List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
+ //finding the vlanrange in which the vlanTag lies.
+ for (Pair <Integer,Integer> vnet : vnetList){
+ if (vlanTag >= vnet.first() && vlanTag <= vnet.second()){
+ lowestVlanTag = vnet.first();
+ }
+ }
+ if (lowestVlanTag == null) {
+ throw new InvalidParameterValueException ("The vlan tag dose not belong to any of the existing vlan ranges");
+ }
return vlanTag - lowestVlanTag;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 70d1d0d..12c6068 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -19,16 +19,10 @@ package com.cloud.network;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.DataCenter;
+import com.cloud.dc.*;
import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Pod;
import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.AccountVlanMapDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
+import com.cloud.dc.dao.*;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
@@ -89,6 +83,7 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.vm.*;
import com.cloud.vm.dao.*;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
@@ -206,6 +201,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
HostDao _hostDao;
@Inject
HostPodDao _hostPodDao;
+ @Inject
+ DataCenterVnetDao _datacneter_vnet;
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@@ -538,7 +535,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
} else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
Account caller = UserContext.current().getCaller();
long callerUserId = UserContext.current().getCallerUserId();
- _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
+ _accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseNetwork, false, network);
//handle the basic networks here
VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId());
if (vm == null) {
@@ -758,18 +755,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// in the zone when using external networking
PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (pNetwork.getVnet() != null) {
- String vlanRange[] = pNetwork.getVnet().split("-");
- int lowestVlanTag = Integer.valueOf(vlanRange[0]);
- int highestVlanTag = Integer.valueOf(vlanRange[1]);
- for (int vlan=lowestVlanTag; vlan <= highestVlanTag; ++vlan) {
- int offset = vlan - lowestVlanTag;
- String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
- int cidrSize = 8 + Integer.parseInt(globalVlanBits);
- String guestNetworkCidr = zone.getGuestNetworkCidr();
- String[] cidrTuple = guestNetworkCidr.split("\\/");
- long newCidrAddress = (NetUtils.ip2Long(cidrTuple[0]) & 0xff000000) | (offset << (32 - cidrSize));
- if (NetUtils.isNetworksOverlap(NetUtils.long2Ip(newCidrAddress), cidr)) {
- throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR that is reserved for zone vlan " + vlan);
+ List <Pair<Integer,Integer>> vlanList = pNetwork.getVnet();
+ for (Pair<Integer,Integer> vlanRange : vlanList){
+ Integer lowestVlanTag = vlanRange.first();
+ Integer highestVlanTag = vlanRange.second();
+ for (int vlan=lowestVlanTag; vlan <= highestVlanTag; ++vlan) {
+ int offset = vlan - lowestVlanTag;
+ String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
+ int cidrSize = 8 + Integer.parseInt(globalVlanBits);
+ String guestNetworkCidr = zone.getGuestNetworkCidr();
+ String[] cidrTuple = guestNetworkCidr.split("\\/");
+ long newCidrAddress = (NetUtils.ip2Long(cidrTuple[0]) & 0xff000000) | (offset << (32 - cidrSize));
+ if (NetUtils.isNetworksOverlap(NetUtils.long2Ip(newCidrAddress), cidr)) {
+ throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR that is reserved for zone vlan " + vlan);
+ }
}
}
}
@@ -2198,7 +2197,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
} catch (NumberFormatException e) {
throw new InvalidParameterValueException("Please specify valid integers for the vlan range.");
}
-
if ((vnetStart > vnetEnd) || (vnetStart < 0) || (vnetEnd > 4096)) {
s_logger.warn("Invalid vnet range: start range:" + vnetStart + " end range:" + vnetEnd);
throw new InvalidParameterValueException("Vnet range should be between 0-4096 and start range should be lesser than or equal to end range");
@@ -2289,7 +2287,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_UPDATE, eventDescription = "updating physical network", async = true)
- public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state) {
+ public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state, String removeVlan) {
// verify input parameters
PhysicalNetworkVO network = _physicalNetworkDao.findById(id);
@@ -2314,6 +2312,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
+ if (removeVlan != null){
+ List<Integer> tokens = processVlanRange(network,removeVlan);
+ boolean result = removeVlanRange(network, tokens.get(0), tokens.get(1));
+
+ }
+
if (tags != null && tags.size() > 1) {
throw new InvalidParameterException("Unable to support more than one tag on network yet");
}
@@ -2340,88 +2344,209 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
// Vnet range can be extended only
- boolean replaceVnet = false;
- ArrayList<Pair<Integer, Integer>> vnetsToAdd = new ArrayList<Pair<Integer, Integer>>(2);
+ boolean AddVnet = true;
+ List<Pair<Integer, Integer>> vnetsToAdd = new ArrayList<Pair<Integer, Integer>>();
if (newVnetRangeString != null) {
Integer newStartVnet = 0;
Integer newEndVnet = 0;
- String[] newVnetRange = newVnetRangeString.split("-");
- int maxVnet = 4096;
- // for GRE phynets allow up to 32bits
- // TODO: Not happy about this test.
- // What about guru-like objects for physical networs?
- s_logger.debug("ISOLATION METHODS:" + network.getIsolationMethods());
- // Java does not have unsigned types...
- if (network.getIsolationMethods().contains("GRE")) {
- maxVnet = (int)(Math.pow(2, 32)-1);
- }
- String rangeMessage = " between 0 and " + maxVnet;
- if (newVnetRange.length < 2) {
- throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
- }
+ List<Integer> tokens = processVlanRange(network, newVnetRangeString);
+ newStartVnet = tokens.get(0);
+ newEndVnet = tokens.get(1);
+ Integer j=0;
+ List <Pair <Integer,Integer>> existingRanges = network.getVnet();
+ if (!existingRanges.isEmpty()) {
+ for (; j < existingRanges.size(); j++){
+ int existingStartVnet = existingRanges.get(j).first();
+ int existingEndVnet = existingRanges.get(j).second();
+
+ // check if vnet is being extended
+ if (newStartVnet.intValue() >= existingStartVnet & newEndVnet.intValue() <= existingEndVnet) {
+ throw new InvalidParameterValueException("The vlan range you trying to add already exists.");
+ }
- if (newVnetRange[0] == null || newVnetRange[1] == null) {
- throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
- }
+ if (newStartVnet < existingStartVnet & newEndVnet+1 >= existingStartVnet & newEndVnet <= existingEndVnet) {
+ vnetsToAdd.add(new Pair<Integer, Integer>(newStartVnet, existingStartVnet - 1));
+ existingRanges.get(j).first(newStartVnet);
+ AddVnet = false;
+ break;
+ }
+
+ else if (newStartVnet > existingStartVnet & newStartVnet-1 <= existingEndVnet & newEndVnet >= existingEndVnet) {
+ vnetsToAdd.add(new Pair<Integer, Integer>(existingEndVnet + 1, newEndVnet));
+ existingRanges.get(j).second(newEndVnet);
+ AddVnet = false;
+ break;
+ }
+
+ else if (newStartVnet< existingStartVnet & newEndVnet > existingEndVnet){
+ vnetsToAdd.add(new Pair<Integer, Integer>(newStartVnet,existingStartVnet-1));
+ vnetsToAdd.add(new Pair<Integer, Integer>(existingEndVnet+1,newEndVnet));
+ existingRanges.get(j).first(newStartVnet);
+ existingRanges.get(j).second(newEndVnet);
+ break;
+ }
+ }
- try {
- newStartVnet = Integer.parseInt(newVnetRange[0]);
- newEndVnet = Integer.parseInt(newVnetRange[1]);
- } catch (NumberFormatException e) {
- s_logger.warn("Unable to parse vnet range:", e);
- throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
}
- if (newStartVnet < 0 || newEndVnet > maxVnet) {
- throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage);
+ if (AddVnet){
+ vnetsToAdd.add(new Pair<Integer, Integer>(newStartVnet, newEndVnet));
+ existingRanges.add(new Pair<Integer, Integer>(newStartVnet,newEndVnet));
+ }
+
+ Map <Integer,Integer> vnetMap = new HashMap<Integer, Integer>(existingRanges.size());
+ Map <Integer, Integer> IndexMap = new HashMap<Integer, Integer>(existingRanges.size());
+ for (int i=0; i< existingRanges.size(); i++){
+ vnetMap.put(existingRanges.get(i).first(),existingRanges.get(i).second());
+ IndexMap.put(existingRanges.get(i).first(),i);
+ }
+
+ Integer value;
+ Integer index;
+ String vnetString = "";
+ for (int i=0; i < existingRanges.size(); i++){
+ value = vnetMap.get((existingRanges.get(i).second()+1));
+ if (value != null) {
+ vnetMap.remove((existingRanges.get(i).second()+1));
+ vnetMap.remove(existingRanges.get(i).first());
+ vnetMap.put(existingRanges.get(i).first(),value);
+ existingRanges.add(new Pair<Integer,Integer>(existingRanges.get(i).first(),value));
+ index = IndexMap.get(existingRanges.get(i).second()+1);
+ existingRanges.get(index).first(-1);
+ existingRanges.get(index).second(-1);
+ existingRanges.get(i).first(-1);
+ existingRanges.get(i).second(-1);
+ }
+ value = vnetMap.get((existingRanges.get(i).second()));
+ if (value != null) {
+ vnetMap.remove((existingRanges.get(i).second()));
+ vnetMap.remove(existingRanges.get(i).first());
+ vnetMap.put(existingRanges.get(i).first(),value);
+ existingRanges.add(new Pair<Integer,Integer>(existingRanges.get(i).first(),value));
+ index = IndexMap.get(existingRanges.get(i).second());
+ existingRanges.get(index).first(-1);
+ existingRanges.get(index).second(-1);
+ existingRanges.get(i).first(-1);
+ existingRanges.get(i).second(-1);
+ }
}
- if (newStartVnet > newEndVnet) {
- throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage + " and start range should be lesser than or equal to stop range");
+
+
+ if (newVnetRangeString != null) {
+ for (Pair<Integer,Integer> vnetRange : existingRanges ){
+ value=vnetMap.get(vnetRange.first());
+ if (value != null){
+ vnetString = vnetString+vnetRange.first().toString()+"-"+value.toString()+";";
+ }
+ }
+ vnetString = vnetString+"*";
+ vnetString = vnetString.replace(";*","");
+ network.setVnet(vnetString);
}
-
- if (physicalNetworkHasAllocatedVnets(network.getDataCenterId(), network.getId())) {
- String[] existingRange = network.getVnet().split("-");
- int existingStartVnet = Integer.parseInt(existingRange[0]);
- int existingEndVnet = Integer.parseInt(existingRange[1]);
-
- // check if vnet is being extended
- if (newStartVnet.intValue() > existingStartVnet || newEndVnet.intValue() < existingEndVnet) {
- throw new InvalidParameterValueException("Can't shrink existing vnet range as it the range has vnets allocated. Only extending existing vnet is supported");
- }
- if (newStartVnet < existingStartVnet) {
- vnetsToAdd.add(new Pair<Integer, Integer>(newStartVnet, existingStartVnet - 1));
- }
- if (newEndVnet > existingEndVnet) {
- vnetsToAdd.add(new Pair<Integer, Integer>(existingEndVnet + 1, newEndVnet));
- }
- } else {
- vnetsToAdd.add(new Pair<Integer, Integer>(newStartVnet, newEndVnet));
- replaceVnet = true;
+ _physicalNetworkDao.update(id, network);
+
+ for (Pair<Integer, Integer> vnetToAdd : vnetsToAdd) {
+ s_logger.debug("Adding vnet range " + vnetToAdd.first() + "-" + vnetToAdd.second() + " for the physicalNetwork id= " + id + " and zone id=" + network.getDataCenterId()
+ + " as a part of updatePhysicalNetwork call");
+ _dcDao.addVnet(network.getDataCenterId(), network.getId(), vnetToAdd.first(), vnetToAdd.second());
}
}
- if (newVnetRangeString != null) {
- network.setVnet(newVnetRangeString);
+ return network;
+ }
+
+ private List<Integer> processVlanRange(PhysicalNetworkVO network, String removeVlan) {
+ Integer StartVnet;
+ Integer EndVnet;
+ String[] VnetRange = removeVlan.split("-");
+ int maxVnet = 4096;
+ // for GRE phynets allow up to 32bits
+ // TODO: Not happy about this test.
+ // What about guru-like objects for physical networs?
+ s_logger.debug("ISOLATION METHODS:" + network.getIsolationMethods());
+ // Java does not have unsigned types...
+ if (network.getIsolationMethods().contains("GRE")) {
+ maxVnet = (int)(Math.pow(2, 32)-1);
+ }
+ String rangeMessage = " between 0 and " + maxVnet;
+ if (VnetRange.length < 2) {
+ throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
}
- _physicalNetworkDao.update(id, network);
+ if (VnetRange[0] == null || VnetRange[1] == null) {
+ throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
+ }
- if (replaceVnet) {
- s_logger.debug("Deleting existing vnet range for the physicalNetwork id= " + id + " and zone id=" + network.getDataCenterId() + " as a part of updatePhysicalNetwork call");
- _dcDao.deleteVnet(network.getId());
+ try {
+ StartVnet = Integer.parseInt(VnetRange[0]);
+ EndVnet = Integer.parseInt(VnetRange[1]);
+ } catch (NumberFormatException e) {
+ s_logger.warn("Unable to parse vnet range:", e);
+ throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
+ }
+ if (StartVnet < 0 || EndVnet > maxVnet) {
+ throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage);
}
- for (Pair<Integer, Integer> vnetToAdd : vnetsToAdd) {
- s_logger.debug("Adding vnet range " + vnetToAdd.first() + "-" + vnetToAdd.second() + " for the physicalNetwork id= " + id + " and zone id=" + network.getDataCenterId()
- + " as a part of updatePhysicalNetwork call");
- _dcDao.addVnet(network.getDataCenterId(), network.getId(), vnetToAdd.first(), vnetToAdd.second());
+ if (StartVnet > EndVnet) {
+ throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage + " and start range should be lesser than or equal to stop range");
}
+ List<Integer> tokens = new ArrayList<Integer>();
+ tokens.add(StartVnet);
+ tokens.add(EndVnet);
+ return tokens;
- return network;
+ }
+
+
+ private boolean removeVlanRange( PhysicalNetworkVO network, Integer start, Integer end) {
+ Integer temp=0;
+ int i;
+ List <Pair <Integer,Integer>> existingRanges = network.getVnet();
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ _physicalNetworkDao.acquireInLockTable(network.getId(),10);
+ _datacneter_vnet.lockRange(network.getDataCenterId(), network.getId(), start, end);
+ List<DataCenterVnetVO> result = _datacneter_vnet.listAllocatedVnetsInRange(network.getDataCenterId(), network.getId(), start, end);
+ if (!result.isEmpty()){
+ txn.close();
+ throw new InvalidParameterValueException("Some of the vnets from this range are allocated, can only remove a range which has no allocated vnets");
+ }
+ for (i=0; i<existingRanges.size(); i++){
+ if (existingRanges.get(i).first()<= start & existingRanges.get(i).second()>= end){
+ temp = existingRanges.get(i).second();
+ existingRanges.get(i).second(start - 1);
+ existingRanges.add(new Pair<Integer, Integer>((end+1),temp));
+ break;
+ }
+ }
+
+ if (temp == 0){
+ throw new InvalidParameterValueException("The vlan range you are trying to delete dose not exist.");
+ }
+ if(existingRanges.get(i).first() > existingRanges.get(i).second()){
+ existingRanges.remove(i);
+ }
+ if(existingRanges.get(existingRanges.size()-1).first() > existingRanges.get(existingRanges.size()-1).second()){
+ existingRanges.remove(existingRanges.size()-1);
+ }
+ _datacneter_vnet.deleteRange(txn, network.getDataCenterId(), network.getId(), start, end);
+
+ String vnetString="";
+ for (Pair<Integer,Integer> vnetRange : existingRanges ){
+ vnetString=vnetString+vnetRange.first().toString()+"-"+vnetRange.second().toString()+";";
+ }
+ vnetString = vnetString+"*";
+ vnetString = vnetString.replace(";*","");
+ network.setVnet(vnetString);
+ _physicalNetworkDao.update(network.getId(), network);
+ txn.commit();
+ _physicalNetworkDao.releaseFromLockTable(network.getId());
+ return true;
}
private boolean physicalNetworkHasAllocatedVnets(long zoneId, long physicalNetworkId) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/network/dao/PhysicalNetworkVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkVO.java b/server/src/com/cloud/network/dao/PhysicalNetworkVO.java
index e5ffcfb..f68eee1 100644
--- a/server/src/com/cloud/network/dao/PhysicalNetworkVO.java
+++ b/server/src/com/cloud/network/dao/PhysicalNetworkVO.java
@@ -34,11 +34,9 @@ import javax.persistence.Table;
import javax.persistence.TableGenerator;
import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.BroadcastDomainRange;
-import com.cloud.network.PhysicalNetwork.State;
import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
-import org.apache.cloudstack.api.InternalIdentity;
/**
* NetworkConfigurationVO contains information about a specific physical network.
@@ -205,7 +203,21 @@ public class PhysicalNetworkVO implements PhysicalNetwork {
}
@Override
- public String getVnet() {
+ public List<Pair<Integer, Integer>> getVnet() {
+ List <Pair<Integer,Integer>> vnetList = new ArrayList<Pair<Integer, Integer>>();
+ if (vnet != null) {
+ String [] Temp = vnet.split(";");
+ String [] vnetSplit = null;
+ for (String vnetRange : Temp){
+ vnetSplit = vnetRange.split("-");
+ vnetList.add(new Pair<Integer,Integer>(Integer.parseInt(vnetSplit[0]),Integer.parseInt(vnetSplit[1])));
+ }
+ }
+ return vnetList;
+ }
+
+ @Override
+ public String getVnetString() {
return vnet;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/src/com/cloud/network/guru/GuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
index 9c0205a..92607e2 100755
--- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
@@ -26,6 +26,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import com.cloud.event.ActionEventUtils;
+import com.cloud.utils.Pair;
import org.apache.log4j.Logger;
import com.cloud.configuration.Config;
@@ -274,8 +275,17 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
if (pNetwork.getVnet() == null) {
throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
}
- String vlanRange[] = pNetwork.getVnet().split("-");
- int lowestVlanTag = Integer.valueOf(vlanRange[0]);
+ Integer lowestVlanTag = null;
+ List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
+ //finding the vlanrange in which the vlanTag lies.
+ for (Pair <Integer,Integer> vnet : vnetList){
+ if (vlanTag >= vnet.first() && vlanTag <= vnet.second()){
+ lowestVlanTag = vnet.first();
+ }
+ }
+ if (lowestVlanTag == null) {
+ throw new InvalidParameterValueException ("The vlan tag dose not belong to any of the existing vlan ranges");
+ }
return vlanTag - lowestVlanTag;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/test/com/cloud/network/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index 9042f03..6a0263e 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -322,7 +322,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
}
@Override
- public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state) {
+ public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state, String removeVlan) {
// TODO Auto-generated method stub
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java b/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java
new file mode 100644
index 0000000..ca9d149
--- /dev/null
+++ b/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java
@@ -0,0 +1,68 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network;
+import com.cloud.capacity.CapacityManagerImpl;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.network.NetworkServiceImpl;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.utils.Pair;
+import org.junit.Test;
+import org.junit.*;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+public class UpdatePhysicalNetworkTest {
+ private PhysicalNetworkDao _physicalNetworkDao = mock(PhysicalNetworkDao.class);
+ private DataCenterDao _datacenterDao = mock(DataCenterDao.class);
+ private DataCenterVO datacentervo = mock(DataCenterVO.class);
+ private PhysicalNetworkVO physicalNetworkVO = mock(PhysicalNetworkVO.class);
+ List<Pair<Integer,Integer>> existingRange = new ArrayList<Pair<Integer, Integer>>();
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
+
+ public NetworkServiceImpl setUp() {
+ NetworkServiceImpl networkService = new NetworkServiceImpl();
+ ((NetworkServiceImpl)networkService)._dcDao= _datacenterDao;
+ networkService._physicalNetworkDao = _physicalNetworkDao;
+ return networkService;
+ }
+
+ @Test
+ public void updatePhysicalNetworkTest(){
+ NetworkServiceImpl networkService = setUp();
+ existingRange.add(new Pair<Integer, Integer>(520, 524));
+ when(_physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetworkVO);
+ when(_datacenterDao.findById(anyLong())).thenReturn(datacentervo);
+ when(_physicalNetworkDao.update(anyLong(), any(physicalNetworkVO.getClass()))).thenReturn(true);
+ when(physicalNetworkVO.getVnet()).thenReturn(existingRange);
+ networkService.updatePhysicalNetwork(1l, null, null, "525-530", null, null);
+ verify(physicalNetworkVO).setVnet(argumentCaptor.capture());
+ assertEquals("520-530", argumentCaptor.getValue());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index 3a585ce..bfcccf5 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -328,7 +328,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
*/
@Override
public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags,
- String newVnetRangeString, String state) {
+ String newVnetRangeString, String state, String removeVlan) {
// TODO Auto-generated method stub
return null;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8b40e393/test/integration/smoke/test_non_contigiousvlan.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_non_contigiousvlan.py b/test/integration/smoke/test_non_contigiousvlan.py
new file mode 100644
index 0000000..fe70f87
--- /dev/null
+++ b/test/integration/smoke/test_non_contigiousvlan.py
@@ -0,0 +1,125 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+""" BVT tests for Primary Storage
+"""
+import marvin
+from marvin import cloudstackTestCase
+from marvin.cloudstackTestCase import *
+
+import unittest
+import hashlib
+import random
+
+
+class TestUpdatePhysicalNetwork(cloudstackTestCase):
+ """
+ This test updates the existing physicalnetwork with a new vlan range.
+ """
+ def setUp(self):
+ """
+ CloudStack internally saves its passwords in md5 form and that is how we
+ specify it in the API. Python's hashlib library helps us to quickly hash
+ strings as follows
+ """
+ mdf = hashlib.md5()
+ mdf.update('password')
+ mdf_pass = mdf.hexdigest()
+
+ self.apiClient = self.testClient.getApiClient() #Get ourselves an API client
+
+ self.acct = createAccount.createAccountCmd() #The createAccount command
+ self.acct.accounttype = 0 #We need a regular user. admins have accounttype=1
+ self.acct.firstname = 'bharat'
+ self.acct.lastname = 'kumar' #What's up doc?
+ self.acct.password = mdf_pass #The md5 hashed password string
+ self.acct.username = 'bharat'
+ self.acct.email = 'bharat@kumar.com'
+ self.acct.account = 'bharat'
+ self.acct.domainid = 1 #The default ROOT domain
+ self.acctResponse = self.apiClient.createAccount(self.acct)
+ # using the default debug logger of the test framework
+ self.debug("successfully created account: %s, user: %s, id: \
+ %s"%(self.acctResponse.account.account, \
+ self.acctResponse.account.username, \
+ self.acctResponse.account.id))
+
+ def test_UpdatePhysicalNetwork(self):
+ """
+ Let's start by defining the attributes of our VM that we will be
+ deploying on CloudStack. We will be assuming a single zone is available
+ and is configured and all templates are Ready
+
+ The hardcoded values are used only for brevity.
+ """
+ listPhysicalNetworksCmd = listPhysicalNetworks.listPhysicalNetworksCmd()
+ listPhysicalNetworksResponse = self.apiClient.listPhysicalNetworks(listPhysicalNetworksCmd)
+
+ self.assertNotEqual(len(listPhysicalNetworksResponse), 0, "Check if the list API \
+ returns a non-empty response")
+
+ networkid = listPhysicalNetworksResponse[0].id
+ updatePhysicalNetworkCmd = updatePhysicalNetwork.updatePhysicalNetworkCmd()
+ updatePhysicalNetworkCmd.id = networkid
+ updatePhysicalNetworkCmd.vlan = "4090-4091"
+ updatePhysicalNetworkResponse = self.apiClient.updatePhysicalNetwork(updatePhysicalNetworkCmd)
+ self.assertNotEqual((updatePhysicalNetworkResponse.len), 0, "Check if the list API \
+ returns a non-empty response")
+
+ updatePhysicalNetworkCmd = updatePhysicalNetwork.updatePhysicalNetworkCmd()
+ updatePhysicalNetworkCmd.id = networkid
+ updatePhysicalNetworkCmd.vlan = "4092-4096"
+ updatePhysicalNetworkResponse = self.apiClient.updatePhysicalNetwork(updatePhysicalNetworkCmd)
+ self.assertNotEqual((updatePhysicalNetworkResponse.len), 0, "Check if the list API \
+ returns a non-empty response")
+
+ vlanranges= updatePhysicalNetworkResponse.vlan
+ range = ""
+ vlanranges = vlanranges.split(";")
+ for vlan in vlanranges:
+ if (vlan == "4090-4096"):
+ range = vlan
+
+ self.assertEqual(range, "4090-4096", "check if adding the range is successful")
+
+ updatePhysicalNetworkCmd = updatePhysicalNetwork.updatePhysicalNetworkCmd()
+ updatePhysicalNetworkCmd.id = networkid
+ updatePhysicalNetworkCmd.removevlan = "4090-4096"
+ updatePhysicalNetworkResponse = self.apiClient.updatePhysicalNetwork(updatePhysicalNetworkCmd)
+ self.assertNotEqual((updatePhysicalNetworkResponse.len), 0, "Check if the list API \
+ returns a non-empty response")
+
+ vlanranges= updatePhysicalNetworkResponse.vlan
+ range = ""
+ vlanranges = vlanranges.split(";")
+
+ for vlan in vlanranges:
+ if (vlan == "4090-4096"):
+ range = vlan
+
+
+ self.assertEqual(range, "", "check if removing the range is successful")
+
+
+ def tearDown(self): # Teardown will delete the Account as well as the VM once the VM reaches "Running" state
+ """
+ And finally let us cleanup the resources we created by deleting the
+ account. All good unittests are atomic and rerunnable this way
+ """
+ deleteAcct = deleteAccount.deleteAccountCmd()
+ deleteAcct.id = self.acctResponse.account.id
+ self.apiClient.deleteAccount(deleteAcct)
+