Skip to content

Commit 86939e7

Browse files
authored
server: Fixed private gateway can't be deleted (#4016)
When the static route service is not available on the VPC and a static route is created, the static route is created in a revoked state. Currently, the UI doesn't distinguish between active or revoked static routes. This PR adds the missing state filter to the list routes command and only lists active routes in the UI. It also ignores revoked routes when the private gateway is being removed but clears out the inactive routes before the gateway is removed. Fixes #2908
1 parent f843c53 commit 86939e7

6 files changed

Lines changed: 38 additions & 3 deletions

File tree

api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public void execute() throws ResourceUnavailableException {
109109
routeResponse.setResponseName(getCommandName());
110110
} finally {
111111
if (!success || route == null) {
112-
_vpcService.revokeStaticRoute(getEntityId());
112+
_entityMgr.remove(StaticRoute.class, getEntityId());
113113
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create static route");
114114
}
115115
}

api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public class ListStaticRoutesCmd extends BaseListTaggedResourcesCmd {
4848
@Parameter(name = ApiConstants.GATEWAY_ID, type = CommandType.UUID, entityType = PrivateGatewayResponse.class, description = "list static routes by gateway id")
4949
private Long gatewayId;
5050

51+
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "list static routes by state")
52+
private String state;
53+
5154
public Long getId() {
5255
return id;
5356
}
@@ -60,6 +63,10 @@ public Long getGatewayId() {
6063
return gatewayId;
6164
}
6265

66+
public String getState() {
67+
return state;
68+
}
69+
6370
/////////////////////////////////////////////////////
6471
/////////////////// Accessors ///////////////////////
6572
/////////////////////////////////////////////////////

engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public interface StaticRouteDao extends GenericDao<StaticRouteVO, Long> {
3030

3131
List<StaticRouteVO> listByVpcId(long vpcId);
3232

33+
List<StaticRouteVO> listByGatewayId(long gatewayId);
34+
3335
long countRoutesByGateway(long gatewayId);
3436

3537
}

engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ protected StaticRouteDaoImpl() {
6262
RoutesByGatewayCount = createSearchBuilder(Long.class);
6363
RoutesByGatewayCount.select(null, Func.COUNT, RoutesByGatewayCount.entity().getId());
6464
RoutesByGatewayCount.and("gatewayId", RoutesByGatewayCount.entity().getVpcGatewayId(), Op.EQ);
65+
RoutesByGatewayCount.and("state", RoutesByGatewayCount.entity().getState(), Op.EQ);
6566
RoutesByGatewayCount.done();
6667
}
6768

@@ -91,10 +92,18 @@ public List<StaticRouteVO> listByVpcId(long vpcId) {
9192
return listBy(sc);
9293
}
9394

95+
@Override
96+
public List<StaticRouteVO> listByGatewayId(long gatewayId) {
97+
SearchCriteria<StaticRouteVO> sc = AllFieldsSearch.create();
98+
sc.setParameters("gatewayId", gatewayId);
99+
return listBy(sc);
100+
}
101+
94102
@Override
95103
public long countRoutesByGateway(long gatewayId) {
96104
SearchCriteria<Long> sc = RoutesByGatewayCount.create();
97105
sc.setParameters("gatewayId", gatewayId);
106+
sc.setParameters("state", "Active");
98107
return customSearch(sc, null).get(0);
99108
}
100109

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2027,7 +2027,10 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
20272027
}
20282028
}
20292029

2030-
// 2) Delete private gateway from the DB
2030+
// 2) Clean up any remaining routes
2031+
cleanUpRoutesByGatewayId(gatewayId);
2032+
2033+
// 3) Delete private gateway from the DB
20312034
return deletePrivateGatewayFromTheDB(gateway);
20322035

20332036
} finally {
@@ -2037,6 +2040,13 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
20372040
}
20382041
}
20392042

2043+
private void cleanUpRoutesByGatewayId(long gatewayId){
2044+
List<StaticRouteVO> routes = _staticRouteDao.listByGatewayId(gatewayId);
2045+
for (StaticRouteVO route: routes){
2046+
_staticRouteDao.remove(route.getId());
2047+
}
2048+
}
2049+
20402050
@DB
20412051
protected boolean deletePrivateGatewayFromTheDB(final PrivateGateway gateway) {
20422052
// check if there are ips allocted in the network
@@ -2329,6 +2339,7 @@ public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(final ListSta
23292339
final List<Long> permittedAccounts = new ArrayList<Long>();
23302340
final Map<String, String> tags = cmd.getTags();
23312341
final Long projectId = cmd.getProjectId();
2342+
final String state = cmd.getState();
23322343

23332344
final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
23342345
null);
@@ -2344,6 +2355,7 @@ public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(final ListSta
23442355
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
23452356
sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
23462357
sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ);
2358+
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
23472359

23482360
if (tags != null && !tags.isEmpty()) {
23492361
final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
@@ -2371,6 +2383,10 @@ public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(final ListSta
23712383
sc.addAnd("vpcGatewayId", Op.EQ, gatewayId);
23722384
}
23732385

2386+
if (state != null) {
2387+
sc.addAnd("state", Op.EQ, state);
2388+
}
2389+
23742390
if (tags != null && !tags.isEmpty()) {
23752391
int count = 0;
23762392
sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.StaticRoute.toString());

ui/scripts/vpc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2652,7 +2652,8 @@
26522652
url: createURL('listStaticRoutes'),
26532653
data: {
26542654
gatewayid: args.context.vpcGateways[0].id,
2655-
listAll: true
2655+
listAll: true,
2656+
state: "Active"
26562657
},
26572658
success: function(json) {
26582659
var items = json.liststaticroutesresponse.staticroute;

0 commit comments

Comments
 (0)