diff --git a/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java index daeb9dd40d3..de97686a9af 100644 --- a/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java +++ b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java @@ -129,7 +129,7 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd { @Override public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException, ResourceUnavailableException { - PrivateGateway result = _vpcService.applyVpcPrivateGateway(getEntityId()); + PrivateGateway result = _vpcService.applyVpcPrivateGateway(getEntityId(), true); if (result != null) { PrivateGatewayResponse response = _responseGenerator.createPrivateGatewayResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/response/AsyncJobResponse.java b/api/src/com/cloud/api/response/AsyncJobResponse.java index 153d1a8619b..b2176793cb6 100644 --- a/api/src/com/cloud/api/response/AsyncJobResponse.java +++ b/api/src/com/cloud/api/response/AsyncJobResponse.java @@ -136,6 +136,10 @@ public class AsyncJobResponse extends BaseResponse { this.jobInstanceId.setTableName("autoscale_vmprofiles"); } else if (jobInstanceType.equalsIgnoreCase(AsyncJob.Type.AutoScaleVmGroup.toString())) { this.jobInstanceId.setTableName("autoscale_vmgroups"); + } else if (jobInstanceType.equalsIgnoreCase(AsyncJob.Type.StaticRoute.toString())) { + this.jobInstanceId.setTableName("static_routes"); + } else if (jobInstanceType.equalsIgnoreCase(AsyncJob.Type.PrivateGateway.toString())) { + this.jobInstanceId.setTableName("vpc_gateways"); } else if (!jobInstanceType.equalsIgnoreCase(AsyncJob.Type.None.toString())){ // TODO : when we hit here, we need to add instanceType -> UUID entity table mapping assert(false); diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index e478ec0b3df..707443da106 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -168,11 +168,12 @@ public interface VpcService { /** * @param gatewayId + * @param destroyOnFailure TODO * @return * @throws ResourceUnavailableException * @throws ConcurrentOperationException */ - public PrivateGateway applyVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException; + public PrivateGateway applyVpcPrivateGateway(long gatewayId, boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException; /** * @param id @@ -180,7 +181,7 @@ public interface VpcService { * @throws ResourceUnavailableException * @throws ConcurrentOperationException */ - boolean deleteVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException; + boolean deleteVpcPrivateGateway(long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException; /** * @param listPrivateGatewaysCmd diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 8d61fe9076b..7cb7796ef1d 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1005,7 +1005,11 @@ public class VpcManagerImpl implements VpcManager, Manager{ } + @DB protected void validateNewVpcGuestNetwork(String cidr, String gateway, Account networkOwner, Vpc vpc, String networkDomain) { + + Transaction txn = Transaction.currentTxn(); + txn.start(); Vpc locked = _vpcDao.acquireInLockTable(vpc.getId()); if (locked == null) { throw new CloudRuntimeException("Unable to acquire lock on " + vpc); @@ -1070,7 +1074,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr broadcast ip", null); } - + txn.commit(); } finally { s_logger.debug("Releasing lock for " + locked); _vpcDao.releaseFromLockTable(locked.getId()); @@ -1258,16 +1262,14 @@ public class VpcManagerImpl implements VpcManager, Manager{ @Override - @DB - public PrivateGateway applyVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { - VpcGatewayVO vo = _vpcGatewayDao.acquireInLockTable(gatewayId); - if (vo == null) { - throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId); - } + public PrivateGateway applyVpcPrivateGateway(long gatewayId, boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException { + VpcGatewayVO vo = _vpcGatewayDao.findById(gatewayId); + boolean success = false; try { PrivateGateway gateway = getVpcPrivateGateway(gatewayId); - if (getVpcElement().createPrivateGateway(gateway)) { + success = getVpcElement().createPrivateGateway(gateway); + if (success) { s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); if (vo.getState() != VpcGateway.State.Ready) { vo.setState(VpcGateway.State.Ready); @@ -1280,32 +1282,45 @@ public class VpcManagerImpl implements VpcManager, Manager{ return null; } } finally { - if (vo != null) { - _vpcGatewayDao.releaseFromLockTable(gatewayId); + //do cleanup + if (!success) { + if (destroyOnFailure) { + s_logger.debug("Destroying private gateway " + vo + " that failed to start"); + if (deleteVpcPrivateGateway(gatewayId)) { + s_logger.warn("Successfully destroyed vpc " + vo + " that failed to start"); + } else { + s_logger.warn("Failed to destroy vpc " + vo + " that failed to start"); + } + } } - } + } } @Override @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway") @DB - public boolean deleteVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean deleteVpcPrivateGateway(long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { + + Transaction txn = Transaction.currentTxn(); + txn.start(); VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId); if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) { throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId); } - try { - _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); - s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting); + try { //don't allow to remove gateway when there are static routes associated with it long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); if (routeCount > 0) { throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + " static routes applied. Remove the routes first"); } - + gatewayVO.setState(VpcGateway.State.Deleting); + _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO); + s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting); + + txn.commit(); //1) delete the gateway on the backend PrivateGateway gateway = getVpcPrivateGateway(gatewayId);