mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-9317: Fixed disable static nat on leaving ips on interface
This commit is contained in:
parent
7434d91614
commit
c20e0ef88f
@ -38,6 +38,7 @@ public abstract class NetworkElementCommand extends Command {
|
|||||||
public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private";
|
public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private";
|
||||||
public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default";
|
public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default";
|
||||||
public static final String ROUTER_MONITORING_ENABLE = "router.monitor.enable";
|
public static final String ROUTER_MONITORING_ENABLE = "router.monitor.enable";
|
||||||
|
public static final String NETWORK_PUB_LAST_IP = "newtork.public.last.ip";
|
||||||
|
|
||||||
private String routerAccessIp;
|
private String routerAccessIp;
|
||||||
|
|
||||||
|
|||||||
@ -1734,6 +1734,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
|
|
||||||
final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||||
final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||||
|
final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
|
||||||
Connect conn;
|
Connect conn;
|
||||||
|
|
||||||
|
|
||||||
@ -1770,11 +1771,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
}
|
}
|
||||||
nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
|
nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
|
||||||
|
|
||||||
if (numOfIps == 1 && !ip.isAdd()) {
|
if (lastIp != null && !ip.isAdd()) {
|
||||||
|
// in isolated network eth2 is the default public interface. We don't want to delete it.
|
||||||
|
if (nicNum != 2) {
|
||||||
vifHotUnPlug(conn, routerName, ip.getVifMacAddress());
|
vifHotUnPlug(conn, routerName, ip.getVifMacAddress());
|
||||||
networkUsage(routerIp, "deleteVif", "eth" + nicNum);
|
networkUsage(routerIp, "deleteVif", "eth" + nicNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (final LibvirtException e) {
|
} catch (final LibvirtException e) {
|
||||||
s_logger.error("ipassoccmd failed", e);
|
s_logger.error("ipassoccmd failed", e);
|
||||||
|
|||||||
@ -595,6 +595,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
final Connection conn = getConnection();
|
final Connection conn = getConnection();
|
||||||
final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||||
final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||||
|
final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final IpAddressTO[] ips = cmd.getIpAddresses();
|
final IpAddressTO[] ips = cmd.getIpAddresses();
|
||||||
final int ipsCount = ips.length;
|
final int ipsCount = ips.length;
|
||||||
@ -625,15 +627,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
|
|
||||||
// there is only one ip in this public vlan and removing it, so
|
// there is only one ip in this public vlan and removing it, so
|
||||||
// remove the nic
|
// remove the nic
|
||||||
if (ipsCount == 1 && !ip.isAdd()) {
|
if (lastIp != null && !ip.isAdd()) {
|
||||||
|
final VIF correctVif = getCorrectVif(conn, router, network);
|
||||||
|
// in isolated network eth2 is the default public interface. We don't want to delete it.
|
||||||
|
if (correctVif != null && !correctVif.getDevice(conn).equals("2")) {
|
||||||
removeVif = true;
|
removeVif = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (removeVif) {
|
if (removeVif) {
|
||||||
|
|
||||||
// Determine the correct VIF on DomR to
|
// Determine the correct VIF on DomR to
|
||||||
// associate/disassociate the
|
// associate/disassociate the
|
||||||
// IP address with
|
// IP address with
|
||||||
|
|
||||||
final VIF correctVif = getCorrectVif(conn, router, network);
|
final VIF correctVif = getCorrectVif(conn, router, network);
|
||||||
if (correctVif != null) {
|
if (correctVif != null) {
|
||||||
network = correctVif.getNetwork(conn);
|
network = correctVif.getNetwork(conn);
|
||||||
@ -5222,7 +5229,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
//Remove the folder before creating it.
|
//Remove the folder before creating it.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
deleteLocalFolder("/tmp/"+isoPath);
|
deleteLocalFolder("/tmp/" + isoPath);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
|
s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
|||||||
@ -1716,6 +1716,22 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||||||
|
|
||||||
Random _rand = new Random(System.currentTimeMillis());
|
Random _rand = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of public IPs that need to be applied for a static NAT enable/disable operation.
|
||||||
|
* Manipulating only these ips prevents concurrency issues when disabling static nat at the same time.
|
||||||
|
* @param staticNats
|
||||||
|
* @return The list of IPs that need to be applied for the static NAT to work.
|
||||||
|
*/
|
||||||
|
public List<IPAddressVO> getStaticNatSourceIps(List<? extends StaticNat> staticNats) {
|
||||||
|
List<IPAddressVO> userIps = new ArrayList<>();
|
||||||
|
|
||||||
|
for (StaticNat snat : staticNats) {
|
||||||
|
userIps.add(_ipAddressDao.findById(snat.getSourceIpAddressId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return userIps;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException {
|
public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException {
|
||||||
if (staticNats == null || staticNats.size() == 0) {
|
if (staticNats == null || staticNats.size() == 0) {
|
||||||
@ -1732,8 +1748,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the list of public ip's owned by the network
|
List<IPAddressVO> userIps = getStaticNatSourceIps(staticNats);
|
||||||
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
|
||||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||||
if (userIps != null && !userIps.isEmpty()) {
|
if (userIps != null && !userIps.isEmpty()) {
|
||||||
for (IPAddressVO userIp : userIps) {
|
for (IPAddressVO userIp : userIps) {
|
||||||
|
|||||||
@ -84,6 +84,7 @@ import com.cloud.network.dao.FirewallRulesDao;
|
|||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.network.dao.NetworkDao;
|
import com.cloud.network.dao.NetworkDao;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
|
import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
|
||||||
import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
||||||
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
|
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
|
||||||
@ -175,6 +176,8 @@ public class CommandSetupHelper {
|
|||||||
@Inject
|
@Inject
|
||||||
private IPAddressDao _ipAddressDao;
|
private IPAddressDao _ipAddressDao;
|
||||||
@Inject
|
@Inject
|
||||||
|
private FirewallRulesDao _firewallsDao;
|
||||||
|
@Inject
|
||||||
private GuestOSDao _guestOSDao;
|
private GuestOSDao _guestOSDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -845,6 +848,21 @@ public class CommandSetupHelper {
|
|||||||
associatedWithNetworkId = ipAddrList.get(0).getNetworkId();
|
associatedWithNetworkId = ipAddrList.get(0).getNetworkId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for network if the ips does not have any rules, then only last ip
|
||||||
|
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(associatedWithNetworkId, null);
|
||||||
|
|
||||||
|
int ipsWithrules = 0;
|
||||||
|
int ipsStaticNat = 0;
|
||||||
|
for (IPAddressVO ip : userIps) {
|
||||||
|
if ( _firewallsDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active) > 0 ) {
|
||||||
|
ipsWithrules++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip.isOneToOneNat()) {
|
||||||
|
ipsStaticNat++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final IpAssocCommand cmd = new IpAssocCommand(ipsToSend);
|
final IpAssocCommand cmd = new IpAssocCommand(ipsToSend);
|
||||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
|
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
|
||||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(associatedWithNetworkId, router.getId()));
|
cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(associatedWithNetworkId, router.getId()));
|
||||||
@ -852,6 +870,17 @@ public class CommandSetupHelper {
|
|||||||
final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
|
final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
|
||||||
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
|
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
|
||||||
|
|
||||||
|
boolean remove = false;
|
||||||
|
// if there is only one static nat then it will be checked for remove at the resource
|
||||||
|
if (ipsWithrules == 0 && (ipsStaticNat == 0 || ipsStaticNat == 1)) {
|
||||||
|
remove = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove) {
|
||||||
|
// there is only one ip address for the network.
|
||||||
|
cmd.setAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP, "true");
|
||||||
|
}
|
||||||
|
|
||||||
cmds.addCommand(ipAssocCommand, cmd);
|
cmds.addCommand(ipAssocCommand, cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
71
server/test/com/cloud/network/IpAddressManagerTest.java
Normal file
71
server/test/com/cloud/network/IpAddressManagerTest.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// 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 org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
|
import com.cloud.network.rules.StaticNat;
|
||||||
|
import com.cloud.network.rules.StaticNatImpl;
|
||||||
|
import com.cloud.utils.net.Ip;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.anyLong;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
public class IpAddressManagerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
IPAddressDao _ipAddrDao;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
IpAddressManagerImpl _ipManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetStaticNatSourceIps() {
|
||||||
|
String publicIpAddress = "192.168.1.3";
|
||||||
|
IPAddressVO vo = mock(IPAddressVO.class);
|
||||||
|
when(vo.getAddress()).thenReturn(new Ip(publicIpAddress));
|
||||||
|
when(vo.getId()).thenReturn(1l);
|
||||||
|
|
||||||
|
when(_ipAddrDao.findById(anyLong())).thenReturn(vo);
|
||||||
|
StaticNat snat = new StaticNatImpl(1, 1, 1, 1, publicIpAddress, false);
|
||||||
|
|
||||||
|
List<IPAddressVO> ips = _ipManager.getStaticNatSourceIps(Collections.singletonList(snat));
|
||||||
|
Assert.assertNotNull(ips);
|
||||||
|
Assert.assertEquals(1, ips.size());
|
||||||
|
|
||||||
|
IPAddressVO returnedVO = ips.get(0);
|
||||||
|
Assert.assertEquals(vo, returnedVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user