CS-6840: Add Site2SiteVpnServiceProvider

This commit is contained in:
Sheng Yang 2012-06-27 19:00:55 -07:00
parent 52e80e5fb0
commit 8670b703d2
9 changed files with 236 additions and 8 deletions

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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<? extends RemoteAccessVPNServiceProvider> getRemoteAccessVpnElements();
List<? extends Site2SiteVpnServiceProvider> getSite2SiteVpnElements();
PublicIpAddress getPublicIpAddress(long ipAddressId);

View File

@ -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<? extends Site2SiteVpnServiceProvider> getSite2SiteVpnElements() {
List<Site2SiteVpnServiceProvider> elements = new ArrayList<Site2SiteVpnServiceProvider>();
for (NetworkElement element : _networkElements) {
if (element instanceof Site2SiteVpnServiceProvider) {
Site2SiteVpnServiceProvider e = (Site2SiteVpnServiceProvider) element;
elements.add(e);
}
}
return elements;
}
@Override
public void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm) {
if (s_logger.isDebugEnabled()) {

View File

@ -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<Service, Map<Capability, String>> capabilities = setCapabilities();
@ -585,6 +586,9 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
capabilities.put(Service.StaticNat, null);
capabilities.put(Service.PortForwarding, null);
Map<Capability, String> s2sVpnCapabilities = new HashMap<Capability, String>();
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<DomainRouterVO> 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<DomainRouterVO> 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;
}
}

View File

@ -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<UserVm> vm, DeployDestination dest,
List<DomainRouterVO> routers) throws ResourceUnavailableException;
boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List<DomainRouterVO> routers) throws ResourceUnavailableException;
boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List<DomainRouterVO> routers) throws ResourceUnavailableException;
}

View File

@ -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<DomainRouterVO> 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);
}
}

View File

@ -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 <? extends Site2SiteVpnServiceProvider> 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<Site2SiteCustomerGateway> searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) {
// TODO Auto-generated method stub
return null;
Long id = cmd.getId();
List<Site2SiteCustomerGateway> results = new ArrayList<Site2SiteCustomerGateway>();
if (id != null) {
results.add(_customerGatewayDao.findById(cmd.getId()));
}
return results;
}
@Override
public List<Site2SiteVpnGateway> searchForVpnGateways(ListVpnGatewaysCmd cmd) {
// TODO Auto-generated method stub
return null;
Long id = cmd.getId();
List<Site2SiteVpnGateway> results = new ArrayList<Site2SiteVpnGateway>();
if (id != null) {
results.add(_vpnGatewayDao.findById(cmd.getId()));
}
return results;
}
@Override
public List<Site2SiteVpnConnection> searchForVpnConnections(ListVpnConnectionsCmd cmd) {
// TODO Auto-generated method stub
return null;
Long id = cmd.getId();
List<Site2SiteVpnConnection> results = new ArrayList<Site2SiteVpnConnection>();
if (id != null) {
results.add(_vpnConnectionDao.findById(cmd.getId()));
}
return results;
}
}