CS-6840: Add hypervisor commands for site-to-site vpn

Conflicts:

	plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
This commit is contained in:
Sheng Yang 2012-06-27 19:00:56 -07:00
parent cd9854336a
commit 8d4079d477
13 changed files with 382 additions and 141 deletions

View File

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

View File

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

View File

@ -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<Site2SiteCustomerGateway> searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd);
List<Site2SiteVpnGateway> searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd);
List<Site2SiteVpnConnection> searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd);

View File

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

View File

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

26
scripts/network/domr/s2s_vpn.sh Executable file
View File

@ -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 $?

View File

@ -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<Service, Map<Capability, String>> capabilities = setCapabilities();
@ -586,9 +585,6 @@ 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,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<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

@ -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<Service, Map<Capability, String>> 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<Capability, String> vpnCapabilities = capabilities.get(Service.Vpn);
if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) {
return false;
}
List<DomainRouterVO> 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<Capability, String> vpnCapabilities = capabilities.get(Service.Vpn);
if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) {
return false;
}
List<DomainRouterVO> 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;
}
}

View File

@ -94,8 +94,4 @@ 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

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

@ -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<StaticRouteProfile> routes, List<DomainRouterVO> 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;
}

View File

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

View File

@ -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 <? extends Site2SiteVpnServiceProvider> 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 <? extends Site2SiteVpnServiceProvider> 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