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 "  esp=$esppolicy" >> $vpnconffile && | ||||||
|     sudo echo "  salifetime=${esplifetime}s" >> $vpnconffile && |     sudo echo "  salifetime=${esplifetime}s" >> $vpnconffile && | ||||||
|     sudo echo "  pfs=$pfs" >> $vpnconffile && |     sudo echo "  pfs=$pfs" >> $vpnconffile && | ||||||
|     sudo echo "  keyingtries=3" >> $vpnconffile && |     sudo echo "  keyingtries=2" >> $vpnconffile && | ||||||
|     sudo echo "  auto=add" >> $vpnconffile && |     sudo echo "  auto=add" >> $vpnconffile && | ||||||
|     sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile && |     sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile && | ||||||
|     sudo chmod 0400 $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" |   logger -t cloud "$(basename $0): done ipsec tunnel entry for right peer=$rightpeer right networks=$rightnets" | ||||||
| 
 | 
 | ||||||
|   #20 seconds for checking if it's ready |   #5 seconds for checking if it's ready | ||||||
|   for i in {1..4} |   for i in {1..5} | ||||||
|   do |   do | ||||||
|     logger -t cloud "$(basename $0): checking connection status..." |     logger -t cloud "$(basename $0): checking connection status..." | ||||||
|     /opt/cloud/bin/checks2svpn.sh $rightpeer |     /opt/cloud/bin/checks2svpn.sh $rightpeer | ||||||
| @ -172,7 +172,7 @@ ipsec_tunnel_add() { | |||||||
|     then |     then | ||||||
|         break |         break | ||||||
|     fi |     fi | ||||||
|     sleep 5 |     sleep 1 | ||||||
|   done |   done | ||||||
|   if [ $result -eq 0 ] |   if [ $result -eq 0 ] | ||||||
|   then |   then | ||||||
|  | |||||||
| @ -909,6 +909,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @DB | ||||||
|     protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) { |     protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) { | ||||||
|         for (DomainRouterVO router : routers) { |         for (DomainRouterVO router : routers) { | ||||||
|             List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router); |             List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router); | ||||||
| @ -958,26 +959,34 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian | |||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 for (Site2SiteVpnConnectionVO conn : conns) { |                 for (Site2SiteVpnConnectionVO conn : conns) { | ||||||
|                     if (conn.getState() != Site2SiteVpnConnection.State.Connected && |                     Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId()); | ||||||
|                             conn.getState() != Site2SiteVpnConnection.State.Disconnected) { |                     if (lock == null) { | ||||||
|                         continue; |                         throw new CloudRuntimeException("Unable to acquire lock on " + lock); | ||||||
|                     } |                     } | ||||||
|                     Site2SiteVpnConnection.State oldState = conn.getState(); |                     try { | ||||||
|                     Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId()); |                         if (conn.getState() != Site2SiteVpnConnection.State.Connected && | ||||||
|                     if (answer.isConnected(gw.getGatewayIp())) { |                                 conn.getState() != Site2SiteVpnConnection.State.Disconnected) { | ||||||
|                         conn.setState(Site2SiteVpnConnection.State.Connected); |                             continue; | ||||||
|                     } else { |                         } | ||||||
|                         conn.setState(Site2SiteVpnConnection.State.Disconnected); |                         Site2SiteVpnConnection.State oldState = conn.getState(); | ||||||
|                     } |                         Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId()); | ||||||
|                     _s2sVpnConnectionDao.persist(conn); |                         if (answer.isConnected(gw.getGatewayIp())) { | ||||||
|                     if (oldState != conn.getState()) { |                             conn.setState(Site2SiteVpnConnection.State.Connected); | ||||||
|                         String title = "Site-to-site Vpn Connection to " + gw.getName() + |                         } else { | ||||||
|                                 " just switch from " + oldState + " to " + conn.getState(); |                             conn.setState(Site2SiteVpnConnection.State.Disconnected); | ||||||
|                         String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() +  |                         } | ||||||
|                                 "(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState(); |                         _s2sVpnConnectionDao.persist(conn); | ||||||
|                         s_logger.info(context); |                         if (oldState != conn.getState()) { | ||||||
|                         _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, |                             String title = "Site-to-site Vpn Connection to " + gw.getName() + | ||||||
|                                 router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); |                                     " 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 { |     ConcurrentOperationException, ResourceUnavailableException { | ||||||
|         s_logger.debug("Starting router " + router); |         s_logger.debug("Starting router " + router); | ||||||
|         if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { |         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()); |             return _routerDao.findById(router.getId()); | ||||||
|         } else { |         } else { | ||||||
|             return null; |             return null; | ||||||
|  | |||||||
| @ -11,4 +11,5 @@ public interface Site2SiteVpnManager extends Site2SiteVpnService { | |||||||
|     void markDisconnectVpnConnByVpc(long vpcId); |     void markDisconnectVpnConnByVpc(long vpcId); | ||||||
|     List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router); |     List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router); | ||||||
|     boolean deleteCustomerGatewayByAccount(long accountId); |     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.Ternary; | ||||||
| import com.cloud.utils.component.Inject; | import com.cloud.utils.component.Inject; | ||||||
| import com.cloud.utils.component.Manager; | import com.cloud.utils.component.Manager; | ||||||
|  | import com.cloud.utils.db.DB; | ||||||
| import com.cloud.utils.db.Filter; | import com.cloud.utils.db.Filter; | ||||||
| import com.cloud.utils.db.GenericDao; | import com.cloud.utils.db.GenericDao; | ||||||
| import com.cloud.utils.db.JoinBuilder; | import com.cloud.utils.db.JoinBuilder; | ||||||
| @ -240,28 +241,37 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  |     @DB | ||||||
|     public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { |     public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { | ||||||
|         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); |         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); | ||||||
|         if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) { |         if (conn == null) { | ||||||
|             throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(pending or disconnected) to process!"); |             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); |             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); |  | ||||||
|             _vpnConnectionDao.persist(conn); |             _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 |     @Override | ||||||
| @ -419,24 +429,33 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @DB | ||||||
|     private void stopVpnConnection(Long id) throws ResourceUnavailableException { |     private void stopVpnConnection(Long id) throws ResourceUnavailableException { | ||||||
|         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); |         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); | ||||||
|         if (conn.getState() != State.Connected && conn.getState() != State.Error) { |         if (conn == null) { | ||||||
|             throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(connected) to process disconnect!"); |             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(); |             conn.setState(State.Disconnected); | ||||||
|         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); |  | ||||||
|             _vpnConnectionDao.persist(conn); |             _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 |     @Override | ||||||
|  |     @DB | ||||||
|     public void markDisconnectVpnConnByVpc(long vpcId) { |     public void markDisconnectVpnConnByVpc(long vpcId) { | ||||||
|         List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId); |         List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId); | ||||||
|         for (Site2SiteVpnConnectionVO conn : conns) { |         for (Site2SiteVpnConnectionVO conn : conns) { | ||||||
|             if (conn == null) { |             if (conn == null) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             if (conn.getState() == Site2SiteVpnConnection.State.Connected) { |             Site2SiteVpnConnectionVO lock = _vpnConnectionDao.acquireInLockTable(conn.getId()); | ||||||
|                 conn.setState(Site2SiteVpnConnection.State.Disconnected); |             if (lock == null) { | ||||||
|                 _vpnConnectionDao.persist(conn); |                 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; |         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