Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1076,18 +1076,20 @@ public CheckRouterTask() {
@Override
protected void runInContext() {
try {
final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(null);
logger.debug("Found " + routers.size() + " routers to update status. ");

updateSite2SiteVpnConnectionState(routers);

// Site-to-site VPN connections only exist on VPC routers, so check every VPC router,
// including ones with no tier in use (no running VMs)
final List<DomainRouterVO> routers = new ArrayList<>();
List<NetworkVO> networks = new ArrayList<>();
for (Vpc vpc : _vpcDao.listAll()) {
routers.addAll(_routerDao.listByVpcId(vpc.getId()));
List<NetworkVO> vpcNetworks = _networkDao.listByVpc(vpc.getId());
if (!vpcNetworks.isEmpty()) {
networks.add(vpcNetworks.get(0));
}
}
logger.debug("Found " + routers.size() + " routers to update status. ");
updateSite2SiteVpnConnectionState(routers);

logger.debug("Found " + networks.size() + " VPC's to update Redundant State. ");
pushToUpdateQueue(networks);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,20 @@ public void testUpdateSite2SiteVpnConnectionState() throws Exception{
}
}

@Test
public void testCheckRouterTaskChecksVpnOnVpcRouterWithoutTiers() {
VpcVO vpc = Mockito.mock(VpcVO.class);
when(vpc.getId()).thenReturn(10L);
DomainRouterVO router = Mockito.mock(DomainRouterVO.class);
when(_vpcDao.listAll()).thenReturn(List.of(vpc));
when(_routerDao.listByVpcId(10L)).thenReturn(List.of(router));

virtualNetworkApplianceManagerImpl.new CheckRouterTask().runInContext();

Mockito.verify(_s2sVpnMgr).getConnectionsForRouter(router);
Mockito.verify(_routerDao, Mockito.never()).listIsolatedByHostId(null);
}

@Test
public void checkLogrotateTimerPatternTestDoNotMatchWithRegex(){
String foo = "non-sense";
Expand Down
13 changes: 13 additions & 0 deletions systemvm/debian/opt/cloud/bin/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,19 @@ def configure_ipsec(self, local_ip, obj):
ipinsubnet = '.'.join(octets)
CsHelper.execute("timeout 5 ping -c 3 %s" % ipinsubnet)

# The ping above only matches the tunnel when the router has an address in
# the local subnet. A VPC tier gets one only once a VM is deployed in it, so
# without VMs the ping leaves from the public IP and the tunnel never starts.
# The active side starts it explicitly instead. The passive side waits.
if not obj.get('passive', False):
self.start_connections(rightpeer, len(peerlistarr) if splitconnections else 1)

def start_connections(self, rightpeer, count):
for peeridx in range(0, count):
conn = 'vpn-%s' % rightpeer if peeridx == 0 else 'vpn-%s-%d' % (rightpeer, peeridx + 1)
if len(CsHelper.execute('ipsec status %s | grep ESTABLISHED' % conn)) == 0:
CsHelper.execute('timeout 20 ipsec up %s' % conn)

def convert_sec_to_min(self, val):
mins = int(val / 60)
return "%sm" % mins
Expand Down
53 changes: 53 additions & 0 deletions systemvm/test/TestCsSite2SiteVpn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with 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.

import unittest
import mock
import configure
from configure import CsSite2SiteVpn


class TestCsSite2SiteVpn(unittest.TestCase):

def setUp(self):
self.vpn = CsSite2SiteVpn.__new__(CsSite2SiteVpn)

@mock.patch('configure.CsHelper.execute')
def test_start_connections_brings_up_a_connection_that_is_not_established(self, mock_execute):
mock_execute.return_value = []
self.vpn.start_connections('10.0.0.2', 1)
mock_execute.assert_any_call('timeout 20 ipsec up vpn-10.0.0.2')

@mock.patch('configure.CsHelper.execute')
def test_start_connections_skips_a_connection_that_is_established(self, mock_execute):
mock_execute.return_value = ['vpn-10.0.0.2[1]: ESTABLISHED 5 seconds ago']
self.vpn.start_connections('10.0.0.2', 1)
for call in mock_execute.call_args_list:
self.assertNotIn('ipsec up', call[0][0])

@mock.patch('configure.CsHelper.execute')
def test_start_connections_covers_every_split_connection(self, mock_execute):
mock_execute.return_value = []
self.vpn.start_connections('10.0.0.2', 3)
ups = [call[0][0] for call in mock_execute.call_args_list if 'ipsec up' in call[0][0]]
self.assertEqual(ups, ['timeout 20 ipsec up vpn-10.0.0.2',
'timeout 20 ipsec up vpn-10.0.0.2-2',
'timeout 20 ipsec up vpn-10.0.0.2-3'])


if __name__ == '__main__':
unittest.main()
Loading