mirror of https://github.com/apache/cloudstack.git
S2S VPN: CS-15642: Re-initiate the VPN connections after router reboot
This commit is contained in:
parent
da9bd84e09
commit
7779097653
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -900,6 +900,7 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) {
|
||||
for (DomainRouterVO router : routers) {
|
||||
List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
|
||||
|
|
@ -949,26 +950,34 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
|
|||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2311,6 +2320,11 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import com.cloud.utils.IdentityProxy;
|
|||
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;
|
||||
|
|
@ -251,30 +252,39 @@ 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) {
|
||||
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
|
||||
idList.add(new IdentityProxy(conn, id, "connectionId"));
|
||||
throw new InvalidParameterValueException("Site to site VPN connection with specified connectionId not in correct state(pending or disconnected) to process!", idList);
|
||||
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) {
|
||||
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
|
||||
idList.add(new IdentityProxy(conn, id, "connectionId"));
|
||||
throw new InvalidParameterValueException("Site to site VPN connection with specified connectionId not in correct state(pending or disconnected) to process!", idList);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -439,26 +449,35 @@ 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) {
|
||||
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
|
||||
idList.add(new IdentityProxy(conn, id, "vpnConnectionId"));
|
||||
throw new InvalidParameterValueException("Site to site VPN connection with specified id is not in correct state(connected) to process disconnect!", idList);
|
||||
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) {
|
||||
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
|
||||
idList.add(new IdentityProxy(conn, id, "vpnConnectionId"));
|
||||
throw new InvalidParameterValueException("Site to site VPN connection with specified id is not in correct state(connected) to process disconnect!", idList);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -641,15 +660,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -675,4 +703,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…
Reference in New Issue