S2S VPN: CS-15642: Re-initiate the VPN connections after router reboot

Conflicts:

	server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
This commit is contained in:
Sheng Yang 2012-08-02 19:39:01 -07:00
parent 84a1a311f9
commit 6e7b4bc07b
4 changed files with 118 additions and 57 deletions

View File

@ -142,7 +142,7 @@ ipsec_tunnel_add() {
sudo echo " esp=$esppolicy" >> $vpnconffile &&
sudo echo " salifetime=${esplifetime}s" >> $vpnconffile &&
sudo echo " pfs=$pfs" >> $vpnconffile &&
sudo echo " keyingtries=3" >> $vpnconffile &&
sudo echo " keyingtries=2" >> $vpnconffile &&
sudo echo " auto=add" >> $vpnconffile &&
sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile &&
sudo chmod 0400 $vpnsecretsfile
@ -162,8 +162,8 @@ ipsec_tunnel_add() {
logger -t cloud "$(basename $0): done ipsec tunnel entry for right peer=$rightpeer right networks=$rightnets"
#20 seconds for checking if it's ready
for i in {1..4}
#5 seconds for checking if it's ready
for i in {1..5}
do
logger -t cloud "$(basename $0): checking connection status..."
/opt/cloud/bin/checks2svpn.sh $rightpeer
@ -172,7 +172,7 @@ ipsec_tunnel_add() {
then
break
fi
sleep 5
sleep 1
done
if [ $result -eq 0 ]
then

View File

@ -909,6 +909,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
}
@DB
protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) {
for (DomainRouterVO router : routers) {
List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
@ -958,26 +959,34 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
continue;
}
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
continue;
Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId());
if (lock == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + lock);
}
Site2SiteVpnConnection.State oldState = conn.getState();
Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
if (answer.isConnected(gw.getGatewayIp())) {
conn.setState(Site2SiteVpnConnection.State.Connected);
} else {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
}
_s2sVpnConnectionDao.persist(conn);
if (oldState != conn.getState()) {
String title = "Site-to-site Vpn Connection to " + gw.getName() +
" just switch from " + oldState + " to " + conn.getState();
String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() +
"(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState();
s_logger.info(context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER,
router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
try {
if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
continue;
}
Site2SiteVpnConnection.State oldState = conn.getState();
Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
if (answer.isConnected(gw.getGatewayIp())) {
conn.setState(Site2SiteVpnConnection.State.Connected);
} else {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
}
_s2sVpnConnectionDao.persist(conn);
if (oldState != conn.getState()) {
String title = "Site-to-site Vpn Connection to " + gw.getName() +
" just switch from " + oldState + " to " + conn.getState();
String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() +
"(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState();
s_logger.info(context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER,
router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
}
} finally {
_s2sVpnConnectionDao.releaseFromLockTable(lock.getId());
}
}
}
@ -2320,6 +2329,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
ConcurrentOperationException, ResourceUnavailableException {
s_logger.debug("Starting router " + router);
if (_itMgr.start(router, params, user, caller, planToDeploy) != null) {
// We don't want the failure of VPN Connection affect the status of router, so we try to make connection only after router start successfully
Long vpcId = router.getVpcId();
if (vpcId != null) {
_s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId);
}
return _routerDao.findById(router.getId());
} else {
return null;

View File

@ -11,4 +11,5 @@ public interface Site2SiteVpnManager extends Site2SiteVpnService {
void markDisconnectVpnConnByVpc(long vpcId);
List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router);
boolean deleteCustomerGatewayByAccount(long accountId);
void reconnectDisconnectedVpnByVpc(Long vpcId);
}

View File

@ -53,6 +53,7 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.JoinBuilder;
@ -240,28 +241,37 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
@Override
@DB
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!");
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) {
throw new InvalidParameterValueException("Site to site VPN connection with specified connectionId not in correct state(pending or disconnected) to process!");
}
conn.setState(State.Pending);
_vpnConnectionDao.persist(conn);
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.startSite2SiteVpn(conn);
}
if (result) {
conn.setState(State.Connected);
conn.setState(State.Pending);
_vpnConnectionDao.persist(conn);
return conn;
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.startSite2SiteVpn(conn);
}
if (result) {
conn.setState(State.Connected);
_vpnConnectionDao.persist(conn);
return conn;
}
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
} finally {
_vpnConnectionDao.releaseFromLockTable(conn.getId());
}
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
}
@Override
@ -419,24 +429,33 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
return true;
}
@DB
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
if (conn.getState() != State.Connected && conn.getState() != State.Error) {
throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(connected) to process disconnect!");
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() != State.Connected && conn.getState() != State.Error) {
throw new InvalidParameterValueException("Site to site VPN connection with specified id is not in correct state(connected) to process disconnect!");
}
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
conn.setState(State.Disconnected);
_vpnConnectionDao.persist(conn);
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.stopSite2SiteVpn(conn);
}
if (!result) {
conn.setState(State.Error);
conn.setState(State.Disconnected);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.stopSite2SiteVpn(conn);
}
if (!result) {
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
}
} finally {
_vpnConnectionDao.releaseFromLockTable(conn.getId());
}
}
@ -617,15 +636,24 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
@Override
@DB
public void markDisconnectVpnConnByVpc(long vpcId) {
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId);
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn == null) {
continue;
}
if (conn.getState() == Site2SiteVpnConnection.State.Connected) {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
_vpnConnectionDao.persist(conn);
Site2SiteVpnConnectionVO lock = _vpnConnectionDao.acquireInLockTable(conn.getId());
if (lock == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() == Site2SiteVpnConnection.State.Connected) {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
_vpnConnectionDao.persist(conn);
}
} finally {
_vpnConnectionDao.releaseFromLockTable(lock.getId());
}
}
}
@ -651,4 +679,22 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
return result;
}
@Override
public void reconnectDisconnectedVpnByVpc(Long vpcId) {
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId);
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn == null) {
continue;
}
if (conn.getState() == Site2SiteVpnConnection.State.Disconnected) {
try {
startVpnConnection(conn.getId());
} catch (ResourceUnavailableException e) {
Site2SiteCustomerGatewayVO gw = _customerGatewayDao.findById(conn.getCustomerGatewayId());
s_logger.warn("Site2SiteVpnManager: Fail to re-initiate VPN connection " + conn.getId() + " which connect to " + gw.getName());
}
}
}
}
}