Skip to content

Commit 00fe5f1

Browse files
authored
cleanup validations for VPN connection creation (#9195)
1 parent 67ce326 commit 00fe5f1

File tree

2 files changed

+67
-55
lines changed

2 files changed

+67
-55
lines changed

server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323
import javax.inject.Inject;
2424
import javax.naming.ConfigurationException;
2525

26-
import org.apache.cloudstack.annotation.AnnotationService;
27-
import org.apache.cloudstack.annotation.dao.AnnotationDao;
26+
import org.apache.commons.collections.CollectionUtils;
2827
import org.apache.log4j.Logger;
2928
import org.springframework.stereotype.Component;
3029

30+
import org.apache.cloudstack.annotation.AnnotationService;
31+
import org.apache.cloudstack.annotation.dao.AnnotationDao;
3132
import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
3233
import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd;
3334
import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd;
@@ -46,7 +47,6 @@
4647
import com.cloud.event.ActionEvent;
4748
import com.cloud.event.EventTypes;
4849
import com.cloud.exception.InvalidParameterValueException;
49-
import com.cloud.exception.NetworkRuleConflictException;
5050
import com.cloud.exception.PermissionDeniedException;
5151
import com.cloud.exception.ResourceUnavailableException;
5252
import com.cloud.network.Site2SiteCustomerGateway;
@@ -108,7 +108,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
108108
@Inject
109109
private AnnotationDao annotationDao;
110110

111-
String _name;
112111
int _connLimit;
113112
int _subnetsLimit;
114113

@@ -255,35 +254,23 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm
255254

256255
@Override
257256
@ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "creating s2s vpn connection", create = true)
258-
public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException {
257+
public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) {
259258
Account caller = CallContext.current().getCallingAccount();
260259
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
261260

262261
//Verify that caller can perform actions in behalf of vpc owner
263262
_accountMgr.checkAccess(caller, null, false, owner);
264263

265264
Long customerGatewayId = cmd.getCustomerGatewayId();
266-
Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId);
267-
if (customerGateway == null) {
268-
throw new InvalidParameterValueException("Unable to found specified Site to Site VPN customer gateway " + customerGatewayId + " !");
269-
}
270-
_accountMgr.checkAccess(caller, null, false, customerGateway);
265+
Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(customerGatewayId, caller);
271266

272267
Long vpnGatewayId = cmd.getVpnGatewayId();
273-
Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId);
274-
if (vpnGateway == null) {
275-
throw new InvalidParameterValueException("Unable to found specified Site to Site VPN gateway " + vpnGatewayId + " !");
276-
}
277-
_accountMgr.checkAccess(caller, null, false, vpnGateway);
268+
Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(vpnGatewayId, caller);
278269

279-
if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) {
280-
throw new InvalidParameterValueException("VPN connection can only be esitablished between same account's VPN gateway and customer gateway!");
281-
}
270+
validateVpnConnectionOfTheRightAccount(customerGateway, vpnGateway);
271+
validateVpnConnectionDoesntExist(vpnGatewayId, customerGatewayId);
272+
validatePrerequisiteVpnGateway(vpnGateway);
282273

283-
if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) {
284-
throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId +
285-
" already existed!");
286-
}
287274
String[] cidrList = customerGateway.getGuestCidrList().split(",");
288275

289276
// Remote sub nets cannot overlap VPC's sub net
@@ -326,13 +313,51 @@ public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) th
326313
return conn;
327314
}
328315

316+
private Site2SiteCustomerGateway getAndValidateSite2SiteCustomerGateway(Long customerGatewayId, Account caller) {
317+
Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId);
318+
if (customerGateway == null) {
319+
throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN customer gateway %s !", customerGatewayId));
320+
}
321+
_accountMgr.checkAccess(caller, null, false, customerGateway);
322+
return customerGateway;
323+
}
324+
325+
private Site2SiteVpnGateway getAndValidateSite2SiteVpnGateway(Long vpnGatewayId, Account caller) {
326+
Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId);
327+
if (vpnGateway == null) {
328+
throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN gateway %s !", vpnGatewayId));
329+
}
330+
_accountMgr.checkAccess(caller, null, false, vpnGateway);
331+
return vpnGateway;
332+
}
333+
334+
private void validateVpnConnectionOfTheRightAccount(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) {
335+
if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) {
336+
throw new InvalidParameterValueException("VPN connection can only be established between same account's VPN gateway and customer gateway!");
337+
}
338+
}
339+
340+
private void validateVpnConnectionDoesntExist(Long vpnGatewayId, Long customerGatewayId) {
341+
if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) {
342+
throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId +
343+
" already existed!");
344+
}
345+
}
346+
347+
private void validatePrerequisiteVpnGateway(Site2SiteVpnGateway vpnGateway) {
348+
// check if gateway has been defined on the VPC
349+
if (_vpnGatewayDao.findByVpcId(vpnGateway.getVpcId()) == null) {
350+
throw new InvalidParameterValueException("we can not create a VPN connection for a VPC that does not have a VPN gateway defined");
351+
}
352+
}
353+
329354
@Override
330355
@DB
331356
@ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "starting s2s vpn connection", async = true)
332357
public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException {
333358
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
334359
if (conn == null) {
335-
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
360+
throw new CloudRuntimeException("Unable to acquire lock for starting of VPN connection with ID " + id);
336361
}
337362
try {
338363
if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) {
@@ -382,19 +407,15 @@ public boolean deleteCustomerGateway(DeleteVpnCustomerGatewayCmd cmd) {
382407
Account caller = CallContext.current().getCallingAccount();
383408

384409
Long id = cmd.getId();
385-
Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(id);
386-
if (customerGateway == null) {
387-
throw new InvalidParameterValueException("Fail to find customer gateway with " + id + " !");
388-
}
389-
_accountMgr.checkAccess(caller, null, false, customerGateway);
410+
Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(id, caller);
390411

391412
return doDeleteCustomerGateway(customerGateway);
392413
}
393414

394415
protected boolean doDeleteCustomerGateway(Site2SiteCustomerGateway gw) {
395416
long id = gw.getId();
396417
List<Site2SiteVpnConnectionVO> vpnConnections = _vpnConnectionDao.listByCustomerGatewayId(id);
397-
if (vpnConnections != null && vpnConnections.size() != 0) {
418+
if (!CollectionUtils.isEmpty(vpnConnections)) {
398419
throw new InvalidParameterValueException("Unable to delete VPN customer gateway with id " + id + " because there is still related VPN connections!");
399420
}
400421
annotationDao.removeByEntityType(AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(), gw.getUuid());
@@ -404,7 +425,7 @@ protected boolean doDeleteCustomerGateway(Site2SiteCustomerGateway gw) {
404425

405426
protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) {
406427
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpnGatewayId(gw.getId());
407-
if (conns != null && conns.size() != 0) {
428+
if (!CollectionUtils.isEmpty(conns)) {
408429
throw new InvalidParameterValueException("Unable to delete VPN gateway " + gw.getId() + " because there is still related VPN connections!");
409430
}
410431
_vpnGatewayDao.remove(gw.getId());
@@ -417,12 +438,7 @@ public boolean deleteVpnGateway(DeleteVpnGatewayCmd cmd) {
417438
Account caller = CallContext.current().getCallingAccount();
418439

419440
Long id = cmd.getId();
420-
Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(id);
421-
if (vpnGateway == null) {
422-
throw new InvalidParameterValueException("Fail to find vpn gateway with " + id + " !");
423-
}
424-
425-
_accountMgr.checkAccess(caller, null, false, vpnGateway);
441+
Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(id, caller);
426442

427443
doDeleteVpnGateway(vpnGateway);
428444
return true;
@@ -578,7 +594,7 @@ public boolean deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUn
578594
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
579595
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
580596
if (conn == null) {
581-
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
597+
throw new CloudRuntimeException("Unable to acquire lock for stopping of VPN connection with ID " + id);
582598
}
583599
try {
584600
if (conn.getState() == State.Pending) {
@@ -639,10 +655,9 @@ public Pair<List<? extends Site2SiteCustomerGateway>, Integer> searchForCustomer
639655
String keyword = cmd.getKeyword();
640656

641657
Account caller = CallContext.current().getCallingAccount();
642-
List<Long> permittedAccounts = new ArrayList<Long>();
658+
List<Long> permittedAccounts = new ArrayList<>();
643659

644-
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
645-
ListProjectResourcesCriteria>(domainId, isRecursive, null);
660+
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
646661
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
647662
domainId = domainIdRecursiveListProject.first();
648663
isRecursive = domainIdRecursiveListProject.second();
@@ -667,7 +682,7 @@ public Pair<List<? extends Site2SiteCustomerGateway>, Integer> searchForCustomer
667682
}
668683

669684
Pair<List<Site2SiteCustomerGatewayVO>, Integer> result = _customerGatewayDao.searchAndCount(sc, searchFilter);
670-
return new Pair<List<? extends Site2SiteCustomerGateway>, Integer>(result.first(), result.second());
685+
return new Pair<>(result.first(), result.second());
671686
}
672687

673688
@Override
@@ -684,10 +699,9 @@ public Pair<List<? extends Site2SiteVpnGateway>, Integer> searchForVpnGateways(L
684699
long pageSizeVal = cmd.getPageSizeVal();
685700

686701
Account caller = CallContext.current().getCallingAccount();
687-
List<Long> permittedAccounts = new ArrayList<Long>();
702+
List<Long> permittedAccounts = new ArrayList<>();
688703

689-
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
690-
ListProjectResourcesCriteria>(domainId, isRecursive, null);
704+
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
691705
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
692706
domainId = domainIdRecursiveListProject.first();
693707
isRecursive = domainIdRecursiveListProject.second();
@@ -717,7 +731,7 @@ public Pair<List<? extends Site2SiteVpnGateway>, Integer> searchForVpnGateways(L
717731
}
718732

719733
Pair<List<Site2SiteVpnGatewayVO>, Integer> result = _vpnGatewayDao.searchAndCount(sc, searchFilter);
720-
return new Pair<List<? extends Site2SiteVpnGateway>, Integer>(result.first(), result.second());
734+
return new Pair<>(result.first(), result.second());
721735
}
722736

723737
@Override
@@ -734,10 +748,9 @@ public Pair<List<? extends Site2SiteVpnConnection>, Integer> searchForVpnConnect
734748
long pageSizeVal = cmd.getPageSizeVal();
735749

736750
Account caller = CallContext.current().getCallingAccount();
737-
List<Long> permittedAccounts = new ArrayList<Long>();
751+
List<Long> permittedAccounts = new ArrayList<>();
738752

739-
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
740-
ListProjectResourcesCriteria>(domainId, isRecursive, null);
753+
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
741754
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
742755
domainId = domainIdRecursiveListProject.first();
743756
isRecursive = domainIdRecursiveListProject.second();
@@ -771,7 +784,7 @@ public Pair<List<? extends Site2SiteVpnConnection>, Integer> searchForVpnConnect
771784
}
772785

773786
Pair<List<Site2SiteVpnConnectionVO>, Integer> result = _vpnConnectionDao.searchAndCount(sc, searchFilter);
774-
return new Pair<List<? extends Site2SiteVpnConnection>, Integer>(result.first(), result.second());
787+
return new Pair<>(result.first(), result.second());
775788
}
776789

777790
@Override
@@ -818,7 +831,7 @@ public void markDisconnectVpnConnByVpc(long vpcId) {
818831

819832
@Override
820833
public List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router) {
821-
List<Site2SiteVpnConnectionVO> conns = new ArrayList<Site2SiteVpnConnectionVO>();
834+
List<Site2SiteVpnConnectionVO> conns = new ArrayList<>();
822835
// One router for one VPC
823836
Long vpcId = router.getVpcId();
824837
if (router.getVpcId() == null) {
@@ -831,7 +844,6 @@ public List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO rou
831844
@Override
832845
public boolean deleteCustomerGatewayByAccount(long accountId) {
833846
boolean result = true;
834-
;
835847
List<Site2SiteCustomerGatewayVO> gws = _customerGatewayDao.listByAccountId(accountId);
836848
for (Site2SiteCustomerGatewayVO gw : gws) {
837849
result = result & doDeleteCustomerGateway(gw);

ui/src/views/network/VpcTab.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,12 @@ export default {
795795
796796
this.formRef.value.validate().then(() => {
797797
const values = toRaw(this.form)
798-
799-
api('createVpnConnection', {
800-
s2svpngatewayid: this.vpnGateways[0].id,
798+
const params = {
799+
s2svpngatewayid: this.vpnGateways[0] ? this.vpnGateways[0].id : null,
801800
s2scustomergatewayid: values.vpncustomergateway,
802801
passive: values.passive ? values.passive : false
803-
}).then(response => {
802+
}
803+
api('createVpnConnection', params).then(response => {
804804
this.$pollJob({
805805
jobId: response.createvpnconnectionresponse.jobid,
806806
title: this.$t('label.vpn.connection'),

0 commit comments

Comments
 (0)