Implement the new VPC restart

- behaves just like network restart: if clean up is checked, all routers destroyed; if 1 router is gone and no
    clean up, only 1 new router created.
This commit is contained in:
wilderrodrigues 2015-01-28 14:15:12 +01:00
parent 9bec4b64e7
commit 88129adac1
7 changed files with 92 additions and 65 deletions

View File

@ -48,7 +48,7 @@ public interface VpcService {
* @throws ResourceAllocationException TODO * @throws ResourceAllocationException TODO
*/ */
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain, Boolean displayVpc) 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 * Deletes a VPC
@ -98,8 +98,8 @@ public interface VpcService {
* @return * @return
*/ */
public Pair<List<? extends Vpc>, Integer> listVpcs(Long id, String vpcName, String displayText, List<String> supportedServicesStr, String cidr, Long vpcOffId, String state, public Pair<List<? extends Vpc>, Integer> listVpcs(Long id, String vpcName, String displayText, List<String> 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, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired,
Map<String, String> tags, Long projectId, Boolean display); Map<String, String> tags, Long projectId, Boolean display);
/** /**
* Starts VPC which includes starting VPC provider and applying all the neworking rules on the backend * Starts VPC which includes starting VPC provider and applying all the neworking rules on the backend
@ -130,7 +130,7 @@ public interface VpcService {
* @return * @return
* @throws InsufficientCapacityException * @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 * Returns a Private gateway found in the VPC by id
@ -160,7 +160,7 @@ public interface VpcService {
* @throws ResourceAllocationException * @throws ResourceAllocationException
*/ */
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId, 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 * Applies VPC private gateway on the backend, so it becomes functional
@ -246,7 +246,7 @@ public interface VpcService {
* @throws ConcurrentOperationException * @throws ConcurrentOperationException
*/ */
IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException,
ConcurrentOperationException; ConcurrentOperationException;
/** /**
* @param routeId * @param routeId

View File

@ -16,8 +16,6 @@
// under the License. // under the License.
package org.apache.cloudstack.api.command.user.vpc; package org.apache.cloudstack.api.command.user.vpc;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand; 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.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
@ -37,7 +36,7 @@ import com.cloud.network.vpc.Vpc;
import com.cloud.user.Account; import com.cloud.user.Account;
@APICommand(name = "restartVPC", description = "Restarts a VPC", responseObject = VpcResponse.class, entityType = {Vpc.class}, @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 class RestartVPCCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName()); public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName());
private static final String s_name = "restartvpcresponse"; 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") @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VpcResponse.class, required = true, description = "the id of the VPC")
private Long id; private Long id;
@Parameter(name = ApiConstants.CLEANUP, type = CommandType.BOOLEAN, required = false, description = "If cleanup old network elements")
private Boolean cleanup;
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////////// Accessors /////////////////////// /////////////////// Accessors ///////////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@ -57,6 +59,13 @@ public class RestartVPCCmd extends BaseAsyncCmd {
return id; return id;
} }
public Boolean getCleanup() {
if (cleanup != null) {
return cleanup;
}
return true;
}
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////// API Implementation/////////////////// /////////////// API Implementation///////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@ -67,7 +76,7 @@ public class RestartVPCCmd extends BaseAsyncCmd {
@Override @Override
public long getEntityOwnerId() { public long getEntityOwnerId() {
Vpc vpc = _entityMgr.findById(Vpc.class, getId()); final Vpc vpc = _entityMgr.findById(Vpc.class, getId());
if (vpc != null) { if (vpc != null) {
return vpc.getAccountId(); return vpc.getAccountId();
} }
@ -78,20 +87,20 @@ public class RestartVPCCmd extends BaseAsyncCmd {
@Override @Override
public void execute() { public void execute() {
try { try {
boolean result = _vpcService.restartVpc(getId()); final boolean result = _vpcService.restartVpc(getId(), getCleanup());
if (result) { if (result) {
SuccessResponse response = new SuccessResponse(getCommandName()); final SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response); setResponseObject(response);
} else { } else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restart VPC"); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restart VPC");
} }
} catch (ResourceUnavailableException ex) { } catch (final ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex); s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) { } catch (final ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex); s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (InsufficientCapacityException ex) { } catch (final InsufficientCapacityException ex) {
s_logger.info(ex); s_logger.info(ex);
s_logger.trace(ex); s_logger.trace(ex);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());

View File

@ -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") @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's", since = "4.4")
private boolean usesDistributedRouter; private boolean usesDistributedRouter;
@SerializedName((ApiConstants.REGION_LEVEL_VPC)) @SerializedName(ApiConstants.REGION_LEVEL_VPC)
@Param(description = "true if VPC is region level", since = "4.4") @Param(description = "true if VPC is region level", since = "4.4")
private Boolean regionLevelVpc; private Boolean regionLevelVpc;
@SerializedName(ApiConstants.REDUNDANT_VPC_ROUTER) @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; private boolean redundantRouter;
public void setId(String id) { public void setId(final String id) {
this.id = id; this.id = id;
} }
public void setName(String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
public void setDisplayText(String displayText) { public void setDisplayText(final String displayText) {
this.displayText = displayText; this.displayText = displayText;
} }
public void setCreated(Date created) { public void setCreated(final Date created) {
this.created = created; this.created = created;
} }
public void setServices(List<ServiceResponse> services) { public void setServices(final List<ServiceResponse> services) {
this.services = services; this.services = services;
} }
public void setState(String state) { public void setState(final String state) {
this.state = state; this.state = state;
} }
@Override @Override
public void setAccountName(String accountName) { public void setAccountName(final String accountName) {
this.accountName = accountName; this.accountName = accountName;
} }
@Override @Override
public void setProjectId(String projectId) { public void setProjectId(final String projectId) {
this.projectId = projectId; this.projectId = projectId;
} }
@Override @Override
public void setProjectName(String projectName) { public void setProjectName(final String projectName) {
this.projectName = projectName; this.projectName = projectName;
} }
@Override @Override
public void setDomainId(String domainId) { public void setDomainId(final String domainId) {
this.domainId = domainId; this.domainId = domainId;
} }
@Override @Override
public void setDomainName(String domainName) { public void setDomainName(final String domainName) {
this.domain = domainName; domain = domainName;
} }
public void setZoneId(String zoneId) { public void setZoneId(final String zoneId) {
this.zoneId = zoneId; this.zoneId = zoneId;
} }
public void setCidr(String cidr) { public void setCidr(final String cidr) {
this.cidr = cidr; this.cidr = cidr;
} }
public void setVpcOfferingId(String vpcOfferingId) { public void setVpcOfferingId(final String vpcOfferingId) {
this.vpcOfferingId = vpcOfferingId; this.vpcOfferingId = vpcOfferingId;
} }
@ -188,39 +188,39 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
return networks; return networks;
} }
public void setNetworks(List<NetworkResponse> networks) { public void setNetworks(final List<NetworkResponse> networks) {
this.networks = networks; this.networks = networks;
} }
public void setRestartRequired(Boolean restartRequired) { public void setRestartRequired(final Boolean restartRequired) {
this.restartRequired = restartRequired; this.restartRequired = restartRequired;
} }
public void setNetworkDomain(String networkDomain) { public void setNetworkDomain(final String networkDomain) {
this.networkDomain = networkDomain; this.networkDomain = networkDomain;
} }
public void setZoneName(String zoneName) { public void setZoneName(final String zoneName) {
this.zoneName = zoneName; this.zoneName = zoneName;
} }
public void setTags(List<ResourceTagResponse> tags) { public void setTags(final List<ResourceTagResponse> tags) {
this.tags = tags; this.tags = tags;
} }
public void setForDisplay(Boolean forDisplay) { public void setForDisplay(final Boolean forDisplay) {
this.forDisplay = forDisplay; this.forDisplay = forDisplay;
} }
public void setRegionLevelVpc(Boolean regionLevelVpc) { public void setRegionLevelVpc(final Boolean regionLevelVpc) {
this.regionLevelVpc = regionLevelVpc; this.regionLevelVpc = regionLevelVpc;
} }
public void setUsesDistributedRouter(Boolean usesDistributedRouter) { public void setUsesDistributedRouter(final Boolean usesDistributedRouter) {
this.usesDistributedRouter = usesDistributedRouter; this.usesDistributedRouter = usesDistributedRouter;
} }
public void setRedundantRouter(Boolean redundantRouter) { public void setRedundantRouter(final Boolean redundantRouter) {
this.redundantRouter = redundantRouter; this.redundantRouter = redundantRouter;
} }
} }

View File

@ -1488,7 +1488,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override @Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc") @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(); final Account caller = CallContext.current().getCallingAccount();
// Verify input parameters // Verify input parameters
@ -1504,11 +1504,15 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
s_logger.debug("Restarting VPC " + vpc); s_logger.debug("Restarting VPC " + vpc);
boolean restartRequired = false; boolean restartRequired = false;
try { try {
s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process"); if (cleanUp) {
if (!shutdownVpc(vpcId)) { s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process");
s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process"); if (!shutdownVpc(vpcId)) {
restartRequired = true; s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process");
return false; 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"); s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process");

View File

@ -71,6 +71,9 @@ import com.cloud.vm.dao.VMInstanceDao;
public class RouterDeploymentDefinition { public class RouterDeploymentDefinition {
private static final Logger logger = Logger.getLogger(RouterDeploymentDefinition.class); 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 NetworkDao networkDao;
protected DomainRouterDao routerDao; protected DomainRouterDao routerDao;
protected PhysicalNetworkServiceProviderDao physicalProviderDao; protected PhysicalNetworkServiceProviderDao physicalProviderDao;
@ -280,7 +283,7 @@ public class RouterDeploymentDefinition {
protected int getNumberOfRoutersToDeploy() { protected int getNumberOfRoutersToDeploy() {
// TODO Are we sure this makes sense? Somebody said 5 was too many? // 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!"); logger.error("Too many redundant routers!");
} }

View File

@ -108,13 +108,6 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition {
return destinations; 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() * @see RouterDeploymentDefinition#prepareDeployment()
* *
@ -125,13 +118,6 @@ public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition {
return true; return true;
} }
@Override
protected void setupPriorityOfRedundantRouter() {
// Implement Redundant Vpc
// TODO Remove this method unless we need to actually add some behavior
super.setupPriorityOfRedundantRouter();
}
@Override @Override
protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException { protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException {
sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc); 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. // This call will associate any existing router to the "routers" attribute.
// It's needed in order to continue with the VMs deployment. // It's needed in order to continue with the VMs deployment.
planDeploymentRouters(); planDeploymentRouters();
if (!routers.isEmpty()) { if (routers.size() == MAX_NUMBER_OF_ROUTERS) {
// If routers are found, just return: nothing need to be done here. // If we have 2 routers already deployed, do nothing and return.
return; return;
} }
} }

View File

@ -5508,6 +5508,29 @@
restart: { restart: {
label: 'label.restart.vpc', 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: { messages: {
confirm: function(args) { confirm: function(args) {
return 'message.restart.vpc'; return 'message.restart.vpc';
@ -5516,11 +5539,13 @@
return 'label.restart.vpc'; return 'label.restart.vpc';
} }
}, },
action: function(args) { action: function(args) {
$.ajax({ $.ajax({
url: createURL("restartVPC"), url: createURL("restartVPC"),
data: { data: {
id: args.context.vpc[0].id id: args.context.vpc[0].id,
cleanup: (args.data.cleanup == "on")
}, },
success: function(json) { success: function(json) {
var jid = json.restartvpcresponse.jobid; var jid = json.restartvpcresponse.jobid;