mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	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:
		
							parent
							
								
									84a1a311f9
								
							
						
					
					
						commit
						6e7b4bc07b
					
				| @ -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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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); | ||||
| } | ||||
|  | ||||
| @ -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()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user