Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2512C108FE for ; Mon, 28 Dec 2015 10:22:34 +0000 (UTC) Received: (qmail 73519 invoked by uid 500); 28 Dec 2015 10:22:26 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 73202 invoked by uid 500); 28 Dec 2015 10:22:26 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 72563 invoked by uid 99); 28 Dec 2015 10:22:26 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Dec 2015 10:22:26 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E7383E041F; Mon, 28 Dec 2015 10:22:25 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: remi@apache.org To: commits@cloudstack.apache.org Date: Mon, 28 Dec 2015 10:22:30 -0000 Message-Id: <021ce44bbfe64afcb92a52055e28fc78@git.apache.org> In-Reply-To: <0b0e97a9b7434d539f9a1d5b47eed727@git.apache.org> References: <0b0e97a9b7434d539f9a1d5b47eed727@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [06/16] git commit: updated refs/heads/master to 67b753c CLOUDSTACK-9074: Support Shared Networks in NiciraNVP Plugin Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c6763718 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c6763718 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c6763718 Branch: refs/heads/master Commit: c67637180f9d7be627a4fe36fd2709c58c952e94 Parents: 55f4607 Author: nvazquez Authored: Tue Dec 1 11:54:27 2015 -0800 Committer: nvazquez Committed: Thu Dec 24 16:07:06 2015 -0300 ---------------------------------------------------------------------- .../com/cloud/vm/VirtualMachineManagerImpl.java | 8 +- .../orchestration/NetworkOrchestrator.java | 113 ++++++---- .../src/com/cloud/network/dao/NetworkVO.java | 11 + .../network/dao/NiciraNvpRouterMappingDao.java | 2 + .../dao/NiciraNvpRouterMappingDaoImpl.java | 9 + .../cloud/network/element/NiciraNvpElement.java | 86 +++++++- .../network/guru/NiciraNvpGuestNetworkGuru.java | 96 ++++++++- .../network/element/NiciraNvpElementTest.java | 213 ++++++++++++++++++- .../guru/NiciraNvpGuestNetworkGuruTest.java | 4 +- .../cloud/network/guru/DirectNetworkGuru.java | 3 +- 10 files changed, 493 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 5c58389..aa3b7ce 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -4575,7 +4575,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } assert vm != null; - orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner())); + try{ + orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner())); + } + catch (CloudRuntimeException e){ + s_logger.info("Caught CloudRuntimeException, returning job failed"); + return new Pair(JobInfo.Status.FAILED, null); + } return new Pair(JobInfo.Status.SUCCEEDED, null); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index d99c9ef..fa6cd82 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -140,6 +140,7 @@ import com.cloud.network.element.NetworkElement; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; +import com.cloud.network.guru.NetworkGuruAdditionalFunctions; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRule; @@ -168,6 +169,7 @@ import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.utils.Pair; +import com.cloud.utils.UuidUtils; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -670,8 +672,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra vpcId, offering.getRedundantRouter()); vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled); vo.setStrechedL2Network(offering.getSupportsStrechedL2()); - networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, - finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); + NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, + finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId())); + networks.add(networkPersisted); + + if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){ + NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru; + functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID()); + } if (domainId != null && aclType == ACLType.Domain) { _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess); @@ -1020,6 +1028,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } catch (NoTransitionException e) { s_logger.error(e.getMessage()); return null; + } catch (CloudRuntimeException e) { + s_logger.error("Caught exception: " + e.getMessage()); + return null; } finally { if (implemented.first() == null) { s_logger.debug("Cleaning up because we're unable to implement the network " + network); @@ -1911,43 +1922,45 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName()); } - String uri = BroadcastDomainType.fromString(vlanId).toString(); - // For Isolated networks, don't allow to create network with vlan that already exists in the zone - if (ntwkOff.getGuestType() == GuestType.Isolated) { - if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { - throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); - } else { - List dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); - //for the network that is created as part of private gateway, - //the vnet is not coming from the data center vnet table, so the list can be empty - if (!dcVnets.isEmpty()) { - DataCenterVnetVO dcVnet = dcVnets.get(0); - // Fail network creation if specified vlan is dedicated to a different account - if (dcVnet.getAccountGuestVlanMapId() != null) { - Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); - AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); - if (map.getAccountId() != owner.getAccountId()) { - throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); - } - // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool - } else { - List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); - if (maps != null && !maps.isEmpty()) { - int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); - int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); - if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { - throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " - + owner.getAccountName()); + if (! UuidUtils.validateUUID(vlanId)){ + String uri = BroadcastDomainType.fromString(vlanId).toString(); + // For Isolated networks, don't allow to create network with vlan that already exists in the zone + if (ntwkOff.getGuestType() == GuestType.Isolated) { + if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { + throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); + } else { + List dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); + //for the network that is created as part of private gateway, + //the vnet is not coming from the data center vnet table, so the list can be empty + if (!dcVnets.isEmpty()) { + DataCenterVnetVO dcVnet = dcVnets.get(0); + // Fail network creation if specified vlan is dedicated to a different account + if (dcVnet.getAccountGuestVlanMapId() != null) { + Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); + AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); + if (map.getAccountId() != owner.getAccountId()) { + throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); + } + // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool + } else { + List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); + if (maps != null && !maps.isEmpty()) { + int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); + int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); + if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { + throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " + + owner.getAccountName()); + } } } } } - } - } else { - // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or - // shared network with same Vlan ID in the zone - if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) { - throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId); + } else { + // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or + // shared network with same Vlan ID in the zone + if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) { + throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId); + } } } @@ -2038,7 +2051,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (vlanIdFinal != null) { if (isolatedPvlan == null) { - URI uri = BroadcastDomainType.fromString(vlanIdFinal); + URI uri = null; + if (UuidUtils.validateUUID(vlanIdFinal)){ + //Logical router's UUID provided as VLAN_ID + userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field + } + else { + uri = BroadcastDomainType.fromString(vlanIdFinal); + } userNetwork.setBroadcastUri(uri); if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) { userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); @@ -2647,6 +2667,27 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } else { result = _nicDao.listByVmIdAndNicIdAndNtwkId(vmId, nicId, networkId); } + + for (NicVO nic : result) { + if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) { + //For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result + s_logger.info("Listing NSX logical switch and logical switch por for each nic"); + NetworkVO network = _networksDao.findById(nic.getNetworkId()); + NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName()); + NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru; + + Map nsxParams = guruFunctions.listAdditionalNicParams(nic.getUuid()); + if (nsxParams != null){ + String lswitchUuuid = (nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID)) + ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) : null; + String lswitchPortUuuid = (nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID)) + ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) : null; + nic.setNsxLogicalSwitchUuid(lswitchUuuid); + nic.setNsxLogicalSwitchPortUuid(lswitchPortUuuid); + } + } + } + return result; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/engine/schema/src/com/cloud/network/dao/NetworkVO.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java index 65929d5..5b8ded7 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkVO.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkVO.java @@ -172,6 +172,17 @@ public class NetworkVO implements Network { @Column(name = "streched_l2") boolean strechedL2Network = false; + @Transient + transient String vlanIdAsUUID; + + public String getVlanIdAsUUID() { + return vlanIdAsUUID; + } + + public void setVlanIdAsUUID(String vlanIdAsUUID) { + this.vlanIdAsUUID = vlanIdAsUUID; + } + public NetworkVO() { uuid = UUID.randomUUID().toString(); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java index b64fb90..b7e999b 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java @@ -25,4 +25,6 @@ import com.cloud.utils.db.GenericDao; public interface NiciraNvpRouterMappingDao extends GenericDao { public NiciraNvpRouterMappingVO findByNetworkId(long id); + + public boolean existsMappingForNetworkId(long id); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java index 239072f..ef6acb4 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java @@ -19,6 +19,7 @@ package com.cloud.network.dao; +import java.util.List; import org.springframework.stereotype.Component; @@ -46,4 +47,12 @@ public class NiciraNvpRouterMappingDaoImpl extends GenericDaoBase sc = networkSearch.create(); + sc.setParameters("network_id", id); + List mappings = search(sc, null); + return mappings.size() > 0; + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java index 909134d..1146a54 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java @@ -33,7 +33,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; @@ -42,6 +41,10 @@ import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureSharedNetworkUuidAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkUuidCommand; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdCommand; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalRouterAnswer; @@ -67,6 +70,7 @@ import com.cloud.api.commands.ListNiciraNvpDevicesCmd; import com.cloud.api.response.NiciraNvpDeviceResponse; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.Vlan; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -82,6 +86,7 @@ import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.Network.Capability; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkModel; @@ -239,8 +244,14 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { * multiple operations that should be done only once. */ - // Implement SourceNat immediately as we have al the info already - if (networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + if (network.getGuestType().equals(GuestType.Shared)){ + //Support Shared Networks + String lSwitchUuid = BroadcastDomainType.getValue(network.getBroadcastUri()); + String ownerName = context.getDomain().getName() + "-" + context.getAccount().getAccountName(); + return sharedNetworkSupport(network, lSwitchUuid, ownerName, niciraNvpHost); + } + else if (network.getGuestType().equals(GuestType.Isolated) && networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + // Implement SourceNat immediately as we have al the info already s_logger.debug("Apparently we are supposed to provide SourceNat on this network"); PublicIp sourceNatIp = ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); @@ -271,14 +282,74 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { return false; } - // Store the uuid so we can easily find it during cleanup NiciraNvpRouterMappingVO routermapping = new NiciraNvpRouterMappingVO(answer.getLogicalRouterUuid(), network.getId()); niciraNvpRouterMappingDao.persist(routermapping); + + } + + return true; + } + + private boolean sharedNetworkSupport(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + //Support Shared Networks, we won’t be creating logical router, 2 cases: + //Case 1) UUID Supplied for VLAN -> This is UUID of the logical router to attach lswitch + //Case 2) Numerical ID supplied for VLAN -> lswitch is connected to L2 gateway service that we have as an attribute of the NVP device. If no L2 gateway attribute exists then exception. + + if (niciraNvpRouterMappingDao.existsMappingForNetworkId(network.getId())){ + //Case 1) + return sharedNetworkSupportUUIDVlanId(network, lSwitchUuid, ownerName, niciraNvpHost); + } + else { + //Case 2) + return sharedNetworkSupportNumericalVlanId(network, lSwitchUuid, ownerName, niciraNvpHost); + } + } + + private boolean sharedNetworkSupportUUIDVlanId(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + String networkCidr = network.getCidr(); + String vlanGateway = network.getGateway(); + String portIpAddress = createLogicalRouterPortIpAddress(networkCidr, vlanGateway); + NiciraNvpRouterMappingVO mapRouterNetwork = niciraNvpRouterMappingDao.findByNetworkId(network.getId()); + String lRouterUuid = mapRouterNetwork.getLogicalRouterUuid(); + ConfigureSharedNetworkUuidCommand cmd = + new ConfigureSharedNetworkUuidCommand(lRouterUuid, lSwitchUuid, portIpAddress, ownerName, network.getId()); + ConfigureSharedNetworkUuidAnswer answer = (ConfigureSharedNetworkUuidAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to configure Logical Router for Shared network " + network.getDisplayText()); + return false; } + return true; + } + private boolean sharedNetworkSupportNumericalVlanId(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + List networkVlans = vlanDao.listVlansByNetworkId(network.getId()); + if (networkVlans.size() == 1){ + for (VlanVO vlanVO : networkVlans) { + long vlanId = Long.parseLong(vlanVO.getVlanTag()); + String l2GatewayServiceUuid = niciraNvpHost.getDetail("l2gatewayserviceuuid"); + if (l2GatewayServiceUuid == null){ + throw new CloudRuntimeException("No L2 Gateway Service Uuid found on " + niciraNvpHost.getName()); + } + ConfigureSharedNetworkVlanIdCommand cmd = + new ConfigureSharedNetworkVlanIdCommand(lSwitchUuid, l2GatewayServiceUuid , vlanId, ownerName, network.getId()); + ConfigureSharedNetworkVlanIdAnswer answer = (ConfigureSharedNetworkVlanIdAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to configure Shared network " + network.getDisplayText()); + return false; + } + } + } return true; } + + private String createLogicalRouterPortIpAddress(String networkCidr, String vlanGateway) { + if (networkCidr != null && vlanGateway != null){ + return networkCidr.replaceFirst("[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}", vlanGateway); + } + return null; + } + @Override public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { @@ -393,7 +464,8 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); - if (networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + //Dont destroy logical router when removing Shared Networks + if (! network.getGuestType().equals(GuestType.Shared) && networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { s_logger.debug("Apparently we were providing SourceNat on this network"); // Deleting the LogicalRouter will also take care of all provisioned @@ -537,6 +609,9 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { if (cmd.getL3GatewayServiceUuid() != null) { params.put("l3gatewayserviceuuid", cmd.getL3GatewayServiceUuid()); } + if (cmd.getL2GatewayServiceUuid() != null) { + params.put("l2gatewayserviceuuid", cmd.getL2GatewayServiceUuid()); + } Map hostdetails = new HashMap(); hostdetails.putAll(params); @@ -582,6 +657,7 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { response.setHostName(niciraNvpHost.getDetail("ip")); response.setTransportZoneUuid(niciraNvpHost.getDetail("transportzoneuuid")); response.setL3GatewayServiceUuid(niciraNvpHost.getDetail("l3gatewayserviceuuid")); + response.setL2GatewayServiceUuid(niciraNvpHost.getDetail("l2gatewayserviceuuid")); response.setObjectName("niciranvpdevice"); return response; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java index fc41286..f83f8ee 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java @@ -21,7 +21,9 @@ package com.cloud.network.guru; import java.net.URI; import java.net.URISyntaxException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.inject.Inject; @@ -30,8 +32,12 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.CreateLogicalSwitchAnswer; import com.cloud.agent.api.CreateLogicalSwitchCommand; +import com.cloud.agent.api.DeleteLogicalRouterPortAnswer; +import com.cloud.agent.api.DeleteLogicalRouterPortCommand; import com.cloud.agent.api.DeleteLogicalSwitchAnswer; import com.cloud.agent.api.DeleteLogicalSwitchCommand; +import com.cloud.agent.api.FindLogicalRouterPortAnswer; +import com.cloud.agent.api.FindLogicalRouterPortCommand; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; @@ -48,6 +54,8 @@ import com.cloud.network.Network.Service; import com.cloud.network.Network.State; import com.cloud.network.NetworkModel; import com.cloud.network.NetworkProfile; +import com.cloud.network.NiciraNvpNicMappingVO; +import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.NiciraNvpDeviceVO; import com.cloud.network.PhysicalNetwork; @@ -55,6 +63,8 @@ import com.cloud.network.PhysicalNetwork.IsolationMethod; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NiciraNvpDao; +import com.cloud.network.dao.NiciraNvpNicMappingDao; +import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; @@ -66,7 +76,7 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; -public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { +public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions{ private static final int MAX_NAME_LENGTH = 40; private static final Logger s_logger = Logger.getLogger(NiciraNvpGuestNetworkGuru.class); @@ -93,6 +103,10 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { protected HostDetailsDao hostDetailsDao; @Inject protected NetworkOfferingServiceMapDao ntwkOfferingSrvcDao; + @Inject + protected NiciraNvpRouterMappingDao niciraNvpRouterMappingDao; + @Inject + protected NiciraNvpNicMappingDao niciraNvpNicMappingDao; public NiciraNvpGuestNetworkGuru() { super(); @@ -102,15 +116,24 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { @Override protected boolean canHandle(final NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { // This guru handles only Guest Isolated network that supports Source nat service - if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated + if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && supportedGuestTypes(offering, Network.GuestType.Isolated, Network.GuestType.Shared) && isMyIsolationMethod(physicalNetwork) && ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)) { return true; } else { - s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); return false; } } + private boolean supportedGuestTypes(NetworkOffering offering, GuestType... types) { + for (GuestType guestType : types) { + if (offering.getGuestType().equals(guestType)){ + return true; + } + } + return false; + } + @Override public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) { // Check of the isolation type of the related physical network is supported @@ -134,6 +157,9 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { return null; } networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch); + if (offering.getGuestType().equals(GuestType.Shared)){ + networkObject.setState(State.Allocated); + } return networkObject; } @@ -231,7 +257,13 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); - final DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(BroadcastDomainType.getValue(networkObject.getBroadcastUri())); + String logicalSwitchUuid = BroadcastDomainType.getValue(networkObject.getBroadcastUri()); + + if (offering.getGuestType().equals(GuestType.Shared)){ + sharedNetworksCleanup(networkObject, logicalSwitchUuid, niciraNvpHost); + } + + final DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(logicalSwitchUuid); final DeleteLogicalSwitchAnswer answer = (DeleteLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -241,9 +273,65 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { super.shutdown(profile, offering); } + private void sharedNetworksCleanup(NetworkVO networkObject, String logicalSwitchUuid, HostVO niciraNvpHost) { + NiciraNvpRouterMappingVO routermapping = niciraNvpRouterMappingDao.findByNetworkId(networkObject.getId()); + if (routermapping == null) { + // Case 1: Numerical Vlan Provided -> No lrouter used. + s_logger.info("Shared Network " + networkObject.getDisplayText() + " didn't use Logical Router"); + } + else { + //Case 2: Logical Router's UUID provided as Vlan id -> Remove lrouter port but not lrouter. + String lRouterUuid = routermapping.getLogicalRouterUuid(); + s_logger.debug("Finding Logical Router Port on Logical Router " + lRouterUuid + " with attachment_lswitch_uuid=" + logicalSwitchUuid + " to delete it"); + final FindLogicalRouterPortCommand cmd = new FindLogicalRouterPortCommand(lRouterUuid, logicalSwitchUuid); + final FindLogicalRouterPortAnswer answer = (FindLogicalRouterPortAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd); + + if (answer != null && answer.getResult()) { + String logicalRouterPortUuid = answer.getLogicalRouterPortUuid(); + s_logger.debug("Found Logical Router Port " + logicalRouterPortUuid + ", deleting it"); + final DeleteLogicalRouterPortCommand cmdDeletePort = new DeleteLogicalRouterPortCommand(lRouterUuid, logicalRouterPortUuid); + final DeleteLogicalRouterPortAnswer answerDelete = (DeleteLogicalRouterPortAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmdDeletePort); + + if (answerDelete != null && answerDelete.getResult()){ + s_logger.info("Successfully deleted Logical Router Port " + logicalRouterPortUuid); + } + else { + s_logger.error("Could not delete Logical Router Port " + logicalRouterPortUuid); + } + } + else { + s_logger.error("Find Logical Router Port failed"); + } + } + } + @Override public boolean trash(final Network network, final NetworkOffering offering) { + //Since NVP Plugin supports Shared networks, remove mapping when deleting network implemented or allocated + if (network.getGuestType() == GuestType.Shared && niciraNvpRouterMappingDao.existsMappingForNetworkId(network.getId())){ + NiciraNvpRouterMappingVO mappingVO = niciraNvpRouterMappingDao.findByNetworkId(network.getId()); + niciraNvpRouterMappingDao.remove(mappingVO.getId()); + } return super.trash(network, offering); } + @Override + public void finalizeNetworkDesign(long networkId, String vlanIdAsUUID) { + if (vlanIdAsUUID == null) return; + NiciraNvpRouterMappingVO routermapping = new NiciraNvpRouterMappingVO(vlanIdAsUUID, networkId); + niciraNvpRouterMappingDao.persist(routermapping); + } + + @Override + public Map listAdditionalNicParams(String nicUuid) { + NiciraNvpNicMappingVO mapping = niciraNvpNicMappingDao.findByNicUuid(nicUuid); + if (mapping != null){ + Map result = new HashMap(); + result.put(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID, mapping.getLogicalSwitchUuid()); + result.put(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID, mapping.getLogicalSwitchPortUuid()); + return result; + } + return null; + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java index bf8ce18..858e908 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java @@ -29,7 +29,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -40,12 +43,17 @@ import javax.naming.ConfigurationException; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureSharedNetworkUuidAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdAnswer; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; @@ -61,21 +69,27 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkModel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.IpAddressManager; import com.cloud.network.NiciraNvpDeviceVO; import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.PublicIpAddress; +import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NiciraNvpDao; import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; import com.cloud.user.Account; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.vm.ReservationContext; public class NiciraNvpElementTest { private static final long NETWORK_ID = 42L; + private static final long NICIRA_NVP_HOST_ID = 9L; + private static final String NETWORK_CIDR = "10.0.0.0/24"; + private static final String NETWORK_GATEWAY = "10.0.0.1"; NiciraNvpElement element = new NiciraNvpElement(); NetworkOrchestrationService networkManager = mock(NetworkOrchestrationService.class); NetworkModel networkModel = mock(NetworkModel.class); @@ -84,6 +98,8 @@ public class NiciraNvpElementTest { HostDao hostDao = mock(HostDao.class); NiciraNvpDao niciraNvpDao = mock(NiciraNvpDao.class); NiciraNvpRouterMappingDao niciraNvpRouterMappingDao = mock(NiciraNvpRouterMappingDao.class); + VlanDao vlanDao = mock(VlanDao.class); + IpAddressManager ipAddressManager = mock(IpAddressManager.class); @Before public void setUp() throws ConfigurationException { @@ -95,6 +111,8 @@ public class NiciraNvpElementTest { element.hostDao = hostDao; element.niciraNvpDao = niciraNvpDao; element.niciraNvpRouterMappingDao = niciraNvpRouterMappingDao; + element.vlanDao = vlanDao; + element.ipAddrMgr = ipAddressManager; // Standard responses when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); @@ -133,17 +151,32 @@ public class NiciraNvpElementTest { } @Test - public void implementTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public void implementIsolatedNetworkTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException { final Network network = mock(Network.class); when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Isolated); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); final NetworkOffering offering = mock(NetworkOffering.class); when(offering.getId()).thenReturn(NETWORK_ID); when(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Isolated); - mock(DeployDestination.class); + final DeployDestination dest = mock(DeployDestination.class); final Domain dom = mock(Domain.class); when(dom.getName()).thenReturn("domain"); @@ -152,6 +185,26 @@ public class NiciraNvpElementTest { final ReservationContext context = mock(ReservationContext.class); when(context.getDomain()).thenReturn(dom); when(context.getAccount()).thenReturn(acc); + + //ISOLATED NETWORK + when(networkModel.isProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NiciraNvp)).thenReturn(true); + + PublicIp sourceNatIp = mock(PublicIp.class); + Ip ip = mock(Ip.class); + when(ip.addr()).thenReturn("10.0.0.0"); + when(sourceNatIp.getAddress()).thenReturn(ip); + when(sourceNatIp.getVlanNetmask()).thenReturn("255.255.255.0"); + when(sourceNatIp.getVlanTag()).thenReturn("111"); + + when(ipAddressManager.assignSourceNatIpAddressToGuestNetwork(acc, network)).thenReturn(sourceNatIp); + when(network.getGateway()).thenReturn(NETWORK_GATEWAY); + when(network.getCidr()).thenReturn(NETWORK_CIDR); + + final CreateLogicalRouterAnswer answer = mock(CreateLogicalRouterAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); } @Test @@ -214,4 +267,158 @@ public class NiciraNvpElementTest { } })); } + + @Test + public void implementSharedNetworkUuidVlanIdTest() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // SHARED NETWORKS CASE 1: LOGICAL ROUTER'S UUID AS VLAN ID + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 1 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(true); + when(network.getCidr()).thenReturn(NETWORK_CIDR); + when(network.getGateway()).thenReturn(NETWORK_GATEWAY); + + NiciraNvpRouterMappingVO mapping = mock(NiciraNvpRouterMappingVO.class); + when(mapping.getLogicalRouterUuid()).thenReturn("xxxx-xxxx-xxxx"); + when(niciraNvpRouterMappingDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping); + + final ConfigureSharedNetworkUuidAnswer answer = mock(ConfigureSharedNetworkUuidAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); + } + + @Test + public void implementSharedNetworkNumericalVlanIdTest() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // SHARED NETWORKS CASE 2: NUMERICAL VLAN ID + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 2 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(false); + + VlanVO vlanVO = mock(VlanVO.class); + when(vlanVO.getVlanTag()).thenReturn("111"); + when(vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Arrays.asList(new VlanVO[] {vlanVO})); + + when(niciraNvpHost.getDetail("l2gatewayserviceuuid")).thenReturn("bbbb-bbbb-bbbb"); + + final ConfigureSharedNetworkVlanIdAnswer answer = mock(ConfigureSharedNetworkVlanIdAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); + } + + @Test(expected=CloudRuntimeException.class) + public void implementSharedNetworkNumericalVlanIdWithoutL2GatewayService() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 2 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(false); + + VlanVO vlanVO = mock(VlanVO.class); + when(vlanVO.getVlanTag()).thenReturn("111"); + when(vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Arrays.asList(new VlanVO[] {vlanVO})); + + when(niciraNvpHost.getDetail("l2gatewayserviceuuid")).thenReturn(null); + + element.implement(network, offering, dest, context); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java index 36e4643..d7c83b4 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java @@ -129,10 +129,10 @@ public class NiciraNvpGuestNetworkGuruTest { when(offering.getTrafficType()).thenReturn(TrafficType.Management); assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); - // Not supported: GuestType Shared + // Supported: GuestType Shared when(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Shared); - assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet)); // Not supported: Basic networking when(offering.getGuestType()).thenReturn(GuestType.Isolated); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c6763718/server/src/com/cloud/network/guru/DirectNetworkGuru.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index f741651..09afd6b 100644 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -120,7 +120,8 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { protected boolean canHandle(NetworkOffering offering, DataCenter dc) { // this guru handles only Guest networks in Advance zone with source nat service disabled if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == GuestType.Shared - && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp)) { + && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp) + && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NiciraNvp)) { return true; } else { s_logger.trace("We only take care of Guest networks of type " + GuestType.Shared);