diff --git a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java new file mode 100644 index 00000000000..a0d1717db82 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -0,0 +1,69 @@ +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 ipsecPsk; + + @Override + public boolean executeInSequence() { + return true; + } + + public Site2SiteVpnCfgCommand () { + this.create = false; + } + + public Site2SiteVpnCfgCommand (boolean create, String gatewayIp, String guestIp, String guestCidr, String ipsecPsk) { + this.create = create; + this.gatewayIp = gatewayIp; + this.guestIp = guestIp; + this.guestCidr = guestCidr; + this.ipsecPsk = ipsecPsk; + } + + public boolean isCreate() { + return create; + } + + public void setCreate(boolean create) { + 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; + } + + public void setIpsecPsk(String ipsecPsk) { + this.ipsecPsk = ipsecPsk; + } + + +} diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 236a5a84e37..17ea4e72c61 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -162,7 +162,6 @@ public interface Network extends ControlledEntity { public static final Capability ElasticLb = new Capability("ElasticLb"); public static final Capability FirewallType = new Capability("FirewallType"); - private String name; public Capability(String name) { diff --git a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java new file mode 100644 index 00000000000..8826283944e --- /dev/null +++ b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java @@ -0,0 +1,13 @@ +package com.cloud.network.element; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Site2SiteVpnConnection; + +public interface Site2SiteVpnServiceProvider extends NetworkElement { + boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException; + + boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException; + + IpDeployer getIpDeployer(Network network); +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index a41eeeb423b..65d35da25ec 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -39,6 +39,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; +import com.cloud.network.element.Site2SiteVpnServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; @@ -136,6 +137,8 @@ public interface NetworkManager extends NetworkService { public boolean validateRule(FirewallRule rule); List getRemoteAccessVpnElements(); + + List getSite2SiteVpnElements(); PublicIpAddress getPublicIpAddress(long ipAddressId); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 3899ec6d322..f5d51ed6f72 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -130,6 +130,7 @@ import com.cloud.network.element.NetworkACLServiceProvider; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.RemoteAccessVPNServiceProvider; +import com.cloud.network.element.Site2SiteVpnServiceProvider; import com.cloud.network.element.SourceNatServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; @@ -737,9 +738,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } purposes.add(Purpose.StaticNat); } + //TODO Need to check site 2 site vpn ip assignment if (purposes == null || purposes.isEmpty()) { // since no active rules are there check if any rules are applied on the public IP but are in // revoking state + purposes = getPublicIpPurposeInRules(ip, true, includingFirewall); if (ip.isOneToOneNat()) { if (purposes == null) { @@ -2451,6 +2454,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return elements; } + @Override + public List getSite2SiteVpnElements() { + List elements = new ArrayList(); + for (NetworkElement element : _networkElements) { + if (element instanceof Site2SiteVpnServiceProvider) { + Site2SiteVpnServiceProvider e = (Site2SiteVpnServiceProvider) element; + elements.add(e); + } + } + + return elements; + } + @Override public void cleanupNics(VirtualMachineProfile vm) { if (s_logger.isDebugEnabled()) { diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index d0b90462316..efa5cbaf575 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -44,6 +44,7 @@ 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; @@ -87,7 +88,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, IpDeployer { + LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, Site2SiteVpnServiceProvider, IpDeployer { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); protected static final Map> capabilities = setCapabilities(); @@ -585,6 +586,9 @@ 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,4 +884,42 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl 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/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 56ceac1309c..6861bf742ba 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -22,6 +22,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VpnUser; import com.cloud.network.rules.FirewallRule; @@ -94,4 +95,7 @@ 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 dbaa817b8d0..7bde4d2c995 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -63,6 +63,7 @@ import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; 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.FirewallRuleTO; @@ -128,6 +129,9 @@ 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.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.SshKeysDistriMonitor; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VirtualRouterProvider; @@ -142,6 +146,9 @@ import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.lb.LoadBalancingRule; @@ -305,6 +312,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian VirtualRouterProviderDao _vrProviderDao; @Inject ManagementServerHostDao _msHostDao; + @Inject + Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; + @Inject + Site2SiteVpnGatewayDao _s2sVpnGatewayDao; + @Inject + Site2SiteVpnConnectionDao _s2sVpnConnectionDao; int _routerRamSize; int _routerCpuMHz; @@ -3197,4 +3210,37 @@ 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/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 5bad27cb28e..ef37ad0a739 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -1,5 +1,6 @@ package com.cloud.network.vpn; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -26,6 +27,7 @@ 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; @@ -38,8 +40,10 @@ import com.cloud.network.dao.NetworkDao; 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.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) @@ -133,8 +137,14 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException { Long customerGatewayId = cmd.getCustomerGatewayId(); Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId); + if (customerGateway == null) { + throw new InvalidParameterValueException("Unable to found specified Site to Site VPN customer gateway " + customerGatewayId + " !"); + } Long vpnGatewayId = cmd.getVpnGatewayId(); Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId); + if (vpnGateway == null) { + throw new InvalidParameterValueException("Unable to found specified Site to Site VPN gateway " + vpnGatewayId + " !"); + } if (_vpnConnectionDao.findByCustomerGatewayId(customerGatewayId) != null || _vpnConnectionDao.findByVpnGatewayId(vpnGatewayId) != null) { throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " or vpn gateway id " @@ -151,6 +161,20 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) { 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); + } + + if (result) { + conn.setState(State.Connected); + _vpnConnectionDao.persist(conn); + return conn; + } return null; } @@ -249,19 +273,31 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { @Override public List searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) { - // TODO Auto-generated method stub - return null; + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_customerGatewayDao.findById(cmd.getId())); + } + return results; } @Override public List searchForVpnGateways(ListVpnGatewaysCmd cmd) { - // TODO Auto-generated method stub - return null; + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_vpnGatewayDao.findById(cmd.getId())); + } + return results; } @Override public List searchForVpnConnections(ListVpnConnectionsCmd cmd) { - // TODO Auto-generated method stub - return null; + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_vpnConnectionDao.findById(cmd.getId())); + } + return results; } }