Updated Branches: refs/heads/pvlan [created] 4c0f775e6
PVLAN: Add pvlan in createNetworkCommand Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c26244d1 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c26244d1 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c26244d1 Branch: refs/heads/pvlan Commit: c26244d18a4ae93614195b7f1945d174a35623d1 Parents: bb841d6 Author: Sheng Yang <sheng.y...@citrix.com> Authored: Thu Apr 11 17:39:39 2013 -0700 Committer: Sheng Yang <sheng.y...@citrix.com> Committed: Thu Apr 11 17:39:39 2013 -0700 ---------------------------------------------------------------------- api/src/com/cloud/network/Networks.java | 1 + .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../api/command/user/network/CreateNetworkCmd.java | 7 +++ .../xen/resource/CitrixResourceBase.java | 5 ++ .../configuration/ConfigurationManagerImpl.java | 2 + server/src/com/cloud/network/NetworkManager.java | 3 +- .../src/com/cloud/network/NetworkManagerImpl.java | 35 ++++++++++----- .../src/com/cloud/network/NetworkServiceImpl.java | 13 +++++- .../src/com/cloud/network/vpc/VpcManagerImpl.java | 2 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 4 +- .../com/cloud/network/MockNetworkManagerImpl.java | 2 +- .../test/com/cloud/vpc/MockNetworkManagerImpl.java | 3 +- utils/src/com/cloud/utils/net/NetUtils.java | 26 +++++++++++ utils/test/com/cloud/utils/net/NetUtilsTest.java | 8 +++ 14 files changed, 93 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/api/src/com/cloud/network/Networks.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index f085e9f..5aede05 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -63,6 +63,7 @@ public class Networks { Storage("storage", Integer.class), Lswitch("lswitch", String.class), Mido("mido", String.class), + Pvlan("pvlan", String.class), UnDecided(null, null); private String scheme; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/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 c518830..bd441eb 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -222,6 +222,7 @@ public class ApiConstants { public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids"; public static final String VLAN = "vlan"; public static final String VLAN_ID = "vlanid"; + public static final String ISOLATED_PVLAN = "isolatedpvlan"; public static final String VM_AVAILABLE = "vmavailable"; public static final String VM_LIMIT = "vmlimit"; public static final String VM_TOTAL = "vmtotal"; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java index fc7bd9f..7f699fe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java @@ -86,6 +86,9 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network") private String vlan; + @Parameter(name=ApiConstants.ISOLATED_PVLAN, type=CommandType.STRING, description="the isolated private vlan for this network") + private String isolatedPvlan; + @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") private String networkDomain; @@ -141,6 +144,10 @@ public class CreateNetworkCmd extends BaseCmd { return vlan; } + public String getIsolatedPvlan() { + return isolatedPvlan; + } + public String getAccountName() { return accountName; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c50f13c..e467dc7 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1014,6 +1014,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else if (nic.getBroadcastType() == BroadcastDomainType.Lswitch) { // Nicira Logical Switch return network.getNetwork(); + } else if (nic.getBroadcastType() == BroadcastDomainType.Pvlan) { + URI broadcastUri = nic.getBroadcastUri(); + assert broadcastUri.getScheme().equals(BroadcastDomainType.Pvlan.scheme()); + long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(broadcastUri)); + return enableVlanNetwork(conn, vlan, network); } throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/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 8dbf081..a36a100 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2410,6 +2410,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (uri != null) { String[] vlan = uri.toString().split("vlan:\\/\\/"); networkVlanId = vlan[1]; + //For pvlan + networkVlanId = networkVlanId.split("-")[0]; } if (vlanId != null) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/NetworkManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 851f7f5..d2d2d5c 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -127,7 +127,8 @@ public interface NetworkManager { Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork, - long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr) + long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, + String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; /** http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/NetworkManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index a16288f..60dc1f0 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1867,7 +1867,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L @DB public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, - PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr) + PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, + String ip6Gateway, String ip6Cidr, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); @@ -1957,6 +1958,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L if (ipv6) { throw new InvalidParameterValueException("IPv6 is not supported with security group!"); } + if (isolatedPvlan != null) { + throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!"); + } // Only Account specific Isolated network with sourceNat service disabled are allowed in security group // enabled zone if ( ntwkOff.getGuestType() != GuestType.Shared ){ @@ -2085,13 +2089,20 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } if (vlanId != null) { - userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId)); - userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); - if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); - } else { - userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); - } + if (isolatedPvlan == null) { + userNetwork.setBroadcastUri(URI.create("vlan://" + vlanId)); + if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); + } else { + userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); + } + } else { + if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { + throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!"); + } + userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanId, isolatedPvlan)); + userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan); + } } List<NetworkVO> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, @@ -2675,7 +2686,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network" , owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork, zoneId, ACLType.Account, - null, null, null, null); + null, null, null, null, null); if (guestNetwork == null) { s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + @@ -3516,8 +3527,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L nic.setGateway(ip.getGateway()); nic.setNetmask(ip.getNetmask()); nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + //nic.setBroadcastType(BroadcastDomainType.Vlan); + //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(network.getBroadcastDomainType()); + nic.setBroadcastUri(network.getBroadcastUri()); nic.setFormat(AddressFormat.Ip4); nic.setReservationId(String.valueOf(ip.getVlanTag())); nic.setMacAddress(ip.getMacAddress()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/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 4eb620c..7bb7188 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -813,6 +813,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { String endIPv6 = cmd.getEndIpv6(); String ip6Gateway = cmd.getIp6Gateway(); String ip6Cidr = cmd.getIp6Cidr(); + String isolatedPvlan = cmd.getIsolatedPvlan(); // Validate network offering NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); @@ -999,6 +1000,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } + if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) { + throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!"); + } + // Regular user can create Guest Isolated Source Nat enabled network only if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated @@ -1030,6 +1035,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (ipv6 && providersConfiguredForExternalNetworking(ntwkProviders)) { throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!"); } + if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) { + throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!"); + } if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) { if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) && @@ -1100,7 +1108,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Network offering can be used for VPC networks only"); } network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, - networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr); + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, + ip6Gateway, ip6Cidr, isolatedPvlan); } if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { @@ -3214,7 +3223,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (privateNetwork == null) { //create Guest network privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan, - null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null); + null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null, null); s_logger.debug("Created private network " + privateNetwork); } else { s_logger.debug("Private network already exists: " + privateNetwork); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/network/vpc/VpcManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 3948f2e..e693273 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1937,7 +1937,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis //2) Create network Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, - networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null); + networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, null, null, null); return guestNetwork; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 24bce8b..9edddb4 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2143,7 +2143,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use s_logger.debug("Creating network for account " + owner + " from the network offering id=" +requiredOfferings.get(0).getId() + " as a part of deployVM process"); Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, - null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null); + null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException( @@ -3807,7 +3807,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use requiredOfferings.get(0).getId() + " as a part of deployVM process"); Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, - null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null); + null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, null); // if the network offering has persistent set to true, implement the network if (requiredOfferings.get(0).getIsPersistent()) { DeployDestination dest = new DeployDestination(zone, null, null, null); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/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 6da48ec..f1965a4 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -256,7 +256,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage @Override public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, - PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { // TODO Auto-generated method stub return null; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/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 ead0051..9f455a6 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -848,7 +848,8 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage @Override public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, - PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6, String cidrv6) + PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, + String gatewayv6, String cidrv6, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { // TODO Auto-generated method stub return null; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/utils/src/com/cloud/utils/net/NetUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 5988dd5..4dd404d 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -24,6 +24,7 @@ import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.net.URI; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Formatter; @@ -1290,4 +1291,29 @@ public class NetUtils { } return resultIp; } + + public static URI generateUriForPvlan(String primaryVlan, String isolatedPvlan) { + return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan); + } + + public static String getPrimaryPvlanFromUri(URI uri) { + String[] vlans = uri.getHost().split("-"); + if (vlans.length < 1) { + return null; + } + return vlans[0]; + } + + public static String getIsolatedPvlanFromUri(URI uri) { + String[] vlans = uri.getHost().split("-"); + if (vlans.length < 2) { + return null; + } + for (String vlan : vlans) { + if (vlan.startsWith("i")) { + return vlan.replace("i", " ").trim(); + } + } + return null; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c26244d1/utils/test/com/cloud/utils/net/NetUtilsTest.java ---------------------------------------------------------------------- diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index 28bd71f..16d3402 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -17,6 +17,7 @@ package com.cloud.utils.net; import java.math.BigInteger; +import java.net.URI; import java.util.SortedSet; import java.util.TreeSet; @@ -128,4 +129,11 @@ public class NetUtilsTest extends TestCase { assertFalse(NetUtils.isIp6InRange("1234:5678:abcd::1", null)); assertTrue(NetUtils.isIp6InRange("1234:5678:abcd::1", "1234:5678::1-1234:5679::1")); } + + public void testPvlan() { + URI uri = NetUtils.generateUriForPvlan("123", "456"); + assertTrue(uri.toString().equals("pvlan://123-i456")); + assertTrue(NetUtils.getPrimaryPvlanFromUri(uri).equals("123")); + assertTrue(NetUtils.getIsolatedPvlanFromUri(uri).equals("456")); + } }