mirror of https://github.com/apache/cloudstack.git
Add settings to mark cryptographic algorithms in vpn customer gateways as excluded or obsolete (#12193)
This PR introduces several configuration settings using which an operator can mark certain cryptographic algorithms and parameters as excluded or obsolete for VPN Customer Gateway creation for Site-to-Site VPN. Cloud providers following modern security frameworks (e.g., ISO 27001/27017) are required to enforce and communicate approved cryptographic standards. CloudStack currently accepts several weak or deprecated algorithms without guidance to users. This PR closes that gap by giving operators explicit control over what is disallowed vs discouraged, improving security posture without breaking existing deployments. These settings are: 1. vpn.customer.gateway.excluded.encryption.algorithms 2. vpn.customer.gateway.excluded.hashing.algorithms 3. vpn.customer.gateway.excluded.ike.versions 4. vpn.customer.gateway.excluded.dh.group 5. vpn.customer.gateway.obsolete.encryption.algorithms 6. vpn.customer.gateway.obsolete.hashing.algorithms 7. vpn.customer.gateway.obsolete.ike.versions 8. vpn.customer.gateway.obsolete.dh.group
This commit is contained in:
parent
b31c2f4cae
commit
002d9768b2
|
|
@ -503,6 +503,7 @@ public class EventTypes {
|
||||||
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE";
|
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE";
|
||||||
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE";
|
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE";
|
||||||
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE";
|
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE";
|
||||||
|
public static final String EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS = "VPN.S2S.GATEWAY.OBSOLETE.PARAMS";
|
||||||
public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE";
|
public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE";
|
||||||
public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE";
|
public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE";
|
||||||
public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET";
|
public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET";
|
||||||
|
|
@ -1151,6 +1152,7 @@ public class EventTypes {
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class);
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class);
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class);
|
||||||
|
entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS, Site2SiteCustomerGateway.class);
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class);
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class);
|
||||||
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class);
|
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ public interface AlertService {
|
||||||
public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true);
|
public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true);
|
||||||
public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true);
|
public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true);
|
||||||
public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true);
|
public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true);
|
||||||
|
public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true);
|
||||||
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
|
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
|
||||||
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
|
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1364,6 +1364,10 @@ public class ApiConstants {
|
||||||
|
|
||||||
public static final String RECURSIVE_DOMAINS = "recursivedomains";
|
public static final String RECURSIVE_DOMAINS = "recursivedomains";
|
||||||
|
|
||||||
|
public static final String VPN_CUSTOMER_GATEWAY_PARAMETERS = "vpncustomergatewayparameters";
|
||||||
|
public static final String OBSOLETE_PARAMETERS = "obsoleteparameters";
|
||||||
|
public static final String EXCLUDED_PARAMETERS = "excludedparameters";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
||||||
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
|
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,9 @@ import java.util.Map;
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseCmd;
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.response.CapabilitiesResponse;
|
import org.apache.cloudstack.api.response.CapabilitiesResponse;
|
||||||
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
||||||
|
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
|
|
@ -30,12 +32,22 @@ import com.cloud.user.Account;
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListCapabilitiesCmd extends BaseCmd {
|
public class ListCapabilitiesCmd extends BaseCmd {
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = DomainResponse.class,
|
||||||
|
description = "the domain for listing capabilities.",
|
||||||
|
since = "4.23.0")
|
||||||
|
private Long domainId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEntityOwnerId() {
|
public long getEntityOwnerId() {
|
||||||
return Account.ACCOUNT_ID_SYSTEM;
|
return Account.ACCOUNT_ID_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
Map<String, Object> capabilities = _mgr.listCapabilities(this);
|
Map<String, Object> capabilities = _mgr.listCapabilities(this);
|
||||||
|
|
@ -76,6 +88,10 @@ public class ListCapabilitiesCmd extends BaseCmd {
|
||||||
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
|
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
|
||||||
response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED));
|
response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED));
|
||||||
response.setAdditionalConfigEnabled((Boolean) capabilities.get(ApiConstants.ADDITONAL_CONFIG_ENABLED));
|
response.setAdditionalConfigEnabled((Boolean) capabilities.get(ApiConstants.ADDITONAL_CONFIG_ENABLED));
|
||||||
|
if (capabilities.containsKey(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS)) {
|
||||||
|
Map<String, Object> vpnCustomerGatewayParameters = (Map<String, Object>) capabilities.get(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS);
|
||||||
|
response.setVpnCustomerGatewayParameters(vpnCustomerGatewayParameters);
|
||||||
|
}
|
||||||
response.setObjectName("capability");
|
response.setObjectName("capability");
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.response;
|
package org.apache.cloudstack.api.response;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseResponse;
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
|
@ -153,6 +155,10 @@ public class CapabilitiesResponse extends BaseResponse {
|
||||||
@Param(description = "true if additional configurations or extraconfig can be passed to Instances", since = "4.20.2")
|
@Param(description = "true if additional configurations or extraconfig can be passed to Instances", since = "4.20.2")
|
||||||
private Boolean additionalConfigEnabled;
|
private Boolean additionalConfigEnabled;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS)
|
||||||
|
@Param(description = "Excluded and obsolete VPN customer gateway cryptographic parameters")
|
||||||
|
private Map<String, Object> vpnCustomerGatewayParameters;
|
||||||
|
|
||||||
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
|
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
|
||||||
this.securityGroupsEnabled = securityGroupsEnabled;
|
this.securityGroupsEnabled = securityGroupsEnabled;
|
||||||
}
|
}
|
||||||
|
|
@ -280,4 +286,8 @@ public class CapabilitiesResponse extends BaseResponse {
|
||||||
public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) {
|
public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) {
|
||||||
this.additionalConfigEnabled = additionalConfigEnabled;
|
this.additionalConfigEnabled = additionalConfigEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVpnCustomerGatewayParameters(Map<String, Object> vpnCustomerGatewayParameters) {
|
||||||
|
this.vpnCustomerGatewayParameters = vpnCustomerGatewayParameters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,14 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponseWithAnnotation
|
||||||
@Param(description = "Which IKE Version to use, one of ike (autoselect), IKEv1, or IKEv2. Defaults to ike")
|
@Param(description = "Which IKE Version to use, one of ike (autoselect), IKEv1, or IKEv2. Defaults to ike")
|
||||||
private String ikeVersion;
|
private String ikeVersion;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.OBSOLETE_PARAMETERS)
|
||||||
|
@Param(description = "Contains the list of obsolete/insecure cryptographic parameters that the vpn customer gateway is using.", since = "4.23.0")
|
||||||
|
private String obsoleteParameters;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.EXCLUDED_PARAMETERS)
|
||||||
|
@Param(description = "Contains the list of excluded/not allowed cryptographic parameters that the vpn customer gateway is using.", since = "4.23.0")
|
||||||
|
private String excludedParameters;
|
||||||
|
|
||||||
public void setId(String id) {
|
public void setId(String id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
@ -202,4 +210,12 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponseWithAnnotation
|
||||||
this.domainPath = domainPath;
|
this.domainPath = domainPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContainsObsoleteParameters(String obsoleteParameters) {
|
||||||
|
this.obsoleteParameters = obsoleteParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContainsExcludedParameters(String excludedParameters) {
|
||||||
|
this.excludedParameters = excludedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class ConfigKeyScheduledExecutionWrapper implements Runnable {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigKeyScheduledExecutionWrapper(ScheduledExecutorService executorService, Runnable command,
|
public ConfigKeyScheduledExecutionWrapper(ScheduledExecutorService executorService, Runnable command,
|
||||||
ConfigKey<?> configKey, int enableIntervalSeconds, TimeUnit unit) {
|
ConfigKey<?> configKey, int enableIntervalSeconds, TimeUnit unit) {
|
||||||
validateArgs(executorService, command, configKey);
|
validateArgs(executorService, command, configKey);
|
||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||||
, AlertType.ALERT_TYPE_OOBM_AUTH_ERROR
|
, AlertType.ALERT_TYPE_OOBM_AUTH_ERROR
|
||||||
, AlertType.ALERT_TYPE_HA_ACTION
|
, AlertType.ALERT_TYPE_HA_ACTION
|
||||||
, AlertType.ALERT_TYPE_CA_CERT
|
, AlertType.ALERT_TYPE_CA_CERT
|
||||||
, AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY);
|
, AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY
|
||||||
|
, AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS);
|
||||||
|
|
||||||
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
|
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ import com.cloud.dc.dao.ASNumberRangeDao;
|
||||||
import com.cloud.dc.dao.VlanDetailsDao;
|
import com.cloud.dc.dao.VlanDetailsDao;
|
||||||
import com.cloud.hypervisor.Hypervisor;
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
import com.cloud.network.vpc.VpcGateway;
|
import com.cloud.network.vpc.VpcGateway;
|
||||||
|
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||||
import com.cloud.storage.BucketVO;
|
import com.cloud.storage.BucketVO;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||||
|
|
@ -528,6 +529,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||||
@Inject
|
@Inject
|
||||||
RoutedIpv4Manager routedIpv4Manager;
|
RoutedIpv4Manager routedIpv4Manager;
|
||||||
@Inject
|
@Inject
|
||||||
|
Site2SiteVpnManager site2SiteVpnManager;
|
||||||
|
@Inject
|
||||||
ResourceIconManager resourceIconManager;
|
ResourceIconManager resourceIconManager;
|
||||||
|
|
||||||
public static String getPrettyDomainPath(String path) {
|
public static String getPrettyDomainPath(String path) {
|
||||||
|
|
@ -3884,6 +3887,16 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||||
response.setRemoved(result.getRemoved());
|
response.setRemoved(result.getRemoved());
|
||||||
response.setIkeVersion(result.getIkeVersion());
|
response.setIkeVersion(result.getIkeVersion());
|
||||||
response.setSplitConnections(result.getSplitConnections());
|
response.setSplitConnections(result.getSplitConnections());
|
||||||
|
|
||||||
|
Set<String> obsoleteParameters = site2SiteVpnManager.getObsoleteVpnGatewayParameters(result);
|
||||||
|
if (CollectionUtils.isNotEmpty(obsoleteParameters)) {
|
||||||
|
response.setContainsObsoleteParameters(obsoleteParameters.toString());
|
||||||
|
}
|
||||||
|
Set<String> excludedParameters = site2SiteVpnManager.getExcludedVpnGatewayParameters(result);
|
||||||
|
if (CollectionUtils.isNotEmpty(excludedParameters)) {
|
||||||
|
response.setContainsExcludedParameters(excludedParameters.toString());
|
||||||
|
}
|
||||||
|
|
||||||
response.setObjectName("vpncustomergateway");
|
response.setObjectName("vpncustomergateway");
|
||||||
response.setHasAnnotation(annotationDao.hasAnnotations(result.getUuid(), AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(),
|
response.setHasAnnotation(annotationDao.hasAnnotations(result.getUuid(), AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(),
|
||||||
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
|
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,17 @@
|
||||||
package com.cloud.network.vpn;
|
package com.cloud.network.vpn;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.cloud.network.Site2SiteCustomerGateway;
|
||||||
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
|
|
||||||
public interface Site2SiteVpnManager extends Site2SiteVpnService {
|
public interface Site2SiteVpnManager extends Site2SiteVpnService {
|
||||||
|
Set<String> getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw);
|
||||||
|
|
||||||
|
Set<String> getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw);
|
||||||
|
|
||||||
boolean cleanupVpnConnectionByVpc(long vpcId);
|
boolean cleanupVpnConnectionByVpc(long vpcId);
|
||||||
|
|
||||||
boolean cleanupVpnGatewayByVpc(long vpcId);
|
boolean cleanupVpnGatewayByVpc(long vpcId);
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,22 @@
|
||||||
package com.cloud.network.vpn;
|
package com.cloud.network.vpn;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.alert.AlertService;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||||
import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
|
import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
|
||||||
|
|
@ -41,9 +48,16 @@ import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
|
import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKeyScheduledExecutionWrapper;
|
||||||
|
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||||
|
|
||||||
|
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||||
|
|
||||||
|
import com.cloud.alert.AlertManager;
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
import com.cloud.event.ActionEvent;
|
import com.cloud.event.ActionEvent;
|
||||||
|
import com.cloud.event.ActionEventUtils;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
|
|
@ -72,9 +86,11 @@ import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
|
||||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
|
import com.cloud.user.User;
|
||||||
import com.cloud.user.dao.AccountDao;
|
import com.cloud.user.dao.AccountDao;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.StringUtils;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
|
|
@ -88,7 +104,52 @@ import com.cloud.vm.DomainRouterVO;
|
||||||
import com.cloud.vm.dao.DomainRouterDao;
|
import com.cloud.vm.dao.DomainRouterDao;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager {
|
public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager, Configurable {
|
||||||
|
|
||||||
|
// Configuration keys for VPN gateway cryptographic parameter controls
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayExcludedEncryptionAlgorithms = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.encryption.algorithms", "",
|
||||||
|
"Comma-separated list of encryption algorithms that are excluded and cannot be selected by end users for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are aes128, aes192 and aes256 and 3des.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayExcludedHashingAlgorithms = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.hashing.algorithms", "",
|
||||||
|
"Comma-separated list of hashing algorithms that are excluded and cannot be selected by end users for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are sha1, sha256, sha384 and sha512 and md5.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayExcludedIkeVersions = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.ike.versions", "",
|
||||||
|
"Comma-separated list of IKE versions that are excluded and cannot be selected by end users for VPN Customer Gateways. Allowed values are ikev, ikev1 and ikev2.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayExcludedDhGroup = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.dh.group", "",
|
||||||
|
"Comma-separated list of Diffie-Hellman groups that are excluded and cannot be selected by end users for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are modp1024, modp1536, modp2048, modp3072, modp4096, modp6144 and modp8192.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayObsoleteEncryptionAlgorithms = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.encryption.algorithms", "",
|
||||||
|
"Comma-separated list of encryption algorithms that are marked as obsolete/insecure for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are aes128, aes192 and aes256 and 3des.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayObsoleteHashingAlgorithms = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.hashing.algorithms", "",
|
||||||
|
"Comma-separated list of hashing algorithms that are marked as obsolete/insecure for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are sha1, sha256, sha384 and sha512 and md5.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayObsoleteIkeVersions = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.ike.versions", "",
|
||||||
|
"Comma-separated list of IKE versions that are marked as obsolete/insecure for VPN Customer Gateways. Allowed values are ikev, ikev1 and ikev2.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<String> VpnCustomerGatewayObsoleteDhGroup = new ConfigKey<String>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.dh.group", "",
|
||||||
|
"Comma-separated list of Diffie-Hellman groups that are marked as obsolete/insecure for VPN Customer Gateways." +
|
||||||
|
"Applies to both IKE and ESP phases. Allowed values are modp1024, modp1536, modp2048, modp3072, modp4096, modp6144 and modp8192.",
|
||||||
|
true, ConfigKey.Scope.Domain);
|
||||||
|
public static final ConfigKey<Long> VpnCustomerGatewayObsoleteCheckInterval = new ConfigKey<Long>(
|
||||||
|
ConfigKey.CATEGORY_NETWORK, Long.class, "vpn.customer.gateway.obsolete.check.interval", "0",
|
||||||
|
"Interval in hours to periodically check VPN customer gateways for obsolete/excluded parameters and generate events and alerts. " +
|
||||||
|
"Set to 0 to disable. Default: 0 (disabled).",
|
||||||
|
true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
List<Site2SiteVpnServiceProvider> _s2sProviders;
|
List<Site2SiteVpnServiceProvider> _s2sProviders;
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -117,9 +178,12 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
private IpAddressManager ipAddressManager;
|
private IpAddressManager ipAddressManager;
|
||||||
@Inject
|
@Inject
|
||||||
private VpcManager vpcManager;
|
private VpcManager vpcManager;
|
||||||
|
@Inject
|
||||||
|
private AlertManager _alertMgr;
|
||||||
|
|
||||||
int _connLimit;
|
int _connLimit;
|
||||||
int _subnetsLimit;
|
int _subnetsLimit;
|
||||||
|
private ScheduledExecutorService _vpnCheckExecutor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
|
@ -127,6 +191,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
_connLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnConnectionPerVpnGatewayLimit.key()), 4);
|
_connLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnConnectionPerVpnGatewayLimit.key()), 4);
|
||||||
_subnetsLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnSubnetsPerCustomerGatewayLimit.key()), 10);
|
_subnetsLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnSubnetsPerCustomerGatewayLimit.key()), 10);
|
||||||
assert (_s2sProviders.iterator().hasNext()) : "Did not get injected with a list of S2S providers!";
|
assert (_s2sProviders.iterator().hasNext()) : "Did not get injected with a list of S2S providers!";
|
||||||
|
_vpnCheckExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpnCustomerGateway-ExcludedAndObsoleteCheck"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,7 +211,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
}
|
}
|
||||||
Site2SiteVpnGatewayVO gws = _vpnGatewayDao.findByVpcId(vpcId);
|
Site2SiteVpnGatewayVO gws = _vpnGatewayDao.findByVpcId(vpcId);
|
||||||
if (gws != null) {
|
if (gws != null) {
|
||||||
throw new InvalidParameterValueException(String.format("The VPN gateway of VPC %s already existed!", vpc));
|
throw new InvalidParameterValueException(String.format("The VPN gateway of VPC %s already exists!", vpc));
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddressVO requestedIp = _ipAddressDao.findById(cmd.getIpAddressId());
|
IPAddressVO requestedIp = _ipAddressDao.findById(cmd.getIpAddressId());
|
||||||
|
|
@ -187,6 +252,113 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateVpnCryptographicParameters(String ikePolicy, String espPolicy, String ikeVersion, Long domainId) {
|
||||||
|
String excludedEncryption = VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId);
|
||||||
|
String excludedHashing = VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId);
|
||||||
|
String excludedIkeVersions = VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId);
|
||||||
|
String excludedDhGroup = VpnCustomerGatewayExcludedDhGroup.valueIn(domainId);
|
||||||
|
|
||||||
|
Set<String> excludedParameters = getVpnGatewayParametersInBlockedList(ikePolicy, espPolicy, ikeVersion,
|
||||||
|
excludedEncryption, excludedHashing, excludedIkeVersions, excludedDhGroup);
|
||||||
|
if (!excludedParameters.isEmpty()) {
|
||||||
|
throw new InvalidParameterValueException("The following excluded cryptographic parameter(s) cannot be used in a VPN Customer Gateway: " + excludedParameters.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw) {
|
||||||
|
Long domainId = customerGw.getDomainId();
|
||||||
|
String excludedEncryption = VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId);
|
||||||
|
String excludedHashing = VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId);
|
||||||
|
String excludedIkeVersions = VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId);
|
||||||
|
String excludedDhGroup = VpnCustomerGatewayExcludedDhGroup.valueIn(domainId);
|
||||||
|
|
||||||
|
return getVpnGatewayParametersInBlockedList(customerGw.getIkePolicy(), customerGw.getEspPolicy(), customerGw.getIkeVersion(),
|
||||||
|
excludedEncryption, excludedHashing, excludedIkeVersions, excludedDhGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw) {
|
||||||
|
Long domainId = customerGw.getDomainId();
|
||||||
|
String obsoleteEncryption = VpnCustomerGatewayObsoleteEncryptionAlgorithms.valueIn(domainId);
|
||||||
|
String obsoleteHashing = VpnCustomerGatewayObsoleteHashingAlgorithms.valueIn(domainId);
|
||||||
|
String obsoleteIkeVersions = VpnCustomerGatewayObsoleteIkeVersions.valueIn(domainId);
|
||||||
|
String obsoleteDhGroup = VpnCustomerGatewayObsoleteDhGroup.valueIn(domainId);
|
||||||
|
|
||||||
|
return getVpnGatewayParametersInBlockedList(customerGw.getIkePolicy(), customerGw.getEspPolicy(), customerGw.getIkeVersion(),
|
||||||
|
obsoleteEncryption, obsoleteHashing, obsoleteIkeVersions, obsoleteDhGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getVpnGatewayParametersInBlockedList(String ikePolicy, String espPolicy, String ikeVersion,
|
||||||
|
String blockedEncryptionList, String blockedHashingList,
|
||||||
|
String blockedIkeVersionList, String blockedDhGroupList) {
|
||||||
|
|
||||||
|
Set<String> blockedParameters = new HashSet<>();
|
||||||
|
if (StringUtils.isEmpty(blockedEncryptionList)
|
||||||
|
&& StringUtils.isEmpty(blockedHashingList)
|
||||||
|
&& StringUtils.isEmpty(blockedIkeVersionList)
|
||||||
|
&& StringUtils.isEmpty(blockedDhGroupList)) {
|
||||||
|
return blockedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isParameterInList(ikeVersion, blockedIkeVersionList)) {
|
||||||
|
blockedParameters.add(ikeVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> ikePolicyResult = getVpnGatewayPolicyParametersInBlockedList(ikePolicy, "IKE", blockedEncryptionList, blockedHashingList, blockedDhGroupList);
|
||||||
|
if (CollectionUtils.isNotEmpty(ikePolicyResult)) {
|
||||||
|
blockedParameters.addAll(ikePolicyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> espPolicyResult = getVpnGatewayPolicyParametersInBlockedList(espPolicy, "ESP", blockedEncryptionList, blockedHashingList, blockedDhGroupList);
|
||||||
|
if (CollectionUtils.isNotEmpty(espPolicyResult)) {
|
||||||
|
blockedParameters.addAll(espPolicyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getVpnGatewayPolicyParametersInBlockedList(String policy, String policyType, String blockedEncryptionList, String blockedHashingList, String blockedDhGroupList) {
|
||||||
|
|
||||||
|
String trimmedPolicy = policy.trim();
|
||||||
|
String cipherHash = trimmedPolicy.split(";")[0];
|
||||||
|
String[] parts = cipherHash.split("-");
|
||||||
|
|
||||||
|
String encryption = parts[0].trim();
|
||||||
|
String hashing = parts.length > 1 ? parts[1].trim() : "";
|
||||||
|
|
||||||
|
Set<String> blockedParameters = new HashSet<>();
|
||||||
|
if (isParameterInList(encryption, blockedEncryptionList)) {
|
||||||
|
blockedParameters.add(encryption);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isParameterInList(hashing, blockedHashingList)) {
|
||||||
|
blockedParameters.add(hashing);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trimmedPolicy.equals(cipherHash)) {
|
||||||
|
String dhGroup = trimmedPolicy.split(";")[1].trim();
|
||||||
|
if (isParameterInList(dhGroup, blockedDhGroupList)) {
|
||||||
|
blockedParameters.add(dhGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isParameterInList(String parameter, String list) {
|
||||||
|
if (StringUtils.isEmpty(list) || StringUtils.isEmpty(parameter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] entries = list.split(",");
|
||||||
|
for (String item : entries) {
|
||||||
|
if (item != null && item.trim().equalsIgnoreCase(parameter.trim())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void checkCustomerGatewayCidrList(String guestCidrList) {
|
protected void checkCustomerGatewayCidrList(String guestCidrList) {
|
||||||
String[] cidrList = guestCidrList.split(",");
|
String[] cidrList = guestCidrList.split(",");
|
||||||
if (cidrList.length > _subnetsLimit) {
|
if (cidrList.length > _subnetsLimit) {
|
||||||
|
|
@ -235,6 +407,13 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) {
|
if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) {
|
||||||
throw new InvalidParameterValueException("The customer gateway ESP policy " + espPolicy + " is invalid!");
|
throw new InvalidParameterValueException("The customer gateway ESP policy " + espPolicy + " is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ikeVersion = cmd.getIkeVersion();
|
||||||
|
if (ikeVersion == null) {
|
||||||
|
ikeVersion = "ike";
|
||||||
|
}
|
||||||
|
validateVpnCryptographicParameters(ikePolicy, espPolicy, ikeVersion, owner.getDomainId());
|
||||||
|
|
||||||
Long ikeLifetime = cmd.getIkeLifetime();
|
Long ikeLifetime = cmd.getIkeLifetime();
|
||||||
if (ikeLifetime == null) {
|
if (ikeLifetime == null) {
|
||||||
// Default value of lifetime is 1 day
|
// Default value of lifetime is 1 day
|
||||||
|
|
@ -264,7 +443,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
|
|
||||||
long accountId = owner.getAccountId();
|
long accountId = owner.getAccountId();
|
||||||
if (_customerGatewayDao.findByNameAndAccountId(name, accountId) != null) {
|
if (_customerGatewayDao.findByNameAndAccountId(name, accountId) != null) {
|
||||||
throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!");
|
throw new InvalidParameterValueException("The customer gateway with name " + name + " already exists!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean splitConnections = cmd.getSplitConnections();
|
Boolean splitConnections = cmd.getSplitConnections();
|
||||||
|
|
@ -272,11 +451,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
splitConnections = false;
|
splitConnections = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ikeVersion = cmd.getIkeVersion();
|
|
||||||
if (ikeVersion == null) {
|
|
||||||
ikeVersion = "ike";
|
|
||||||
}
|
|
||||||
|
|
||||||
checkCustomerGatewayCidrList(peerCidrList);
|
checkCustomerGatewayCidrList(peerCidrList);
|
||||||
|
|
||||||
Site2SiteCustomerGatewayVO gw =
|
Site2SiteCustomerGatewayVO gw =
|
||||||
|
|
@ -374,7 +548,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
|
|
||||||
private void validateVpnConnectionDoesntExist(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) {
|
private void validateVpnConnectionDoesntExist(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) {
|
||||||
if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGateway.getId(), customerGateway.getId()) != null) {
|
if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGateway.getId(), customerGateway.getId()) != null) {
|
||||||
throw new InvalidParameterValueException(String.format("The vpn connection with customer gateway %s and vpn gateway %s already existed!", customerGateway, vpnGateway));
|
throw new InvalidParameterValueException(String.format("The vpn connection with customer gateway %s and vpn gateway %s already exists!", customerGateway, vpnGateway));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,6 +695,10 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) {
|
if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) {
|
||||||
throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!");
|
throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ikeVersion = cmd.getIkeVersion();
|
||||||
|
validateVpnCryptographicParameters(ikePolicy, espPolicy, ikeVersion, gw.getDomainId());
|
||||||
|
|
||||||
Long ikeLifetime = cmd.getIkeLifetime();
|
Long ikeLifetime = cmd.getIkeLifetime();
|
||||||
if (ikeLifetime == null) {
|
if (ikeLifetime == null) {
|
||||||
// Default value of lifetime is 1 day
|
// Default value of lifetime is 1 day
|
||||||
|
|
@ -550,14 +728,12 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
|
|
||||||
Boolean splitConnections = cmd.getSplitConnections();
|
Boolean splitConnections = cmd.getSplitConnections();
|
||||||
|
|
||||||
String ikeVersion = cmd.getIkeVersion();
|
|
||||||
|
|
||||||
checkCustomerGatewayCidrList(guestCidrList);
|
checkCustomerGatewayCidrList(guestCidrList);
|
||||||
|
|
||||||
long accountId = gw.getAccountId();
|
long accountId = gw.getAccountId();
|
||||||
Site2SiteCustomerGatewayVO existedGw = _customerGatewayDao.findByNameAndAccountId(name, accountId);
|
Site2SiteCustomerGatewayVO existedGw = _customerGatewayDao.findByNameAndAccountId(name, accountId);
|
||||||
if (existedGw != null && existedGw.getId() != gw.getId()) {
|
if (existedGw != null && existedGw.getId() != gw.getId()) {
|
||||||
throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!");
|
throw new InvalidParameterValueException("The customer gateway with name " + name + " already exists!");
|
||||||
}
|
}
|
||||||
|
|
||||||
gw.setName(name);
|
gw.setName(name);
|
||||||
|
|
@ -977,4 +1153,83 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
|
||||||
return _vpnGatewayDao.findById(id);
|
return _vpnGatewayDao.findById(id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start() {
|
||||||
|
ConfigKeyScheduledExecutionWrapper runner = new ConfigKeyScheduledExecutionWrapper(
|
||||||
|
_vpnCheckExecutor,
|
||||||
|
new CheckVpnCustomerGatewayObsoleteParametersTask(),
|
||||||
|
VpnCustomerGatewayObsoleteCheckInterval,
|
||||||
|
3600,
|
||||||
|
TimeUnit.HOURS);
|
||||||
|
runner.start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stop() {
|
||||||
|
if (_vpnCheckExecutor != null) {
|
||||||
|
_vpnCheckExecutor.shutdownNow();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigComponentName() {
|
||||||
|
return Site2SiteVpnManager.class.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
|
return new ConfigKey<?>[] { VpnCustomerGatewayExcludedEncryptionAlgorithms, VpnCustomerGatewayExcludedHashingAlgorithms,
|
||||||
|
VpnCustomerGatewayExcludedIkeVersions, VpnCustomerGatewayExcludedDhGroup, VpnCustomerGatewayObsoleteEncryptionAlgorithms,
|
||||||
|
VpnCustomerGatewayObsoleteHashingAlgorithms, VpnCustomerGatewayObsoleteIkeVersions, VpnCustomerGatewayObsoleteDhGroup,
|
||||||
|
VpnCustomerGatewayObsoleteCheckInterval};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class CheckVpnCustomerGatewayObsoleteParametersTask extends ManagedContextRunnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void runInContext() {
|
||||||
|
List<Site2SiteCustomerGatewayVO> allGateways = _customerGatewayDao.listAll();
|
||||||
|
int obsoleteCount = 0;
|
||||||
|
int excludedCount = 0;
|
||||||
|
|
||||||
|
for (Site2SiteCustomerGatewayVO gateway : allGateways) {
|
||||||
|
Set<String> excludedParameters = getExcludedVpnGatewayParameters(gateway);
|
||||||
|
Set<String> obsoleteParameters = getObsoleteVpnGatewayParameters(gateway);
|
||||||
|
|
||||||
|
List<String> message = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(excludedParameters)) {
|
||||||
|
excludedCount++;
|
||||||
|
message.add("excluded parameter(s) " + excludedParameters.toString());
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(obsoleteParameters)) {
|
||||||
|
obsoleteCount++;
|
||||||
|
message.add("obsolete parameter(s) " + obsoleteParameters.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(message)) {
|
||||||
|
Account account = _accountDao.findById(gateway.getAccountId());
|
||||||
|
String description = String.format("VPN customer gateway '%s' (Account: %s) contains %s.",
|
||||||
|
gateway.getName(), account.getAccountName(), String.join(" and ", message));
|
||||||
|
ActionEventUtils.onActionEvent(User.UID_SYSTEM, gateway.getAccountId(), gateway.getDomainId(),
|
||||||
|
EventTypes.EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS, description,
|
||||||
|
gateway.getId(), Site2SiteCustomerGateway.class.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> message = new ArrayList<>();
|
||||||
|
if (excludedCount > 0) {
|
||||||
|
message.add("excluded parameters: " + excludedCount);
|
||||||
|
}
|
||||||
|
if (obsoleteCount > 0) {
|
||||||
|
message.add("obsolete parameters: " + obsoleteCount);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(message)) {
|
||||||
|
String subject = String.format("VPN customer gateways using " + String.join(", ", message));
|
||||||
|
_alertMgr.sendAlert(AlertService.AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS, 0L, 0L, subject, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -720,6 +720,7 @@ import com.cloud.deploy.DeploymentPlan;
|
||||||
import com.cloud.deploy.DeploymentPlanner;
|
import com.cloud.deploy.DeploymentPlanner;
|
||||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||||
import com.cloud.deploy.DeploymentPlanningManager;
|
import com.cloud.deploy.DeploymentPlanningManager;
|
||||||
|
import com.cloud.domain.Domain;
|
||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.domain.dao.DomainDao;
|
import com.cloud.domain.dao.DomainDao;
|
||||||
import com.cloud.event.ActionEvent;
|
import com.cloud.event.ActionEvent;
|
||||||
|
|
@ -761,6 +762,7 @@ import com.cloud.network.IpAddressManagerImpl;
|
||||||
import com.cloud.network.Network;
|
import com.cloud.network.Network;
|
||||||
import com.cloud.network.NetworkModel;
|
import com.cloud.network.NetworkModel;
|
||||||
import com.cloud.network.Networks;
|
import com.cloud.network.Networks;
|
||||||
|
import com.cloud.network.vpn.Site2SiteVpnManagerImpl;
|
||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.network.dao.IPAddressVO;
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
import com.cloud.network.dao.LoadBalancerDao;
|
import com.cloud.network.dao.LoadBalancerDao;
|
||||||
|
|
@ -4778,6 +4780,14 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||||
final Map<String, Object> capabilities = new HashMap<>();
|
final Map<String, Object> capabilities = new HashMap<>();
|
||||||
|
|
||||||
final Account caller = getCaller();
|
final Account caller = getCaller();
|
||||||
|
Long domainId = cmd.getDomainId();
|
||||||
|
if (domainId == null) {
|
||||||
|
domainId = caller.getDomainId();
|
||||||
|
} else {
|
||||||
|
Domain domain = _domainDao.findById(domainId);
|
||||||
|
_accountService.checkAccess(caller, domain);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean isCallerRootAdmin = _accountService.isRootAdmin(caller.getId());
|
final boolean isCallerRootAdmin = _accountService.isRootAdmin(caller.getId());
|
||||||
final boolean isCallerAdmin = isCallerRootAdmin || _accountService.isAdmin(caller.getId());
|
final boolean isCallerAdmin = isCallerRootAdmin || _accountService.isAdmin(caller.getId());
|
||||||
boolean securityGroupsEnabled = false;
|
boolean securityGroupsEnabled = false;
|
||||||
|
|
@ -4812,7 +4822,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||||
final boolean allowUserExpungeRecoverVolume = (VolumeApiServiceImpl.AllowUserExpungeRecoverVolume.valueIn(caller.getId()) | isCallerAdmin);
|
final boolean allowUserExpungeRecoverVolume = (VolumeApiServiceImpl.AllowUserExpungeRecoverVolume.valueIn(caller.getId()) | isCallerAdmin);
|
||||||
final boolean allowUserForceStopVM = (UserVmManager.AllowUserForceStopVm.valueIn(caller.getId()) | isCallerAdmin);
|
final boolean allowUserForceStopVM = (UserVmManager.AllowUserForceStopVm.valueIn(caller.getId()) | isCallerAdmin);
|
||||||
|
|
||||||
final boolean allowUserViewAllDomainAccounts = (QueryService.AllowUserViewAllDomainAccounts.valueIn(caller.getDomainId()));
|
final boolean allowUserViewAllDomainAccounts = (QueryService.AllowUserViewAllDomainAccounts.valueIn(domainId));
|
||||||
|
|
||||||
final boolean kubernetesServiceEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.service.enabled"));
|
final boolean kubernetesServiceEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.service.enabled"));
|
||||||
final boolean kubernetesClusterExperimentalFeaturesEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.cluster.experimental.features.enabled"));
|
final boolean kubernetesClusterExperimentalFeaturesEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.cluster.experimental.features.enabled"));
|
||||||
|
|
@ -4865,9 +4875,53 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||||
}
|
}
|
||||||
capabilities.put(ApiConstants.ADDITONAL_CONFIG_ENABLED, UserVmManager.EnableAdditionalVmConfig.valueIn(caller.getId()));
|
capabilities.put(ApiConstants.ADDITONAL_CONFIG_ENABLED, UserVmManager.EnableAdditionalVmConfig.valueIn(caller.getId()));
|
||||||
|
|
||||||
|
Map<String, Object> vpnParams = getVpnCustomerGatewayParameters(domainId);
|
||||||
|
if (!vpnParams.isEmpty()) {
|
||||||
|
capabilities.put(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS, vpnParams);
|
||||||
|
}
|
||||||
|
|
||||||
return capabilities;
|
return capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> getVpnCustomerGatewayParameters(Long domainId) {
|
||||||
|
Map<String, Object> vpnParams = new HashMap<>();
|
||||||
|
|
||||||
|
String excludedEncryption = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId);
|
||||||
|
String excludedHashing = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId);
|
||||||
|
String excludedIkeVersions = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId);
|
||||||
|
String excludedDhGroup = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup.valueIn(domainId);
|
||||||
|
String obsoleteEncryption = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms.valueIn(domainId);
|
||||||
|
String obsoleteHashing = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms.valueIn(domainId);
|
||||||
|
String obsoleteIkeVersions = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions.valueIn(domainId);
|
||||||
|
String obsoleteDhGroup = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup.valueIn(domainId);
|
||||||
|
|
||||||
|
if (!excludedEncryption.isEmpty()) {
|
||||||
|
vpnParams.put("excludedencryptionalgorithms", excludedEncryption);
|
||||||
|
}
|
||||||
|
if (!obsoleteEncryption.isEmpty()) {
|
||||||
|
vpnParams.put("obsoleteencryptionalgorithms", obsoleteEncryption);
|
||||||
|
}
|
||||||
|
if (!excludedHashing.isEmpty()) {
|
||||||
|
vpnParams.put("excludedhashingalgorithms", excludedHashing);
|
||||||
|
}
|
||||||
|
if (!obsoleteHashing.isEmpty()) {
|
||||||
|
vpnParams.put("obsoletehashingalgorithms", obsoleteHashing);
|
||||||
|
}
|
||||||
|
if (!excludedIkeVersions.isEmpty()) {
|
||||||
|
vpnParams.put("excludedikeversions", excludedIkeVersions);
|
||||||
|
}
|
||||||
|
if (!obsoleteIkeVersions.isEmpty()) {
|
||||||
|
vpnParams.put("obsoleteikeversions", obsoleteIkeVersions);
|
||||||
|
}
|
||||||
|
if (!excludedDhGroup.isEmpty()) {
|
||||||
|
vpnParams.put("excludeddhgroups", excludedDhGroup);
|
||||||
|
}
|
||||||
|
if (!obsoleteDhGroup.isEmpty()) {
|
||||||
|
vpnParams.put("obsoletedhgroups", obsoleteDhGroup);
|
||||||
|
}
|
||||||
|
return vpnParams;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuestOSVO getGuestOs(final Long guestOsId) {
|
public GuestOSVO getGuestOs(final Long guestOsId) {
|
||||||
return _guestOSDao.findById(guestOsId);
|
return _guestOSDao.findById(guestOsId);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,944 @@
|
||||||
|
/*
|
||||||
|
* 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 com.cloud.network.vpn;
|
||||||
|
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import com.cloud.network.Site2SiteVpnConnection;
|
||||||
|
import com.cloud.network.Site2SiteVpnConnection.State;
|
||||||
|
import com.cloud.network.Site2SiteVpnGateway;
|
||||||
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
|
import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
|
||||||
|
import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
|
||||||
|
import com.cloud.network.dao.Site2SiteVpnConnectionDao;
|
||||||
|
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
||||||
|
import com.cloud.network.dao.Site2SiteVpnGatewayDao;
|
||||||
|
import com.cloud.network.dao.Site2SiteVpnGatewayVO;
|
||||||
|
import com.cloud.network.element.Site2SiteVpnServiceProvider;
|
||||||
|
import com.cloud.network.vpc.VpcManager;
|
||||||
|
import com.cloud.network.vpc.VpcVO;
|
||||||
|
import com.cloud.network.vpc.dao.VpcDao;
|
||||||
|
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.AccountManager;
|
||||||
|
import com.cloud.user.AccountVO;
|
||||||
|
import com.cloud.user.User;
|
||||||
|
import com.cloud.user.UserVO;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.utils.net.NetUtils;
|
||||||
|
import com.cloud.vm.DomainRouterVO;
|
||||||
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
|
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;
|
||||||
|
import org.apache.cloudstack.api.command.user.vpn.DeleteVpnConnectionCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.vpn.DeleteVpnCustomerGatewayCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.vpn.DeleteVpnGatewayCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||||
|
public class Site2SiteVpnManagerImplTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Site2SiteCustomerGatewayDao _customerGatewayDao;
|
||||||
|
@Mock
|
||||||
|
private Site2SiteVpnGatewayDao _vpnGatewayDao;
|
||||||
|
@Mock
|
||||||
|
private Site2SiteVpnConnectionDao _vpnConnectionDao;
|
||||||
|
@Mock
|
||||||
|
private VpcDao _vpcDao;
|
||||||
|
@Mock
|
||||||
|
private IPAddressDao _ipAddressDao;
|
||||||
|
@Mock
|
||||||
|
private VpcManager _vpcMgr;
|
||||||
|
@Mock
|
||||||
|
private AccountManager _accountMgr;
|
||||||
|
@Mock
|
||||||
|
private AnnotationDao annotationDao;
|
||||||
|
@Mock
|
||||||
|
private List<Site2SiteVpnServiceProvider> _s2sProviders;
|
||||||
|
@Mock
|
||||||
|
VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private Site2SiteVpnManagerImpl site2SiteVpnManager;
|
||||||
|
|
||||||
|
private AccountVO account;
|
||||||
|
private UserVO user;
|
||||||
|
private VpcVO vpc;
|
||||||
|
private IPAddressVO ipAddress;
|
||||||
|
private Site2SiteVpnGatewayVO vpnGateway;
|
||||||
|
private Site2SiteCustomerGatewayVO customerGateway;
|
||||||
|
private Site2SiteVpnConnectionVO vpnConnection;
|
||||||
|
|
||||||
|
private static final Long ACCOUNT_ID = 1L;
|
||||||
|
private static final Long DOMAIN_ID = 2L;
|
||||||
|
private static final Long VPC_ID = 3L;
|
||||||
|
private static final Long VPN_GATEWAY_ID = 4L;
|
||||||
|
private static final Long CUSTOMER_GATEWAY_ID = 5L;
|
||||||
|
private static final Long VPN_CONNECTION_ID = 6L;
|
||||||
|
private static final Long IP_ADDRESS_ID = 7L;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
account = new AccountVO("testaccount", DOMAIN_ID, "networkdomain", Account.Type.NORMAL, UUID.randomUUID().toString());
|
||||||
|
account.setId(ACCOUNT_ID);
|
||||||
|
user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone",
|
||||||
|
UUID.randomUUID().toString(), User.Source.UNKNOWN);
|
||||||
|
CallContext.register(user, account);
|
||||||
|
|
||||||
|
vpc = mock(VpcVO.class);
|
||||||
|
when(vpc.getId()).thenReturn(VPC_ID);
|
||||||
|
when(vpc.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||||
|
when(vpc.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
when(vpc.getCidr()).thenReturn("10.0.0.0/16");
|
||||||
|
|
||||||
|
ipAddress = mock(IPAddressVO.class);
|
||||||
|
when(ipAddress.getId()).thenReturn(IP_ADDRESS_ID);
|
||||||
|
when(ipAddress.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
|
||||||
|
vpnGateway = mock(Site2SiteVpnGatewayVO.class);
|
||||||
|
when(vpnGateway.getId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
when(vpnGateway.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(vpnGateway.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||||
|
when(vpnGateway.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
customerGateway = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(customerGateway.getId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
when(customerGateway.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||||
|
when(customerGateway.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
when(customerGateway.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(customerGateway.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(customerGateway.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(customerGateway.getIkeVersion()).thenReturn("ike");
|
||||||
|
|
||||||
|
vpnConnection = new Site2SiteVpnConnectionVO(ACCOUNT_ID, DOMAIN_ID, VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID, false);
|
||||||
|
vpnConnection.setState(State.Pending);
|
||||||
|
|
||||||
|
when(_accountMgr.getAccount(ACCOUNT_ID)).thenReturn(account);
|
||||||
|
doNothing().when(_accountMgr).checkAccess(any(Account.class), nullable(SecurityChecker.AccessType.class), anyBoolean(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms);
|
||||||
|
resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup);
|
||||||
|
CallContext.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setConfigKeyValue(ConfigKey<String> configKey, String value) {
|
||||||
|
try {
|
||||||
|
Field valueField = ConfigKey.class.getDeclaredField("_value");
|
||||||
|
valueField.setAccessible(true);
|
||||||
|
valueField.set(configKey, value);
|
||||||
|
|
||||||
|
Field dynamicField = ConfigKey.class.getDeclaredField("_isDynamic");
|
||||||
|
dynamicField.setAccessible(true);
|
||||||
|
dynamicField.setBoolean(configKey, false);
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException("Failed to set ConfigKey value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetConfigKeyValue(ConfigKey<String> configKey) {
|
||||||
|
try {
|
||||||
|
Field valueField = ConfigKey.class.getDeclaredField("_value");
|
||||||
|
valueField.setAccessible(true);
|
||||||
|
valueField.set(configKey, null);
|
||||||
|
|
||||||
|
Field dynamicField = ConfigKey.class.getDeclaredField("_isDynamic");
|
||||||
|
dynamicField.setAccessible(true);
|
||||||
|
dynamicField.setBoolean(configKey, true);
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException("Failed to reset ConfigKey value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateVpnGatewaySuccess() {
|
||||||
|
CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class);
|
||||||
|
when(cmd.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
when(cmd.isDisplay()).thenReturn(true);
|
||||||
|
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(vpc);
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null);
|
||||||
|
when(_ipAddressDao.listByAssociatedVpc(VPC_ID, true)).thenReturn(List.of(ipAddress));
|
||||||
|
when(_vpnGatewayDao.persist(any(Site2SiteVpnGatewayVO.class))).thenReturn(vpnGateway);
|
||||||
|
|
||||||
|
Site2SiteVpnGateway result = site2SiteVpnManager.createVpnGateway(cmd);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
verify(_vpnGatewayDao).persist(any(Site2SiteVpnGatewayVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateVpnGatewayInvalidVpc() {
|
||||||
|
CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class);
|
||||||
|
when(cmd.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(null);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createVpnGateway(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateVpnGatewayAlreadyExists() {
|
||||||
|
CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class);
|
||||||
|
when(cmd.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(vpc);
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createVpnGateway(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CloudRuntimeException.class)
|
||||||
|
public void testCreateVpnGatewayNoSourceNatIp() {
|
||||||
|
CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class);
|
||||||
|
when(cmd.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(vpc);
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null);
|
||||||
|
when(_ipAddressDao.listByAssociatedVpc(VPC_ID, true)).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
site2SiteVpnManager.createVpnGateway(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidIp() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("invalid-ip");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("invalid-ip")).thenReturn(false);
|
||||||
|
netUtilsMock.when(() -> NetUtils.verifyDomainName("invalid-ip")).thenReturn(false);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidCidrList() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("invalid-cidr");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("invalid-cidr")).thenReturn(false);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidIkePolicy() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("invalid-policy");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "invalid-policy")).thenReturn(false);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidEspPolicy() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("invalid-policy");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "invalid-policy")).thenReturn(false);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayWithExcludedParameters() throws Exception {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getName()).thenReturn("test-gateway");
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIpsecPsk()).thenReturn("test-psk");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("3des-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "3des-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayDuplicateName() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getName()).thenReturn("test-gateway");
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
|
||||||
|
when(_customerGatewayDao.findByNameAndAccountId("test-gateway", ACCOUNT_ID)).thenReturn(customerGateway);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidIkeLifetime() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getIkeLifetime()).thenReturn(86401L);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayInvalidEspLifetime() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspLifetime()).thenReturn(86401L);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayTooManySubnets() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
String tooManyCidrs = "192.168.1.0/24,192.168.2.0/24,192.168.3.0/24,192.168.4.0/24,192.168.5.0/24," +
|
||||||
|
"192.168.6.0/24,192.168.7.0/24,192.168.8.0/24,192.168.9.0/24,192.168.10.0/24,192.168.11.0/24";
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn(tooManyCidrs);
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList(tooManyCidrs)).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.getCleanIp4CidrList(tooManyCidrs)).thenReturn(tooManyCidrs);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateCustomerGatewayOverlappingSubnets() {
|
||||||
|
CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getGatewayIp()).thenReturn("1.2.3.4");
|
||||||
|
when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24,192.168.1.0/25");
|
||||||
|
when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
String cidrList = "192.168.1.0/24,192.168.1.0/25";
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidCidrList(cidrList)).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.getCleanIp4CidrList(cidrList)).thenReturn(cidrList);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true);
|
||||||
|
netUtilsMock.when(() -> NetUtils.isNetworksOverlap("192.168.1.0/24", "192.168.1.0/25")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateVpnConnectionCidrOverlapWithVpc() {
|
||||||
|
CreateVpnConnectionCmd cmd = mock(CreateVpnConnectionCmd.class);
|
||||||
|
when(cmd.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
when(cmd.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
Site2SiteCustomerGatewayVO customerGw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(customerGw.getGuestCidrList()).thenReturn("10.0.0.0/24");
|
||||||
|
when(customerGw.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||||
|
when(customerGw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGw);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID)).thenReturn(null);
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(vpc);
|
||||||
|
|
||||||
|
try (MockedStatic<NetUtils> netUtilsMock = Mockito.mockStatic(NetUtils.class)) {
|
||||||
|
netUtilsMock.when(() -> NetUtils.isNetworksOverlap("10.0.0.0/16", "10.0.0.0/24")).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createVpnConnection(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testCreateVpnConnectionExceedsLimit() {
|
||||||
|
CreateVpnConnectionCmd cmd = mock(CreateVpnConnectionCmd.class);
|
||||||
|
when(cmd.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
when(cmd.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID);
|
||||||
|
|
||||||
|
when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID)).thenReturn(null);
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpcDao.findById(VPC_ID)).thenReturn(vpc);
|
||||||
|
|
||||||
|
List<Site2SiteVpnConnectionVO> existingConns = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
existingConns.add(mock(Site2SiteVpnConnectionVO.class));
|
||||||
|
}
|
||||||
|
when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(existingConns);
|
||||||
|
|
||||||
|
site2SiteVpnManager.createVpnConnection(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteCustomerGatewaySuccess() {
|
||||||
|
DeleteVpnCustomerGatewayCmd cmd = mock(DeleteVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
|
||||||
|
when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway);
|
||||||
|
when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.deleteCustomerGateway(cmd);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_customerGatewayDao).remove(CUSTOMER_GATEWAY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testDeleteCustomerGatewayWithConnections() {
|
||||||
|
DeleteVpnCustomerGatewayCmd cmd = mock(DeleteVpnCustomerGatewayCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
|
||||||
|
when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway);
|
||||||
|
when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(List.of(vpnConnection));
|
||||||
|
|
||||||
|
site2SiteVpnManager.deleteCustomerGateway(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteVpnGatewaySuccess() {
|
||||||
|
DeleteVpnGatewayCmd cmd = mock(DeleteVpnGatewayCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.deleteVpnGateway(cmd);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_vpnGatewayDao).remove(VPN_GATEWAY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testDeleteVpnGatewayWithConnections() {
|
||||||
|
DeleteVpnGatewayCmd cmd = mock(DeleteVpnGatewayCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(List.of(vpnConnection));
|
||||||
|
|
||||||
|
site2SiteVpnManager.deleteVpnGateway(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteVpnConnectionSuccess() throws ResourceUnavailableException {
|
||||||
|
DeleteVpnConnectionCmd cmd = mock(DeleteVpnConnectionCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(VPN_CONNECTION_ID);
|
||||||
|
|
||||||
|
when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
vpnConnection.setState(State.Pending);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true);
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.deleteVpnConnection(cmd);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_vpnConnectionDao).remove(VPN_CONNECTION_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartVpnConnectionSuccess() throws ResourceUnavailableException {
|
||||||
|
when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
vpnConnection.setState(State.Pending);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class);
|
||||||
|
when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true);
|
||||||
|
when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator());
|
||||||
|
when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(vpnConnection);
|
||||||
|
when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true);
|
||||||
|
|
||||||
|
Site2SiteVpnConnection result = site2SiteVpnManager.startVpnConnection(VPN_CONNECTION_ID);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
verify(_vpnConnectionDao, org.mockito.Mockito.atLeastOnce()).persist(any(Site2SiteVpnConnectionVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testStartVpnConnectionWrongState() throws ResourceUnavailableException {
|
||||||
|
when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
vpnConnection.setState(State.Connected);
|
||||||
|
|
||||||
|
site2SiteVpnManager.startVpnConnection(VPN_CONNECTION_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResetVpnConnectionSuccess() throws ResourceUnavailableException {
|
||||||
|
ResetVpnConnectionCmd cmd = mock(ResetVpnConnectionCmd.class);
|
||||||
|
when(cmd.getId()).thenReturn(VPN_CONNECTION_ID);
|
||||||
|
|
||||||
|
when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
vpnConnection.setState(State.Connected);
|
||||||
|
when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class);
|
||||||
|
when(provider.stopSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true);
|
||||||
|
when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true);
|
||||||
|
when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator());
|
||||||
|
when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(vpnConnection);
|
||||||
|
when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true);
|
||||||
|
|
||||||
|
Site2SiteVpnConnection result = site2SiteVpnManager.resetVpnConnection(cmd);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCleanupVpnConnectionByVpc() {
|
||||||
|
when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(vpnConnection));
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.cleanupVpnConnectionByVpc(VPC_ID);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_vpnConnectionDao).remove(vpnConnection.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCleanupVpnGatewayByVpc() {
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.cleanupVpnGatewayByVpc(VPC_ID);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_vpnGatewayDao).remove(VPN_GATEWAY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCleanupVpnGatewayByVpcNotFound() {
|
||||||
|
when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null);
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.cleanupVpnGatewayByVpc(VPC_ID);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_vpnGatewayDao, never()).remove(anyLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetConnectionsForRouter() {
|
||||||
|
DomainRouterVO router = mock(DomainRouterVO.class);
|
||||||
|
when(router.getVpcId()).thenReturn(VPC_ID);
|
||||||
|
when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(vpnConnection));
|
||||||
|
|
||||||
|
List<Site2SiteVpnConnectionVO> result = site2SiteVpnManager.getConnectionsForRouter(router);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetConnectionsForRouterNoVpc() {
|
||||||
|
DomainRouterVO router = mock(DomainRouterVO.class);
|
||||||
|
when(router.getVpcId()).thenReturn(null);
|
||||||
|
|
||||||
|
List<Site2SiteVpnConnectionVO> result = site2SiteVpnManager.getConnectionsForRouter(router);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertTrue(result.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteCustomerGatewayByAccount() {
|
||||||
|
when(_customerGatewayDao.listByAccountId(ACCOUNT_ID)).thenReturn(List.of(customerGateway));
|
||||||
|
when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
boolean result = site2SiteVpnManager.deleteCustomerGatewayByAccount(ACCOUNT_ID);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
verify(_customerGatewayDao).remove(CUSTOMER_GATEWAY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReconnectDisconnectedVpnByVpc() throws ResourceUnavailableException {
|
||||||
|
Site2SiteVpnConnectionVO conn = mock(Site2SiteVpnConnectionVO.class);
|
||||||
|
when(conn.getId()).thenReturn(VPN_CONNECTION_ID);
|
||||||
|
when(conn.getState()).thenReturn(State.Disconnected);
|
||||||
|
when(conn.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID);
|
||||||
|
when(conn.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID);
|
||||||
|
when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(conn));
|
||||||
|
when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway);
|
||||||
|
when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(conn);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class);
|
||||||
|
when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true);
|
||||||
|
when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator());
|
||||||
|
when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(conn);
|
||||||
|
when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true);
|
||||||
|
|
||||||
|
site2SiteVpnManager.reconnectDisconnectedVpnByVpc(VPC_ID);
|
||||||
|
|
||||||
|
verify(_vpnConnectionDao, org.mockito.Mockito.atLeastOnce()).persist(any(Site2SiteVpnConnectionVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateVpnConnection() {
|
||||||
|
when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
when(_vpnConnectionDao.update(anyLong(), any(Site2SiteVpnConnectionVO.class))).thenReturn(true);
|
||||||
|
when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection);
|
||||||
|
|
||||||
|
Site2SiteVpnConnection result = site2SiteVpnManager.updateVpnConnection(VPN_CONNECTION_ID, "custom-id", true);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateVpnGateway() {
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
when(_vpnGatewayDao.update(anyLong(), any(Site2SiteVpnGatewayVO.class))).thenReturn(true);
|
||||||
|
when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway);
|
||||||
|
|
||||||
|
Site2SiteVpnGateway result = site2SiteVpnManager.updateVpnGateway(VPN_GATEWAY_ID, "custom-id", true);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersWithExcludedIkeVersion() throws Exception {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ikev1");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "ikev1");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect excluded IKE version", result.isEmpty());
|
||||||
|
assertEquals("Should detect excluded IKE version", "[ikev1]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersWithExcludedEncryption() throws Exception {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("3des-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect excluded encryption algorithm", result.isEmpty());
|
||||||
|
assertEquals("Should detect excluded encryption algorithm", "[3des]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersWithExcludedHashing() throws Exception {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-md5;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "aes128");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "md5");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect excluded algorithms", result.isEmpty());
|
||||||
|
assertEquals("Should detect excluded algorithms", "[aes128, md5]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersWithExcludedDhGroup() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp1024");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "modp1024");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect excluded DH group", result.isEmpty());
|
||||||
|
assertEquals("Should detect excluded DH group", "[modp1024]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersNoExcludedParameters() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertTrue("Should not detect excluded parameters when none are configured", result.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsExcludedParametersWithExcludedEspPolicy() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("3des-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect excluded encryption in ESP policy", result.isEmpty());
|
||||||
|
assertEquals("Should detect excluded encryption in ESP policy", "[3des]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersWithObsoleteIkeVersion() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ikev1");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "ikev1");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect obsolete IKE version", result.isEmpty());
|
||||||
|
assertEquals("Should detect obsolete IKE version", "[ikev1]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersWithObsoleteEncryption() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("3des-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "3des");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect obsolete encryption algorithm", result.isEmpty());
|
||||||
|
assertEquals("Should detect obsolete encryption algorithm", "[3des]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersWithObsoleteHashing() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-md5;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "md5");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect obsolete hashing algorithm", result.isEmpty());
|
||||||
|
assertEquals("Should detect obsolete hashing algorithm", "[md5]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersWithObsoleteDhGroup() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp1024");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "modp1024");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect obsolete DH group", result.isEmpty());
|
||||||
|
assertEquals("Should detect obsolete DH group", "[modp1024]", result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersNoObsoleteParameters() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertTrue("Should not detect obsolete parameters when none are configured", result.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnGatewayContainsObsoleteParametersWithObsoleteEspPolicy() {
|
||||||
|
Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class);
|
||||||
|
when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048");
|
||||||
|
when(gw.getEspPolicy()).thenReturn("3des-sha256;modp2048");
|
||||||
|
when(gw.getIkeVersion()).thenReturn("ike");
|
||||||
|
when(gw.getDomainId()).thenReturn(DOMAIN_ID);
|
||||||
|
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "3des");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "");
|
||||||
|
setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "");
|
||||||
|
|
||||||
|
java.util.Set<String> result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw);
|
||||||
|
assertFalse("Should detect obsolete encryption in ESP policy", result.isEmpty());
|
||||||
|
assertEquals("Should detect obsolete encryption in ESP policy", "[3des]", result.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ import com.cloud.network.Site2SiteVpnConnection;
|
||||||
import com.cloud.network.Site2SiteVpnGateway;
|
import com.cloud.network.Site2SiteVpnGateway;
|
||||||
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
import com.cloud.network.dao.Site2SiteVpnConnectionVO;
|
||||||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||||
import com.cloud.network.vpn.Site2SiteVpnService;
|
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
|
|
@ -41,11 +40,13 @@ import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class MockSite2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager, Site2SiteVpnService {
|
public class MockSite2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.cloud.network.vpn.Site2SiteVpnService#createVpnGateway(org.apache.cloudstack.api.commands.CreateVpnGatewayCmd)
|
* @see com.cloud.network.vpn.Site2SiteVpnService#createVpnGateway(org.apache.cloudstack.api.commands.CreateVpnGatewayCmd)
|
||||||
|
|
@ -275,4 +276,16 @@ public class MockSite2SiteVpnManagerImpl extends ManagerBase implements Site2Sit
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -807,7 +807,7 @@
|
||||||
"label.delete.tungsten.service.group": "Delete Service Group",
|
"label.delete.tungsten.service.group": "Delete Service Group",
|
||||||
"label.delete.volumes": "Data volumes to be deleted",
|
"label.delete.volumes": "Data volumes to be deleted",
|
||||||
"label.delete.vpn.connection": "Delete VPN connection",
|
"label.delete.vpn.connection": "Delete VPN connection",
|
||||||
"label.delete.vpn.customer.gateway": "Delete VPN customer gateway",
|
"label.delete.vpn.customer.gateway": "Delete VPN Customer Gateway",
|
||||||
"label.delete.vpn.gateway": "Delete VPN gateway",
|
"label.delete.vpn.gateway": "Delete VPN gateway",
|
||||||
"label.delete.vpn.user": "Delete VPN User",
|
"label.delete.vpn.user": "Delete VPN User",
|
||||||
"label.delete.webhook": "Delete Webhook",
|
"label.delete.webhook": "Delete Webhook",
|
||||||
|
|
@ -2629,6 +2629,7 @@
|
||||||
"label.update.to": "updated to",
|
"label.update.to": "updated to",
|
||||||
"label.update.traffic.label": "Update traffic labels",
|
"label.update.traffic.label": "Update traffic labels",
|
||||||
"label.update.vmware.datacenter": "Update VMWare datacenter",
|
"label.update.vmware.datacenter": "Update VMWare datacenter",
|
||||||
|
"label.update.vpn.customer.gateway": "Update VPN Customer Gateway",
|
||||||
"label.update.webhook": "Update Webhook",
|
"label.update.webhook": "Update Webhook",
|
||||||
"label.updating": "Updating",
|
"label.updating": "Updating",
|
||||||
"label.upgrade.router.newer.template": "Upgrade router to use newer Template",
|
"label.upgrade.router.newer.template": "Upgrade router to use newer Template",
|
||||||
|
|
@ -3093,8 +3094,8 @@
|
||||||
"message.add.volume": "Please fill in the following data to add a new volume.",
|
"message.add.volume": "Please fill in the following data to add a new volume.",
|
||||||
"message.add.vpn.connection.failed": "Adding VPN connection failed",
|
"message.add.vpn.connection.failed": "Adding VPN connection failed",
|
||||||
"message.add.vpn.connection.processing": "Adding VPN Connection...",
|
"message.add.vpn.connection.processing": "Adding VPN Connection...",
|
||||||
"message.add.vpn.customer.gateway": "Adding VPN customer gateway",
|
"message.add.vpn.customer.gateway": "Adding VPN Customer Gateway",
|
||||||
"message.add.vpn.customer.gateway.processing": "Creation of VPN customer gateway is in progress",
|
"message.add.vpn.customer.gateway.processing": "Creation of VPN Customer Gateway is in progress",
|
||||||
"message.add.vpn.gateway": "Please confirm that you want to add a VPN Gateway.",
|
"message.add.vpn.gateway": "Please confirm that you want to add a VPN Gateway.",
|
||||||
"message.add.vpn.gateway.failed": "Adding VPN gateway failed",
|
"message.add.vpn.gateway.failed": "Adding VPN gateway failed",
|
||||||
"message.add.vpn.gateway.processing": "Adding VPN gateway...",
|
"message.add.vpn.gateway.processing": "Adding VPN gateway...",
|
||||||
|
|
@ -3242,7 +3243,7 @@
|
||||||
"message.create.volume.failed": "Failed to create Volume.",
|
"message.create.volume.failed": "Failed to create Volume.",
|
||||||
"message.create.volume.processing": "Volume creation in progress",
|
"message.create.volume.processing": "Volume creation in progress",
|
||||||
"message.create.vpc.offering": "VPC offering created.",
|
"message.create.vpc.offering": "VPC offering created.",
|
||||||
"message.create.vpn.customer.gateway.failed": "VPN customer gateway creation failed.",
|
"message.create.vpn.customer.gateway.failed": "VPN Customer Gateway creation failed.",
|
||||||
"message.creating.autoscale.vmgroup": "Creating AutoScaling Group",
|
"message.creating.autoscale.vmgroup": "Creating AutoScaling Group",
|
||||||
"message.creating.autoscale.vmprofile": "Creating AutoScale Instance profile",
|
"message.creating.autoscale.vmprofile": "Creating AutoScale Instance profile",
|
||||||
"message.creating.autoscale.scaledown.conditions": "Creating ScaleDown conditions",
|
"message.creating.autoscale.scaledown.conditions": "Creating ScaleDown conditions",
|
||||||
|
|
@ -3293,7 +3294,7 @@
|
||||||
"message.delete.tungsten.tag": "Are you sure you want to remove this Tag from this Policy?",
|
"message.delete.tungsten.tag": "Are you sure you want to remove this Tag from this Policy?",
|
||||||
"message.delete.user": "Please confirm that you would like to delete this User.",
|
"message.delete.user": "Please confirm that you would like to delete this User.",
|
||||||
"message.delete.vpn.connection": "Please confirm that you want to delete VPN connection.",
|
"message.delete.vpn.connection": "Please confirm that you want to delete VPN connection.",
|
||||||
"message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN customer gateway.",
|
"message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN Customer Gateway.",
|
||||||
"message.delete.vpn.gateway": "Please confirm that you want to delete this VPN Gateway.",
|
"message.delete.vpn.gateway": "Please confirm that you want to delete this VPN Gateway.",
|
||||||
"message.delete.vpn.gateway.failed": "Failed to delete VPN Gateway.",
|
"message.delete.vpn.gateway.failed": "Failed to delete VPN Gateway.",
|
||||||
"message.delete.webhook": "Please confirm that you want to delete this Webhook.",
|
"message.delete.webhook": "Please confirm that you want to delete this Webhook.",
|
||||||
|
|
@ -3834,7 +3835,7 @@
|
||||||
"message.success.add.tungsten.routing.policy": "Successfully added Tungsten-Fabric routing policy",
|
"message.success.add.tungsten.routing.policy": "Successfully added Tungsten-Fabric routing policy",
|
||||||
"message.success.add.vpc": "Successfully added a Virtual Private Cloud",
|
"message.success.add.vpc": "Successfully added a Virtual Private Cloud",
|
||||||
"message.success.add.vpc.network": "Successfully added a VPC network",
|
"message.success.add.vpc.network": "Successfully added a VPC network",
|
||||||
"message.success.add.vpn.customer.gateway": "Successfully added VPN customer gateway",
|
"message.success.add.vpn.customer.gateway": "Successfully added VPN Customer Gateway",
|
||||||
"message.success.add.vpn.gateway": "Successfully added VPN gateway",
|
"message.success.add.vpn.gateway": "Successfully added VPN gateway",
|
||||||
"message.success.add.webhook.filter": "Successfully added Webhook Filter",
|
"message.success.add.webhook.filter": "Successfully added Webhook Filter",
|
||||||
"message.success.assign.sslcert": "Successfully assigned SSL certificate",
|
"message.success.assign.sslcert": "Successfully assigned SSL certificate",
|
||||||
|
|
@ -3960,6 +3961,7 @@
|
||||||
"message.success.update.network": "Successfully updated Network",
|
"message.success.update.network": "Successfully updated Network",
|
||||||
"message.success.update.template": "Successfully updated Template",
|
"message.success.update.template": "Successfully updated Template",
|
||||||
"message.success.update.user": "Successfully updated User",
|
"message.success.update.user": "Successfully updated User",
|
||||||
|
"message.success.update.vpn.customer.gateway": "Successfully updated VPN Customer Gateway",
|
||||||
"message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes Cluster",
|
"message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes Cluster",
|
||||||
"message.success.upload": "Successfully uploaded",
|
"message.success.upload": "Successfully uploaded",
|
||||||
"message.success.upload.description": "This ISO file has been uploaded. Please check its status in the Templates menu.",
|
"message.success.upload.description": "This ISO file has been uploaded. Please check its status in the Templates menu.",
|
||||||
|
|
@ -3987,6 +3989,9 @@
|
||||||
"message.update.condition.failed": "Failed to update condition",
|
"message.update.condition.failed": "Failed to update condition",
|
||||||
"message.update.condition.processing": "Updating condition...",
|
"message.update.condition.processing": "Updating condition...",
|
||||||
"message.update.failed": "Update failed",
|
"message.update.failed": "Update failed",
|
||||||
|
"message.update.vpn.customer.gateway": "Update VPN Customer Gateway",
|
||||||
|
"message.update.vpn.customer.gateway.failed": "Updating the VPN Customer Gateway failed",
|
||||||
|
"message.update.vpn.customer.gateway.processing": "Updating VPN Customer Gateway...",
|
||||||
"message.test.webhook.delivery": "Test delivery to the Webhook with an optional payload",
|
"message.test.webhook.delivery": "Test delivery to the Webhook with an optional payload",
|
||||||
"message.two.factor.authorization.failed": "Unable to verify 2FA with provided code, please retry.",
|
"message.two.factor.authorization.failed": "Unable to verify 2FA with provided code, please retry.",
|
||||||
"message.two.fa.auth": "Open the two-factor authentication app on your mobile device to view your authentication code.",
|
"message.two.fa.auth": "Open the two-factor authentication app on your mobile device to view your authentication code.",
|
||||||
|
|
@ -4074,6 +4079,11 @@
|
||||||
"message.volumes.managed": "Volumes controlled by CloudStack.",
|
"message.volumes.managed": "Volumes controlled by CloudStack.",
|
||||||
"message.volumes.unmanaged": "Volumes not controlled by CloudStack.",
|
"message.volumes.unmanaged": "Volumes not controlled by CloudStack.",
|
||||||
"message.vpc.restart.required": "Restart is required for VPC(s). Click here to view VPC(s) which require restart.",
|
"message.vpc.restart.required": "Restart is required for VPC(s). Click here to view VPC(s) which require restart.",
|
||||||
|
"message.vpn.customer.gateway.contains.excluded.obsolete.parameters": "This VPN Customer Gateway contains cryptographic parameters that are marked as excluded or obsolete by the Administrator. Consider changing them using the Update VPN Customer Gateway form.",
|
||||||
|
"message.vpn.customer.gateway.excluded.parameter": " is marked as excluded. Please choose another value.",
|
||||||
|
"message.vpn.customer.gateway.obsolete.parameter": " is marked as obsolete/insecure. Please choose another value.",
|
||||||
|
"message.vpn.customer.gateway.obsolete.parameter.tooltip": "This parameter value is marked as obsolete/insecure.",
|
||||||
|
"message.vr.alert.upon.network.offering.creation.l2": "As virtual routers are not created for L2 Networks, the compute offering will not be used.",
|
||||||
"message.vr.alert.upon.network.offering.creation.others": "As none of the obligatory services for creating a virtual router (VPN, DHCP, DNS, Firewall, LB, UserData, SourceNat, StaticNat, PortForwarding) are enabled, the virtual router will not be created and the compute offering will not be used.",
|
"message.vr.alert.upon.network.offering.creation.others": "As none of the obligatory services for creating a virtual router (VPN, DHCP, DNS, Firewall, LB, UserData, SourceNat, StaticNat, PortForwarding) are enabled, the virtual router will not be created and the compute offering will not be used.",
|
||||||
"message.warn.change.primary.storage.scope": "This feature is tested and supported for the following configurations:<br>KVM - NFS/Ceph - DefaultPrimary<br>VMware - NFS - DefaultPrimary<br>*There might be extra steps involved to make it work for other configurations.",
|
"message.warn.change.primary.storage.scope": "This feature is tested and supported for the following configurations:<br>KVM - NFS/Ceph - DefaultPrimary<br>VMware - NFS - DefaultPrimary<br>*There might be extra steps involved to make it work for other configurations.",
|
||||||
"message.warn.filetype": "jpg, jpeg, png, bmp and svg are the only supported image formats.",
|
"message.warn.filetype": "jpg, jpeg, png, bmp and svg are the only supported image formats.",
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,14 @@
|
||||||
<warning-outlined style="color: #f5222d" />
|
<warning-outlined style="color: #f5222d" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
|
<span v-else-if="$route.path.startsWith('/vpncustomergateway')">
|
||||||
|
|
||||||
|
<a-tooltip
|
||||||
|
v-if="record.excludedparameters || record.obsoleteparameters"
|
||||||
|
:title="$t('message.vpn.customer.gateway.contains.excluded.obsolete.parameters')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="record.leaseduration !== undefined"
|
v-if="record.leaseduration !== undefined"
|
||||||
|
|
|
||||||
|
|
@ -1263,15 +1263,11 @@ export default {
|
||||||
{
|
{
|
||||||
api: 'updateVpnCustomerGateway',
|
api: 'updateVpnCustomerGateway',
|
||||||
icon: 'edit-outlined',
|
icon: 'edit-outlined',
|
||||||
label: 'label.edit',
|
label: 'label.update.vpn.customer.gateway',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#updating-and-removing-a-vpn-customer-gateway',
|
docHelp: 'adminguide/networking_and_traffic.html#updating-and-removing-a-vpn-customer-gateway',
|
||||||
dataView: true,
|
dataView: true,
|
||||||
args: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap'],
|
popup: true,
|
||||||
mapping: {
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/UpdateVpnCustomerGateway.vue')))
|
||||||
ikeversion: {
|
|
||||||
options: ['ike', 'ikev1', 'ikev2']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
api: 'deleteVpnCustomerGateway',
|
api: 'deleteVpnCustomerGateway',
|
||||||
|
|
|
||||||
|
|
@ -15,352 +15,58 @@
|
||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<vpn-customer-gateway
|
||||||
<a-form
|
ref="vpnCustomerGatewayForm"
|
||||||
class="form-layout"
|
:apiParams="apiParams"
|
||||||
:ref="formRef"
|
@submit="handleSubmit"
|
||||||
:model="form"
|
@cancel="closeModal"
|
||||||
:rules="rules"
|
/>
|
||||||
layout="vertical"
|
|
||||||
@finish="handleSubmit"
|
|
||||||
v-ctrl-enter="handleSubmit"
|
|
||||||
>
|
|
||||||
<a-form-item ref="name" name="name">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.name')" :tooltip="apiParams.name.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.name"
|
|
||||||
:placeholder="apiParams.name.description"
|
|
||||||
v-focus="true" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="gateway" name="gateway">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.gateway')" :tooltip="apiParams.gateway.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.gateway"
|
|
||||||
:placeholder="apiParams.gateway.description" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="cidrlist" name="cidrlist">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.cidrlist')" :tooltip="apiParams.cidrlist.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.cidrlist"
|
|
||||||
:placeholder="apiParams.cidrlist.description" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ipsecpsk" name="ipsecpsk">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.ipsecpsk')" :tooltip="apiParams.ipsecpsk.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.ipsecpsk"
|
|
||||||
:placeholder="apiParams.ipsecpsk.description" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ikeEncryption" name="ikeEncryption" :label="$t('label.ikeencryption')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.ikeEncryption"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="value"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option :value="algo" v-for="(algo, idx) in encryptionAlgo" :key="idx">
|
|
||||||
{{ algo }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ikeHash" name="ikeHash" :label="$t('label.ikehash')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.ikeHash"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="value"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option :value="h" v-for="(h, idx) in hash" :key="idx">
|
|
||||||
{{ h }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ikeversion" name="ikeversion">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.ikeversion')" :tooltip="apiParams.ikeversion.description"/>
|
|
||||||
</template>
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.ikeversion"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="value"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option :value="vers" v-for="(vers, idx) in ikeVersions" :key="idx">
|
|
||||||
{{ vers }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ikeDh" name="ikeDh" :label="$t('label.ikedh')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.ikeDh"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="label"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option
|
|
||||||
:value="DHGroups[group]"
|
|
||||||
v-for="(group, idx) in Object.keys(DHGroups)"
|
|
||||||
:key="idx"
|
|
||||||
:label="group + '(' + DHGroups[group] + ')'">
|
|
||||||
<div v-if="group !== ''">
|
|
||||||
{{ group+"("+DHGroups[group]+")" }}
|
|
||||||
</div>
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="espEncryption" name="espEncryption" :label="$t('label.espencryption')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.espEncryption"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="value"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option :value="algo" v-for="(algo, idx) in encryptionAlgo" :key="idx">
|
|
||||||
{{ algo }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="espHash" name="espHash" :label="$t('label.esphash')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.espHash"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="value"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option :value="h" v-for="(h, idx) in hash" :key="idx">
|
|
||||||
{{ h }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="perfectForwardSecrecy" name="perfectForwardSecrecy" :label="$t('label.perfectforwardsecrecy')">
|
|
||||||
<a-select
|
|
||||||
v-model:value="form.perfectForwardSecrecy"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="label"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}" >
|
|
||||||
<a-select-option
|
|
||||||
:value="DHGroups[group]"
|
|
||||||
v-for="(group, idx) in Object.keys(DHGroups)"
|
|
||||||
:key="idx"
|
|
||||||
:label="group === '' ? DHGroups[group] : group + '(' + DHGroups[group] + ')'">
|
|
||||||
<div v-if="group === ''">
|
|
||||||
{{ DHGroups[group] }}
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
{{ group+"("+DHGroups[group]+")" }}
|
|
||||||
</div>
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="ikelifetime" name="ikelifetime">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.ikelifetime')" :tooltip="apiParams.ikelifetime.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.ikelifetime"
|
|
||||||
:placeholder="apiParams.ikelifetime.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="esplifetime" name="esplifetime">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.esplifetime')" :tooltip="apiParams.esplifetime.description"/>
|
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-model:value="form.esplifetime"
|
|
||||||
:placeholder="apiParams.esplifetime.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="dpd" name="dpd">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.dpd')" :tooltip="apiParams.dpd.description"/>
|
|
||||||
</template>
|
|
||||||
<a-switch v-model:checked="form.dpd"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="splitconnections" name="splitconnections" v-if="form.ikeversion !== 'ikev1'">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.splitconnections')" :tooltip="apiParams.splitconnections.description"/>
|
|
||||||
</template>
|
|
||||||
<a-switch v-model:checked="form.splitconnections"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item ref="forceencap" name="forceencap">
|
|
||||||
<template #label>
|
|
||||||
<tooltip-label :title="$t('label.forceencap')" :tooltip="apiParams.forceencap.description"/>
|
|
||||||
</template>
|
|
||||||
<a-switch v-model:checked="form.forceencap"/>
|
|
||||||
</a-form-item>
|
|
||||||
<div class="action-button">
|
|
||||||
<a-button @click="closeModal">
|
|
||||||
{{ $t('label.cancel') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="primary" @click="handleSubmit" html-type="submit">
|
|
||||||
{{ $t('label.ok') }}
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, toRaw } from 'vue'
|
|
||||||
import { postAPI } from '@/api'
|
import { postAPI } from '@/api'
|
||||||
import { mixinForm } from '@/utils/mixin'
|
import VpnCustomerGateway from './VpnCustomerGateway.vue'
|
||||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreateVpnCustomerGateway',
|
name: 'CreateVpnCustomerGateway',
|
||||||
mixins: [mixinForm],
|
|
||||||
components: {
|
components: {
|
||||||
TooltipLabel
|
VpnCustomerGateway
|
||||||
},
|
|
||||||
props: {
|
|
||||||
resource: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
encryptionAlgo: [
|
|
||||||
'aes128',
|
|
||||||
'aes192',
|
|
||||||
'aes256',
|
|
||||||
'3des'
|
|
||||||
],
|
|
||||||
hash: [
|
|
||||||
'sha1',
|
|
||||||
'sha256',
|
|
||||||
'sha384',
|
|
||||||
'sha512',
|
|
||||||
'md5'
|
|
||||||
],
|
|
||||||
ikeVersions: [
|
|
||||||
'ike',
|
|
||||||
'ikev1',
|
|
||||||
'ikev2'
|
|
||||||
],
|
|
||||||
DHGroups: {
|
|
||||||
'': 'None',
|
|
||||||
'Group 2': 'modp1024',
|
|
||||||
'Group 5': 'modp1536',
|
|
||||||
'Group 14': 'modp2048',
|
|
||||||
'Group 15': 'modp3072',
|
|
||||||
'Group 16': 'modp4096',
|
|
||||||
'Group 17': 'modp6144',
|
|
||||||
'Group 18': 'modp8192'
|
|
||||||
},
|
|
||||||
ikeDhGroupInitialValue: 'Group 5(modp1536)',
|
|
||||||
isSubmitted: false,
|
|
||||||
ikeversion: 'ike'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
beforeCreate () {
|
beforeCreate () {
|
||||||
this.apiParams = this.$getApiParams('createVpnCustomerGateway')
|
this.apiParams = this.$getApiParams('createVpnCustomerGateway')
|
||||||
},
|
},
|
||||||
created () {
|
|
||||||
this.initForm()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
initForm () {
|
|
||||||
this.formRef = ref()
|
|
||||||
this.form = reactive({
|
|
||||||
ikeEncryption: 'aes128',
|
|
||||||
ikeHash: 'sha1',
|
|
||||||
ikeversion: 'ike',
|
|
||||||
ikeDh: 'Group 5(modp1536)',
|
|
||||||
espEncryption: 'aes128',
|
|
||||||
espHash: 'sha1',
|
|
||||||
perfectForwardSecrecy: 'None',
|
|
||||||
ikelifetime: '86400',
|
|
||||||
esplifetime: '3600',
|
|
||||||
dpd: false,
|
|
||||||
splitconnections: false,
|
|
||||||
forceencap: false
|
|
||||||
})
|
|
||||||
this.rules = reactive({
|
|
||||||
name: [{ required: true, message: this.$t('label.required') }],
|
|
||||||
gateway: [{ required: true, message: this.$t('label.required') }],
|
|
||||||
cidrlist: [{ required: true, message: this.$t('label.required') }],
|
|
||||||
ipsecpsk: [{ required: true, message: this.$t('label.required') }]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
closeModal () {
|
closeModal () {
|
||||||
this.$emit('close-action')
|
this.$emit('close-action')
|
||||||
},
|
},
|
||||||
handleSubmit (e) {
|
handleSubmit ({ payload }) {
|
||||||
e.preventDefault()
|
postAPI('createVpnCustomerGateway', payload).then(response => {
|
||||||
if (this.isSubmitted) return
|
this.$pollJob({
|
||||||
this.formRef.value.validate().then(() => {
|
jobId: response.createvpncustomergatewayresponse.jobid,
|
||||||
const formRaw = toRaw(this.form)
|
title: this.$t('message.add.vpn.customer.gateway'),
|
||||||
const values = this.handleRemoveFields(formRaw)
|
description: payload.name,
|
||||||
let ikepolicy = values.ikeEncryption + '-' + values.ikeHash + ';'
|
successMessage: this.$t('message.success.add.vpn.customer.gateway'),
|
||||||
ikepolicy += (values.ikeDh !== this.ikeDhGroupInitialValue) ? values.ikeDh : (values.ikeDh.split('(')[1]).split(')')[0]
|
successMethod: () => {
|
||||||
let esppolicy = values.espEncryption + '-' + values.espHash
|
this.closeModal()
|
||||||
if (values.perfectForwardSecrecy !== 'None') {
|
},
|
||||||
esppolicy += ';' + (values.perfectForwardSecrecy)
|
errorMessage: this.$t('message.create.vpn.customer.gateway.failed'),
|
||||||
}
|
errorMethod: () => {
|
||||||
postAPI('createVpnCustomerGateway', {
|
this.closeModal()
|
||||||
name: values.name,
|
},
|
||||||
gateway: values.gateway,
|
loadingMessage: this.$t('message.add.vpn.customer.gateway.processing'),
|
||||||
cidrlist: values.cidrlist,
|
catchMessage: this.$t('error.fetching.async.job.result'),
|
||||||
ipsecpsk: values.ipsecpsk,
|
catchMethod: () => {
|
||||||
ikelifetime: values.ikelifetime,
|
this.closeModal()
|
||||||
esplifetime: values.esplifetime,
|
}
|
||||||
dpd: values.dpd,
|
|
||||||
forceencap: values.forceencap,
|
|
||||||
ikepolicy: ikepolicy,
|
|
||||||
esppolicy: esppolicy,
|
|
||||||
splitconnections: values.splitconnections,
|
|
||||||
ikeversion: values.ikeversion
|
|
||||||
}).then(response => {
|
|
||||||
this.$pollJob({
|
|
||||||
jobId: response.createvpncustomergatewayresponse.jobid,
|
|
||||||
title: this.$t('message.add.vpn.customer.gateway'),
|
|
||||||
description: values.name,
|
|
||||||
successMessage: this.$t('message.success.add.vpn.customer.gateway'),
|
|
||||||
successMethod: () => {
|
|
||||||
this.closeModal()
|
|
||||||
this.isSubmitted = false
|
|
||||||
},
|
|
||||||
errorMessage: `${this.$t('message.create.vpn.customer.gateway.failed')} ` + response,
|
|
||||||
errorMethod: () => {
|
|
||||||
this.closeModal()
|
|
||||||
this.isSubmitted = false
|
|
||||||
},
|
|
||||||
loadingMessage: this.$t('message.add.vpn.customer.gateway.processing'),
|
|
||||||
catchMessage: this.$t('error.fetching.async.job.result'),
|
|
||||||
catchMethod: () => {
|
|
||||||
this.closeModal()
|
|
||||||
this.isSubmitted = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.closeModal()
|
|
||||||
this.formRef.value.resetFields()
|
|
||||||
}).catch(error => {
|
|
||||||
console.error(error)
|
|
||||||
this.$message.error(this.$t('message.add.vpn.customer.gateway.failed'))
|
|
||||||
this.isSubmitted = false
|
|
||||||
})
|
})
|
||||||
|
this.closeModal()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.formRef.value.scrollToField(error.errorFields[0].name)
|
this.$refs.vpnCustomerGatewayForm.resetSubmission()
|
||||||
|
const errResponse = error.response?.data?.createvpncustomergatewayresponse
|
||||||
|
const errText = errResponse?.errortext || this.$t('message.create.vpn.customer.gateway.failed')
|
||||||
|
this.$message.error(errText)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
|
||||||
.form-layout {
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
// 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.
|
||||||
|
<template>
|
||||||
|
<vpn-customer-gateway
|
||||||
|
ref="vpnCustomerGatewayForm"
|
||||||
|
:initial-values="initialValues"
|
||||||
|
:apiParams="apiParams"
|
||||||
|
@submit="handleSubmit"
|
||||||
|
@cancel="closeModal"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { postAPI } from '@/api'
|
||||||
|
import VpnCustomerGateway from './VpnCustomerGateway.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UpdateVpnCustomerGateway',
|
||||||
|
components: {
|
||||||
|
VpnCustomerGateway
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
resource: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeCreate () {
|
||||||
|
this.apiParams = this.$getApiParams('updateVpnCustomerGateway')
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
initialValues () {
|
||||||
|
const ikepolicy = this.parseIkePolicy(this.resource.ikepolicy)
|
||||||
|
const esppolicy = this.parseEspPolicy(this.resource.esppolicy)
|
||||||
|
return {
|
||||||
|
id: this.resource.id,
|
||||||
|
name: this.resource.name,
|
||||||
|
domainid: this.resource.domainid,
|
||||||
|
gateway: this.resource.gateway,
|
||||||
|
cidrlist: this.resource.cidrlist,
|
||||||
|
ipsecpsk: this.resource.ipsecpsk,
|
||||||
|
ikeEncryption: ikepolicy.encryption,
|
||||||
|
ikeHash: ikepolicy.hash,
|
||||||
|
ikeDh: ikepolicy.dh,
|
||||||
|
espEncryption: esppolicy.encryption,
|
||||||
|
espHash: esppolicy.hash,
|
||||||
|
espDh: esppolicy.dh,
|
||||||
|
ikelifetime: this.resource.ikelifetime,
|
||||||
|
esplifetime: this.resource.esplifetime,
|
||||||
|
dpd: this.resource.dpd,
|
||||||
|
splitconnections: this.resource.splitconnections,
|
||||||
|
forceencap: this.resource.forceencap,
|
||||||
|
ikeversion: this.resource.ikeversion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
closeModal () {
|
||||||
|
this.$emit('close-action')
|
||||||
|
},
|
||||||
|
parseIkePolicy (ikePolicy) {
|
||||||
|
console.log('ikePolicy', ikePolicy)
|
||||||
|
if (!ikePolicy) return { encryption: null, hash: null, dh: null }
|
||||||
|
const parts = ikePolicy.split(';')
|
||||||
|
const cipherHash = parts[0] || ''
|
||||||
|
const dhGroup = parts[1] || null
|
||||||
|
const cipherHashParts = cipherHash.split('-')
|
||||||
|
const encryption = cipherHashParts[0] || null
|
||||||
|
const hash = cipherHashParts[1] || null
|
||||||
|
return { encryption, hash, dh: dhGroup }
|
||||||
|
},
|
||||||
|
parseEspPolicy (espPolicy) {
|
||||||
|
if (!espPolicy) return { encryption: null, hash: null, dh: null }
|
||||||
|
const parts = espPolicy.split(';')
|
||||||
|
const cipherHash = parts[0] || ''
|
||||||
|
const dhGroup = parts[1] || null
|
||||||
|
const cipherHashParts = cipherHash.split('-')
|
||||||
|
const encryption = cipherHashParts[0] || null
|
||||||
|
const hash = cipherHashParts[1] || null
|
||||||
|
return { encryption, hash, dh: dhGroup }
|
||||||
|
},
|
||||||
|
handleSubmit ({ payload }) {
|
||||||
|
postAPI('updateVpnCustomerGateway', {
|
||||||
|
id: this.resource.id,
|
||||||
|
...payload
|
||||||
|
}).then(response => {
|
||||||
|
this.$pollJob({
|
||||||
|
jobId: response.updatevpncustomergatewayresponse.jobid,
|
||||||
|
title: this.$t('message.update.vpn.customer.gateway'),
|
||||||
|
description: payload.name,
|
||||||
|
successMessage: this.$t('message.success.update.vpn.customer.gateway'),
|
||||||
|
successMethod: () => {
|
||||||
|
this.closeModal()
|
||||||
|
},
|
||||||
|
errorMessage: this.$t('message.update.vpn.customer.gateway.failed'),
|
||||||
|
errorMethod: () => {
|
||||||
|
this.closeModal()
|
||||||
|
},
|
||||||
|
loadingMessage: this.$t('message.update.vpn.customer.gateway.processing'),
|
||||||
|
catchMessage: this.$t('error.fetching.async.job.result'),
|
||||||
|
catchMethod: () => {
|
||||||
|
this.closeModal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.closeModal()
|
||||||
|
}).catch(error => {
|
||||||
|
this.$refs.vpnCustomerGatewayForm.resetSubmission()
|
||||||
|
const errResponse = error.response?.data?.createvpncustomergatewayresponse
|
||||||
|
const errText = errResponse?.errortext || this.$t('message.update.vpn.customer.gateway.failed')
|
||||||
|
this.$message.error(errText)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,581 @@
|
||||||
|
// 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.
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-form
|
||||||
|
class="form-layout"
|
||||||
|
:ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
layout="vertical"
|
||||||
|
@finish="handleSubmit"
|
||||||
|
v-ctrl-enter="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form-item ref="name" name="name">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.name')" :tooltip="apiParams.name.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.name"
|
||||||
|
:placeholder="apiParams.name.description"
|
||||||
|
v-focus="true" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="gateway" name="gateway">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.gateway')" :tooltip="apiParams.gateway.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.gateway"
|
||||||
|
:placeholder="apiParams.gateway.description" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="cidrlist" name="cidrlist">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.cidrlist')" :tooltip="apiParams.cidrlist.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.cidrlist"
|
||||||
|
:placeholder="apiParams.cidrlist.description" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ipsecpsk" name="ipsecpsk">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.ipsecpsk')" :tooltip="apiParams.ipsecpsk.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.ipsecpsk"
|
||||||
|
:placeholder="apiParams.ipsecpsk.description" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ikeEncryption" name="ikeEncryption" :label="$t('label.ikeencryption')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.ikeEncryption"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="value"
|
||||||
|
:loading="loadingParameters"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option :value="algo" v-for="(algo, idx) in allowedEncryptionAlgos" :key="idx">
|
||||||
|
{{ algo }}
|
||||||
|
<a-tooltip v-if="isObsolete('encryption', algo)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('encryption', form.ikeEncryption)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.ikeEncryption }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('encryption', form.ikeEncryption)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.ikeEncryption }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ikeHash" name="ikeHash" :label="$t('label.ikehash')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.ikeHash"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="value"
|
||||||
|
:loading="loadingParameters"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option :value="h" v-for="(h, idx) in allowedHashingAlgos" :key="idx">
|
||||||
|
{{ h }}
|
||||||
|
<a-tooltip v-if="isObsolete('hash', h)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('hash', form.ikeHash)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.ikeHash }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('hash', form.ikeHash)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.ikeHash }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ikeversion" name="ikeversion">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.ikeversion')" :tooltip="apiParams.ikeversion.description"/>
|
||||||
|
</template>
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.ikeversion"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="value"
|
||||||
|
:loading="loadingParameters"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option :value="vers" v-for="(vers, idx) in allowedIkeVersions" :key="idx">
|
||||||
|
{{ vers }}
|
||||||
|
<a-tooltip v-if="isObsolete('ikeversion', vers)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('ikeversion', form.ikeversion)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.ikeversion }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('ikeversion', form.ikeversion)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.ikeversion }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ikeDh" name="ikeDh" :label="$t('label.ikedh')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.ikeDh"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="label"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option
|
||||||
|
:value="group + '(' + DHGroups[group] + ')'"
|
||||||
|
v-for="(group, idx) in allowedDhGroupKeys"
|
||||||
|
:key="idx"
|
||||||
|
:label="group + '(' + DHGroups[group] + ')'">
|
||||||
|
<div v-if="group !== ''">
|
||||||
|
{{ group+"("+DHGroups[group]+")" }}
|
||||||
|
<a-tooltip v-if="isObsolete('dh', group)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('dh', form.ikeDh)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.ikeDh }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('dh', form.ikeDh)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.ikeDh }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="espEncryption" name="espEncryption" :label="$t('label.espencryption')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.espEncryption"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="value"
|
||||||
|
:loading="loadingParameters"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option :value="algo" v-for="(algo, idx) in allowedEncryptionAlgos" :key="idx">
|
||||||
|
{{ algo }}
|
||||||
|
<a-tooltip v-if="isObsolete('encryption', algo)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('encryption', form.espEncryption)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.espEncryption }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('encryption', form.espEncryption)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.espEncryption }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="espHash" name="espHash" :label="$t('label.esphash')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.espHash"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="value"
|
||||||
|
:loading="loadingParameters"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option :value="h" v-for="(h, idx) in allowedHashingAlgos" :key="idx">
|
||||||
|
{{ h }}
|
||||||
|
<a-tooltip v-if="isObsolete('hash', h)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('hash', form.espHash)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.espHash }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('hash', form.espHash)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.espHash }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="perfectForwardSecrecy" name="perfectForwardSecrecy" :label="$t('label.perfectforwardsecrecy')">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.perfectForwardSecrecy"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="label"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}" >
|
||||||
|
<a-select-option
|
||||||
|
:value="group + '(' + DHGroups[group] + ')'"
|
||||||
|
v-for="(group, idx) in allowedDhGroupKeys"
|
||||||
|
:key="idx"
|
||||||
|
:label="group === '' ? DHGroups[group] : group + '(' + DHGroups[group] + ')'">
|
||||||
|
<div v-if="group === ''">
|
||||||
|
{{ DHGroups[group] }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ group+"("+DHGroups[group]+")" }}
|
||||||
|
<a-tooltip v-if="isObsolete('dh', group)" :title="$t('message.vpn.customer.gateway.obsolete.parameter.tooltip')">
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<template #extra v-if="isExcluded('dh', form.perfectForwardSecrecy)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@error-color'] }" />
|
||||||
|
{{ form.perfectForwardSecrecy }} {{ $t('message.vpn.customer.gateway.excluded.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #extra v-else-if="isObsolete('dh', form.perfectForwardSecrecy)">
|
||||||
|
<span>
|
||||||
|
<warning-outlined :style="{ color: $config.theme['@warning-color'] }" />
|
||||||
|
{{ form.perfectForwardSecrecy }} {{ $t('message.vpn.customer.gateway.obsolete.parameter') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="ikelifetime" name="ikelifetime">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.ikelifetime')" :tooltip="apiParams.ikelifetime.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.ikelifetime"
|
||||||
|
:placeholder="apiParams.ikelifetime.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="esplifetime" name="esplifetime">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.esplifetime')" :tooltip="apiParams.esplifetime.description"/>
|
||||||
|
</template>
|
||||||
|
<a-input
|
||||||
|
v-model:value="form.esplifetime"
|
||||||
|
:placeholder="apiParams.esplifetime.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="dpd" name="dpd">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.dpd')" :tooltip="apiParams.dpd.description"/>
|
||||||
|
</template>
|
||||||
|
<a-switch v-model:checked="form.dpd"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="splitconnections" name="splitconnections" v-if="form.ikeversion !== 'ikev1'">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.splitconnections')" :tooltip="apiParams.splitconnections.description"/>
|
||||||
|
</template>
|
||||||
|
<a-switch v-model:checked="form.splitconnections"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item ref="forceencap" name="forceencap">
|
||||||
|
<template #label>
|
||||||
|
<tooltip-label :title="$t('label.forceencap')" :tooltip="apiParams.forceencap.description"/>
|
||||||
|
</template>
|
||||||
|
<a-switch v-model:checked="form.forceencap"/>
|
||||||
|
</a-form-item>
|
||||||
|
<div class="action-button">
|
||||||
|
<a-button @click="$emit('cancel')">
|
||||||
|
{{ $t('label.cancel') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" @click="handleSubmit" html-type="submit">
|
||||||
|
{{ $t('label.ok') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { getAPI } from '@/api'
|
||||||
|
import { ref, reactive, toRaw } from 'vue'
|
||||||
|
import { mixinForm } from '@/utils/mixin'
|
||||||
|
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'VpnCustomerGateway',
|
||||||
|
mixins: [mixinForm],
|
||||||
|
components: {
|
||||||
|
TooltipLabel
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
initialValues: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
apiParams: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
encryptionAlgo: [
|
||||||
|
'aes128',
|
||||||
|
'aes192',
|
||||||
|
'aes256',
|
||||||
|
'3des'
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
'sha1',
|
||||||
|
'sha256',
|
||||||
|
'sha384',
|
||||||
|
'sha512',
|
||||||
|
'md5'
|
||||||
|
],
|
||||||
|
ikeVersions: [
|
||||||
|
'ike',
|
||||||
|
'ikev1',
|
||||||
|
'ikev2'
|
||||||
|
],
|
||||||
|
DHGroups: {
|
||||||
|
'Group 2': 'modp1024',
|
||||||
|
'Group 5': 'modp1536',
|
||||||
|
'Group 14': 'modp2048',
|
||||||
|
'Group 15': 'modp3072',
|
||||||
|
'Group 16': 'modp4096',
|
||||||
|
'Group 17': 'modp6144',
|
||||||
|
'Group 18': 'modp8192'
|
||||||
|
},
|
||||||
|
ikeDhGroupInitialKey: 'Group 5',
|
||||||
|
isSubmitted: false,
|
||||||
|
ikeversion: 'ike',
|
||||||
|
allowedEncryptionAlgos: [],
|
||||||
|
allowedHashingAlgos: [],
|
||||||
|
allowedIkeVersions: [],
|
||||||
|
allowedDhGroupKeys: [],
|
||||||
|
allowedDhGroupValues: [],
|
||||||
|
obsoleteEncryptionAlgos: [],
|
||||||
|
obsoleteHashingAlgos: [],
|
||||||
|
obsoleteIkeVersions: [],
|
||||||
|
obsoleteDhGroups: [],
|
||||||
|
loadingParameters: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.initForm()
|
||||||
|
this.fetchVpnCustomerGatewayParameters()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initForm () {
|
||||||
|
this.formRef = ref()
|
||||||
|
const defaults = {
|
||||||
|
name: '',
|
||||||
|
gateway: '',
|
||||||
|
cidrlist: '',
|
||||||
|
ipsecpsk: '',
|
||||||
|
ikeEncryption: '',
|
||||||
|
ikeHash: '',
|
||||||
|
ikeversion: '',
|
||||||
|
ikeDh: '',
|
||||||
|
espEncryption: '',
|
||||||
|
espHash: '',
|
||||||
|
perfectForwardSecrecy: 'None',
|
||||||
|
ikelifetime: '86400',
|
||||||
|
esplifetime: '3600',
|
||||||
|
dpd: false,
|
||||||
|
splitconnections: false,
|
||||||
|
forceencap: false
|
||||||
|
}
|
||||||
|
this.form = reactive({
|
||||||
|
...defaults,
|
||||||
|
...this.initialValues
|
||||||
|
})
|
||||||
|
if (this.initialValues.ikeDh) {
|
||||||
|
const ikeDhKey = Object.keys(this.DHGroups).find(key => this.DHGroups[key] === this.initialValues.ikeDh)
|
||||||
|
this.form.ikeDh = ikeDhKey + '(' + this.initialValues.ikeDh + ')'
|
||||||
|
}
|
||||||
|
if (this.initialValues.espDh) {
|
||||||
|
const espDhKey = Object.keys(this.DHGroups).find(key => this.DHGroups[key] === this.initialValues.espDh)
|
||||||
|
this.form.perfectForwardSecrecy = espDhKey + '(' + this.initialValues.espDh + ')'
|
||||||
|
}
|
||||||
|
this.rules = reactive({
|
||||||
|
name: [{ required: true, message: this.$t('label.required') }],
|
||||||
|
gateway: [{ required: true, message: this.$t('label.required') }],
|
||||||
|
cidrlist: [{ required: true, message: this.$t('label.required') }],
|
||||||
|
ipsecpsk: [{ required: true, message: this.$t('label.required') }]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeModal () {
|
||||||
|
this.$emit('close-action')
|
||||||
|
},
|
||||||
|
resetSubmission () {
|
||||||
|
this.isSubmitted = false
|
||||||
|
},
|
||||||
|
buildPolicies (values) {
|
||||||
|
let ikepolicy = values.ikeEncryption + '-' + values.ikeHash + ';'
|
||||||
|
ikepolicy += (values.ikeDh.split('(')[1]).split(')')[0]
|
||||||
|
|
||||||
|
let esppolicy = values.espEncryption + '-' + values.espHash
|
||||||
|
if (values.perfectForwardSecrecy !== 'None') {
|
||||||
|
esppolicy += ';' + (values.perfectForwardSecrecy.split('(')[1]).split(')')[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ikepolicy, esppolicy }
|
||||||
|
},
|
||||||
|
isObsolete (type, value) {
|
||||||
|
switch (type) {
|
||||||
|
case 'encryption':
|
||||||
|
return this.obsoleteEncryptionAlgos.some(v => v.toLowerCase() === value)
|
||||||
|
case 'hash':
|
||||||
|
return this.obsoleteHashingAlgos.some(v => v.toLowerCase() === value)
|
||||||
|
case 'ikeversion':
|
||||||
|
return this.obsoleteIkeVersions.some(v => v.toLowerCase() === value)
|
||||||
|
case 'dh': {
|
||||||
|
const key = value.split('(')[0]
|
||||||
|
return this.obsoleteDhGroups.some(v => v.toLowerCase() === this.DHGroups[key])
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isExcluded (type, value) {
|
||||||
|
switch (type) {
|
||||||
|
case 'encryption':
|
||||||
|
return !this.allowedEncryptionAlgos.some(v => v.toLowerCase() === value)
|
||||||
|
case 'hash':
|
||||||
|
return !this.allowedHashingAlgos.some(v => v.toLowerCase() === value)
|
||||||
|
case 'ikeversion':
|
||||||
|
return !this.allowedIkeVersions.some(v => v.toLowerCase() === value)
|
||||||
|
case 'dh': {
|
||||||
|
if (value === '' || value === 'None') return false
|
||||||
|
const key = value.split('(')[0]
|
||||||
|
return !this.allowedDhGroupValues.some(v => v.toLowerCase() === this.DHGroups[key])
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async fetchVpnCustomerGatewayParameters () {
|
||||||
|
const getParam = (obj, key) => {
|
||||||
|
const val = obj?.[key.toLowerCase()]
|
||||||
|
return typeof val === 'string'
|
||||||
|
? val.split(',').map(s => s.trim()).filter(Boolean)
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
const getAllowed = (baseList, excludedList) => {
|
||||||
|
const excluded = new Set(excludedList.map(v => v.toLowerCase()))
|
||||||
|
return baseList.filter(item => !excluded.has(item.toLowerCase()))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadingParameters = true
|
||||||
|
|
||||||
|
const response = await getAPI('listCapabilities', { domainid: this.initialValues.domainid })
|
||||||
|
const capability = response.listcapabilitiesresponse?.capability || {}
|
||||||
|
const parameters = capability.vpncustomergatewayparameters || {}
|
||||||
|
|
||||||
|
const excludedEnc = getParam(parameters, 'excludedEncryptionAlgorithms')
|
||||||
|
const excludedHash = getParam(parameters, 'excludedHashingAlgorithms')
|
||||||
|
const excludedIke = getParam(parameters, 'excludedIkeVersions')
|
||||||
|
const excludedDh = getParam(parameters, 'excludedDhGroups')
|
||||||
|
|
||||||
|
this.allowedEncryptionAlgos = getAllowed(this.encryptionAlgo, excludedEnc)
|
||||||
|
this.allowedHashingAlgos = getAllowed(this.hash, excludedHash)
|
||||||
|
this.allowedIkeVersions = getAllowed(this.ikeVersions, excludedIke)
|
||||||
|
|
||||||
|
const dhValues = Object.values(this.DHGroups)
|
||||||
|
this.allowedDhGroupValues = getAllowed(dhValues, excludedDh)
|
||||||
|
this.allowedDhGroupKeys = Object.entries(this.DHGroups)
|
||||||
|
.filter(([key, value]) => this.allowedDhGroupValues.includes(value))
|
||||||
|
.map(([key]) => key)
|
||||||
|
|
||||||
|
this.form.ikeEncryption = this.form.ikeEncryption || this.allowedEncryptionAlgos[0]
|
||||||
|
this.form.ikeHash = this.form.ikeHash || this.allowedHashingAlgos[0]
|
||||||
|
this.form.ikeversion = this.form.ikeversion || this.allowedIkeVersions[0]
|
||||||
|
this.form.espEncryption = this.form.espEncryption || this.allowedEncryptionAlgos[0]
|
||||||
|
this.form.espHash = this.form.espHash || this.allowedHashingAlgos[0]
|
||||||
|
if (!this.initialValues.ikeDh) {
|
||||||
|
if (this.allowedDhGroupKeys.includes(this.ikeDhGroupInitialKey)) {
|
||||||
|
this.form.ikeDh = this.ikeDhGroupInitialKey + '(' + this.DHGroups[this.ikeDhGroupInitialKey] + ')'
|
||||||
|
} else {
|
||||||
|
this.form.ikeDh = this.allowedDhGroupKeys[0] + '(' + this.DHGroups[this.allowedDhGroupKeys[0]] + ')'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.obsoleteEncryptionAlgos = getParam(parameters, 'obsoleteEncryptionAlgorithms')
|
||||||
|
this.obsoleteHashingAlgos = getParam(parameters, 'obsoleteHashingAlgorithms')
|
||||||
|
this.obsoleteIkeVersions = getParam(parameters, 'obsoleteIkeVersions')
|
||||||
|
this.obsoleteDhGroups = getParam(parameters, 'obsoleteDhGroups')
|
||||||
|
|
||||||
|
this.loadingParameters = false
|
||||||
|
},
|
||||||
|
handleSubmit (e) {
|
||||||
|
if (e && e.preventDefault) {
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
if (this.isSubmitted) return
|
||||||
|
|
||||||
|
this.formRef.value.validate().then(() => {
|
||||||
|
this.isSubmitted = true
|
||||||
|
const formRaw = toRaw(this.form)
|
||||||
|
const values = this.handleRemoveFields(formRaw)
|
||||||
|
const { ikepolicy, esppolicy } = this.buildPolicies(values)
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
name: values.name,
|
||||||
|
gateway: values.gateway,
|
||||||
|
cidrlist: values.cidrlist,
|
||||||
|
ipsecpsk: values.ipsecpsk,
|
||||||
|
ikelifetime: values.ikelifetime,
|
||||||
|
esplifetime: values.esplifetime,
|
||||||
|
dpd: values.dpd,
|
||||||
|
forceencap: values.forceencap,
|
||||||
|
ikepolicy: ikepolicy,
|
||||||
|
esppolicy: esppolicy,
|
||||||
|
splitconnections: values.splitconnections,
|
||||||
|
ikeversion: values.ikeversion
|
||||||
|
}
|
||||||
|
this.$emit('submit', {
|
||||||
|
payload,
|
||||||
|
rawValues: values
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
this.formRef.value.scrollToField(error.errorFields[0].name)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.form-layout {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue