diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index 713844dca9c..a2a6fe79ead 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -48,7 +48,7 @@ public interface VpcService { * @throws ResourceAllocationException TODO */ public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain, Boolean displayVpc) - throws ResourceAllocationException; + throws ResourceAllocationException; /** * Deletes a VPC @@ -98,8 +98,8 @@ public interface VpcService { * @return */ public Pair, Integer> listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, String cidr, Long vpcOffId, String state, - String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, - Map tags, Long projectId, Boolean display); + String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, + Map tags, Long projectId, Boolean display); /** * Starts VPC which includes starting VPC provider and applying all the neworking rules on the backend @@ -130,7 +130,7 @@ public interface VpcService { * @return * @throws InsufficientCapacityException */ - boolean restartVpc(long id) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean restartVpc(long id, boolean cleanUp) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; /** * Returns a Private gateway found in the VPC by id @@ -160,7 +160,7 @@ public interface VpcService { * @throws ResourceAllocationException */ public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId, - Long networkOfferingId, Boolean isSoruceNat, Long aclId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException; + Long networkOfferingId, Boolean isSoruceNat, Long aclId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException; /** * Applies VPC private gateway on the backend, so it becomes functional @@ -246,7 +246,7 @@ public interface VpcService { * @throws ConcurrentOperationException */ IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, - ConcurrentOperationException; + ConcurrentOperationException; /** * @param routeId diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java index 84e790c3b2e..20df9eab237 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.vpc; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -28,6 +26,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; @@ -37,7 +36,7 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; @APICommand(name = "restartVPC", description = "Restarts a VPC", responseObject = VpcResponse.class, entityType = {Vpc.class}, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RestartVPCCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName()); private static final String s_name = "restartvpcresponse"; @@ -49,6 +48,9 @@ public class RestartVPCCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VpcResponse.class, required = true, description = "the id of the VPC") private Long id; + @Parameter(name = ApiConstants.CLEANUP, type = CommandType.BOOLEAN, required = false, description = "If cleanup old network elements") + private Boolean cleanup; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -57,6 +59,13 @@ public class RestartVPCCmd extends BaseAsyncCmd { return id; } + public Boolean getCleanup() { + if (cleanup != null) { + return cleanup; + } + return true; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -67,7 +76,7 @@ public class RestartVPCCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + final Vpc vpc = _entityMgr.findById(Vpc.class, getId()); if (vpc != null) { return vpc.getAccountId(); } @@ -78,20 +87,20 @@ public class RestartVPCCmd extends BaseAsyncCmd { @Override public void execute() { try { - boolean result = _vpcService.restartVpc(getId()); + final boolean result = _vpcService.restartVpc(getId(), getCleanup()); if (result) { - SuccessResponse response = new SuccessResponse(getCommandName()); + final SuccessResponse response = new SuccessResponse(getCommandName()); setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restart VPC"); } - } catch (ResourceUnavailableException ex) { + } catch (final ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); - } catch (ConcurrentOperationException ex) { + } catch (final ConcurrentOperationException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); - } catch (InsufficientCapacityException ex) { + } catch (final InsufficientCapacityException ex) { s_logger.info(ex); s_logger.trace(ex); throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/org/apache/cloudstack/api/response/VpcResponse.java index 7f9565affb1..61ed88b142c 100644 --- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java @@ -115,72 +115,72 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's", since = "4.4") private boolean usesDistributedRouter; - @SerializedName((ApiConstants.REGION_LEVEL_VPC)) + @SerializedName(ApiConstants.REGION_LEVEL_VPC) @Param(description = "true if VPC is region level", since = "4.4") private Boolean regionLevelVpc; @SerializedName(ApiConstants.REDUNDANT_VPC_ROUTER) - @Param(description = "if this VPC has redundant router", since = "4.4") + @Param(description = "if this VPC has redundant router", since = "4.6") private boolean redundantRouter; - public void setId(String id) { + public void setId(final String id) { this.id = id; } - public void setName(String name) { + public void setName(final String name) { this.name = name; } - public void setDisplayText(String displayText) { + public void setDisplayText(final String displayText) { this.displayText = displayText; } - public void setCreated(Date created) { + public void setCreated(final Date created) { this.created = created; } - public void setServices(List services) { + public void setServices(final List services) { this.services = services; } - public void setState(String state) { + public void setState(final String state) { this.state = state; } @Override - public void setAccountName(String accountName) { + public void setAccountName(final String accountName) { this.accountName = accountName; } @Override - public void setProjectId(String projectId) { + public void setProjectId(final String projectId) { this.projectId = projectId; } @Override - public void setProjectName(String projectName) { + public void setProjectName(final String projectName) { this.projectName = projectName; } @Override - public void setDomainId(String domainId) { + public void setDomainId(final String domainId) { this.domainId = domainId; } @Override - public void setDomainName(String domainName) { - this.domain = domainName; + public void setDomainName(final String domainName) { + domain = domainName; } - public void setZoneId(String zoneId) { + public void setZoneId(final String zoneId) { this.zoneId = zoneId; } - public void setCidr(String cidr) { + public void setCidr(final String cidr) { this.cidr = cidr; } - public void setVpcOfferingId(String vpcOfferingId) { + public void setVpcOfferingId(final String vpcOfferingId) { this.vpcOfferingId = vpcOfferingId; } @@ -188,39 +188,39 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons return networks; } - public void setNetworks(List networks) { + public void setNetworks(final List networks) { this.networks = networks; } - public void setRestartRequired(Boolean restartRequired) { + public void setRestartRequired(final Boolean restartRequired) { this.restartRequired = restartRequired; } - public void setNetworkDomain(String networkDomain) { + public void setNetworkDomain(final String networkDomain) { this.networkDomain = networkDomain; } - public void setZoneName(String zoneName) { + public void setZoneName(final String zoneName) { this.zoneName = zoneName; } - public void setTags(List tags) { + public void setTags(final List tags) { this.tags = tags; } - public void setForDisplay(Boolean forDisplay) { + public void setForDisplay(final Boolean forDisplay) { this.forDisplay = forDisplay; } - public void setRegionLevelVpc(Boolean regionLevelVpc) { + public void setRegionLevelVpc(final Boolean regionLevelVpc) { this.regionLevelVpc = regionLevelVpc; } - public void setUsesDistributedRouter(Boolean usesDistributedRouter) { + public void setUsesDistributedRouter(final Boolean usesDistributedRouter) { this.usesDistributedRouter = usesDistributedRouter; } - public void setRedundantRouter(Boolean redundantRouter) { + public void setRedundantRouter(final Boolean redundantRouter) { this.redundantRouter = redundantRouter; } } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index a85b11279de..c71da96a48c 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1488,7 +1488,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc") - public boolean restartVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public boolean restartVpc(final long vpcId, final boolean cleanUp) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { final Account caller = CallContext.current().getCallingAccount(); // Verify input parameters @@ -1504,11 +1504,15 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis s_logger.debug("Restarting VPC " + vpc); boolean restartRequired = false; try { - s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process"); - if (!shutdownVpc(vpcId)) { - s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process"); - restartRequired = true; - return false; + if (cleanUp) { + s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process"); + if (!shutdownVpc(vpcId)) { + s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process"); + restartRequired = true; + return false; + } + } else { + s_logger.info("Will not shutdown vpc as a part of VPC " + vpc + " restart process."); } s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process"); diff --git a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java index 3d985cda7e9..42c756a651d 100644 --- a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java +++ b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java @@ -71,6 +71,9 @@ import com.cloud.vm.dao.VMInstanceDao; public class RouterDeploymentDefinition { private static final Logger logger = Logger.getLogger(RouterDeploymentDefinition.class); + protected static final int LIMIT_NUMBER_OF_ROUTERS = 5; + protected static final int MAX_NUMBER_OF_ROUTERS = 2; + protected NetworkDao networkDao; protected DomainRouterDao routerDao; protected PhysicalNetworkServiceProviderDao physicalProviderDao; @@ -280,7 +283,7 @@ public class RouterDeploymentDefinition { protected int getNumberOfRoutersToDeploy() { // TODO Are we sure this makes sense? Somebody said 5 was too many? - if (routers.size() >= 5) { + if (routers.size() >= LIMIT_NUMBER_OF_ROUTERS) { logger.error("Too many redundant routers!"); } diff --git a/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java b/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java index 514c37c43b1..5124195d04c 100644 --- a/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java +++ b/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java @@ -108,13 +108,6 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition { return destinations; } - @Override - protected int getNumberOfRoutersToDeploy() { - // Enable redundant Vpc, with the same behavior a Non Vpc Router - // TODO Remove this method unless we need to actually add some behavior - return super.getNumberOfRoutersToDeploy(); - } - /** * @see RouterDeploymentDefinition#prepareDeployment() * @@ -125,13 +118,6 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition { return true; } - @Override - protected void setupPriorityOfRedundantRouter() { - // Implement Redundant Vpc - // TODO Remove this method unless we need to actually add some behavior - super.setupPriorityOfRedundantRouter(); - } - @Override protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException { sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc); @@ -144,8 +130,8 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition { // This call will associate any existing router to the "routers" attribute. // It's needed in order to continue with the VMs deployment. planDeploymentRouters(); - if (!routers.isEmpty()) { - // If routers are found, just return: nothing need to be done here. + if (routers.size() == MAX_NUMBER_OF_ROUTERS) { + // If we have 2 routers already deployed, do nothing and return. return; } } diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 50d0d592fb2..d1bd7eb47f3 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -5508,6 +5508,29 @@ restart: { label: 'label.restart.vpc', + createForm: { + title: 'label.restart.vpc', + desc: 'message.restart.vpc', + preFilter: function(args) { + var zoneObj; + $.ajax({ + url: createURL("listZones&id=" + args.context.vpc[0].zoneid), + dataType: "json", + async: false, + success: function(json) { + zoneObj = json.listzonesresponse.zone[0]; + } + }); + args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked + args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown + }, + fields: { + cleanup: { + label: 'label.clean.up', + isBoolean: true + } + } + }, messages: { confirm: function(args) { return 'message.restart.vpc'; @@ -5516,11 +5539,13 @@ return 'label.restart.vpc'; } }, + action: function(args) { $.ajax({ url: createURL("restartVPC"), data: { - id: args.context.vpc[0].id + id: args.context.vpc[0].id, + cleanup: (args.data.cleanup == "on") }, success: function(json) { var jid = json.restartvpcresponse.jobid;