Skip to content

Commit 9856b81

Browse files
author
Pearl Dsilva
committed
Add check to prevent deletion of n/w resources when last VM/non-persistent network is deleted but there exists another n/w with overlapping vlan which is persistent
1 parent 2b65552 commit 9856b81

File tree

9 files changed

+67
-10
lines changed

9 files changed

+67
-10
lines changed

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
import javax.inject.Inject;
4141
import javax.naming.ConfigurationException;
4242

43+
import com.cloud.api.query.dao.DomainRouterJoinDao;
4344
import com.cloud.api.query.dao.UserVmJoinDao;
45+
import com.cloud.api.query.vo.DomainRouterJoinVO;
4446
import com.cloud.api.query.vo.UserVmJoinVO;
4547
import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
4648
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@@ -356,6 +358,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
356358
private UserVmJoinDao userVmJoinDao;
357359
@Inject
358360
private NetworkOfferingDao networkOfferingDao;
361+
@Inject
362+
private DomainRouterJoinDao domainRouterJoinDao;
359363

360364
VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
361365

@@ -1844,14 +1848,29 @@ private void orchestrateStop(final String vmUuid, final boolean cleanUpEvenIfUna
18441848
advanceStop(vm, cleanUpEvenIfUnableToStop);
18451849
}
18461850

1851+
private void getPersistenceMap(Map<String, Boolean> vlanToPersistenceMap, NetworkVO networkVO) {
1852+
NetworkOfferingVO offeringVO = networkOfferingDao.findById(networkVO.getNetworkOfferingId());
1853+
Pair<String, Boolean> data = getVMNetworkDetails(networkVO, offeringVO.isPersistent());
1854+
Boolean shouldDeleteNwResource = MapUtils.isNotEmpty(vlanToPersistenceMap) ? vlanToPersistenceMap.get(data.first()) : null;
1855+
if (shouldDeleteNwResource == null || shouldDeleteNwResource){
1856+
vlanToPersistenceMap.put(data.first(), data.second());
1857+
}
1858+
}
1859+
18471860
private Map<String, Boolean> getVlanToPersistenceMapForVM(long vmId) {
18481861
List<UserVmJoinVO> userVmJoinVOS = userVmJoinDao.searchByIds(vmId);
18491862
Map<String, Boolean> vlanToPersistenceMap = new HashMap<>();
18501863
for (UserVmJoinVO userVmJoinVO : userVmJoinVOS) {
18511864
NetworkVO networkVO = _networkDao.findById(userVmJoinVO.getNetworkId());
1852-
NetworkOfferingVO offeringVO = networkOfferingDao.findById(networkVO.getNetworkOfferingId());
1853-
Pair<String, Boolean> data = getVMNetworkDetails(networkVO, offeringVO.isPersistent());
1854-
vlanToPersistenceMap.put(data.first(), data.second());
1865+
getPersistenceMap(vlanToPersistenceMap, networkVO);
1866+
}
1867+
if (userVmJoinVOS.isEmpty()) {
1868+
VMInstanceVO vmInstanceVO = _vmDao.findById(vmId);
1869+
if (vmInstanceVO.getType() == VirtualMachine.Type.DomainRouter) {
1870+
DomainRouterJoinVO routerVO = domainRouterJoinDao.findById(vmId);
1871+
NetworkVO networkVO = _networkDao.findById(routerVO.getNetworkId());
1872+
getPersistenceMap(vlanToPersistenceMap, networkVO);
1873+
}
18551874
}
18561875
return vlanToPersistenceMap;
18571876
}
@@ -1869,9 +1888,15 @@ private Pair<String, Boolean> getVMNetworkDetails(NetworkVO networkVO, boolean i
18691888
URI broadcastUri = networkVO.getBroadcastUri();
18701889
String scheme = broadcastUri.getScheme();
18711890
String vlanId = Networks.BroadcastDomainType.getValue(broadcastUri);
1872-
Boolean shouldDelete = !((networkVO.getGuestType() == Network.GuestType.L2 || networkVO.getGuestType() == Network.GuestType.Isolated) &&
1891+
boolean shouldDelete = !((networkVO.getGuestType() == Network.GuestType.L2 || networkVO.getGuestType() == Network.GuestType.Isolated) &&
18731892
(scheme.equalsIgnoreCase("vlan"))
18741893
&& isPersistent);
1894+
if (shouldDelete) {
1895+
int persistentNetworksCount = _networkDao.getOtherPersistentNetworksCount(networkVO.getId(), networkVO.getBroadcastUri().toString(), true);
1896+
if (persistentNetworksCount > 0) {
1897+
shouldDelete = false;
1898+
}
1899+
}
18751900
return new Pair<>(vlanId, shouldDelete);
18761901
}
18771902

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2962,7 +2962,8 @@ private void cleanupPersistentnNetworkResources(NetworkVO network) {
29622962
long networkOfferingId = network.getNetworkOfferingId();
29632963
NetworkOfferingVO offering = _networkOfferingDao.findById(networkOfferingId);
29642964
if (offering != null) {
2965-
if (networkMeetsPersistenceCriteria(network, offering, true)) {
2965+
if (networkMeetsPersistenceCriteria(network, offering, true) &&
2966+
_networksDao.getOtherPersistentNetworksCount(network.getId(), network.getBroadcastUri().toString(), offering.isPersistent()) == 0) {
29662967
List<HostVO> hosts = resourceManager.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.Routing, network.getDataCenterId());
29672968
for (HostVO host : hosts) {
29682969
try {

engine/schema/src/main/java/com/cloud/network/dao/NetworkDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
4545

4646
List<NetworkVO> getNetworksForOffering(long offeringId, long dataCenterId, long accountId);
4747

48+
int getOtherPersistentNetworksCount(long id, String broadcastURI, boolean isPersistent);
49+
4850
@Override
4951
@Deprecated
5052
NetworkVO persist(NetworkVO vo);

engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
7979
SearchBuilder<NetworkVO> SourceNATSearch;
8080
GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
8181
SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
82+
SearchBuilder<NetworkVO> PersistentNetworkSearch;
8283

8384
GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
8485
SearchBuilder<NetworkVO> PrivateNetworkSearch;
@@ -181,6 +182,16 @@ protected void init() {
181182
CountBy.join("offerings", ntwkOffJoin, CountBy.entity().getNetworkOfferingId(), ntwkOffJoin.entity().getId(), JoinBuilder.JoinType.INNER);
182183
CountBy.done();
183184

185+
PersistentNetworkSearch = createSearchBuilder();
186+
PersistentNetworkSearch.and("id", PersistentNetworkSearch.entity().getId(), Op.NEQ);
187+
PersistentNetworkSearch.and("guestType", PersistentNetworkSearch.entity().getGuestType(), Op.IN);
188+
PersistentNetworkSearch.and("broadcastUri", PersistentNetworkSearch.entity().getBroadcastUri(), Op.EQ);
189+
PersistentNetworkSearch.and("removed", PersistentNetworkSearch.entity().getRemoved(), Op.NULL);
190+
final SearchBuilder<NetworkOfferingVO> persistentNtwkOffJoin = _ntwkOffDao.createSearchBuilder();
191+
persistentNtwkOffJoin.and("persistent", persistentNtwkOffJoin.entity().isPersistent(), Op.EQ);
192+
PersistentNetworkSearch.join("persistent", persistentNtwkOffJoin, PersistentNetworkSearch.entity().getNetworkOfferingId(), persistentNtwkOffJoin.entity().getId(), JoinType.INNER);
193+
PersistentNetworkSearch.done();
194+
184195
PhysicalNetworkSearch = createSearchBuilder();
185196
PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ);
186197
PhysicalNetworkSearch.done();
@@ -265,6 +276,8 @@ protected void init() {
265276
join10.and("vpc", join10.entity().getVpcId(), Op.EQ);
266277
PrivateNetworkSearch.join("vpcgateways", join10, PrivateNetworkSearch.entity().getId(), join10.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
267278
PrivateNetworkSearch.done();
279+
280+
268281
}
269282

270283
@Override
@@ -390,6 +403,18 @@ public List<NetworkVO> getNetworksForOffering(final long offeringId, final long
390403
return search(sc, null);
391404
}
392405

406+
@Override
407+
public int getOtherPersistentNetworksCount(long id, String broadcastURI, boolean isPersistent) {
408+
Object[] guestTypes = {"Isolated", "L2"};
409+
final SearchCriteria<NetworkVO> sc = PersistentNetworkSearch.create();
410+
sc.setParameters("id", id);
411+
sc.setParameters("broadcastUri", broadcastURI);
412+
sc.setParameters("guestType", guestTypes);
413+
sc.setJoinParameters("persistent", "persistent", isPersistent);
414+
List<NetworkVO> persistentNetworks = search(sc, null);
415+
return persistentNetworks.size();
416+
}
417+
393418
@Override
394419
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
395420
final SequenceFetcher fetch = SequenceFetcher.getInstance();

plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.ArrayList;
2121
import java.util.HashMap;
2222
import java.util.HashSet;
23-
import java.util.LinkedHashSet;
2423
import java.util.List;
2524
import java.util.Map;
2625
import java.util.Set;
@@ -68,7 +67,7 @@ public boolean start() {
6867
if (s_apiNameDiscoveryResponseMap == null) {
6968
long startTime = System.nanoTime();
7069
s_apiNameDiscoveryResponseMap = new HashMap<String, ApiDiscoveryResponse>();
71-
Set<Class<?>> cmdClasses = new LinkedHashSet<Class<?>>();
70+
Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
7271
for (PluggableService service : _services) {
7372
s_logger.debug(String.format("getting api commands of service: %s", service.getClass().getName()));
7473
cmdClasses.addAll(service.getCommands());

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ private String generateVxnetBrName(String pifName, String vnetId) {
289289
return "brvx-" + vnetId;
290290
}
291291

292-
public String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
292+
private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
293293
String nic = _pifs.get(pifKey);
294294
if (nic == null) {
295295
// if not found in bridge map, maybe traffic label refers to pif already?

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ private boolean shouldDeleteBridge(Map<String, Boolean> vlanToPersistenceMap, St
305305
if (MapUtils.isNotEmpty(vlanToPersistenceMap) && vlanId != null && vlanToPersistenceMap.containsKey(vlanId)) {
306306
return vlanToPersistenceMap.get(vlanId);
307307
}
308-
return false;
308+
return true;
309309
}
310310

311311
/**

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,6 @@ private boolean shouldDeleteBridge(Map<String, Boolean> vlanToPersistenceMap, St
103103
if (MapUtils.isNotEmpty(vlanToPersistenceMap) && vlanId != null && vlanToPersistenceMap.containsKey(vlanId)) {
104104
return vlanToPersistenceMap.get(vlanId);
105105
}
106-
return false;
106+
return true;
107107
}
108108
}

server/src/test/java/com/cloud/vpc/dao/MockNetworkDaoImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public List<NetworkVO> getNetworksForOffering(final long offeringId, final long
7474
return null;
7575
}
7676

77+
@Override
78+
public int getOtherPersistentNetworksCount(long id, String broadcastURI, boolean isPersistent) {
79+
return 0;
80+
}
81+
7782
@Override
7883
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
7984
return null;

0 commit comments

Comments
 (0)