Merge branch '4.19'
diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
index e76c52b..094f816 100644
--- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
@@ -23,10 +23,11 @@
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import org.apache.cloudstack.annotation.AnnotationService;
-import org.apache.cloudstack.annotation.dao.AnnotationDao;
+import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
+import org.apache.cloudstack.annotation.AnnotationService;
+import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd;
import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd;
@@ -45,7 +46,6 @@
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Site2SiteCustomerGateway;
@@ -106,7 +106,6 @@
@Inject
private AnnotationDao annotationDao;
- String _name;
int _connLimit;
int _subnetsLimit;
@@ -253,7 +252,7 @@
@Override
@ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "creating s2s vpn connection", create = true)
- public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException {
+ public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
@@ -261,27 +260,15 @@
_accountMgr.checkAccess(caller, null, false, owner);
Long customerGatewayId = cmd.getCustomerGatewayId();
- Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId);
- if (customerGateway == null) {
- throw new InvalidParameterValueException("Unable to found specified Site to Site VPN customer gateway " + customerGatewayId + " !");
- }
- _accountMgr.checkAccess(caller, null, false, customerGateway);
+ Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(customerGatewayId, caller);
Long vpnGatewayId = cmd.getVpnGatewayId();
- Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId);
- if (vpnGateway == null) {
- throw new InvalidParameterValueException("Unable to found specified Site to Site VPN gateway " + vpnGatewayId + " !");
- }
- _accountMgr.checkAccess(caller, null, false, vpnGateway);
+ Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(vpnGatewayId, caller);
- if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) {
- throw new InvalidParameterValueException("VPN connection can only be esitablished between same account's VPN gateway and customer gateway!");
- }
+ validateVpnConnectionOfTheRightAccount(customerGateway, vpnGateway);
+ validateVpnConnectionDoesntExist(vpnGatewayId, customerGatewayId);
+ validatePrerequisiteVpnGateway(vpnGateway);
- if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) {
- throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId +
- " already existed!");
- }
String[] cidrList = customerGateway.getGuestCidrList().split(",");
// Remote sub nets cannot overlap VPC's sub net
@@ -324,13 +311,51 @@
return conn;
}
+ private Site2SiteCustomerGateway getAndValidateSite2SiteCustomerGateway(Long customerGatewayId, Account caller) {
+ Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId);
+ if (customerGateway == null) {
+ throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN customer gateway %s !", customerGatewayId));
+ }
+ _accountMgr.checkAccess(caller, null, false, customerGateway);
+ return customerGateway;
+ }
+
+ private Site2SiteVpnGateway getAndValidateSite2SiteVpnGateway(Long vpnGatewayId, Account caller) {
+ Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId);
+ if (vpnGateway == null) {
+ throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN gateway %s !", vpnGatewayId));
+ }
+ _accountMgr.checkAccess(caller, null, false, vpnGateway);
+ return vpnGateway;
+ }
+
+ private void validateVpnConnectionOfTheRightAccount(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) {
+ if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) {
+ throw new InvalidParameterValueException("VPN connection can only be established between same account's VPN gateway and customer gateway!");
+ }
+ }
+
+ private void validateVpnConnectionDoesntExist(Long vpnGatewayId, Long customerGatewayId) {
+ if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) {
+ throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId +
+ " already existed!");
+ }
+ }
+
+ private void validatePrerequisiteVpnGateway(Site2SiteVpnGateway vpnGateway) {
+ // check if gateway has been defined on the VPC
+ if (_vpnGatewayDao.findByVpcId(vpnGateway.getVpcId()) == null) {
+ throw new InvalidParameterValueException("we can not create a VPN connection for a VPC that does not have a VPN gateway defined");
+ }
+ }
+
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "starting s2s vpn connection", async = true)
public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException {
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
- throw new CloudRuntimeException("Unable to acquire lock on " + conn);
+ throw new CloudRuntimeException("Unable to acquire lock for starting of VPN connection with ID " + id);
}
try {
if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) {
@@ -380,11 +405,7 @@
Account caller = CallContext.current().getCallingAccount();
Long id = cmd.getId();
- Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(id);
- if (customerGateway == null) {
- throw new InvalidParameterValueException("Fail to find customer gateway with " + id + " !");
- }
- _accountMgr.checkAccess(caller, null, false, customerGateway);
+ Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(id, caller);
return doDeleteCustomerGateway(customerGateway);
}
@@ -392,7 +413,7 @@
protected boolean doDeleteCustomerGateway(Site2SiteCustomerGateway gw) {
long id = gw.getId();
List<Site2SiteVpnConnectionVO> vpnConnections = _vpnConnectionDao.listByCustomerGatewayId(id);
- if (vpnConnections != null && vpnConnections.size() != 0) {
+ if (!CollectionUtils.isEmpty(vpnConnections)) {
throw new InvalidParameterValueException("Unable to delete VPN customer gateway with id " + id + " because there is still related VPN connections!");
}
annotationDao.removeByEntityType(AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(), gw.getUuid());
@@ -402,7 +423,7 @@
protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) {
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpnGatewayId(gw.getId());
- if (conns != null && conns.size() != 0) {
+ if (!CollectionUtils.isEmpty(conns)) {
throw new InvalidParameterValueException("Unable to delete VPN gateway " + gw.getId() + " because there is still related VPN connections!");
}
_vpnGatewayDao.remove(gw.getId());
@@ -415,12 +436,7 @@
Account caller = CallContext.current().getCallingAccount();
Long id = cmd.getId();
- Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(id);
- if (vpnGateway == null) {
- throw new InvalidParameterValueException("Fail to find vpn gateway with " + id + " !");
- }
-
- _accountMgr.checkAccess(caller, null, false, vpnGateway);
+ Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(id, caller);
doDeleteVpnGateway(vpnGateway);
return true;
@@ -576,7 +592,7 @@
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
- throw new CloudRuntimeException("Unable to acquire lock on " + conn);
+ throw new CloudRuntimeException("Unable to acquire lock for stopping of VPN connection with ID " + id);
}
try {
if (conn.getState() == State.Pending) {
@@ -637,10 +653,9 @@
String keyword = cmd.getKeyword();
Account caller = CallContext.current().getCallingAccount();
- List<Long> permittedAccounts = new ArrayList<Long>();
+ List<Long> permittedAccounts = new ArrayList<>();
- Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
- ListProjectResourcesCriteria>(domainId, isRecursive, null);
+ Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@@ -665,7 +680,7 @@
}
Pair<List<Site2SiteCustomerGatewayVO>, Integer> result = _customerGatewayDao.searchAndCount(sc, searchFilter);
- return new Pair<List<? extends Site2SiteCustomerGateway>, Integer>(result.first(), result.second());
+ return new Pair<>(result.first(), result.second());
}
@Override
@@ -682,10 +697,9 @@
long pageSizeVal = cmd.getPageSizeVal();
Account caller = CallContext.current().getCallingAccount();
- List<Long> permittedAccounts = new ArrayList<Long>();
+ List<Long> permittedAccounts = new ArrayList<>();
- Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
- ListProjectResourcesCriteria>(domainId, isRecursive, null);
+ Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@@ -715,7 +729,7 @@
}
Pair<List<Site2SiteVpnGatewayVO>, Integer> result = _vpnGatewayDao.searchAndCount(sc, searchFilter);
- return new Pair<List<? extends Site2SiteVpnGateway>, Integer>(result.first(), result.second());
+ return new Pair<>(result.first(), result.second());
}
@Override
@@ -732,10 +746,9 @@
long pageSizeVal = cmd.getPageSizeVal();
Account caller = CallContext.current().getCallingAccount();
- List<Long> permittedAccounts = new ArrayList<Long>();
+ List<Long> permittedAccounts = new ArrayList<>();
- Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
- ListProjectResourcesCriteria>(domainId, isRecursive, null);
+ Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@@ -769,7 +782,7 @@
}
Pair<List<Site2SiteVpnConnectionVO>, Integer> result = _vpnConnectionDao.searchAndCount(sc, searchFilter);
- return new Pair<List<? extends Site2SiteVpnConnection>, Integer>(result.first(), result.second());
+ return new Pair<>(result.first(), result.second());
}
@Override
@@ -816,7 +829,7 @@
@Override
public List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router) {
- List<Site2SiteVpnConnectionVO> conns = new ArrayList<Site2SiteVpnConnectionVO>();
+ List<Site2SiteVpnConnectionVO> conns = new ArrayList<>();
// One router for one VPC
Long vpcId = router.getVpcId();
if (router.getVpcId() == null) {
@@ -829,7 +842,6 @@
@Override
public boolean deleteCustomerGatewayByAccount(long accountId) {
boolean result = true;
- ;
List<Site2SiteCustomerGatewayVO> gws = _customerGatewayDao.listByAccountId(accountId);
for (Site2SiteCustomerGatewayVO gw : gws) {
result = result & doDeleteCustomerGateway(gw);
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index cbde58d..87b3dd3 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -4859,7 +4859,7 @@
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+ sb.and("keyword", sb.entity().getName(), SearchCriteria.Op.LIKE);
final SearchCriteria<UserDataVO> sc = sb.create();
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
@@ -4872,7 +4872,7 @@
}
if (keyword != null) {
- sc.setParameters("name", "%" + keyword + "%");
+ sc.setParameters("keyword", "%" + keyword + "%");
}
final Pair<List<UserDataVO>, Integer> result = userDataDao.searchAndCount(sc, searchFilter);
diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue
index 87e6d96..f2d679e 100644
--- a/ui/src/views/compute/EditVM.vue
+++ b/ui/src/views/compute/EditVM.vue
@@ -84,7 +84,7 @@
}"
:options="groups.opts" />
</a-form-item>
- <a-form-item>
+ <a-form-item v-if="userDataEnabled">
<template #label>
<tooltip-label :title="$t('label.userdata')" :tooltip="apiParams.userdata.description"/>
</template>
@@ -150,6 +150,7 @@
return {
serviceOffering: {},
template: {},
+ userDataEnabled: false,
securityGroupsEnabled: false,
dynamicScalingVmConfig: false,
loading: false,
@@ -297,15 +298,37 @@
return decodedData.toString('utf-8')
},
fetchUserData () {
- const params = {
- id: this.resource.id,
- userdata: true
+ let networkId
+ this.resource.nic.forEach(nic => {
+ if (nic.isdefault) {
+ networkId = nic.networkid
+ }
+ })
+ if (!networkId) {
+ return
}
+ const listNetworkParams = {
+ id: networkId,
+ listall: true
+ }
+ api(`listNetworks`, listNetworkParams).then(json => {
+ json.listnetworksresponse.network[0].service.forEach(service => {
+ if (service.name === 'UserData') {
+ this.userDataEnabled = true
- api('listVirtualMachines', params).then(json => {
- this.form.userdata = this.decodeUserData(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '')
+ const listVmParams = {
+ id: this.resource.id,
+ userdata: true,
+ listall: true
+ }
+ api('listVirtualMachines', listVmParams).then(json => {
+ this.form.userdata = atob(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '')
+ })
+ }
+ })
})
},
+
handleSubmit () {
this.formRef.value.validate().then(() => {
const values = toRaw(this.form)
diff --git a/ui/src/views/network/VpcTab.vue b/ui/src/views/network/VpcTab.vue
index 452d393..9090654 100644
--- a/ui/src/views/network/VpcTab.vue
+++ b/ui/src/views/network/VpcTab.vue
@@ -800,12 +800,12 @@
this.formRef.value.validate().then(() => {
const values = toRaw(this.form)
-
- api('createVpnConnection', {
- s2svpngatewayid: this.vpnGateways[0].id,
+ const params = {
+ s2svpngatewayid: this.vpnGateways[0] ? this.vpnGateways[0].id : null,
s2scustomergatewayid: values.vpncustomergateway,
passive: values.passive ? values.passive : false
- }).then(response => {
+ }
+ api('createVpnConnection', params).then(response => {
this.$pollJob({
jobId: response.createvpnconnectionresponse.jobid,
title: this.$t('label.vpn.connection'),