From a28a19962aa4df91a4b4f17e8affc59c300f907e Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 19 Apr 2013 14:38:09 +0200 Subject: [PATCH] CLOUDSTACK-2092 Don't push IP to the Nicira Controller when it is about to be released. --- .../network/element/NiciraNvpElement.java | 5 + .../network/element/NiciraNvpElementTest.java | 234 ++++++++++++------ 2 files changed, 167 insertions(+), 72 deletions(-) diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index 3ca34473cd7..c22f669796c 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -843,6 +843,11 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer { List cidrs = new ArrayList(); for (PublicIpAddress ip : ipAddress) { + if (ip.getState() == IpAddress.State.Releasing) { + // If we are releasing we don't need to push this ip to + // the Logical Router + continue; + } cidrs.add(ip.getAddress().addr() + "/" + NetUtils.getCidrSize(ip.getNetmask())); } ConfigurePublicIpsOnLogicalRouterCommand cmd = new ConfigurePublicIpsOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java index 09d50a33a64..40685fa4236 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java @@ -16,107 +16,197 @@ // under the License. package com.cloud.network.element; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import javax.naming.ConfigurationException; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentMatcher; +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.deploy.DeployDestination; import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.network.Network; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.IpAddress; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkModel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.NiciraNvpDeviceVO; +import com.cloud.network.NiciraNvpRouterMappingVO; +import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NiciraNvpDao; +import com.cloud.network.dao.NiciraNvpRouterMappingDao; +import com.cloud.network.nicira.NatRule; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; import com.cloud.user.Account; +import com.cloud.utils.net.Ip; import com.cloud.vm.ReservationContext; import static org.junit.Assert.*; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; public class NiciraNvpElementTest { - - NiciraNvpElement _element = new NiciraNvpElement(); - NetworkManager _networkManager = mock(NetworkManager.class); - NetworkModel _networkModel = mock(NetworkModel.class); - NetworkServiceMapDao _ntwkSrvcDao = mock (NetworkServiceMapDao.class); - - @Before - public void setUp() throws ConfigurationException { - _element._resourceMgr = mock(ResourceManager.class); - _element._networkManager = _networkManager; - _element._ntwkSrvcDao = _ntwkSrvcDao; - _element._networkModel = _networkModel; - - // Standard responses - when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(true); - - _element.configure("NiciraNvpTestElement", Collections. emptyMap()); - } - @Test - public void canHandleTest() { - Network net = mock(Network.class); - when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); - when(net.getId()).thenReturn(42L); - - when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); - // Golden path - assertTrue(_element.canHandle(net, Service.Connectivity)); - - when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan); - // Only broadcastdomaintype lswitch is supported - assertFalse(_element.canHandle(net, Service.Connectivity)); - - when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); - when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(false); - // No nvp provider in the network - assertFalse(_element.canHandle(net, Service.Connectivity)); - - when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(false); - when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); - // NVP provider does not provide Connectivity for this network - assertFalse(_element.canHandle(net, Service.Connectivity)); - - when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(true); - // Only service Connectivity is supported - assertFalse(_element.canHandle(net, Service.Dhcp)); - - } - - @Test - public void implementTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - Network network = mock(Network.class); - when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); - when(network.getId()).thenReturn(42L); - - NetworkOffering offering = mock(NetworkOffering.class); - when(offering.getId()).thenReturn(42L); - when(offering.getTrafficType()).thenReturn(TrafficType.Guest); - when(offering.getGuestType()).thenReturn(GuestType.Isolated); - - DeployDestination dest = mock(DeployDestination.class); - - Domain dom = mock(Domain.class); - when(dom.getName()).thenReturn("domain"); - Account acc = mock(Account.class); - when(acc.getAccountName()).thenReturn("accountname"); - ReservationContext context = mock(ReservationContext.class); - when(context.getDomain()).thenReturn(dom); - when(context.getAccount()).thenReturn(acc); - - //assertTrue(_element.implement(network, offering, dest, context)); - } + NiciraNvpElement _element = new NiciraNvpElement(); + NetworkManager _networkManager = mock(NetworkManager.class); + NetworkModel _networkModel = mock(NetworkModel.class); + NetworkServiceMapDao _ntwkSrvcDao = mock(NetworkServiceMapDao.class); + AgentManager _agentManager = mock(AgentManager.class); + HostDao _hostDao = mock(HostDao.class); + NiciraNvpDao _niciraNvpDao = mock(NiciraNvpDao.class); + NiciraNvpRouterMappingDao _niciraNvpRouterMappingDao = mock(NiciraNvpRouterMappingDao.class); -} + @Before + public void setUp() throws ConfigurationException { + _element._resourceMgr = mock(ResourceManager.class); + _element._networkManager = _networkManager; + _element._ntwkSrvcDao = _ntwkSrvcDao; + _element._networkModel = _networkModel; + _element._agentMgr = _agentManager; + _element._hostDao = _hostDao; + _element._niciraNvpDao = _niciraNvpDao; + _element._niciraNvpRouterMappingDao = _niciraNvpRouterMappingDao; + + // Standard responses + when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(true); + + _element.configure("NiciraNvpTestElement", Collections. emptyMap()); + } + + @Test + public void canHandleTest() { + Network net = mock(Network.class); + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(net.getId()).thenReturn(42L); + + when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + // Golden path + assertTrue(_element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan); + // Only broadcastdomaintype lswitch is supported + assertFalse(_element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(false); + // No nvp provider in the network + assertFalse(_element.canHandle(net, Service.Connectivity)); + + when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(false); + when(_ntwkSrvcDao.canProviderSupportServiceInNetwork(42L, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + // NVP provider does not provide Connectivity for this network + assertFalse(_element.canHandle(net, Service.Connectivity)); + + when(_networkModel.isProviderForNetwork(Provider.NiciraNvp, 42L)).thenReturn(true); + // Only service Connectivity is supported + assertFalse(_element.canHandle(net, Service.Dhcp)); + + } + + @Test + public void implementTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getId()).thenReturn(42L); + + NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(42L); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + DeployDestination dest = mock(DeployDestination.class); + + Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + // assertTrue(_element.implement(network, offering, dest, context)); + } + + @Test + public void applyIpTest() throws ResourceUnavailableException { + Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getId()).thenReturn(42L); + when(network.getPhysicalNetworkId()).thenReturn(42L); + + NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(42L); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + List ipAddresses = new ArrayList(); + PublicIpAddress pipReleased = mock(PublicIpAddress.class); + PublicIpAddress pipAllocated = mock(PublicIpAddress.class); + Ip ipReleased = new Ip("42.10.10.10"); + Ip ipAllocated = new Ip("10.10.10.10"); + when(pipAllocated.getState()).thenReturn(IpAddress.State.Allocated); + when(pipAllocated.getAddress()).thenReturn(ipAllocated); + when(pipAllocated.getNetmask()).thenReturn("255.255.255.0"); + when(pipReleased.getState()).thenReturn(IpAddress.State.Releasing); + when(pipReleased.getAddress()).thenReturn(ipReleased); + when(pipReleased.getNetmask()).thenReturn("255.255.255.0"); + ipAddresses.add(pipAllocated); + ipAddresses.add(pipReleased); + + Set services = new HashSet(); + services.add(Service.SourceNat); + services.add(Service.StaticNat); + services.add(Service.PortForwarding); + + List deviceList = new ArrayList(); + NiciraNvpDeviceVO nndVO = mock(NiciraNvpDeviceVO.class); + NiciraNvpRouterMappingVO nnrmVO = mock(NiciraNvpRouterMappingVO.class); + when(_niciraNvpRouterMappingDao.findByNetworkId(42L)).thenReturn(nnrmVO); + when(nnrmVO.getLogicalRouterUuid()).thenReturn("abcde"); + when(nndVO.getHostId()).thenReturn(42L); + HostVO hvo = mock(HostVO.class); + when(hvo.getId()).thenReturn(42L); + when(hvo.getDetail("l3gatewayserviceuuid")).thenReturn("abcde"); + when(_hostDao.findById(42L)).thenReturn(hvo); + deviceList.add(nndVO); + when(_niciraNvpDao.listByPhysicalNetwork(42L)).thenReturn(deviceList); + + ConfigurePublicIpsOnLogicalRouterAnswer answer = mock(ConfigurePublicIpsOnLogicalRouterAnswer.class); + when(answer.getResult()).thenReturn(true); + when(_agentManager.easySend(eq(42L), any(ConfigurePublicIpsOnLogicalRouterCommand.class))).thenReturn(answer); + + assertTrue(_element.applyIps(network, ipAddresses, services)); + + verify(_agentManager, atLeast(1)).easySend(eq(42L), + argThat(new ArgumentMatcher() { + @Override + public boolean matches(Object argument) { + ConfigurePublicIpsOnLogicalRouterCommand command = (ConfigurePublicIpsOnLogicalRouterCommand) argument; + if (command.getPublicCidrs().size() == 1) + return true; + return false; + } + })); + } +} \ No newline at end of file