diff --git a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java index a0d1717db82..6e438f27fda 100644 --- a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java +++ b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -3,10 +3,15 @@ package com.cloud.agent.api.routing; public class Site2SiteVpnCfgCommand extends NetworkElementCommand { private boolean create; - private String gatewayIp; - private String guestIp; - private String guestCidr; + private String localPublicIp; + private String localGuestCidr; + private String localPublicGateway; + private String peerGatewayIp; + private String peerGuestCidrList; private String ipsecPsk; + private String ikePolicy; + private String espPolicy; + private long lifetime; @Override public boolean executeInSequence() { @@ -17,12 +22,18 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { this.create = false; } - public Site2SiteVpnCfgCommand (boolean create, String gatewayIp, String guestIp, String guestCidr, String ipsecPsk) { + public Site2SiteVpnCfgCommand (boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, + String peerGatewayIp, String peerGuestCidrList, String ikePolicy, String espPolicy, long lifetime, String ipsecPsk) { this.create = create; - this.gatewayIp = gatewayIp; - this.guestIp = guestIp; - this.guestCidr = guestCidr; + this.setLocalPublicIp(localPublicIp); + this.setLocalPublicGateway(localPublicGateway); + this.setLocalGuestCidr(localGuestCidr); + this.setPeerGatewayIp(peerGatewayIp); + this.setPeerGuestCidrList(peerGuestCidrList); this.ipsecPsk = ipsecPsk; + this.ikePolicy = ikePolicy; + this.espPolicy = espPolicy; + this.lifetime = lifetime; } public boolean isCreate() { @@ -33,30 +44,6 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { this.create = create; } - public String getGatewayIp() { - return gatewayIp; - } - - public void setGatewayIp(String gatewayIp) { - this.gatewayIp = gatewayIp; - } - - public String getGuestIp() { - return guestIp; - } - - public void setGuestIp(String guestIp) { - this.guestIp = guestIp; - } - - public String getGuestCidr() { - return guestCidr; - } - - public void setGuestCidr(String guestCidr) { - this.guestCidr = guestCidr; - } - public String getIpsecPsk() { return ipsecPsk; } @@ -64,6 +51,68 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { public void setIpsecPsk(String ipsecPsk) { this.ipsecPsk = ipsecPsk; } - - + + public String getIkePolicy() { + return ikePolicy; + } + + public void setIkePolicy(String ikePolicy) { + this.ikePolicy = ikePolicy; + } + + public String getEspPolicy() { + return espPolicy; + } + + public void setEspPolicy(String espPolicy) { + this.espPolicy = espPolicy; + } + + public long getLifetime() { + return lifetime; + } + + public void setLifetime(long lifetime) { + this.lifetime = lifetime; + } + + public String getLocalPublicIp() { + return localPublicIp; + } + + public void setLocalPublicIp(String localPublicIp) { + this.localPublicIp = localPublicIp; + } + + public String getLocalGuestCidr() { + return localGuestCidr; + } + + public void setLocalGuestCidr(String localGuestCidr) { + this.localGuestCidr = localGuestCidr; + } + + public String getLocalPublicGateway() { + return localPublicGateway; + } + + public void setLocalPublicGateway(String localPublicGateway) { + this.localPublicGateway = localPublicGateway; + } + + public String getPeerGatewayIp() { + return peerGatewayIp; + } + + public void setPeerGatewayIp(String peerGatewayIp) { + this.peerGatewayIp = peerGatewayIp; + } + + public String getPeerGuestCidrList() { + return peerGuestCidrList; + } + + public void setPeerGuestCidrList(String peerGuestCidrList) { + this.peerGuestCidrList = peerGuestCidrList; + } } diff --git a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java index 8826283944e..0dc4a5ad190 100644 --- a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java +++ b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java @@ -5,9 +5,7 @@ import com.cloud.network.Network; import com.cloud.network.Site2SiteVpnConnection; public interface Site2SiteVpnServiceProvider extends NetworkElement { - boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException; + boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException; - boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException; - - IpDeployer getIpDeployer(Network network); + boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java index 4ad4760a455..f3f188d430c 100644 --- a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java +++ b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java @@ -40,8 +40,8 @@ public interface Site2SiteVpnService { Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException; Site2SiteCustomerGateway deleteCustomerGateway(DeleteVpnCustomerGatewayCmd deleteVpnCustomerGatewayCmd); Site2SiteVpnGateway deleteVpnGateway(DeleteVpnGatewayCmd deleteVpnGatewayCmd); - Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd); - Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd); + Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd) throws ResourceUnavailableException; + Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd) throws ResourceUnavailableException; List searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd); List searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd); List searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd); diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 54ae0f6471d..656ca37be5e 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -57,6 +57,7 @@ import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.IpAddressTO; @@ -132,6 +133,8 @@ public class VirtualRoutingResource implements Manager { return execute((VpnUsersCfgCommand)cmd); } else if (cmd instanceof GetDomRVersionCmd) { return execute((GetDomRVersionCmd)cmd); + } else if (cmd instanceof Site2SiteVpnCfgCommand) { + return execute((Site2SiteVpnCfgCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); @@ -540,6 +543,42 @@ public class VirtualRoutingResource implements Manager { protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); } + + protected Answer execute(Site2SiteVpnCfgCommand cmd) { + String args; + if (cmd.isCreate()) { + args = "-A"; + args += " -l "; + args += cmd.getLocalPublicIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -g "; + args += cmd.getLocalPublicGateway(); + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + args += " -e "; + args += cmd.getEspPolicy(); + args += " -i "; + args += cmd.getIkePolicy(); + args += " -t "; + args += Long.toString(cmd.getLifetime()); + args += " -s "; + args += cmd.getIpsecPsk(); + } else { + args = "-D"; + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + } + String result = routerProxy("ipsectunnel", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + if (result != null) { + return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); + } + return new Answer(cmd); + } private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { String result = null; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 835c8929e7e..bbd456fcf3c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -158,6 +158,7 @@ import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticRouteAnswer; import com.cloud.agent.api.routing.SetStaticRouteCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; @@ -546,6 +547,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((SetPortForwardingRulesVpcCommand) cmd); } else if (clazz == SetStaticRouteCommand.class) { return execute((SetStaticRouteCommand) cmd); + } else if (clazz == Site2SiteVpnCfgCommand.class) { + return execute((Site2SiteVpnCfgCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -7161,7 +7164,43 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return null; } - + protected Answer execute(Site2SiteVpnCfgCommand cmd) { + Connection conn = getConnection(); + String args = "ipsectunnel.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + if (cmd.isCreate()) { + args += " -A"; + args += " -l "; + args += cmd.getLocalPublicIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -g "; + args += cmd.getLocalPublicGateway(); + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + args += " -e "; + args += cmd.getEspPolicy(); + args += " -i "; + args += cmd.getIkePolicy(); + args += " -t "; + args += Long.toString(cmd.getLifetime()); + args += " -s "; + args += cmd.getIpsecPsk(); + } else { + args += " -D"; + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + } + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + return new Answer(cmd, false, "Configure site to site VPN failed! "); + } + return new Answer(cmd); + } + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { //FIXME - add implementation here return null; diff --git a/scripts/network/domr/s2s_vpn.sh b/scripts/network/domr/s2s_vpn.sh new file mode 100755 index 00000000000..0bdccc4f7b7 --- /dev/null +++ b/scripts/network/domr/s2s_vpn.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + +# @VERSION@ + +cert="/root/.ssh/id_rsa.cloud" +domr=$1 +shift +ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/ipsectunnel.sh $*" >/dev/null + +exit $? diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index efa5cbaf575..05d8a99c02c 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -44,7 +44,6 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.VpnUser; @@ -88,7 +87,7 @@ import com.google.gson.Gson; @Local(value = NetworkElement.class) public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, - LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, Site2SiteVpnServiceProvider, IpDeployer { + LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); protected static final Map> capabilities = setCapabilities(); @@ -586,9 +585,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl capabilities.put(Service.StaticNat, null); capabilities.put(Service.PortForwarding, null); - Map s2sVpnCapabilities = new HashMap(); - s2sVpnCapabilities.put(Capability.SupportedSite2SiteVpnTypes, "ipsec"); - return capabilities; } @@ -880,46 +876,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl public IpDeployer getIpDeployer(Network network) { return this; } - + protected VirtualRouterProviderType getVirtualRouterProvider() { return VirtualRouterProviderType.VirtualRouter; } - - @Override - public boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException { - if (!canHandle(network, Service.Site2SiteVpn)) { - return false; - } - - List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); - return true; - } - - if (!_routerMgr.startSite2SiteVpn(network, conn, routers)) { - throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId()); - } - - return true; - } - - @Override - public boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException { - if (!canHandle(network, Service.Site2SiteVpn)) { - return false; - } - - List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); - return true; - } - - if (!_routerMgr.stopSite2SiteVpn(network, conn, routers)) { - throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId()); - } - - return true; - } } diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index c5e2efdee98..1ad48217dc2 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -28,6 +28,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; @@ -35,6 +36,12 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkService; import com.cloud.network.PublicIpAddress; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; @@ -59,7 +66,7 @@ import com.cloud.vm.VirtualMachineProfile; * @author Alena Prokharchyk */ @Local(value = NetworkElement.class) -public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, NetworkACLServiceProvider{ +public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, Site2SiteVpnServiceProvider, NetworkACLServiceProvider{ private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class); @Inject NetworkService _ntwkService; @@ -67,6 +74,14 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc VpcManager _vpcMgr; @Inject VpcVirtualNetworkApplianceManager _vpcRouterMgr; + @Inject + Site2SiteCustomerGatewayDao _customerGatewayDao; + @Inject + Site2SiteVpnGatewayDao _vpnGatewayDao; + @Inject + Site2SiteVpnConnectionDao _vpnConnectionDao; + @Inject + IPAddressDao _ipAddressDao; private static final Map> capabilities = setCapabilities(); @@ -419,4 +434,61 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc return true; } } + + public boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + + /* + if (!canHandle(network, Service.Vpn)) { + return false; + } + */ + + Map vpnCapabilities = capabilities.get(Service.Vpn); + if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) { + return false; + } + + List routers = _vpcMgr.getVpcRouters(ip.getVpcId()); + if (routers == null || routers.size() != 1) { + s_logger.debug("Cannot enable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId()); + return true; + } + + if (!_vpcRouterMgr.startSite2SiteVpn(conn, routers.get(0))) { + throw new CloudRuntimeException("Failed to apply site-to-site VPN in VPC " + ip.getVpcId()); + } + + return true; + } + + @Override + public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + + /* + if (!canHandle(network, Service.Vpn)) { + return false; + } + */ + + Map vpnCapabilities = capabilities.get(Service.Vpn); + if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) { + return false; + } + + List routers = _vpcMgr.getVpcRouters(ip.getVpcId()); + if (routers == null || routers.size() != 1) { + s_logger.debug("Cannot disable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId()); + return true; + } + + if (!_vpcRouterMgr.stopSite2SiteVpn(conn, routers.get(0))) { + throw new CloudRuntimeException("Failed to apply site-to-site VPN in VPC " + ip.getVpcId()); + } + + return true; + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 6861bf742ba..b2c1cd02df1 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -94,8 +94,4 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; - - boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List routers) throws ResourceUnavailableException; - - boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List routers) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index a83a70711bd..2e5481b45ad 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3207,37 +3207,4 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); } - - @Override - public boolean startSite2SiteVpn(Network network, final Site2SiteVpnConnection conn, List routers) throws ResourceUnavailableException { - return applyRules(network, routers, "site2site vpn", false, null, false, new RuleApplier() { - @Override - public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - return applySite2SiteVpn(router, conn); - } - }); - } - - protected boolean applySite2SiteVpn(VirtualRouter router, Site2SiteVpnConnection conn) throws ResourceUnavailableException { - Commands cmds = new Commands(OnError.Continue); - createApplySite2SiteVpnCommands(conn, router, cmds); - return sendCommandsToRouter(router, cmds); - } - - private void createApplySite2SiteVpnCommands(Site2SiteVpnConnection conn, VirtualRouter router, Commands cmds) { - Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId()); - String gatewayIp = gw.getGatewayIp(); - String guestIp = gw.getGuestIp(); - String guestCidr = gw.getGuestCidr(); - String ipsecPsk = gw.getIpsecPsk(); - - Site2SiteVpnCfgCommand startS2SVpnCmd = new Site2SiteVpnCfgCommand(true, gatewayIp, guestIp, guestCidr, ipsecPsk); - startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); - startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("startS2SVpn", startS2SVpnCmd); - } } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java index a17c7cfa0f3..f0a3cececd3 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -20,6 +20,7 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.rules.NetworkACL; import com.cloud.network.vpc.StaticRouteProfile; @@ -84,4 +85,19 @@ public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplian */ boolean applyStaticRoutes(List routes, List routers) throws ResourceUnavailableException; + /** + * @param conn + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException; + + /** + * @param conn + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index de6b39d3e6d..f53ae247a76 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticRouteCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NetworkACLTO; import com.cloud.agent.api.to.NicTO; @@ -59,17 +60,23 @@ import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkService; +import com.cloud.network.NetworkVO; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.firewall.NetworkACLService; import com.cloud.network.rules.NetworkACL; import com.cloud.network.vpc.NetworkACLManager; import com.cloud.network.vpc.PrivateGateway; @@ -81,6 +88,7 @@ import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.Dao.StaticRouteDao; import com.cloud.network.vpc.Dao.VpcDao; import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.network.vpn.Site2SiteVpnService; import com.cloud.user.Account; import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; @@ -92,6 +100,7 @@ import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; import com.cloud.vm.dao.VMInstanceDao; @@ -823,7 +832,9 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian createStaticRouteCommands(staticRouteProfiles, router, cmds); } - //4) REPROGRAM GUEST NETWORK + //4) REISSUE VPN CONNECTION + + //5) REPROGRAM GUEST NETWORK boolean reprogramGuestNtwks = true; if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { @@ -1007,4 +1018,45 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); cmds.addCommand(cmd); } + + @Override + public boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException { + return applySite2SiteVpn(true, router, conn); + } + + @Override + public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException { + return applySite2SiteVpn(false, router, conn); + } + + protected boolean applySite2SiteVpn(boolean isCreate, VirtualRouter router, Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplySite2SiteVpnCommands(conn, isCreate, router, cmds); + return sendCommandsToRouter(router, cmds); + } + + private void createApplySite2SiteVpnCommands(Site2SiteVpnConnection conn, boolean isCreate, VirtualRouter router, Commands cmds) { + Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId()); + Site2SiteVpnGatewayVO vpnGw = _s2sVpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + Vpc vpc = _vpcDao.findById(ip.getVpcId()); + String localPublicIp = ip.getAddress().toString(); + String localGuestCidr = vpc.getCidr(); + String localPublicGateway = _vlanDao.findById(ip.getVlanId()).getVlanGateway(); + String peerGatewayIp = gw.getGatewayIp(); + String peerGuestCidrList = gw.getGuestCidrList(); + String ipsecPsk = gw.getIpsecPsk(); + String ikePolicy = gw.getIkePolicy(); + String espPolicy = gw.getEspPolicy(); + Long lifetime = gw.getLifetime(); + + Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, + peerGatewayIp, peerGuestCidrList, ikePolicy, espPolicy, lifetime, ipsecPsk); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("applyS2SVpn", cmd); + } } diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index ef37ad0a739..bc634efaff7 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -25,25 +25,22 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; -import com.cloud.network.Network; import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkVO; import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.network.Site2SiteCustomerGatewayVO; import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Network.GuestType; import com.cloud.network.Site2SiteVpnConnection.State; import com.cloud.network.Site2SiteVpnConnectionVO; import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.Site2SiteCustomerGatewayDao; import com.cloud.network.dao.Site2SiteVpnConnectionDao; import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.vpc.Dao.VpcDao; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; @Local(value = Site2SiteVpnService.class) @@ -54,7 +51,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { @Inject Site2SiteVpnGatewayDao _vpnGatewayDao; @Inject Site2SiteVpnConnectionDao _vpnConnectionDao; @Inject NetworkManager _networkMgr; - @Inject NetworkDao _networkDao; + @Inject VpcDao _vpcDao; + @Inject IPAddressDao _ipAddressDao; String _name; @@ -83,9 +81,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { Long ipId = cmd.getPublicIpId(); IpAddress ip = _networkMgr.getIp(ipId); - Network network = _networkDao.findById(ip.getAssociatedWithNetworkId()); - if (network.getGuestType() != GuestType.Isolated) { - throw new InvalidParameterValueException("The VPN gateway cannot create with non-isolated network " + ip.getAssociatedWithNetworkId()); + if (ip.getVpcId() == null) { + throw new InvalidParameterValueException("The VPN gateway cannot create with ip not belong to VPC"); } Long domainId = ip.getDomainId(); Long accountId = ip.getAccountId(); @@ -151,6 +148,7 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { + vpnGatewayId + " already existed!"); } Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(vpnGatewayId, customerGatewayId); + conn.setState(State.Pending); _vpnConnectionDao.persist(conn); return conn; } @@ -162,12 +160,10 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(pending or disconnected) to process!"); } - Site2SiteVpnGatewayVO vpnGateway = _vpnGatewayDao.findById(conn.getVpnGatewayId()); - Network network = _networkDao.findById(vpnGateway.getNetworkId()); List elements = _networkMgr.getSite2SiteVpnElements(); boolean result = true; for (Site2SiteVpnServiceProvider element : elements) { - result = result & element.startSite2SiteVpn(network, conn); + result = result & element.startSite2SiteVpn(conn); } if (result) { @@ -175,6 +171,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { _vpnConnectionDao.persist(conn); return conn; } + conn.setState(State.Error); + _vpnConnectionDao.persist(conn); return null; } @@ -255,20 +253,51 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { } @Override - public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) { + public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUnavailableException { Long id = cmd.getId(); Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); - if (conn.getState() == State.Connected) { - //TODO disconnect it first + if (conn == null) { + throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to delete!"); } - return null; + if (conn.getState() == State.Connected) { + stopVpnConnection(id); + } + _vpnConnectionDao.remove(id); + return conn; + } + + private void stopVpnConnection(Long id) throws ResourceUnavailableException { + Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); + if (conn.getState() != State.Connected) { + throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(connected) to process disconnect!"); + } + + List elements = _networkMgr.getSite2SiteVpnElements(); + boolean result = true; + conn.setState(State.Disconnecting); + for (Site2SiteVpnServiceProvider element : elements) { + result = result & element.stopSite2SiteVpn(conn); + } + + if (result) { + conn.setState(State.Disconnected); + _vpnConnectionDao.persist(conn); + } + conn.setState(State.Error); } @Override - public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) { + public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) throws ResourceUnavailableException { Long id = cmd.getId(); Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); - return null; + if (conn == null) { + throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to reset!"); + } + if (conn.getState() == State.Connected) { + stopVpnConnection(id); + } + startVpnConnection(id); + return conn; } @Override