CLOUDSTACK-5861: networks that failed to implement can not be destroyed

introduces a force option in delete network to forcifully delete a
network. This comes handy in rare cases where network fails to implenet
and network is in shutdown state, but network shutdown to rollback
implement process fails as well.

Conflicts:
	api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java
	server/src/com/cloud/user/DomainManagerImpl.java
This commit is contained in:
Murali Reddy 2014-01-13 23:20:54 +05:30
parent 470f251cbb
commit af657b3d71
10 changed files with 25 additions and 14 deletions

View File

@ -64,7 +64,7 @@ public interface NetworkService {
Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd);
boolean deleteNetwork(long networkId);
boolean deleteNetwork(long networkId, boolean forced);
boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;

View File

@ -45,6 +45,10 @@ public class DeleteNetworkCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the ID of the network")
private Long id;
@Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force delete a network." +
" Network will be marked as 'Destroy' even when commands to shutdown and cleanup to the backend fails.")
private Boolean forced;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -53,6 +57,10 @@ public class DeleteNetworkCmd extends BaseAsyncCmd {
return id;
}
public boolean isForced() {
return (forced != null) ? forced : false;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -65,7 +73,7 @@ public class DeleteNetworkCmd extends BaseAsyncCmd {
@Override
public void execute() {
CallContext.current().setEventDetails("Network Id: " + id);
boolean result = _networkService.deleteNetwork(id);
boolean result = _networkService.deleteNetwork(id, isForced());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);

View File

@ -125,7 +125,7 @@ public interface NetworkOrchestrationService {
boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements);
boolean destroyNetwork(long networkId, ReservationContext context);
boolean destroyNetwork(long networkId, ReservationContext context, boolean forced);
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,

View File

@ -2068,7 +2068,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Override
@DB
public boolean destroyNetwork(long networkId, final ReservationContext context) {
public boolean destroyNetwork(long networkId, final ReservationContext context, boolean forced) {
final Account callerAccount = context.getAccount();
NetworkVO network = _networksDao.findById(networkId);
@ -2111,7 +2111,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
// get updated state for the network
network = _networksDao.findById(networkId);
if (network.getState() != Network.State.Allocated && network.getState() != Network.State.Setup) {
if (network.getState() != Network.State.Allocated && network.getState() != Network.State.Setup && !forced) {
s_logger.debug("Network is not not in the correct state to be destroyed: " + network.getState());
return false;
}

View File

@ -179,7 +179,7 @@ public class NetworkProviderTest extends TestCase {
List<? extends Network> list = _networkService.getIsolatedNetworksOwnedByAccountInZone(zone.getId(), system);
for (Network net : list) {
s_logger.debug("Delete network " + net.getName());
_networkService.deleteNetwork(net.getId());
_networkService.deleteNetwork(net.getId(), false);
}
}

View File

@ -1762,7 +1762,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Override
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_DELETE, eventDescription = "deleting network", async = true)
public boolean deleteNetwork(long networkId) {
public boolean deleteNetwork(long networkId, boolean forced) {
Account caller = CallContext.current().getCallingAccount();
@ -1788,10 +1788,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// Perform permission check
_accountMgr.checkAccess(caller, null, true, network);
if (forced && !_accountMgr.isRootAdmin(caller.getType())) {
throw new InvalidParameterValueException("Delete network with 'forced' option can only be called by root admins");
}
User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
return _networkMgr.destroyNetwork(networkId, context);
return _networkMgr.destroyNetwork(networkId, context, forced);
}
@Override

View File

@ -1565,7 +1565,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
_ntwkMgr.destroyNetwork(networkId, context);
_ntwkMgr.destroyNetwork(networkId, context, false);
s_logger.debug("Deleted private network id=" + networkId);
}

View File

@ -679,7 +679,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller);
if (!_networkMgr.destroyNetwork(network.getId(), context)) {
if (!_networkMgr.destroyNetwork(network.getId(), context, false)) {
s_logger.warn("Unable to destroy network " + network + " as a part of account id=" + accountId + " cleanup.");
accountCleanupNeeded = true;
networksDeleted = false;

View File

@ -395,8 +395,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(ctx.getCallingUserId()), ctx.getCallingAccount());
for (Long networkId : networkIds) {
s_logger.debug("Deleting network id=" + networkId + " as a part of domain id=" + domainId + " cleanup");
if (!_networkMgr.destroyNetwork(networkId, context)) {
if (!_networkMgr.destroyNetwork(networkId, context, false)) {
s_logger.warn("Unable to destroy network id=" + networkId + " as a part of domain id=" + domainId + " cleanup.");
networksDeleted = false;
} else {

View File

@ -203,7 +203,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
* @see com.cloud.network.NetworkService#deleteNetwork(long)
*/
@Override
public boolean deleteNetwork(long networkId) {
public boolean deleteNetwork(long networkId, boolean forced) {
// TODO Auto-generated method stub
return false;
}
@ -597,7 +597,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
* @see com.cloud.network.NetworkManager#destroyNetwork(long, com.cloud.vm.ReservationContext)
*/
@Override
public boolean destroyNetwork(long networkId, ReservationContext context) {
public boolean destroyNetwork(long networkId, ReservationContext context, boolean forced) {
// TODO Auto-generated method stub
return false;
}