Updated Branches: refs/heads/master 85f38b3e0 -> 3f5b8f706
CLOUDSTACK-4793 : Added UpgradeRouterTemplate API. Added filters to listRouters API. listRouters response includes verion and required upgrade flag. Min VR version is checked before sending commands to router Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3f5b8f70 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3f5b8f70 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3f5b8f70 Branch: refs/heads/master Commit: 3f5b8f70630e8415a611984ccde2e1f631e96bc9 Parents: 85f38b3 Author: Kishan Kavala <[email protected]> Authored: Thu Nov 7 19:42:19 2013 +0530 Committer: Kishan Kavala <[email protected]> Committed: Thu Nov 7 19:49:05 2013 +0530 ---------------------------------------------------------------------- .../network/VirtualNetworkApplianceService.java | 6 + .../com/cloud/network/router/VirtualRouter.java | 1 + .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../cloudstack/api/ResponseGenerator.java | 4 + .../command/admin/router/ListRoutersCmd.java | 11 +- .../admin/router/UpgradeRouterTemplateCmd.java | 143 +++++++++++++++++++ .../api/response/DomainRouterResponse.java | 23 ++- .../response/UpgradeRouterTemplateResponse.java | 45 ++++++ client/tomcatconf/commands.properties.in | 1 + .../src/com/cloud/vm/dao/DomainRouterDao.java | 3 +- .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 7 + server/src/com/cloud/api/ApiResponseHelper.java | 17 +++ .../com/cloud/api/query/QueryManagerImpl.java | 12 +- .../com/cloud/api/query/ViewResponseHelper.java | 2 + .../api/query/dao/DomainRouterJoinDaoImpl.java | 7 + .../VirtualNetworkApplianceManagerImpl.java | 109 +++++++++++++- .../com/cloud/server/ManagementServerImpl.java | 2 + .../MockVpcVirtualNetworkApplianceManager.java | 7 +- utils/src/com/cloud/maint/Version.java | 8 ++ 19 files changed, 394 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/com/cloud/network/VirtualNetworkApplianceService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index 58eead2..fb5d12a 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -23,6 +23,9 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; import com.cloud.user.Account; +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; + +import java.util.List; public interface VirtualNetworkApplianceService { /** @@ -66,4 +69,7 @@ public interface VirtualNetworkApplianceService { VirtualRouter findRouter(long routerId); + List<Long> upgradeRouterTemplate(UpgradeRouterTemplateCmd cmd); + + public static final String _minVRVersion = "4.2.0"; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/com/cloud/network/router/VirtualRouter.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index 9e90e8e..a875218 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -41,4 +41,5 @@ public interface VirtualRouter extends VirtualMachine { * @return */ Long getVpcId(); + String getTemplateVersion(); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/ApiConstants.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 20e848d..bd52593 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -528,6 +528,7 @@ public class ApiConstants { public static final String EXPUNGE = "expunge"; public static final String FOR_DISPLAY = "fordisplay"; public static final String PASSIVE = "passive"; + public static final String VERSION = "version"; public enum HostDetails { all, capacity, events, stats, min; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/ResponseGenerator.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index a8de31d..832f6e3 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -60,6 +60,7 @@ import org.apache.cloudstack.api.response.IpForwardingRuleResponse; import org.apache.cloudstack.api.response.IsolationMethodResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; +import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.LoadBalancerResponse; import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; @@ -99,6 +100,7 @@ import org.apache.cloudstack.api.response.TemplatePermissionsResponse; import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.TrafficMonitorResponse; import org.apache.cloudstack.api.response.TrafficTypeResponse; +import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse; import org.apache.cloudstack.api.response.UsageRecordResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; @@ -446,4 +448,6 @@ public interface ResponseGenerator { IsolationMethodResponse createIsolationMethodResponse(IsolationType method); + ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds); + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index d7f59b96..2752a13 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -75,7 +75,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC routers") private Boolean forVpc; - + + @Parameter(name=ApiConstants.VERSION, type=CommandType.STRING, description="list virtual router elements by version") + private String version; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -115,7 +118,11 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Boolean getForVpc() { return forVpc; } - + + public String getVersion() { + return version; + } + public String getRole() { return Role.VIRTUAL_ROUTER.toString(); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java new file mode 100644 index 0000000..1db22bc --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java @@ -0,0 +1,143 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.router; + + +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AccountResponse; +import org.apache.cloudstack.api.response.ClusterResponse; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.DomainRouterResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PodResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; + +import java.util.List; +import java.util.logging.Logger; + +@APICommand(name = "upgradeRouterTemplate", description="Upgrades router to use newer template", responseObject=BaseResponse.class) +public class UpgradeRouterTemplateCmd extends org.apache.cloudstack.api.BaseCmd { + public static final Logger s_logger = Logger.getLogger(UpgradeRouterTemplateCmd.class.getName()); + private static final String s_name = "upgraderoutertemplateresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name= ApiConstants.ID, type=CommandType.UUID, entityType = DomainRouterResponse.class, + description="upgrades router with the specified Id") + private Long id; + + @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.UUID, entityType= ClusterResponse.class, + description="upgrades all routers within the specified cluster") + private Long clusterId; + + @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class, + description="upgrades all routers within the specified pod") + private Long podId; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, + description="upgrades all routers within the specified zone") + private Long zoneId; + + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType = AccountResponse.class, + description="upgrades all routers owned by the specified account") + private Long accountId; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class, + description="upgrades all routers owned by the specified domain") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getClusterId() { + return clusterId; + } + + public Long getPodId() { + return podId; + } + + public Long getZoneId() { + return zoneId; + } + + public Long getAccountId() { + return accountId; + } + + public Long getDomainId() { + return domainId; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + public ApiCommandJobType getInstanceType() { + return ApiCommandJobType.DomainRouter; + } + + public Long getInstanceId() { + return getId(); + } + + @Override + public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + CallContext.current().setEventDetails("Upgrading router template"); + List<Long> result = _routerService.upgradeRouterTemplate(this); + if (result != null){ + ListResponse<UpgradeRouterTemplateResponse> response = _responseGenerator.createUpgradeRouterTemplateResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade router template"); + } + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 1d31b58..5ea28b9 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -144,8 +144,8 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @SerializedName("redundantstate") @Param(description="the state of redundant virtual router") private String redundantState; - @SerializedName("templateversion") @Param(description="the version of template") - private String templateVersion; + @SerializedName("version") @Param(description="the version of template") + private String version; @SerializedName("scriptsversion") @Param(description="the version of scripts") private String scriptsVersion; @@ -160,6 +160,9 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView responseObject = NicResponse.class, since="4.0") private Set<NicResponse> nics; + @SerializedName("requiresupgrade") @Param(description="true if the router template requires upgrader") + private boolean requiresUpgrade; + public DomainRouterResponse(){ nics = new LinkedHashSet<NicResponse>(); } @@ -308,12 +311,12 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView this.isRedundantRouter = isRedundantRouter; } - public String getTemplateVersion() { - return this.templateVersion; + public String getVersion() { + return this.version; } - public void setTemplateVersion(String templateVersion) { - this.templateVersion = templateVersion; + public void setVersion(String version) { + this.version = version; } public String getScriptsVersion() { @@ -364,4 +367,12 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView public void setRole(String role) { this.role = role; } + + public boolean requiresUpgrade() { + return requiresUpgrade; + } + + public void setRequiresUpgrade(boolean requiresUpgrade) { + this.requiresUpgrade = requiresUpgrade; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java b/api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java new file mode 100644 index 0000000..ba0049b --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java @@ -0,0 +1,45 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; +import org.apache.cloudstack.jobs.JobInfo; + +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +@EntityReference(value = JobInfo.class) +@SuppressWarnings("unused") +public class UpgradeRouterTemplateResponse extends BaseResponse { + @SerializedName(ApiConstants.JOB_ID) @Param(description="the id of AsyncJob") + private String asyncJobId; + + public String getAsyncJobId() { + return asyncJobId; + } + + public void setAsyncJobId(String asyncJobId) { + this.asyncJobId = asyncJobId; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/client/tomcatconf/commands.properties.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 087d8b9..68d7303 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -197,6 +197,7 @@ listRouters=7 listVirtualRouterElements=7 configureVirtualRouterElement=7 createVirtualRouterElement=7 +upgradeRouterTemplate=1 #### system vm commands startSystemVm=1 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java index 95d1ea6..f1912b5 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java @@ -145,5 +145,6 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> { * @param guestNetworkId */ void removeRouterFromGuestNetwork(long routerId, long guestNetworkId); - + + List<DomainRouterVO> listByClusterId(Long clusterId); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 7676e2d..5158e98 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -204,6 +204,13 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im } @Override + public List<DomainRouterVO> listByClusterId(Long clusterId) { + SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create(); + //ToDo: Add cluster criteria + return listBy(sc); + } + + @Override public List<DomainRouterVO> listByPodIdAndStates(Long podId, State... states) { SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create(); sc.setParameters("podId", podId); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/api/ApiResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 36ef4bd..e1c48cf 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -79,6 +79,7 @@ import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; +import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.LoadBalancerResponse; import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; @@ -119,6 +120,7 @@ import org.apache.cloudstack.api.response.TemplatePermissionsResponse; import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.TrafficMonitorResponse; import org.apache.cloudstack.api.response.TrafficTypeResponse; +import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse; import org.apache.cloudstack.api.response.UsageRecordResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; @@ -3793,4 +3795,19 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("networkacllist"); return response; } + + @Override + public ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds){ + ListResponse<UpgradeRouterTemplateResponse> response = new ListResponse<UpgradeRouterTemplateResponse>(); + List<UpgradeRouterTemplateResponse> responses = new ArrayList<UpgradeRouterTemplateResponse>(); + for(Long jobId : jobIds){ + UpgradeRouterTemplateResponse routerResponse = new UpgradeRouterTemplateResponse(); + AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId); + routerResponse.setAsyncJobId((job.getUuid())); + routerResponse.setObjectName("asyncjobs"); + responses.add(routerResponse); + } + response.setResponses(responses); + return response; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/api/query/QueryManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 2934641..2b5b81d 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1090,7 +1090,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { public ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd) { Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), - cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion()); ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>(); List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first() @@ -1103,7 +1103,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { public ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd) { Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), - cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null); ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>(); List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first() @@ -1113,7 +1113,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } private Pair<List<DomainRouterJoinVO>, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, - String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role) { + String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, + String role, String version) { Account caller = CallContext.current().getCallingAccount(); List<Long> permittedAccounts = new ArrayList<Long>(); @@ -1147,6 +1148,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ); + sb.and("version", sb.entity().getTemplateVersion(), SearchCriteria.Op.EQ); if (forVpc != null) { if (forVpc) { @@ -1210,6 +1212,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("role", role); } + if(version != null){ + sc.setParameters("version", "Cloudstack Release "+version + "%"); + } + // search VR details by ids Pair<List<DomainRouterJoinVO>, Integer> uniqueVrPair = _routerJoinDao.searchAndCount(sc, searchFilter); Integer count = uniqueVrPair.second(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/api/query/ViewResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 4051f09..e4be311 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -58,6 +58,7 @@ import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -440,4 +441,5 @@ public class ViewResponseHelper { } return new ArrayList<AffinityGroupResponse>(vrDataList.values()); } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java index 42965bc..f193031 100644 --- a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java @@ -22,6 +22,8 @@ import java.util.List; import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.maint.Version; +import com.cloud.network.VirtualNetworkApplianceService; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; @@ -76,6 +78,11 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO, routerResponse.setState(router.getState()); routerResponse.setIsRedundantRouter(router.isRedundantRouter()); routerResponse.setRedundantState(router.getRedundantState().toString()); + if(router.getTemplateVersion() != null){ + String routerVersion = Version.trimRouterVersion(router.getTemplateVersion()); + routerResponse.setVersion(routerVersion); + routerResponse.setRequiresUpgrade((Version.compare(routerVersion, VirtualNetworkApplianceService._minVRVersion) < 0)); + } if (caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 0f7c5c9..617d6ac 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.UUID; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -42,14 +43,23 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import com.cloud.agent.api.to.*; +import com.cloud.api.ApiAsyncJobDispatcher; +import com.cloud.api.ApiDispatcher; +import com.cloud.api.ApiGsonHelper; +import com.cloud.maint.Version; +import com.cloud.utils.component.ComponentContext; +import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.jobs.AsyncJobManager; +import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -370,8 +380,10 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V ConfigDepot _configDepot; @Inject MonitoringServiceDao _monitorServiceDao; - - + @Inject + AsyncJobManager _asyncMgr; + @Inject + protected ApiAsyncJobDispatcher _asyncDispatcher; int _routerRamSize; int _routerCpuMHz; @@ -3551,6 +3563,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } protected boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { + if(!checkRouterVersion(router)){ + throw new CloudRuntimeException("Router requires upgrade. Unable to send command to router:" + router.getId()); + } Answer[] answers = null; try { answers = _agentMgr.send(router.getHostId(), cmds); @@ -4119,4 +4134,94 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V public VirtualRouter findRouter(long routerId) { return _routerDao.findById(routerId); } + + @Override + public List<Long> upgradeRouterTemplate(UpgradeRouterTemplateCmd cmd){ + + List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>(); + int params = 0; + + Long routerId = cmd.getId(); + if(routerId != null) { + params++; + DomainRouterVO router = _routerDao.findById(routerId); + if(router != null){ + routers.add(router); + } + } + + Long accountId = cmd.getAccountId(); + if(accountId != null){ + params++; + routers = _routerDao.listBy(accountId); + } + + Long domainId = cmd.getDomainId(); + if(domainId != null){ + params++; + routers = _routerDao.listByDomain(domainId); + } + + Long clusterId = cmd.getClusterId(); + if(clusterId != null){ + params++; + routers = _routerDao.listByClusterId(clusterId); + } + + Long podId = cmd.getPodId(); + if(podId != null){ + params++; + routers = _routerDao.listByPodId(podId); + } + + Long zoneId = cmd.getZoneId(); + if(zoneId != null){ + params++; + routers = _routerDao.listByDataCenter(zoneId); + } + + if(params > 1){ + throw new InvalidParameterValueException("Multiple parameters not supported. Specify only one among routerId/zoneId/podId/clusterId/accountId/domainId"); + } + + if(routers != null){ + return rebootRouters(routers); + } + + return null; + } + + //Checks if the router is at the required version + // Compares MS version and router version + private boolean checkRouterVersion(VirtualRouter router){ + String trimmedVersion = Version.trimRouterVersion(router.getTemplateVersion()); + return (Version.compare(trimmedVersion, _minVRVersion) >= 0); + } + + private List<Long> rebootRouters(List<DomainRouterVO> routers){ + List<Long> jobIds = new ArrayList<Long>(); + for(DomainRouterVO router: routers){ + if(!checkRouterVersion(router)){ + s_logger.debug("Upgrading template for router: "+router.getId()); + ApiDispatcher.getInstance(); + Map<String, String> params = new HashMap<String, String>(); + params.put("ctxUserId", "1"); + params.put("ctxAccountId", "" + router.getAccountId()); + + RebootRouterCmd cmd = new RebootRouterCmd(); + ComponentContext.inject(cmd); + params.put("id", ""+router.getId()); + params.put("ctxStartEventId", "1"); + AsyncJobVO job = new AsyncJobVO(UUID.randomUUID().toString(), User.UID_SYSTEM, router.getAccountId(), RebootRouterCmd.class.getName(), + ApiGsonHelper.getBuilder().create().toJson(params), router.getId(), + cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null); + job.setDispatcher(_asyncDispatcher.getName()); + long jobId = _asyncMgr.submitAsyncJob(job); + jobIds.add(jobId); + } else { + s_logger.debug("Router: "+router.getId()+" is already at the latest version. No upgrade required" ); + } + } + return jobIds; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/src/com/cloud/server/ManagementServerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 79b20d0..35bc681 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -42,6 +42,7 @@ import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -2874,6 +2875,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(ReplaceNetworkACLListCmd.class); cmdList.add(UpdateNetworkACLItemCmd.class); cmdList.add(CleanVMReservationsCmd.class); + cmdList.add(UpgradeRouterTemplateCmd.class); return cmdList; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java index acdd9dc..5c216c8 100644 --- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java +++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java @@ -24,7 +24,7 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import com.cloud.network.vpc.NetworkACLItem; -import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; +import org.apache.cloudstack.api.command.admin.router.*; import org.springframework.stereotype.Component; import com.cloud.deploy.DeployDestination; @@ -421,6 +421,11 @@ VpcVirtualNetworkApplianceService { } @Override + public List<Long> upgradeRouterTemplate(UpgradeRouterTemplateCmd cmd) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override public boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId, NicProfile nic) { // TODO Auto-generated method stub http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3f5b8f70/utils/src/com/cloud/maint/Version.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/maint/Version.java b/utils/src/com/cloud/maint/Version.java index 7317547..f900b56 100644 --- a/utils/src/com/cloud/maint/Version.java +++ b/utils/src/com/cloud/maint/Version.java @@ -58,6 +58,14 @@ public class Version { return "0"; return tokens[0] + "." + tokens[1]+ "." + tokens[2]; } + + public static String trimRouterVersion(String version){ + String[] tokens = version.split(" "); + if(tokens.length >= 3){ + return tokens[2]; + } + return "0"; + } public static void main(String[] args) { System.out.println("Result is " + compare(args[0], args[1]));
