Skip to content

Commit c0abfce

Browse files
authored
Health check feature for virtual router (#3575)
1 parent f1149bc commit c0abfce

78 files changed

Lines changed: 3402 additions & 450 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/src/main/java/com/cloud/event/EventTypes.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
import java.util.HashMap;
2020
import java.util.Map;
2121

22+
import org.apache.cloudstack.acl.Role;
23+
import org.apache.cloudstack.acl.RolePermission;
24+
import org.apache.cloudstack.annotation.Annotation;
25+
import org.apache.cloudstack.config.Configuration;
26+
import org.apache.cloudstack.ha.HAConfig;
27+
import org.apache.cloudstack.usage.Usage;
28+
2229
import com.cloud.dc.DataCenter;
2330
import com.cloud.dc.Pod;
2431
import com.cloud.dc.StorageNetworkIpRange;
@@ -69,12 +76,6 @@
6976
import com.cloud.vm.Nic;
7077
import com.cloud.vm.NicSecondaryIp;
7178
import com.cloud.vm.VirtualMachine;
72-
import org.apache.cloudstack.acl.Role;
73-
import org.apache.cloudstack.acl.RolePermission;
74-
import org.apache.cloudstack.annotation.Annotation;
75-
import org.apache.cloudstack.config.Configuration;
76-
import org.apache.cloudstack.ha.HAConfig;
77-
import org.apache.cloudstack.usage.Usage;
7879

7980
public class EventTypes {
8081

@@ -106,6 +107,7 @@ public class EventTypes {
106107
public static final String EVENT_ROUTER_HA = "ROUTER.HA";
107108
public static final String EVENT_ROUTER_UPGRADE = "ROUTER.UPGRADE";
108109
public static final String EVENT_ROUTER_DIAGNOSTICS = "ROUTER.DIAGNOSTICS";
110+
public static final String EVENT_ROUTER_HEALTH_CHECKS = "ROUTER.HEALTH.CHECKS";
109111

110112
// Console proxy
111113
public static final String EVENT_PROXY_CREATE = "PROXY.CREATE";
@@ -603,6 +605,7 @@ public class EventTypes {
603605
entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class);
604606
entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class);
605607
entityEventDetails.put(EVENT_ROUTER_DIAGNOSTICS, VirtualRouter.class);
608+
entityEventDetails.put(EVENT_ROUTER_HEALTH_CHECKS, VirtualRouter.class);
606609

607610
entityEventDetails.put(EVENT_PROXY_CREATE, VirtualMachine.class);
608611
entityEventDetails.put(EVENT_PROXY_DESTROY, VirtualMachine.class);

api/src/main/java/com/cloud/network/NetworkService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long ne
7272

7373
boolean deleteNetwork(long networkId, boolean forced);
7474

75-
boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
75+
boolean restartNetwork(Long networkId, boolean cleanup, boolean makeRedundant, User user) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
76+
77+
boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
7678

7779
int getActiveNicsInNetwork(long networkId);
7880

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package com.cloud.network;
19+
20+
import java.util.Date;
21+
22+
public interface RouterHealthCheckResult {
23+
long getRouterId();
24+
25+
String getCheckName();
26+
27+
String getCheckType();
28+
29+
boolean getCheckResult();
30+
31+
Date getLastUpdateTime();
32+
33+
String getParsedCheckDetails();
34+
}

api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ public interface VirtualNetworkApplianceService {
3131
/**
3232
* Starts domain router
3333
*
34-
* @param cmd
35-
* the command specifying router's id
34+
* @param cmd the command specifying router's id
3635
* @return DomainRouter object
3736
*/
3837
VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
@@ -51,10 +50,8 @@ public interface VirtualNetworkApplianceService {
5150
/**
5251
* Stops domain router
5352
*
54-
* @param id
55-
* of the router
56-
* @param forced
57-
* just do it. caller knows best.
53+
* @param id of the router
54+
* @param forced just do it. caller knows best.
5855
* @return router if successful, null otherwise
5956
* @throws ResourceUnavailableException
6057
* @throws ConcurrentOperationException
@@ -68,4 +65,13 @@ public interface VirtualNetworkApplianceService {
6865
VirtualRouter findRouter(long routerId);
6966

7067
List<Long> upgradeRouterTemplate(UpgradeRouterTemplateCmd cmd);
68+
69+
/**
70+
* Updates router with latest health checkdata, runs health checks and persists health checks on virtual router if feasible.
71+
* Throws relevant exception if feature is disabled or failures occur.
72+
*
73+
* @param routerId id of the router
74+
* @return
75+
*/
76+
boolean performRouterHealthChecks(long routerId);
7177
}

api/src/main/java/com/cloud/network/vpc/VpcService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
2323
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
24+
import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd;
2425

2526
import com.cloud.exception.ConcurrentOperationException;
2627
import com.cloud.exception.InsufficientAddressCapacityException;
@@ -29,6 +30,7 @@
2930
import com.cloud.exception.ResourceAllocationException;
3031
import com.cloud.exception.ResourceUnavailableException;
3132
import com.cloud.network.IpAddress;
33+
import com.cloud.user.User;
3234
import com.cloud.utils.Pair;
3335

3436
public interface VpcService {
@@ -132,7 +134,9 @@ public Pair<List<? extends Vpc>, Integer> listVpcs(Long id, String vpcName, Stri
132134
* @return
133135
* @throws InsufficientCapacityException
134136
*/
135-
boolean restartVpc(long id, boolean cleanUp, boolean makeredundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
137+
boolean restartVpc(RestartVPCCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
138+
139+
boolean restartVpc(Long networkId, boolean cleanup, boolean makeRedundant, User user) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
136140

137141
/**
138142
* Returns a Private gateway found in the VPC by id

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ public class ApiConstants {
727727
public static final String VIRTUAL_SIZE = "virtualsize";
728728
public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
729729
public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid";
730+
public static final String FETCH_ROUTER_HEALTH_CHECK_RESULTS = "fetchhealthcheckresults";
730731

731732
public static final String ZONE_ID_LIST = "zoneids";
732733
public static final String DESTINATION_ZONE_ID_LIST = "destzoneids";
@@ -748,6 +749,13 @@ public class ApiConstants {
748749
public static final String FILES = "files";
749750
public static final String VOLUME_IDS = "volumeids";
750751

752+
public static final String ROUTER_ID = "routerid";
753+
public static final String ROUTER_HEALTH_CHECKS = "healthchecks";
754+
public static final String ROUTER_CHECK_NAME = "checkname";
755+
public static final String ROUTER_CHECK_TYPE = "checktype";
756+
public static final String LAST_UPDATED = "lastupdated";
757+
public static final String PERFORM_FRESH_CHECKS = "performfreshchecks";
758+
751759
public enum HostDetails {
752760
all, capacity, events, stats, min;
753761
}

api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424

25+
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
2526
import org.apache.cloudstack.management.ManagementServerHost;
2627
import org.apache.cloudstack.affinity.AffinityGroup;
2728
import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -146,6 +147,7 @@
146147
import com.cloud.network.PhysicalNetworkServiceProvider;
147148
import com.cloud.network.PhysicalNetworkTrafficType;
148149
import com.cloud.network.RemoteAccessVpn;
150+
import com.cloud.network.RouterHealthCheckResult;
149151
import com.cloud.network.Site2SiteCustomerGateway;
150152
import com.cloud.network.Site2SiteVpnConnection;
151153
import com.cloud.network.Site2SiteVpnGateway;
@@ -466,4 +468,6 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine
466468
SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
467469

468470
ManagementServerResponse createManagementResponse(ManagementServerHost mgmt);
471+
472+
List<RouterHealthCheckResultResponse> createHealthCheckResponse(VirtualMachine router, List<RouterHealthCheckResult> healthCheckResults);
469473
}

api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.internallb;
1818

19+
import org.apache.commons.lang.BooleanUtils;
1920
import org.apache.log4j.Logger;
2021

2122
import org.apache.cloudstack.api.APICommand;
@@ -73,6 +74,11 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd
7374
@Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "if true is passed for this parameter, list only VPC Internal LB VMs")
7475
private Boolean forVpc;
7576

77+
78+
@Parameter(name = ApiConstants.FETCH_ROUTER_HEALTH_CHECK_RESULTS, type = CommandType.BOOLEAN, since = "4.14",
79+
description = "if true is passed for this parameter, also fetch last executed health check results for the VM. Default is false")
80+
private Boolean fetchHealthCheckResults;
81+
7682
/////////////////////////////////////////////////////
7783
/////////////////// Accessors ///////////////////////
7884
/////////////////////////////////////////////////////
@@ -117,6 +123,10 @@ public String getRole() {
117123
return Role.INTERNAL_LB_VM.toString();
118124
}
119125

126+
public boolean shouldFetchHealthCheckResults() {
127+
return BooleanUtils.isTrue(fetchHealthCheckResults);
128+
}
129+
120130
/////////////////////////////////////////////////////
121131
/////////////// API Implementation///////////////////
122132
/////////////////////////////////////////////////////
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.router;
19+
20+
import java.util.List;
21+
22+
import org.apache.cloudstack.api.APICommand;
23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.ServerApiException;
28+
import org.apache.cloudstack.api.response.DomainRouterResponse;
29+
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
30+
import org.apache.cloudstack.api.response.RouterHealthCheckResultsListResponse;
31+
import org.apache.cloudstack.context.CallContext;
32+
import org.apache.commons.lang.BooleanUtils;
33+
import org.apache.log4j.Logger;
34+
35+
import com.cloud.exception.InvalidParameterValueException;
36+
import com.cloud.exception.ResourceUnavailableException;
37+
import com.cloud.network.router.VirtualRouter;
38+
import com.cloud.user.Account;
39+
import com.cloud.utils.exception.CloudRuntimeException;
40+
import com.cloud.vm.VirtualMachine;
41+
42+
@APICommand(name = GetRouterHealthCheckResultsCmd.APINAME,
43+
responseObject = RouterHealthCheckResultsListResponse.class,
44+
description = "Starts a router.",
45+
entityType = {VirtualMachine.class},
46+
requestHasSensitiveInfo = false,
47+
responseHasSensitiveInfo = false,
48+
since = "4.14.0")
49+
public class GetRouterHealthCheckResultsCmd extends BaseCmd {
50+
public static final Logger s_logger = Logger.getLogger(GetRouterHealthCheckResultsCmd.class.getName());
51+
public static final String APINAME = "getRouterHealthCheckResults";
52+
53+
/////////////////////////////////////////////////////
54+
//////////////// API parameters /////////////////////
55+
/////////////////////////////////////////////////////
56+
57+
@Parameter(name = ApiConstants.ROUTER_ID, type = CommandType.UUID, entityType = DomainRouterResponse.class,
58+
required = true, description = "the ID of the router")
59+
private Long routerId;
60+
61+
@Parameter(name = ApiConstants.PERFORM_FRESH_CHECKS, type = CommandType.BOOLEAN, description = "if true is passed for this parameter, " +
62+
"health checks are performed on the fly. Else last performed checks data is fetched")
63+
private Boolean performFreshChecks;
64+
65+
/////////////////////////////////////////////////////
66+
/////////////////// Accessors ///////////////////////
67+
/////////////////////////////////////////////////////
68+
69+
public Long getRouterId() {
70+
return routerId;
71+
}
72+
73+
public boolean shouldPerformFreshChecks() {
74+
return BooleanUtils.isTrue(performFreshChecks);
75+
}
76+
77+
/////////////////////////////////////////////////////
78+
/////////////// API Implementation///////////////////
79+
/////////////////////////////////////////////////////
80+
81+
@Override
82+
public String getCommandName() {
83+
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
84+
}
85+
86+
@Override
87+
public long getEntityOwnerId() {
88+
VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getRouterId());
89+
if (router != null) {
90+
return router.getAccountId();
91+
}
92+
93+
return Account.ACCOUNT_ID_SYSTEM;
94+
}
95+
96+
@Override
97+
public void execute() throws ResourceUnavailableException, InvalidParameterValueException, ServerApiException {
98+
CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getRouterId()));
99+
VirtualRouter router = _routerService.findRouter(getRouterId());
100+
if (router == null || router.getRole() != VirtualRouter.Role.VIRTUAL_ROUTER) {
101+
throw new InvalidParameterValueException("Can't find router by routerId");
102+
}
103+
104+
try {
105+
List<RouterHealthCheckResultResponse> healthChecks = _queryService.listRouterHealthChecks(this);
106+
RouterHealthCheckResultsListResponse routerResponse = new RouterHealthCheckResultsListResponse();
107+
routerResponse.setRouterId(router.getUuid());
108+
routerResponse.setHealthChecks(healthChecks);
109+
routerResponse.setObjectName("routerhealthchecks");
110+
routerResponse.setResponseName(getCommandName());
111+
setResponseObject(routerResponse);
112+
} catch (CloudRuntimeException ex){
113+
ex.printStackTrace();
114+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to execute command due to exception: " + ex.getLocalizedMessage());
115+
}
116+
}
117+
}

api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.router;
1818

19+
import org.apache.commons.lang.BooleanUtils;
1920
import org.apache.log4j.Logger;
2021

2122
import org.apache.cloudstack.api.APICommand;
@@ -80,6 +81,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd {
8081
@Parameter(name = ApiConstants.VERSION, type = CommandType.STRING, description = "list virtual router elements by version")
8182
private String version;
8283

84+
@Parameter(name = ApiConstants.FETCH_ROUTER_HEALTH_CHECK_RESULTS, type = CommandType.BOOLEAN, since = "4.14",
85+
description = "if true is passed for this parameter, also fetch last executed health check results for the router. Default is false")
86+
private Boolean fetchHealthCheckResults;
87+
8388
/////////////////////////////////////////////////////
8489
/////////////////// Accessors ///////////////////////
8590
/////////////////////////////////////////////////////
@@ -132,6 +137,11 @@ public String getRole() {
132137
return Role.VIRTUAL_ROUTER.toString();
133138
}
134139

140+
public boolean shouldFetchHealthCheckResults() {
141+
return BooleanUtils.isTrue(fetchHealthCheckResults);
142+
}
143+
144+
135145
/////////////////////////////////////////////////////
136146
/////////////// API Implementation///////////////////
137147
/////////////////////////////////////////////////////

0 commit comments

Comments
 (0)