From fbdf10bac7d78f018ef1d0af200348875aba2e18 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 25 May 2012 12:04:10 -0700 Subject: [PATCH] 1) Added search by vpcId to listRouters/listNetworks Apis 2) Don't allow to add new networks/implement existing ones for VPC in Disabled state. Disabled state indicates that there was unsuccessful attempt to remove the VPC, and the further cleanup will be taken care of by cleanup thread. --- .../cloud/api/commands/ListNetworksCmd.java | 10 ++- .../cloud/api/commands/ListRoutersCmd.java | 9 ++- .../api/commands/UpdateVPCOfferingCmd.java | 3 +- .../api/response/DomainRouterResponse.java | 9 ++- .../cloud/api/response/NetworkResponse.java | 7 ++ .../cloud/network/element/VpcProvider.java | 4 - api/src/com/cloud/network/vpc/VpcService.java | 4 +- .../src/com/cloud/api/ApiResponseHelper.java | 3 + .../com/cloud/network/NetworkManagerImpl.java | 39 +++++---- .../com/cloud/network/dao/IPAddressDao.java | 3 + .../cloud/network/dao/IPAddressDaoImpl.java | 13 +++ .../element/VpcVirtualRouterElement.java | 12 ++- .../src/com/cloud/network/vpc/Dao/VpcDao.java | 7 ++ .../com/cloud/network/vpc/Dao/VpcDaoImpl.java | 26 +++++- .../src/com/cloud/network/vpc/VpcManager.java | 13 +++ .../com/cloud/network/vpc/VpcManagerImpl.java | 80 +++++++++++++++---- server/src/com/cloud/network/vpc/VpcVO.java | 4 - .../cloud/server/ManagementServerImpl.java | 13 ++- .../com/cloud/user/AccountManagerImpl.java | 36 +++++++-- wscript | 2 +- 20 files changed, 243 insertions(+), 54 deletions(-) diff --git a/api/src/com/cloud/api/commands/ListNetworksCmd.java b/api/src/com/cloud/api/commands/ListNetworksCmd.java index e7bea4d2d2f..9197c548d78 100644 --- a/api/src/com/cloud/api/commands/ListNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -67,6 +67,10 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name=ApiConstants.SPECIFY_IP_RANGES, type=CommandType.BOOLEAN, description="true if need to list only networks which support specifying ip ranges") private Boolean specifyIpRanges; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -112,7 +116,11 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { return specifyIpRanges; } - ///////////////////////////////////////////////////// + public Long getVpcId() { + return vpcId; + } + + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @Override diff --git a/api/src/com/cloud/api/commands/ListRoutersCmd.java b/api/src/com/cloud/api/commands/ListRoutersCmd.java index 2e713e66988..0fb4dcc65c9 100644 --- a/api/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/api/src/com/cloud/api/commands/ListRoutersCmd.java @@ -18,7 +18,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -63,6 +62,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @IdentityMapper(entityTableName="networks") @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="list by network id") private Long networkId; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -95,6 +98,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Long getNetworkId() { return networkId; } + + public Long getVpcId() { + return vpcId; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java index a31a8acb29b..38a519b52f2 100644 --- a/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java +++ b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java @@ -46,7 +46,8 @@ public class UpdateVPCOfferingCmd extends BaseAsyncCmd{ @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC offering") private String displayText; - @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the VPC offering") + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the VPC offering; " + + "supported states - Enabled/Disabled") private String state; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/response/DomainRouterResponse.java b/api/src/com/cloud/api/response/DomainRouterResponse.java index 10c50f5eeec..bd7e7d07d6f 100644 --- a/api/src/com/cloud/api/response/DomainRouterResponse.java +++ b/api/src/com/cloud/api/response/DomainRouterResponse.java @@ -15,8 +15,8 @@ package com.cloud.api.response; import java.util.Date; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.cloud.vm.VirtualMachine.State; import com.google.gson.annotations.SerializedName; @@ -133,6 +133,9 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti @SerializedName("scriptsversion") @Param(description="the version of scripts") private String scriptsVersion; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + @Override public Long getObjectId() { return getId(); @@ -301,4 +304,8 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index 834248b8670..5cb2cb47a86 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -127,6 +127,9 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.SPECIFY_IP_RANGES) @Param(description="true if network supports specifying ip ranges, false otherwise") private Boolean specifyIpRanges; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + public void setId(Long id) { this.id.setValue(id); } @@ -268,4 +271,8 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes public void setSpecifyIpRanges(Boolean specifyIpRanges) { this.specifyIpRanges = specifyIpRanges; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/com/cloud/network/element/VpcProvider.java index e40d188f5e1..63d0ce5af2b 100644 --- a/api/src/com/cloud/network/element/VpcProvider.java +++ b/api/src/com/cloud/network/element/VpcProvider.java @@ -17,12 +17,8 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientNetworkCapacityException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; import com.cloud.network.vpc.Vpc; -import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachineProfile; /** * @author Alena Prokharchyk diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index 5c1ebb3ad4c..e60a5a4224e 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -33,8 +33,10 @@ public interface VpcService { public VpcOffering createVpcOffering(String name, String displayText, List supportedServices); public Vpc getVpc(long vpcId); + + public Vpc getActiveVpc(long vpcId); - public List getVpcNetworks(long vpcId); + public List getVpcNetworks(long vpcId); Map> getVpcOffSvcProvidersMap(long vpcOffId); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 079aa039d2a..187843c5720 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1650,6 +1650,8 @@ public class ApiResponseHelper implements ResponseGenerator { routerResponse.setDns1(zone.getDns1()); routerResponse.setDns2(zone.getDns2()); } + + routerResponse.setVpcId(router.getVpcId()); routerResponse.setObjectName("domainrouter"); return routerResponse; @@ -2884,6 +2886,7 @@ public class ApiResponseHelper implements ResponseGenerator { } response.setSpecifyIpRanges(network.getSpecifyIpRanges()); + response.setVpcId(network.getVpcId()); response.setObjectName("network"); return response; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 23a50dc5b61..21e1d54e984 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -187,7 +187,6 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -1168,8 +1167,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _ipAddressDao.markAsUnavailable(ip.getId()); if (!applyIpAssociations(network, true)) { // if fail to apply ip assciations again, unassign ip address without updating resource -// count and - // generating usage event as there is no need to keep it in the db + // count and generating usage event as there is no need to keep it in the db _ipAddressDao.unassignIpAddress(ip.getId()); } } catch (Exception e) { @@ -1185,7 +1183,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public boolean releasePublicIpAddress(long addrId, long userId, Account caller) { boolean success = true; - // Cleanup all ip address resources - PF/LB/Static nat rules if (!cleanupIpResources(addrId, userId, caller)) { success = false; @@ -1213,10 +1210,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } catch (ResourceUnavailableException e) { throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e); } + } else { + if (ip.getState() == IpAddress.State.Releasing) { + _ipAddressDao.unassignIpAddress(ip.getId()); + } } if (success) { - s_logger.debug("released a public ip id=" + addrId); + s_logger.debug("Released a public ip id=" + addrId); } return success; @@ -2428,9 +2429,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag //validate vpc if (vpcId != null) { - Vpc vpc = _vpcMgr.getVpc(vpcId); + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); if (vpc == null) { - throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); + throw new InvalidParameterValueException("Unable to find enabled vpc by id " + vpcId); } _accountMgr.checkAccess(caller, null, false, vpc); } @@ -2631,7 +2632,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, long vpcId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { - Vpc vpc = _vpcMgr.getVpc(vpcId); + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); //1) Validate if network can be created for VPC _vpcMgr.validateGuestNtkwForVpc(_configMgr.getNetworkOffering(ntwkOffId), cidr, networkDomain, owner, vpc); @@ -2895,6 +2896,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean listAll = cmd.listAll(); boolean isRecursive = cmd.isRecursive(); Boolean specifyIpRanges = cmd.getSpecifyIpRanges(); + Long vpcId = cmd.getVpcId(); // 1) default is system to false if not specified // 2) reset parameter to false if it's specified by the regular user @@ -3005,21 +3007,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (domainId != null) { networksToReturn .addAll(listDomainLevelNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, domainId)); } if (!permittedAccounts.isEmpty()) { networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, permittedAccounts)); } else if (domainId == null || listAll) { networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, path, isRecursive)); } } else { - networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges), + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter); } @@ -3049,8 +3055,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges) { + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId) { SearchCriteria sc = sb.create(); if (isSystem != null) { @@ -3098,6 +3105,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (specifyIpRanges != null) { sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges); } + + if (vpcId != null) { + sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); + } return sc; } diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index 1b44b16ba9e..54867703f36 100755 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -56,4 +56,7 @@ public interface IPAddressDao extends GenericDao { List listByPhysicalNetworkId(long physicalNetworkId); long countFreeIPs(); + + List listByAssociatedVpc(long vpcId, Boolean isSourceNat); + } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index 425c215c430..daa8c18b85b 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -67,6 +67,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen AllFieldsSearch.and("oneToOneNat", AllFieldsSearch.entity().isOneToOneNat(), Op.EQ); AllFieldsSearch.and("sourcenetwork", AllFieldsSearch.entity().getSourceNetworkId(), Op.EQ); AllFieldsSearch.and("physicalNetworkId", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); VlanDbIdSearchUnallocated = createSearchBuilder(); @@ -299,4 +300,16 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen sc.setJoinParameters("vlans", "vlanType", VlanType.VirtualNetwork); return customSearch(sc, null).get(0); } + + @Override + public List listByAssociatedVpc(long vpcId, Boolean isSourceNat) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + + if (isSourceNat != null) { + sc.setParameters("sourceNat", isSourceNat); + } + + return listBy(sc); + } } diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index 89a297e0754..4f352c86cd7 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -99,7 +99,11 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc return false; } - Vpc vpc = _vpcService.getVpc(vpcId); + Vpc vpc = _vpcService.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); @@ -142,7 +146,11 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc return false; } - Vpc vpc = _vpcService.getVpc(vpcId); + Vpc vpc = _vpcService.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDao.java b/server/src/com/cloud/network/vpc/Dao/VpcDao.java index e95b6674de1..75fd56e88b7 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDao.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDao.java @@ -12,6 +12,9 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network.vpc.Dao; +import java.util.List; + +import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcVO; import com.cloud.utils.db.GenericDao; @@ -25,5 +28,9 @@ public interface VpcDao extends GenericDao{ * @return */ int getVpcCountByOfferingId(long offId); + + Vpc getActiveVpcById(long vpcId); + + List listByAccountId(long accountId); } diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java index 4e32541e39f..6d6b03c220b 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -16,10 +16,13 @@ import java.util.List; import javax.ejb.Local; +import com.cloud.domain.Domain.State; +import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; @@ -32,8 +35,8 @@ import com.cloud.utils.db.SearchCriteria.Op; @DB(txn = false) public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ final GenericSearchBuilder CountByOfferingId; + final SearchBuilder AllFieldsSearch; - protected VpcDaoImpl() { super(); @@ -42,6 +45,12 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ CountByOfferingId.and("offeringId", CountByOfferingId.entity().getVpcOfferingId(), Op.EQ); CountByOfferingId.and("removed", CountByOfferingId.entity().getRemoved(), Op.NULL); CountByOfferingId.done(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); + AllFieldsSearch.done(); } @@ -52,5 +61,20 @@ public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ List results = customSearch(sc, null); return results.get(0); } + + @Override + public Vpc getActiveVpcById(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("id", vpcId); + sc.setParameters("state", State.Active); + return findOneBy(sc); + } + + @Override + public List listByAccountId(long accountId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("accountId", accountId); + return listBy(sc, null); + } } diff --git a/server/src/com/cloud/network/vpc/VpcManager.java b/server/src/com/cloud/network/vpc/VpcManager.java index e6f025024de..fe8105876b5 100644 --- a/server/src/com/cloud/network/vpc/VpcManager.java +++ b/server/src/com/cloud/network/vpc/VpcManager.java @@ -17,6 +17,8 @@ import java.util.Map; import java.util.Set; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.element.VpcProvider; @@ -78,4 +80,15 @@ public interface VpcManager extends VpcService{ * @return */ VpcProvider getVpcElement(); + + List getVpcsForAccount(long accountId); + + /** + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientCapacityException + */ + boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 70c36ac2dac..b8e5dd54049 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -36,11 +36,13 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.UnsupportedServiceException; +import com.cloud.network.IPAddressVO; 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.NetworkManager; +import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.element.VpcProvider; import com.cloud.network.vpc.VpcOffering.State; @@ -90,6 +92,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ NetworkDao _ntwkDao; @Inject NetworkManager _ntwkMgr; + @Inject + IPAddressDao _ipAddressDao; private VpcProvider vpcElement = null; @@ -138,9 +142,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ } @Override - public List getVpcNetworks(long vpcId) { - // TODO Auto-generated method stub - return null; + public List getVpcNetworks(long vpcId) { + return _ntwkDao.listByVpc(vpcId); } @Override @@ -226,12 +229,15 @@ public class VpcManagerImpl implements VpcManager, Manager{ return offering; } - - @Override public Vpc getVpc(long vpcId) { return _vpcDao.findById(vpcId); } + + @Override + public Vpc getActiveVpc(long vpcId) { + return _vpcDao.findById(vpcId); + } @Override public Map> getVpcOffSvcProvidersMap(long vpcOffId) { @@ -478,23 +484,47 @@ public class VpcManagerImpl implements VpcManager, Manager{ @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC") public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { UserContext.current().setEventDetails(" Id: " + vpcId); + Account caller = UserContext.current().getCaller(); // Verify vpc id - VpcVO vpc = _vpcDao.findById(vpcId); + Vpc vpc = getVpc(vpcId); if (vpc == null) { throw new InvalidParameterValueException("unable to find VPC id=" + vpcId); } + + //verify permissions + _accountMgr.checkAccess(caller, null, false, vpc); - // don't allow to delete vpc if it's in use by existing networks - int networksCount = _ntwkDao.getNetworkCountByVpcId(vpcId); + return destroyVpc(vpc); + } + + @Override + public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + UserContext ctx = UserContext.current(); + + //don't allow to delete vpc if it's in use by existing networks + int networksCount = _ntwkDao.getNetworkCountByVpcId(vpc.getId()); if (networksCount > 0) { - throw new InvalidParameterValueException("Can't delete VPC " + vpcId + " as its used by " + networksCount + " networks"); + throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks"); } - //shutdown VPC - shutdownVpc(vpcId); + //mark VPC as disabled + s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Disabled + " as a part of vpc delete"); + VpcVO vpcVO = _vpcDao.findById(vpc.getId()); + vpcVO.setState(Vpc.State.Disabled); + _vpcDao.update(vpc.getId(), vpcVO); - if (_vpcDao.remove(vpcId)) { + //shutdown VPC + shutdownVpc(vpc.getId()); + + //cleanup vpc resources + if (!cleanupVpcResources(vpc.getId(), ctx.getCaller(), ctx.getCallerUserId())) { + s_logger.warn("Failed to cleanup resources for vpc " + vpc); + return false; + } + + if (_vpcDao.remove(vpc.getId())) { return true; } else { return false; @@ -652,9 +682,9 @@ public class VpcManagerImpl implements VpcManager, Manager{ User callerUser = _accountMgr.getActiveUser(ctx.getCallerUserId()); //check if vpc exists - Vpc vpc = getVpc(vpcId); + Vpc vpc = getActiveVpc(vpcId); if (vpc == null) { - throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); + throw new InvalidParameterValueException("Unable to find Enabled vpc by id " + vpcId); } //permission check @@ -778,4 +808,26 @@ public class VpcManagerImpl implements VpcManager, Manager{ return vpcElement; } + + @Override + public List getVpcsForAccount(long accountId) { + return _vpcDao.listByAccountId(accountId); + } + + public boolean cleanupVpcResources(long vpcId, Account caller, long callerUserId) { + s_logger.debug("Cleaning up resources for vpc id=" + vpcId); + boolean success = true; + // release all ip addresses + List ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null); + s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup"); + for (IPAddressVO ipToRelease : ipsToRelease) { + success = success && _ntwkMgr.releasePublicIpAddress(ipToRelease.getId(), callerUserId, caller); + if (!success) { + s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup"); + } + } + + return success; + + } } diff --git a/server/src/com/cloud/network/vpc/VpcVO.java b/server/src/com/cloud/network/vpc/VpcVO.java index ad12cc014d5..3d90f3ca8e7 100644 --- a/server/src/com/cloud/network/vpc/VpcVO.java +++ b/server/src/com/cloud/network/vpc/VpcVO.java @@ -12,9 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network.vpc; -import java.util.ArrayList; import java.util.Date; -import java.util.List; import java.util.UUID; import javax.persistence.Column; @@ -25,8 +23,6 @@ import javax.persistence.Id; import javax.persistence.Table; import com.cloud.api.Identity; -import com.cloud.network.Network; -import com.cloud.network.Network.Service; import com.cloud.utils.db.GenericDao; /** diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c98a2977db5..3d2a57571f2 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -160,7 +160,6 @@ import com.cloud.network.NetworkVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; -import com.cloud.offering.ServiceOffering; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -1552,6 +1551,7 @@ public class ManagementServerImpl implements ManagementServer { Long hostId = cmd.getHostId(); String keyword = cmd.getKeyword(); Long networkId = cmd.getNetworkId(); + Long vpcId = cmd.getVpcId(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1572,6 +1572,7 @@ public class ManagementServerImpl implements ManagementServer { sb.and("dataCenterId", sb.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); if (networkId != null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); @@ -1598,24 +1599,34 @@ public class ManagementServerImpl implements ManagementServer { if (name != null) { sc.setParameters("name", "%" + name + "%"); } + if (id != null) { sc.setParameters("id", id); } + if (state != null) { sc.setParameters("state", state); } + if (zone != null) { sc.setParameters("dataCenterId", zone); } + if (pod != null) { sc.setParameters("podId", pod); } + if (hostId != null) { sc.setParameters("hostId", hostId); } + if (networkId != null) { sc.setJoinParameters("nicSearch", "networkId", networkId); } + + if (vpcId != null) { + sc.setParameters("vpcId", vpcId); + } return _routerDao.search(sc, searchFilter); } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index fd9c9c2099e..3503d3f475d 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -77,6 +77,8 @@ import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -199,6 +201,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private ProjectAccountDao _projectAccountDao; @Inject private IPAddressDao _ipAddressDao; + @Inject + private VpcManager _vpcMgr; private Adapters _userAuthenticators; @@ -572,20 +576,36 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } } + + //Delete all VPCs + boolean vpcsDeleted = true; + s_logger.debug("Deleting vpcs for account " + account.getId()); + List vpcs = _vpcMgr.getVpcsForAccount(account.getId()); + for (Vpc vpc : vpcs) { - // release ip addresses belonging to the account - List ipsToRelease = _ipAddressDao.listByAccount(accountId); - for (IpAddress ip : ipsToRelease) { - s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup"); - if (!_networkMgr.releasePublicIpAddress(ip.getId(), callerUserId, caller)) { - s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup"); + if (!_vpcMgr.destroyVpc(vpc)) { + s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup."); accountCleanupNeeded = true; + vpcsDeleted = false; + } else { + s_logger.debug("VPC " + vpc.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup."); + } + } + + if (vpcsDeleted) { + // release ip addresses belonging to the account + List ipsToRelease = _ipAddressDao.listByAccount(accountId); + for (IpAddress ip : ipsToRelease) { + s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup"); + if (!_networkMgr.releasePublicIpAddress(ip.getId(), callerUserId, caller)) { + s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup"); + accountCleanupNeeded = true; + } } } // delete account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned - // up - // successfully + // up successfully if (networksDeleted) { if (!_configMgr.deleteAccountSpecificVirtualRanges(accountId)) { accountCleanupNeeded = true; diff --git a/wscript b/wscript index 1f58c524567..05a9a1061b6 100644 --- a/wscript +++ b/wscript @@ -3,7 +3,7 @@ # the following two variables are used by the target "waf dist" # if you change 'em here, you need to change it also in cloud.spec, add a %changelog entry there, and add an entry in debian/changelog -VERSION = '3.0.3.2012-05-24T22:43:32Z' +VERSION = '3.0.3.2012-05-25T21:12:57Z' APPNAME = 'cloud' import shutil,os