From 01bf0c5784826a2997be4825c5534fe0391f2603 Mon Sep 17 00:00:00 2001 From: Greg Goodrich Date: Wed, 18 Mar 2020 10:15:20 -0500 Subject: [PATCH 1/5] Adding VPN options for IKE version and IKE split connections. IKE version allows selecting ike (autoselect), ikev1, or ikev2. Split connections gives an option of separating the first right subnet from the rest, and kicking out individual statements for each right subnet for better cross-compatibility. update per PR suggestion --- .../network/Site2SiteCustomerGateway.java | 4 ++ .../apache/cloudstack/api/ApiConstants.java | 2 + .../user/vpn/CreateVpnCustomerGatewayCmd.java | 14 +++++ .../user/vpn/UpdateVpnCustomerGatewayCmd.java | 14 +++++ .../Site2SiteCustomerGatewayResponse.java | 16 +++++ .../Site2SiteVpnConnectionResponse.java | 16 +++++ .../api/routing/Site2SiteVpnCfgCommand.java | 23 ++++++- .../facade/Site2SiteVpnConfigItem.java | 2 +- .../virtualnetwork/model/Site2SiteVpn.java | 24 ++++++- .../VirtualRoutingResourceTest.java | 6 +- .../dao/Site2SiteCustomerGatewayVO.java | 28 ++++++++- .../META-INF/db/schema-41500to41510.sql | 4 ++ .../java/com/cloud/api/ApiResponseHelper.java | 4 ++ .../network/router/CommandSetupHelper.java | 4 +- .../network/vpn/Site2SiteVpnManagerImpl.java | 62 ++++++++++++++++--- ...irtualNetworkApplianceManagerImplTest.java | 2 +- systemvm/debian/opt/cloud/bin/configure.py | 35 +++++++++-- systemvm/debian/opt/cloud/bin/ipsectunnel.sh | 35 +++++++++-- ui/public/locales/ca.json | 2 + ui/public/locales/en.json | 4 ++ ui/public/locales/it_IT.json | 2 + ui/public/locales/nb_NO.json | 2 + ui/public/locales/nl_NL.json | 2 + ui/public/locales/pl.json | 2 + ui/src/config/section/network.js | 6 +- .../network/CreateVpnCustomerGateway.vue | 37 ++++++++++- 26 files changed, 320 insertions(+), 32 deletions(-) diff --git a/api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java b/api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java index f9a88bdd8453..de83fddf8132 100644 --- a/api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java +++ b/api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java @@ -43,5 +43,9 @@ public interface Site2SiteCustomerGateway extends ControlledEntity, Identity, In public Date getRemoved(); + public Boolean getSplitConnections(); + + public String getIkeVersion(); + String getName(); } diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index aa4eebc929e7..4c6aef60da3b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -629,12 +629,14 @@ public class ApiConstants { public static final String GUEST_IP = "guestip"; public static final String REMOVED = "removed"; public static final String COMPLETED = "completed"; + public static final String IKE_VERSION = "ikeversion"; public static final String IKE_POLICY = "ikepolicy"; public static final String ESP_POLICY = "esppolicy"; public static final String IKE_LIFETIME = "ikelifetime"; public static final String ESP_LIFETIME = "esplifetime"; public static final String DPD = "dpd"; public static final String FORCE_ENCAP = "forceencap"; + public static final String SPLIT_CONNECTIONS = "splitconnections"; public static final String FOR_VPC = "forvpc"; public static final String SHRINK_OK = "shrinkok"; public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java index 6f591756d2e9..f99ee54c695f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java @@ -92,6 +92,12 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { description = "create site-to-site VPN customer gateway for the project", since = "4.6") private Long projectId; + @Parameter(name = ApiConstants.SPLIT_CONNECTIONS, type = CommandType.BOOLEAN, required = false, description = "For IKEv2, whether to split multiple right subnet cidrs into multiple connection statements.") + private Boolean splitConnections; + + @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + private String ikeVersion; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -146,6 +152,14 @@ public Long getProjectId() { return projectId; } + public Boolean getSplitConnections() { + return splitConnections; + } + + public String getIkeVersion() { + return ikeVersion; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index d7bf5c4b557e..cb8fb9ceae42 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -94,6 +94,12 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { + "gateway associated with the account for the specified domain.") private Long domainId; + @Parameter(name = ApiConstants.SPLIT_CONNECTIONS, type = CommandType.BOOLEAN, required = false, description = "For IKEv2, whether to split multiple right subnet cidrs into multiple connection statements.") + private Boolean splitConnections; + + @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + private String ikeVersion; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -140,6 +146,14 @@ public Boolean getDpd() { public Boolean getEncap() { return encap; } + public boolean getSplitConnections() { + return splitConnections; + } + + public String getIkeVersion() { + return ikeVersion; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java index 8128405cdaee..88e0e1600e5b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java @@ -102,6 +102,14 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponse implements Co @Param(description = "the date and time the host was removed") private Date removed; + @SerializedName(ApiConstants.SPLIT_CONNECTIONS) + @Param(description = "For IKEv2, whether to split multiple right subnet cidrs into multiple connection statements.") + private Boolean splitConnections; + + @SerializedName(ApiConstants.IKE_VERSION) + @Param(description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + private String ikeVersion; + public void setId(String id) { this.id = id; } @@ -148,6 +156,14 @@ public void setDpd(Boolean dpd) { public void setEncap(Boolean encap) { this.encap = encap; } + public void setSplitConnections(Boolean splitConnections) { + this.splitConnections = splitConnections; + } + + public void setIkeVersion(String ikeVersion) { + this.ikeVersion = ikeVersion; + } + public void setRemoved(Date removed) { this.removed = removed; } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java index edaa1b262a74..1f7509239d1a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java @@ -132,6 +132,14 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont @Param(description = "is connection for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) private Boolean forDisplay; + @SerializedName(ApiConstants.SPLIT_CONNECTIONS) + @Param(description = "Split multiple remote networks into multiple phase 2 SAs. Often used with Cisco some products.") + private Boolean splitConnections; + + @SerializedName(ApiConstants.IKE_VERSION) + @Param(description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + private String ikeVersion; + public void setId(String id) { this.id = id; } @@ -200,6 +208,14 @@ public void setRemoved(Date removed) { this.removed = removed; } + public void setSplitConnections(Boolean splitConnections) { + this.splitConnections = splitConnections; + } + + public void setIkeVersion(String ikeVersion) { + this.ikeVersion = ikeVersion; + } + @Override public void setAccountName(String accountName) { this.accountName = accountName; diff --git a/core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java index 685cf4049c79..f679b75d155d 100644 --- a/core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java +++ b/core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -35,6 +35,8 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { private boolean dpd; private boolean passive; private boolean encap; + private boolean splitConnections; + private String ikeVersion; @Override public boolean executeInSequence() { @@ -46,7 +48,8 @@ public Site2SiteVpnCfgCommand() { } public Site2SiteVpnCfgCommand(boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, String peerGatewayIp, String peerGuestCidrList, - String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive, boolean encap) { + String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive, boolean encap, + boolean splitConnections, String ikeVersion) { this.create = create; this.setLocalPublicIp(localPublicIp); this.setLocalPublicGateway(localPublicGateway); @@ -61,6 +64,8 @@ public Site2SiteVpnCfgCommand(boolean create, String localPublicIp, String local this.dpd = dpd; this.passive = passive; this.encap = encap; + this.splitConnections = splitConnections; + this.ikeVersion = ikeVersion; } public boolean isCreate() { @@ -174,4 +179,20 @@ public boolean isPassive() { public void setPassive(boolean passive) { this.passive = passive; } + + public boolean getSplitConnections() { + return splitConnections; + } + + public void setSplitConnections(boolean splitConnections) { + this.splitConnections = splitConnections; + } + + public String getIkeVersion() { + return ikeVersion; + } + + public void setIkeVersion(String ikeVersion) { + this.ikeVersion = ikeVersion; + } } diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java index 5bb466c59352..badd0d376d12 100644 --- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java +++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java @@ -36,7 +36,7 @@ public List generateConfig(final NetworkElementCommand cmd) { final Site2SiteVpn site2siteVpn = new Site2SiteVpn(command.getLocalPublicIp(), command.getLocalGuestCidr(), command.getLocalPublicGateway(), command.getPeerGatewayIp(), command.getPeerGuestCidrList(), command.getEspPolicy(), command.getIkePolicy(), command.getIpsecPsk(), command.getIkeLifetime(), command.getEspLifetime(), command.isCreate(), command.getDpd(), - command.isPassive(), command.getEncap()); + command.isPassive(), command.getEncap(), command.getSplitConnections(), command.getIkeVersion()); return generateConfigItems(site2siteVpn); } diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java index 232e99f099ac..9057bf4f2936 100644 --- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java +++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java @@ -21,9 +21,9 @@ public class Site2SiteVpn extends ConfigBase { - private String localPublicIp, localGuestCidr, localPublicGateway, peerGatewayIp, peerGuestCidrList, espPolicy, ikePolicy, ipsecPsk; + private String localPublicIp, localGuestCidr, localPublicGateway, peerGatewayIp, peerGuestCidrList, espPolicy, ikePolicy, ipsecPsk, ikeVersion; private Long ikeLifetime, espLifetime; - private boolean create, dpd, passive, encap; + private boolean create, dpd, passive, encap, splitConnections; public Site2SiteVpn() { super(ConfigBase.SITE2SITEVPN); @@ -31,7 +31,7 @@ public Site2SiteVpn() { public Site2SiteVpn(String localPublicIp, String localGuestCidr, String localPublicGateway, String peerGatewayIp, String peerGuestCidrList, String espPolicy, String ikePolicy, - String ipsecPsk, Long ikeLifetime, Long espLifetime, boolean create, Boolean dpd, boolean passive, boolean encap) { + String ipsecPsk, Long ikeLifetime, Long espLifetime, boolean create, Boolean dpd, boolean passive, boolean encap, boolean splitConnections, String ikeVersion) { super(ConfigBase.SITE2SITEVPN); this.localPublicIp = localPublicIp; this.localGuestCidr = localGuestCidr; @@ -47,6 +47,8 @@ public Site2SiteVpn(String localPublicIp, String localGuestCidr, String localPub this.dpd = dpd; this.passive = passive; this.encap = encap; + this.splitConnections = splitConnections; + this.ikeVersion = ikeVersion; } public String getLocalPublicIp() { @@ -161,4 +163,20 @@ public void setEncap(boolean encap) { this.encap = encap; } + public boolean getSplitConnections() { + return splitConnections; + } + + public void setSplitConnections(boolean splitConnections) { + this.splitConnections = splitConnections; + } + + public String getIkeVersion() { + return ikeVersion; + } + + public void setIkeVersion(String ikeVersion) { + this.ikeVersion = ikeVersion; + } + } diff --git a/core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java index 200f266b9251..6eb30aeeed9e 100644 --- a/core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java +++ b/core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java @@ -495,17 +495,17 @@ private void verifyArgs(final SetMonitorServiceCommand cmd, final String script, public void testSite2SiteVpnCfgCommand() { _count = 0; - Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false, false); + Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false, false, false, "ike"); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME); Answer answer = _resource.executeRequest(cmd); assertTrue(answer.getResult()); - cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false); + cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false, false, "ike"); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME); answer = _resource.executeRequest(cmd); assertTrue(answer.getResult()); - cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false); + cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false, false, "ike"); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME); answer = _resource.executeRequest(cmd); assertTrue(answer.getResult()); diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java index f1d3ef32712d..c8241518d63e 100644 --- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java +++ b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java @@ -79,6 +79,12 @@ public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { @Column(name = "account_id") private Long accountId; + @Column(name = "split_connections") + private boolean splitConnections; + + @Column(name = "ike_version") + private String ikeVersion; + @Column(name = GenericDao.REMOVED_COLUMN) private Date removed; @@ -86,7 +92,7 @@ public Site2SiteCustomerGatewayVO() { } public Site2SiteCustomerGatewayVO(String name, long accountId, long domainId, String gatewayIp, String guestCidrList, String ipsecPsk, String ikePolicy, - String espPolicy, long ikeLifetime, long espLifetime, boolean dpd, boolean encap) { + String espPolicy, long ikeLifetime, long espLifetime, boolean dpd, boolean encap, boolean splitConnections, String ikeVersion) { this.name = name; this.gatewayIp = gatewayIp; this.guestCidrList = guestCidrList; @@ -100,6 +106,8 @@ public Site2SiteCustomerGatewayVO(String name, long accountId, long domainId, St uuid = UUID.randomUUID().toString(); this.accountId = accountId; this.domainId = domainId; + this.splitConnections = splitConnections; + this.ikeVersion = ikeVersion; } @Override @@ -221,6 +229,24 @@ public long getAccountId() { return accountId; } + @Override + public Boolean getSplitConnections() { + return splitConnections; + } + + public void setSplitConnections(Boolean splitConnections) { + this.splitConnections = splitConnections; + } + + @Override + public String getIkeVersion() { + return ikeVersion; + } + + public void setIkeVersion(String ikeVersion) { + this.ikeVersion = ikeVersion; + } + @Override public Class getEntityType() { return Site2SiteCustomerGateway.class; diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41500to41510.sql b/engine/schema/src/main/resources/META-INF/db/schema-41500to41510.sql index 21d9dcba03be..8aaf8625403d 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41500to41510.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41500to41510.sql @@ -56,3 +56,7 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervis -- Add support for Ubuntu Focal Fossa 20.04 for Xenserver 8.2.0 INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (335, UUID(), 10, 'Ubuntu 20.04 LTS', now()); INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'Xenserver', '8.2.0', 'Ubuntu Focal Fossa 20.04', 330, now(), 0); + +ALTER TABLE `cloud`.`s2s_customer_gateway` ADD COLUMN `ike_version` varchar(5) NOT NULL DEFAULT 'ike' COMMENT 'one of ike, ikev1, ikev2'; +ALTER TABLE `cloud`.`s2s_customer_gateway` ADD COLUMN `split_connections` int(1) NOT NULL DEFAULT 0; + diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 05593fd1f84c..a7da96a82419 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -3251,6 +3251,8 @@ public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(S response.setDpd(result.getDpd()); response.setEncap(result.getEncap()); response.setRemoved(result.getRemoved()); + response.setIkeVersion(result.getIkeVersion()); + response.setSplitConnections(result.getSplitConnections()); response.setObjectName("vpncustomergateway"); populateAccount(response, result.getAccountId()); @@ -3290,6 +3292,8 @@ public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2 response.setEspLifetime(customerGateway.getEspLifetime()); response.setDpd(customerGateway.getDpd()); response.setEncap(customerGateway.getEncap()); + response.setIkeVersion(customerGateway.getIkeVersion()); + response.setSplitConnections(customerGateway.getSplitConnections()); } } diff --git a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java index e344b462b50a..e73a83393f49 100644 --- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java @@ -944,9 +944,11 @@ public void createSite2SiteVpnCfgCommands(final Site2SiteVpnConnection conn, fin final Long espLifetime = gw.getEspLifetime(); final Boolean dpd = gw.getDpd(); final Boolean encap = gw.getEncap(); + final Boolean splitConnections = gw.getSplitConnections(); + final String ikeVersion = gw.getIkeVersion(); final Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, peerGatewayIp, peerGuestCidrList, ikePolicy, - espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive(), encap); + espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive(), encap, splitConnections, ikeVersion); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 7fd3473a85f4..668eb114cb66 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -45,6 +45,7 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.network.Site2SiteVpnConnection; @@ -229,10 +230,20 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!"); } + Boolean splitConnections = cmd.getSplitConnections(); + if (splitConnections == null) { + splitConnections = false; + } + + String ikeVersion = cmd.getIkeVersion(); + if (ikeVersion == null) { + ikeVersion = "ike"; + } + checkCustomerGatewayCidrList(peerCidrList); Site2SiteCustomerGatewayVO gw = - new Site2SiteCustomerGatewayVO(name, accountId, owner.getDomainId(), gatewayIp, peerCidrList, ipsecPsk, ikePolicy, espPolicy, ikeLifetime, espLifetime, dpd, encap); + new Site2SiteCustomerGatewayVO(name, accountId, owner.getDomainId(), gatewayIp, peerCidrList, ipsecPsk, ikePolicy, espPolicy, ikeLifetime, espLifetime, dpd, encap, splitConnections, ikeVersion); _customerGatewayDao.persist(gw); return gw; } @@ -419,14 +430,6 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm } _accountMgr.checkAccess(caller, null, false, gw); - List conns = _vpnConnectionDao.listByCustomerGatewayId(id); - if (conns != null) { - for (Site2SiteVpnConnection conn : conns) { - if (conn.getState() != State.Error) { - throw new InvalidParameterValueException("Unable to update customer gateway with connections in non-Error state!"); - } - } - } String name = cmd.getName(); String gatewayIp = cmd.getGatewayIp(); @@ -476,6 +479,16 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm encap = false; } + Boolean splitConnections = cmd.getSplitConnections(); + if (splitConnections == null) { + splitConnections = false; + } + + String ikeVersion = cmd.getIkeVersion(); + if (ikeVersion == null) { + ikeVersion = "ike"; + } + checkCustomerGatewayCidrList(guestCidrList); long accountId = gw.getAccountId(); @@ -494,7 +507,38 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm gw.setEspLifetime(espLifetime); gw.setDpd(dpd); gw.setEncap(encap); + gw.setSplitConnections(splitConnections); + gw.setIkeVersion(ikeVersion); _customerGatewayDao.persist(gw); + + List conns = _vpnConnectionDao.listByCustomerGatewayId(id); + if (conns != null) { + for (Site2SiteVpnConnection conn : conns) { + try { + _accountMgr.checkAccess(caller, null, false, conn); + } catch (PermissionDeniedException e) { + // Just don't restart this connection, as the user has no rights to it + // Maybe should issue a notification to the system? + s_logger.info("Site2SiteVpnManager:updateCustomerGateway() Not resetting VPN connection " + conn.getId() + " as user lacks permission"); + continue; + } + + if (conn.getState() == State.Pending) { + // Vpn connection cannot be reset when the state is Pending + continue; + } + try { + if (conn.getState() == State.Connected || conn.getState() == State.Error) { + stopVpnConnection(conn.getId()); + } + startVpnConnection(conn.getId()); + } catch (ResourceUnavailableException e) { + // Should never get here, as we are looping on the actual connections, but we must handle it regardless + continue; + } + } + } + return gw; } diff --git a/server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java index 0ddbd845a8c7..aed4769ab964 100644 --- a/server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java +++ b/server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java @@ -278,7 +278,7 @@ public void testUpdateSite2SiteVpnConnectionState() throws Exception{ conns.add(conn); conns.add(conn1); - Site2SiteCustomerGatewayVO gw = new Site2SiteCustomerGatewayVO("Testing gateway", 1L, 1L, "192.168.50.15", "Guest List", "ipsecPsk", "ikePolicy", "espPolicy", 1L, 1L, true, true); + Site2SiteCustomerGatewayVO gw = new Site2SiteCustomerGatewayVO("Testing gateway", 1L, 1L, "192.168.50.15", "Guest List", "ipsecPsk", "ikePolicy", "espPolicy", 1L, 1L, true, true, false, "ike"); HostVO hostVo = new HostVO(1L, "Testing host", Host.Type.Routing, "192.168.50.15", "privateNetmask", "privateMacAddress", "publicIpAddress", "publicNetmask", "publicMacAddress", "storageIpAddress", "storageNetmask", "storageMacAddress", "deuxStorageIpAddress", "duxStorageNetmask", "deuxStorageMacAddress", "guid", Status.Up, "version", "iqn", new Date() , 1L, 1L, 1L, 1L, "parent", 20L, Storage.StoragePoolType.Gluster); hostVo.setManagementServerId(ManagementServerNode.getManagementServerId()); diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py index be67f403c8be..d0a83abd8551 100755 --- a/systemvm/debian/opt/cloud/bin/configure.py +++ b/systemvm/debian/opt/cloud/bin/configure.py @@ -556,10 +556,18 @@ def configure_ipsec(self, obj): vpnsecretsfile = "%s/ipsec.vpn-%s.secrets" % (self.VPNCONFDIR, rightpeer) ikepolicy = obj['ike_policy'].replace(';', '-') esppolicy = obj['esp_policy'].replace(';', '-') + splitconnections = obj['split_connections'] if 'split_connections' in obj else False + ikeversion = obj['ike_version'] if 'ike_version' in obj and obj['ike_version'].lower() in ('ike', 'ikev1', 'ikev2') else 'ike' + + peerlistarr = peerlist.split(',') + if splitconnections: + logging.debug('Splitting rightsubnets %s' % peerlistarr) + peerlist = peerlistarr[0] if rightpeer in self.confips: self.confips.remove(rightpeer) file = CsFile(vpnconffile) + file.repopulate() # This avoids issues when switching off split_connections or removing subnets with split_connections == true file.add("#conn for vpn-%s" % rightpeer, 0) file.search("conn ", "conn vpn-%s" % rightpeer) file.addeq(" left=%s" % leftpeer) @@ -568,7 +576,7 @@ def configure_ipsec(self, obj): file.addeq(" rightsubnet=%s" % peerlist) file.addeq(" type=tunnel") file.addeq(" authby=secret") - file.addeq(" keyexchange=ike") + file.addeq(" keyexchange=%s" % ikeversion) file.addeq(" ike=%s" % ikepolicy) file.addeq(" ikelifetime=%s" % self.convert_sec_to_h(obj['ike_lifetime'])) file.addeq(" esp=%s" % esppolicy) @@ -582,6 +590,14 @@ def configure_ipsec(self, obj): file.addeq(" dpddelay=30") file.addeq(" dpdtimeout=120") file.addeq(" dpdaction=restart") + if splitconnections and peerlistarr.count > 1: + logging.debug('Splitting connections for rightsubnets %s' % peerlistarr) + for peeridx in range(1, len(peerlistarr)): + logging.debug('Adding split connection -%d for subnet %s' % (peeridx + 1, peerlistarr[peeridx])) + file.append('') + file.search('conn vpn-.*-%d' % (peeridx + 1), "conn vpn-%s-%d" % (rightpeer, peeridx + 1)) + file.append(' also=vpn-%s' % rightpeer) + file.append(' rightsubnet=%s' % peerlistarr[peeridx]) secret = CsFile(vpnsecretsfile) secret.search("%s " % leftpeer, "%s %s : PSK \"%s\"" % (leftpeer, rightpeer, obj['ipsec_psk'])) if secret.is_changed() or file.is_changed(): @@ -595,14 +611,25 @@ def configure_ipsec(self, obj): os.chmod(vpnsecretsfile, 0400) for i in xrange(3): - result = CsHelper.execute('ipsec status vpn-%s | grep "%s"' % (rightpeer, peerlist.split(",", 1)[0])) - if len(result) > 0: + done = True + for peeridx in range(0, len(peerlistarr)): + # Check for the proper connection and subnet + conn = rightpeer if not splitconnections else rightpeer if peeridx == 0 else '%s-%d' % (rightpeer, peeridx + 1) + result = CsHelper.execute('ipsec status vpn-%s | grep "%s"' % (conn, peerlistarr[peeridx])) + # If any of the peers hasn't yet finished, continue the outer loop + if len(result) == 0: + done = False + if done: break time.sleep(1) # With 'auto=route', connections are established on an attempt to # communicate over the S2S VPN. This uses ping to initialize the connection. - CsHelper.execute("timeout 5 ping -c 3 %s" % (peerlist.split("/", 1)[0].replace(".0", ".1"))) + for peer in peerlistarr: + octets = peer.split('/', 1)[0].split('.') + octets[3] = str((int(octets[3]) + 1)) + ipinsubnet = '.'.join(octets) + CsHelper.execute("timeout 5 ping -c 3 %s" % ipinsubnet) def convert_sec_to_h(self, val): hrs = int(val) / 3600 diff --git a/systemvm/debian/opt/cloud/bin/ipsectunnel.sh b/systemvm/debian/opt/cloud/bin/ipsectunnel.sh index c42650f8d1de..ad12efddbdb6 100755 --- a/systemvm/debian/opt/cloud/bin/ipsectunnel.sh +++ b/systemvm/debian/opt/cloud/bin/ipsectunnel.sh @@ -23,7 +23,7 @@ vpnoutmark="0x525" vpninmark="0x524" usage() { - printf "Usage: %s: (-A|-D) -l -n -g -r -N -e -i -t -T -s -d [ -p -c -S ]\n" $(basename $0) >&2 + printf "Usage: %s: (-A|-D) -l -n -g -r -N -e -i -t -T -s -d [ -p -c -S -C -v ]\n" $(basename $0) >&2 } #set -x @@ -139,14 +139,21 @@ ipsec_tunnel_add() { check_and_enable_iptables + rsubnets=" rightsubnets={$rightnets}" + if [ $splitconnections -eq 1 ] + then + rsubnetarr=(${rightnets}) + rsubnets=" rightsubnet=${rsubnetarr[0]}" + fi + sudo echo "conn vpn-$rightpeer" > $vpnconffile && sudo echo " left=$leftpeer" >> $vpnconffile && sudo echo " leftsubnet=$leftnet" >> $vpnconffile && sudo echo " right=$rightpeer" >> $vpnconffile && - sudo echo " rightsubnets={$rightnets}" >> $vpnconffile && + sudo echo $rsubnets >> $vpnconffile && sudo echo " type=tunnel" >> $vpnconffile && sudo echo " authby=secret" >> $vpnconffile && - sudo echo " keyexchange=ike" >> $vpnconffile && + sudo echo " keyexchange=${ikeversion:-ike}" >> $vpnconffile && sudo echo " ike=$ikepolicy" >> $vpnconffile && sudo echo " ikelifetime=${ikelifetime}s" >> $vpnconffile && sudo echo " esp=$esppolicy" >> $vpnconffile && @@ -163,6 +170,20 @@ ipsec_tunnel_add() { sudo echo " dpdaction=restart" >> $vpnconffile fi + if [ $splitconnections -eq 1 ] + then + # Split out all but the first right subnet into their own statements + subnetidx=2 + for rsubnet in ${rsubnetarr[@]:1}; do + sudo echo "" >> $vpnconffile && + sudo echo "conn vpn-$rightpeer-$subnetidx" >> $vpnconffile && + sudo echo " also=vpn-$rightpeer" >> $vpnconffile && + sudo echo " auto=route" >> $vpnconffile && + sudo echo " rightsubnet=$rsubnet" >> $vpnconffile + ((++subnetidx)) + done + fi + enable_iptables_subnets sudo ipsec auto --rereadall @@ -215,8 +236,10 @@ passive=0 op="" checkup=0 secure=1 +ikeversion="ike" +splitconnections=0 -while getopts 'ADSpcl:n:g:r:N:e:i:t:T:s:d:' OPTION +while getopts 'ACDSpcl:n:g:r:N:e:i:t:T:s:d:v:' OPTION do case $OPTION in A) opflag=1 @@ -243,6 +266,8 @@ do e) eflag=1 esppolicy="$OPTARG" ;; + v) ikeversion="$OPTARG" + ;; i) iflag=1 ikepolicy="$OPTARG" ;; @@ -264,6 +289,8 @@ do ;; S) secure=0 ;; + C) splitconnections=1 + ;; ?) usage exit 2 ;; diff --git a/ui/public/locales/ca.json b/ui/public/locales/ca.json index 743d82f1e81c..1e312e9965b2 100644 --- a/ui/public/locales/ca.json +++ b/ui/public/locales/ca.json @@ -828,6 +828,7 @@ "label.icmpcode": "ICMP Code", "label.icmptype": "ICMP Type", "label.id": "ID", +"label.ike.version": "IKE Version", "label.ikedh": "IKE DH", "label.ikeencryption": "IKE Encryption", "label.ikehash": "IKE Hash", @@ -897,6 +898,7 @@ "label.ipaddress2": "IP Address", "label.iplimit": "Public IP Limits", "label.ips": "IPs", +"label.ipsec.splitconnections": "Split Connections", "label.ipsecpsk": "IPsec Preshared-Key", "label.iptotal": "Total of IP Addresses", "label.ipv4.cidr": "IPv4 CIDR", diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index ba0d2b13d22f..268f734e9ea4 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1026,11 +1026,13 @@ "label.icmptype.start.port": "ICMP Type / Start Port", "label.id": "ID", "label.identity.and.access": "Identity and Access", +"label.ike.version": "IKE Version", "label.ikedh": "IKE DH", "label.ikeencryption": "IKE Encryption", "label.ikehash": "IKE Hash", "label.ikelifetime": "IKE lifetime (second)", "label.ikepolicy": "IKE policy", +"label.ikeversion": "IKE Version", "label.images": "Images", "label.import.backup.offering": "Import Backup Offering", "label.import.offering": "Import Offering", @@ -1106,6 +1108,7 @@ "label.ipaddress2": "IP Address", "label.iplimit": "Public IP Limits", "label.ips": "IPs", +"label.ipsec.splitconnections": "Split Connections", "label.ipsecpsk": "IPsec Preshared-Key", "label.iptotal": "Total of IP Addresses", "label.ipv4.cidr": "IPv4 CIDR", @@ -1973,6 +1976,7 @@ "label.specify.vxlan": "Specify VXLAN", "label.specifyipranges": "Specify IP ranges", "label.specifyvlan": "Specify VLAN", +"label.splitconnections": "Split Connections", "label.sr.name": "SR Name-Label", "label.srx": "SRX", "label.srx.details": "SRX details", diff --git a/ui/public/locales/it_IT.json b/ui/public/locales/it_IT.json index 9a6be067678c..a8308a0bc05e 100644 --- a/ui/public/locales/it_IT.json +++ b/ui/public/locales/it_IT.json @@ -828,6 +828,7 @@ "label.icmpcode": "Codice ICMP", "label.icmptype": "Tipo ICMP", "label.id": "ID", +"label.ike.version": "Versione di IKE", "label.ikedh": "DH di IKE", "label.ikeencryption": "Encryption di IKE", "label.ikehash": "Hash di IKE", @@ -897,6 +898,7 @@ "label.ipaddress2": "Indirizzo IP", "label.iplimit": "Public IP Limits", "label.ips": "Indirizzi IP", +"label.ipsec.splitconnections": "Connessioni Divise", "label.ipsecpsk": "Preshared-Key di IPsec", "label.iptotal": "Total of IP Addresses", "label.ipv4.cidr": "IPv4 CIDR", diff --git a/ui/public/locales/nb_NO.json b/ui/public/locales/nb_NO.json index 722529319bd7..81cbbbe3668c 100644 --- a/ui/public/locales/nb_NO.json +++ b/ui/public/locales/nb_NO.json @@ -828,6 +828,7 @@ "label.icmpcode": "ICMP-kode", "label.icmptype": "ICMP-type", "label.id": "ID", +"label.ike.version": "IKE versjon", "label.ikedh": "IKE DH", "label.ikeencryption": "IKE kryptering", "label.ikehash": "IKE Hash", @@ -897,6 +898,7 @@ "label.ipaddress2": "IP-adresse", "label.iplimit": "Offentlig IP-addresse Grenser", "label.ips": "IPer", +"label.ipsec.splitconnections": "delte forbindelser", "label.ipsecpsk": "IPSec Delt N\u00f8kkel", "label.iptotal": "Totalt IP-adresser", "label.ipv4.cidr": "IPv4 CIDR", diff --git a/ui/public/locales/nl_NL.json b/ui/public/locales/nl_NL.json index 4a5e606f0737..07aae3063b00 100644 --- a/ui/public/locales/nl_NL.json +++ b/ui/public/locales/nl_NL.json @@ -828,6 +828,7 @@ "label.icmpcode": "ICMP Code", "label.icmptype": "ICMP Type", "label.id": "ID", +"label.ike.version": "IKE Versie", "label.ikedh": "IKE DH", "label.ikeencryption": "IKE Encryptie", "label.ikehash": "IKE Hash", @@ -897,6 +898,7 @@ "label.ipaddress2": "IP Adres", "label.iplimit": "Publieke IP Limieten", "label.ips": "IPs", +"label.ipsec.splitconnections": "Gesplitste Verbindingen", "label.ipsecpsk": "IPsec Preshared-Key", "label.iptotal": "totaal aantal IP adressen", "label.ipv4.cidr": "IPv4 CIDR", diff --git a/ui/public/locales/pl.json b/ui/public/locales/pl.json index 29c1c0617d0a..163f1a2a7274 100644 --- a/ui/public/locales/pl.json +++ b/ui/public/locales/pl.json @@ -828,6 +828,7 @@ "label.icmpcode": "ICMP Code", "label.icmptype": "ICMP Type", "label.id": "ID", +"label.ike.version": "IKE Version", "label.ikedh": "IKE DH", "label.ikeencryption": "IKE Encryption", "label.ikehash": "IKE Hash", @@ -897,6 +898,7 @@ "label.ipaddress2": "IP Address", "label.iplimit": "Public IP Limits", "label.ips": "IP", +"label.ipsec.splitconnections": "Split Connections", "label.ipsecpsk": "IPsec Preshared-Key", "label.iptotal": "Total of IP Addresses", "label.ipv4.cidr": "IPv4 CIDR", diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index f274fd51d737..79dd2a97429b 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -407,7 +407,7 @@ export default { hidden: true, permission: ['listVpnConnections'], columns: ['publicip', 'state', 'gateway', 'ipsecpsk', 'ikepolicy', 'esppolicy'], - details: ['publicip', 'gateway', 'passive', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'esppolicy', 'ikelifetime', 'esplifetime', 'dpd', 'forceencap', 'created'], + details: ['publicip', 'gateway', 'passive', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'esppolicy', 'ikelifetime', 'ikeversion', 'esplifetime', 'dpd', 'splitconnections', 'forceencap', 'created'], actions: [ { api: 'createVpnConnection', @@ -593,7 +593,7 @@ export default { icon: 'lock', permission: ['listVpnCustomerGateways'], columns: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'account'], - details: ['name', 'id', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'esppolicy', 'esplifetime', 'dpd', 'forceencap', 'account', 'domain'], + details: ['name', 'id', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap', 'account', 'domain'], searchFilters: ['keyword', 'domainid', 'account'], actions: [ { @@ -611,7 +611,7 @@ export default { label: 'label.edit', docHelp: 'adminguide/networking_and_traffic.html#updating-and-removing-a-vpn-customer-gateway', dataView: true, - args: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'esppolicy', 'esplifetime', 'dpd', 'forceencap'] + args: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap'] }, { api: 'deleteVpnCustomerGateway', diff --git a/ui/src/views/network/CreateVpnCustomerGateway.vue b/ui/src/views/network/CreateVpnCustomerGateway.vue index 99ff4cd0ec51..2997915325b5 100644 --- a/ui/src/views/network/CreateVpnCustomerGateway.vue +++ b/ui/src/views/network/CreateVpnCustomerGateway.vue @@ -108,6 +108,19 @@ + + + + {{ vers }} + + + + + + {{ $t('label.splitconnections') }} + + + + + + {{ $t('label.forceencap') }} @@ -270,6 +298,11 @@ export default { 'sha512', 'md5' ], + ikeVersions: [ + 'ike', + 'ikev1', + 'ikev2' + ], DHGroups: { '': 'None', 'Group 2': 'modp1024', @@ -317,7 +350,9 @@ export default { dpd: values.dpd, forceencap: values.forceencap, ikepolicy: ikepolicy, - esppolicy: esppolicy + esppolicy: esppolicy, + splitconnections: values.splitconnections, + ikeversion: values.ikeversion }).then(response => { this.$store.dispatch('AddAsyncJob', { title: this.$t('message.add.vpn.customer.gateway'), From 40c53fdc937235b839c629367d192ce9fe58fbda Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 22 Apr 2021 12:16:50 +0200 Subject: [PATCH 2/5] basic/wrapper type guard --- .../api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index cb8fb9ceae42..c7ce4e50c919 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -147,7 +147,7 @@ public Boolean getDpd() { public Boolean getEncap() { return encap; } public boolean getSplitConnections() { - return splitConnections; + return null == splitConnections ? false : splitConnections; } public String getIkeVersion() { From 0ea10c41f6ddf8a4ca4ffdbf1cda69713db08f42 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 26 Apr 2021 13:46:50 +0530 Subject: [PATCH 3/5] send ikeversion at creation of vpn customer gateway --- ui/src/config/section/network.js | 7 ++++++- ui/src/views/network/CreateVpnCustomerGateway.vue | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 79dd2a97429b..4076509ad211 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -611,7 +611,12 @@ export default { label: 'label.edit', docHelp: 'adminguide/networking_and_traffic.html#updating-and-removing-a-vpn-customer-gateway', dataView: true, - args: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap'] + args: ['name', 'gateway', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'ikelifetime', 'ikeversion', 'esppolicy', 'esplifetime', 'dpd', 'splitconnections', 'forceencap'], + mapping: { + ikeversion: { + options: ['ike', 'ikev1', 'ikev2'] + } + } }, { api: 'deleteVpnCustomerGateway', diff --git a/ui/src/views/network/CreateVpnCustomerGateway.vue b/ui/src/views/network/CreateVpnCustomerGateway.vue index 2997915325b5..8daacb3144b9 100644 --- a/ui/src/views/network/CreateVpnCustomerGateway.vue +++ b/ui/src/views/network/CreateVpnCustomerGateway.vue @@ -111,11 +111,12 @@ + ]" + @change="val => { ikeversion = val }"> {{ vers }} @@ -231,7 +232,7 @@ }, ]"/> - + {{ $t('label.splitconnections') }} @@ -313,7 +314,8 @@ export default { 'Group 17': 'modp6144', 'Group 18': 'modp8192' }, - ikeDhGroupInitialValue: 'Group 5(modp1536)' + ikeDhGroupInitialValue: 'Group 5(modp1536)', + ikeversion: 'ike' } }, beforeCreate () { From e537cb249c2ac26f51b7ae050d55d0ff16aa7ccf Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 26 Apr 2021 17:48:14 +0530 Subject: [PATCH 4/5] Update API param description + prevent reset of ike version if not selected during update --- .../command/user/vpn/CreateVpnCustomerGatewayCmd.java | 3 ++- .../command/user/vpn/UpdateVpnCustomerGatewayCmd.java | 3 ++- .../com/cloud/network/vpn/Site2SiteVpnManagerImpl.java | 10 +++------- ui/src/views/network/CreateVpnCustomerGateway.vue | 8 +++++++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java index f99ee54c695f..df7295b9dbf3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java @@ -95,7 +95,8 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.SPLIT_CONNECTIONS, type = CommandType.BOOLEAN, required = false, description = "For IKEv2, whether to split multiple right subnet cidrs into multiple connection statements.") private Boolean splitConnections; - @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. " + + "Connections marked with 'ike' will use 'ikev2' when initiating, but accept any protocol version when responding. Defaults to ike") private String ikeVersion; ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index c7ce4e50c919..f2fcc9170b7b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -97,7 +97,8 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.SPLIT_CONNECTIONS, type = CommandType.BOOLEAN, required = false, description = "For IKEv2, whether to split multiple right subnet cidrs into multiple connection statements.") private Boolean splitConnections; - @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2. Defaults to ike") + @Parameter(name = ApiConstants.IKE_VERSION, type = CommandType.STRING, required = false, description = "Which IKE Version to use, one of ike (autoselect), ikev1, or ikev2." + + "Connections marked with 'ike' will use 'ikev2' when initiating, but accept any protocol version when responding. Defaults to ike") private String ikeVersion; ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 668eb114cb66..da27b8c085de 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -480,14 +480,8 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm } Boolean splitConnections = cmd.getSplitConnections(); - if (splitConnections == null) { - splitConnections = false; - } String ikeVersion = cmd.getIkeVersion(); - if (ikeVersion == null) { - ikeVersion = "ike"; - } checkCustomerGatewayCidrList(guestCidrList); @@ -508,7 +502,9 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm gw.setDpd(dpd); gw.setEncap(encap); gw.setSplitConnections(splitConnections); - gw.setIkeVersion(ikeVersion); + if (ikeVersion != null) { + gw.setIkeVersion(ikeVersion); + } _customerGatewayDao.persist(gw); List conns = _vpnConnectionDao.listByCustomerGatewayId(id); diff --git a/ui/src/views/network/CreateVpnCustomerGateway.vue b/ui/src/views/network/CreateVpnCustomerGateway.vue index 8daacb3144b9..666bece867b4 100644 --- a/ui/src/views/network/CreateVpnCustomerGateway.vue +++ b/ui/src/views/network/CreateVpnCustomerGateway.vue @@ -108,7 +108,13 @@ - + + + {{ $t('label.ikeversion') }} + + + +