You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2012/07/03 01:40:17 UTC

[11/13] CS-6840: Add commands for site-to-site vpn

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/24c480f9/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
new file mode 100644
index 0000000..5bad27c
--- /dev/null
+++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
@@ -0,0 +1,267 @@
+package com.cloud.network.vpn;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.commands.CreateVpnConnectionCmd;
+import com.cloud.api.commands.CreateVpnCustomerGatewayCmd;
+import com.cloud.api.commands.CreateVpnGatewayCmd;
+import com.cloud.api.commands.DeleteVpnConnectionCmd;
+import com.cloud.api.commands.DeleteVpnCustomerGatewayCmd;
+import com.cloud.api.commands.DeleteVpnGatewayCmd;
+import com.cloud.api.commands.ListVpnConnectionsCmd;
+import com.cloud.api.commands.ListVpnCustomerGatewaysCmd;
+import com.cloud.api.commands.ListVpnGatewaysCmd;
+import com.cloud.api.commands.ResetVpnConnectionCmd;
+import com.cloud.api.commands.UpdateVpnCustomerGatewayCmd;
+import com.cloud.domain.Domain;
+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.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.Site2SiteCustomerGatewayDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionDao;
+import com.cloud.network.dao.Site2SiteVpnGatewayDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.net.NetUtils;
+
+@Local(value = Site2SiteVpnService.class)
+public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
+    private static final Logger s_logger = Logger.getLogger(Site2SiteVpnManagerImpl.class);
+
+    @Inject Site2SiteCustomerGatewayDao _customerGatewayDao;
+    @Inject Site2SiteVpnGatewayDao _vpnGatewayDao;
+    @Inject Site2SiteVpnConnectionDao _vpnConnectionDao;
+    @Inject NetworkManager _networkMgr;
+    @Inject NetworkDao _networkDao;
+    
+    String _name;
+    
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    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());
+	    }
+        Long domainId = ip.getDomainId();
+        Long accountId = ip.getAccountId();
+        if (_vpnGatewayDao.findByIpAddrId(ipId) != null) {
+            throw new InvalidParameterValueException("The VPN gateway with ip ID " + ipId + " already existed!");
+        }
+        Site2SiteVpnGatewayVO gw = new Site2SiteVpnGatewayVO(ipId);
+        _vpnGatewayDao.persist(gw);
+        return gw;
+    }
+
+    @Override
+    public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCmd cmd) {
+        String gatewayIp = cmd.getGatewayIp();
+        if (!NetUtils.isValidIp(gatewayIp)) {
+            throw new InvalidParameterValueException("The customer gateway ip " + gatewayIp + " is invalid!");
+        }
+        String guestCidrList = cmd.getGuestCidrList();
+        if (!NetUtils.validateGuestCidrList(guestCidrList)) {
+            throw new InvalidParameterValueException("The customer gateway guest cidr list " + guestCidrList + " is invalid guest cidr!");
+        }
+        String ipsecPsk = cmd.getIpsecPsk();
+        String ikePolicy = cmd.getIkePolicy();
+        String espPolicy = cmd.getEspPolicy();
+        if (!NetUtils.isValidS2SVpnPolicy(ikePolicy)) {
+            throw new InvalidParameterValueException("The customer gateway IKE policy" + ikePolicy + " is invalid!");
+        }
+        if (!NetUtils.isValidS2SVpnPolicy(espPolicy)) {
+            throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!");
+        }
+        Long lifetime = cmd.getLifetime();
+        if (lifetime == null) {
+            // Default value of lifetime is 1 day
+            lifetime = (long) 86400;
+        }
+        if (lifetime > 86400) {
+            throw new InvalidParameterValueException("The lifetime " + lifetime + " of vpn connection is invalid!");
+        }
+        if (_customerGatewayDao.findByGatewayIp(gatewayIp) != null) {
+            throw new InvalidParameterValueException("The customer gateway with ip " + gatewayIp + " already existed!");
+        }
+        Site2SiteCustomerGatewayVO gw = new Site2SiteCustomerGatewayVO(gatewayIp, guestCidrList, ipsecPsk,
+                ikePolicy, espPolicy, lifetime);
+        _customerGatewayDao.persist(gw);
+        return gw;
+    }
+
+    @Override
+    public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException {
+        Long customerGatewayId = cmd.getCustomerGatewayId();
+        Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId);
+        Long vpnGatewayId = cmd.getVpnGatewayId();
+        Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(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 " 
+                    + vpnGatewayId + " already existed!");
+        }
+        Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(vpnGatewayId, customerGatewayId);
+        _vpnConnectionDao.persist(conn);
+        return conn;
+    }
+
+    @Override
+    public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException {
+        Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
+        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!");
+        }
+        return null;
+    }
+
+    @Override
+    public IpAddress getVpnGatewayIp(Long vpnGatewayId) {
+        Site2SiteVpnGatewayVO gateway = _vpnGatewayDao.findById(vpnGatewayId);
+        IpAddress ip = _networkMgr.getIp(gateway.getAddrId());
+        return ip;
+    }
+
+    @Override
+    public Site2SiteCustomerGateway deleteCustomerGateway(DeleteVpnCustomerGatewayCmd cmd) {
+        Long id = cmd.getId();
+        Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(id);
+        if (customerGateway == null) {
+            throw new InvalidParameterValueException("Fail to find customer gateway with " + id + " !");
+        }
+        _customerGatewayDao.remove(id);
+        return customerGateway;
+    }
+
+    @Override
+    public Site2SiteVpnGateway deleteVpnGateway(DeleteVpnGatewayCmd cmd) {
+        Long id = cmd.getId();
+        Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(id);
+        if (vpnGateway == null) {
+            throw new InvalidParameterValueException("Fail to find vpn gateway with " + id + " !");
+        }
+        _vpnGatewayDao.remove(id);
+        return vpnGateway;
+    }
+
+    @Override
+    public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCmd cmd) {
+        Long id = cmd.getId();
+        Site2SiteCustomerGatewayVO gw = _customerGatewayDao.findById(id);
+        if (gw == null) {
+            throw new InvalidParameterValueException("Find to find customer gateway with id " + id);
+        }
+        Site2SiteVpnConnection conn = _vpnConnectionDao.findByCustomerGatewayId(id);
+        if (conn != null && (conn.getState() != State.Disconnected || conn.getState() != State.Error)) {
+            throw new InvalidParameterValueException("Unable to update customer gateway because there is the correlate VPN connection " + conn.getId()
+                    + " still active!");
+        }
+        String gatewayIp = cmd.getGatewayIp();
+        if (!NetUtils.isValidIp(gatewayIp)) {
+            throw new InvalidParameterValueException("The customer gateway ip " + gatewayIp + " is invalid!");
+        }
+        String guestCidrList = cmd.getGuestCidrList();
+        if (!NetUtils.validateGuestCidrList(guestCidrList)) {
+            throw new InvalidParameterValueException("The customer gateway guest cidr list " + guestCidrList + " contains invalid guest cidr!");
+        }
+        String ipsecPsk = cmd.getIpsecPsk();
+        String ikePolicy = cmd.getIkePolicy();
+        String espPolicy = cmd.getEspPolicy();
+        if (!NetUtils.isValidS2SVpnPolicy(ikePolicy)) {
+            throw new InvalidParameterValueException("The customer gateway IKE policy" + ikePolicy + " is invalid!");
+        }
+        if (!NetUtils.isValidS2SVpnPolicy(espPolicy)) {
+            throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!");
+        }
+        Long lifetime = cmd.getLifetime();
+        if (lifetime == null) {
+            // Default value of lifetime is 1 day
+            lifetime = (long) 86400;
+        }
+        if (lifetime > 86400) {
+            throw new InvalidParameterValueException("The lifetime " + lifetime + " of vpn connection is invalid!");
+        }
+        gw.setGatewayIp(gatewayIp);
+        gw.setGuestCidrList(guestCidrList);
+        gw.setIkePolicy(ikePolicy);
+        gw.setEspPolicy(espPolicy);
+        gw.setIpsecPsk(ipsecPsk);
+        gw.setLifetime(lifetime);
+        _customerGatewayDao.persist(gw);
+        return gw;
+    }
+
+    @Override
+    public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) {
+        Long id = cmd.getId();
+        Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
+        if (conn.getState() == State.Connected) {
+            //TODO disconnect it first
+        }
+        return null;
+    }
+
+    @Override
+    public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) {
+        Long id = cmd.getId();
+        Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
+        return null;
+    }
+
+    @Override
+    public List<Site2SiteCustomerGateway> searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<Site2SiteVpnGateway> searchForVpnGateways(ListVpnGatewaysCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<Site2SiteVpnConnection> searchForVpnConnections(ListVpnConnectionsCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/24c480f9/utils/src/com/cloud/utils/net/NetUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java
index 0d3879d..f33fe4a 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -1062,4 +1062,43 @@ public class NetUtils {
         return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift));
     }
 
+    public static boolean isValidS2SVpnPolicy(String policys) {
+        if (policys == null || policys.isEmpty()) {
+            return false;
+        }
+        for (String policy : policys.split(",")) {
+            if (policy.isEmpty()) {
+                return false;
+            }
+            String cipherHash = policy.split(";")[0];
+            if (cipherHash.isEmpty()) {
+                return false;
+            }
+            String pfsGroup = null;
+            if (!policy.equals(cipherHash)) {
+                pfsGroup = policy.split(";")[1];
+            }
+            String cipher = cipherHash.split("-")[0];
+            String hash = cipherHash.split("-")[1];
+            if (!cipher.matches("des|3des|aes|aes128|aes256")) {
+                return false;
+            }
+            if (!hash.matches("md5|sha1")) {
+                return false;
+            }
+            if (pfsGroup != null && !pfsGroup.matches("modp768|modp1024|modp2048")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean validateGuestCidrList(String guestCidrList) {
+        for (String guestCidr : guestCidrList.split(";")) {
+            if (!validateGuestCidr(guestCidr)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/24c480f9/utils/test/com/cloud/utils/net/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java
index 345f1d9..5e387bc 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -52,4 +52,17 @@ public class NetUtilsTest extends TestCase {
         ip = NetUtils.getRandomIpFromCidr(cidr, 30, avoid);
         assertEquals("This should be -1 because we ran out of ip addresses: " + ip, ip, -1);
     }
+
+    public void testVpnPolicy() {
+        assertTrue(NetUtils.isValidS2SVpnPolicy("aes-sha1"));
+        assertTrue(NetUtils.isValidS2SVpnPolicy("des-md5;modp768"));
+        assertTrue(NetUtils.isValidS2SVpnPolicy("des-md5;modp768,aes-sha1;modp2048"));
+        assertTrue(NetUtils.isValidS2SVpnPolicy("3des-sha1,aes-sha1;modp2048"));
+        assertTrue(NetUtils.isValidS2SVpnPolicy("3des-sha1,aes-sha1"));
+        assertFalse(NetUtils.isValidS2SVpnPolicy("abc-123,ase-sha1"));
+        assertFalse(NetUtils.isValidS2SVpnPolicy("de-sh,aes-sha1"));
+        assertFalse(NetUtils.isValidS2SVpnPolicy(""));
+        assertFalse(NetUtils.isValidS2SVpnPolicy(";modp2048"));
+        assertFalse(NetUtils.isValidS2SVpnPolicy(",aes;modp2048,,,"));
+    }
 }