Exemple #1
0
def _proxy_request(request: 'flask.Request', destination: Server, verify=False) -> requests.Response:
    url = destination.url() + request.full_path
    req_data = request.get_json()

    if request.path == '/ping':
        server_data = {'id': str(g.server.id), 'name': g.server.name,
                       'time': get_now().strftime(defaults.DATETIME_FORMAT)}
        if req_data:
            if 'servers' not in req_data:
                req_data['servers'] = {}
            req_data['servers'].update({len(req_data['servers']) + 1: server_data})
        else:
            req_data = dict(servers={1: server_data})
    kwargs = {
        'json': req_data,
        'allow_redirects': False
    }

    headers = {key.lower(): value for key, value in request.headers.items()}

    # Let requests reset the host for us.
    if 'host' in headers:
        del headers['host']

    headers['d-source'] = headers.get('d-source', '') + ':' + str(g.server.id)

    kwargs['headers'] = headers

    cookies = request.cookies

    kwargs['cookies'] = cookies

    return requests.request(request.method, url, verify=verify, **kwargs)
Exemple #2
0
    def test_url(self, mock_url, mock_check_host):
        self.set_servers_and_routes()

        mock_check_host.return_value = True
        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}',
                         self.n1.url())
        self.assertEqual(f'https://n2_dns:{defaults.DEFAULT_PORT}',
                         self.n2.url())
        self.assertEqual(f'https://n3:8000', self.n3.url())
        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}',
                         self.r1.url())
        self.assertEqual(f'https://n2_dns:{defaults.DEFAULT_PORT}',
                         self.r2.url())

        mock_url.return_value = '/'

        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}/',
                         self.n1.url('api'))

        mock_url.assert_called_once_with('api')

        me = Server(name='me',
                    gates=[('127.0.0.1', 5), ('192.168.1.2', 2)],
                    me=True)
        self.assertEqual(f'https://127.0.0.1:5/', me.url('api'))

        with mock.patch('dimensigon.domain.entities.server.current_app'
                        ) as mock_current_app:
            type(mock_current_app.dm.config).http_config = mock.PropertyMock(
                return_value={'keyfile': 'x'})
            me = Server(name='me', gates=[('192.168.1.2', 2)], me=True)
            self.assertEqual(f'http://192.168.1.2:2/', me.url('api'))

        s = Server('test', port=8000)
        with self.assertRaises(errors.UnreachableDestination):
            s.url()
    def test_upgrade_catalog_catalog_mismatch(self, mock_lock, mock_entities):
        mock_lock.return_value.__enter__.return_value = 'applicant'
        mock_entities.return_value = [('ActionTemplate', ActionTemplate),
                                      ('Server', Server)]

        s = Server('server',
                   last_modified_at=dt.datetime(2019,
                                                4,
                                                1,
                                                tzinfo=dt.timezone.utc),
                   port=8000)
        Route(s, cost=0)

        at1 = ActionTemplate(id='aaaaaaaa-1234-5678-1234-56781234aaa1',
                             name='mkdir',
                             version=1,
                             action_type=ActionType.SHELL,
                             code='mkdir {dir}',
                             expected_output=None,
                             expected_rc=None,
                             system_kwargs={},
                             last_modified_at=dt.datetime(
                                 2019, 4, 1, tzinfo=dt.timezone.utc))

        at2 = ActionTemplate(id='aaaaaaaa-1234-5678-1234-56781234aaa2',
                             name='rmdir',
                             version=1,
                             action_type=ActionType.SHELL,
                             code='rmdir {dir}',
                             expected_output=None,
                             expected_rc=None,
                             system_kwargs={},
                             last_modified_at=dt.datetime(
                                 2019, 4, 2, tzinfo=dt.timezone.utc))

        responses.add(
            method='GET',
            url=re.compile('^' + s.url(
                'api_1_0.catalog', data_mark='12345').replace('12345', '')),
            json={"ActionTemplate": [at1.to_json(),
                                     at2.to_json()]})

        with self.assertRaises(errors.CatalogMismatch):
            upgrade_catalog_from_server(s)
    def test_upgrade_catalog_no_data(self, mock_lock, mock_entities):
        mock_lock.return_value.__enter__.return_value = 'applicant'
        mock_entities.return_value = [('ActionTemplate', ActionTemplate)]

        s = Server('server',
                   last_modified_at=dt.datetime(2019,
                                                4,
                                                1,
                                                tzinfo=dt.timezone.utc))
        g = Gate(server=s, port=80)
        Route(s, cost=0)

        responses.add(
            method='GET',
            url=re.compile('^' + s.url(
                'api_1_0.catalog', data_mark='12345').replace('12345', '')),
            json={"ActionTemplate": []})

        upgrade_catalog_from_server(s)

        atl = [at.to_json() for at in ActionTemplate.query.all()]

        self.assertEqual(0, len(atl))
Exemple #5
0
class TestLock(FlaskAppMixin, TestCase):
    def setUp(self):
        super().setUp()

        set_initial()

        self.n1 = Server("node1", port=8000)
        Route(self.n1, cost=0)
        self.n2 = Server("node2", port=8000)
        Route(self.n2, cost=0)
        db.session.add_all([self.n1, self.n2])
        db.session.commit()
        self.datemark = Catalog.max_catalog(str)

    def test_lock_no_server(self):
        with self.assertRaises(errors.NoServerToLock):
            ret = lock(Scope.ORCHESTRATION)

    @aioresponses()
    def test_lock_catalog(self, m):
        def callback_prevent(url, **kwargs):
            assert kwargs['json'] == {
                'scope': 'CATALOG',
                'datemark': self.datemark,
                'applicant': [Server.get_current().id, self.n1.id, self.n2.id]
            }
            return CallbackResult("{'message': 'Preventing lock acquired'}",
                                  status=200)

        def callback_lock(url, **kwargs):
            assert kwargs['json'] == {
                'scope':
                'CATALOG',
                'applicant': [
                    str(Server.get_current().id),
                    str(self.n1.id),
                    str(self.n2.id)
                ]
            }
            return CallbackResult("{'message': 'Locked'}", status=200)

        m.post(Server.get_current().url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n1.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n2.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(Server.get_current().url('api_1_0.locker_lock'),
               callback=callback_lock)
        m.post(self.n1.url('api_1_0.locker_lock'), callback=callback_lock)
        m.post(self.n2.url('api_1_0.locker_lock'), callback=callback_lock)

        applicant = lock(Scope.CATALOG,
                         [Server.get_current(), self.n1, self.n2],
                         identity=ROOT)

        self.assertEqual(applicant,
                         [Server.get_current().id, self.n1.id, self.n2.id])

    @aioresponses()
    def test_lock_catalog_error_on_preventing(self, m):
        def callback_prevent(url, **kwargs):
            self.assertDictEqual(
                kwargs['json'], {
                    'scope':
                    'CATALOG',
                    'applicant': [
                        str(Server.get_current().id),
                        str(self.n1.id),
                        str(self.n2.id)
                    ]
                })
            return CallbackResult("{'message': 'Preventing lock acquired'}",
                                  status=200)

        def callback_unlock(url, **kwargs):
            self.assertDictEqual(
                kwargs['json'], {
                    'scope':
                    'CATALOG',
                    'action':
                    'UNLOCK',
                    'applicant': [
                        str(Server.get_current().id),
                        str(self.n1.id),
                        str(self.n2.id)
                    ]
                })
            return CallbackResult("{'message': 'UnLocked'}", status=200)

        m.post(Server.get_current().url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n1.url('api_1_0.locker_prevent'),
               exception=ClientConnectionError())
        m.post(self.n2.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(Server.get_current().url('api_1_0.locker_unlock'),
               callback=callback_unlock)
        m.post(self.n2.url('api_1_0.locker_unlock'), callback=callback_unlock)

        with self.assertRaises(errors.LockError):
            lock(Scope.CATALOG, [Server.get_current(), self.n1, self.n2],
                 identity=ROOT)

        c = Locker.query.get(Scope.CATALOG)
        self.assertEqual(State.UNLOCKED, c.state)

    @aioresponses()
    def test_lock_unreachable_network(self, m):
        def callback_prevent(url, **kwargs):
            return CallbackResult("{'message': 'Preventing lock acquired'}",
                                  status=200)

        def callback_unlock(url, **kwargs):
            return CallbackResult("{'message': 'UnLocked'}", status=200)

        m.post(self.n1.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n2.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n2.url('api_1_0.locker_unlock'), callback=callback_unlock)

        self.n1.route.cost = None
        self.n1.route.gate = None
        self.n1.route.proxy_server = None

        with self.assertRaises(errors.LockError) as e:
            lock(Scope.CATALOG, servers=[self.n1, self.n2], identity=ROOT)

        self.assertEqual(Scope.CATALOG, e.exception.scope)
        self.assertEqual(errors.LockError.action_map['P'], e.exception.action)
        self.assertDictEqual(
            errors.format_error_content(
                errors.LockError(
                    Scope.CATALOG,
                    action='P',
                    responses=[
                        Response(exception=errors.UnreachableDestination(
                            self.n1),
                                 server=self.n1)
                    ])), errors.format_error_content(e.exception))
        self.assertEqual(2, len(m.requests))
Exemple #6
0
class TestLockUnlock(TestCase):
    def setUp(self):
        """Create and configure a new app instance for each test."""
        # create the app with common test config
        self.app = create_app('test')
        self.app_context = self.app.app_context()
        self.app_context.push()
        self.client = self.app.test_client()
        self.headers = {
            "Authorization":
            f"Bearer {create_access_token('00000000-0000-0000-0000-000000000001')}"
        }

        db.create_all()
        set_initial()

        self.n1 = Server("node1", port=8000)
        Route(self.n1, cost=0)
        self.n2 = Server("node2", port=8000)
        Route(self.n2, cost=0)
        db.session.add_all([self.n1, self.n2])
        db.session.commit()
        self.datamark = Catalog.max_catalog(str)

    def tearDown(self) -> None:
        db.session.remove()
        db.drop_all()
        self.app_context.pop()

    @aioresponses()
    def test_lock_unlock_lock(self, m):
        def callback_prevent(url, **kwargs):
            self.assertDictEqual(
                kwargs['json'], {
                    'scope': 'ORCHESTRATION',
                    'datemark': self.datamark,
                    'applicant': [str(self.n1.id),
                                  str(self.n2.id)]
                })
            return CallbackResult("{'message': 'Preventing lock acquired'}",
                                  status=200)

        def callback_lock(url, **kwargs):
            self.assertDictEqual(
                kwargs['json'], {
                    'scope': 'ORCHESTRATION',
                    'applicant': [str(self.n1.id),
                                  str(self.n2.id)]
                })
            return CallbackResult("{'message': 'Locked'}", status=200)

        m.post(self.n1.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n2.url('api_1_0.locker_prevent'),
               callback=callback_prevent)
        m.post(self.n1.url('api_1_0.locker_lock'), callback=callback_lock)
        m.post(self.n2.url('api_1_0.locker_lock'), callback=callback_lock)

        ret = lock_unlock('L',
                          Scope.ORCHESTRATION, [self.n1, self.n2],
                          applicant=[str(self.n1.id),
                                     str(self.n2.id)],
                          identity=ROOT)

        self.assertIsNone(ret)

    @aioresponses()
    def test_lock_unlock_lock_with_error_on_preventing(self, m):
        m.post(self.n1.url('api_1_0.locker_prevent'),
               status=200,
               payload={'message': 'Preventing lock acquired'})
        m.post(self.n2.url('api_1_0.locker_prevent'),
               status=409,
               payload={'error': 'Unable to request for lock'})

        with self.assertRaises(errors.LockerError) as e:
            ret = lock_unlock('L',
                              Scope.ORCHESTRATION, [self.n1, self.n2],
                              identity=ROOT)

        self.assertEqual(Scope.ORCHESTRATION, e.exception.scope)
        self.assertEqual('prevent', e.exception.action)
        self.assertEqual(1, len(e.exception.responses))
        self.assertListEqual([
            Response(msg={'error': 'Unable to request for lock'},
                     code=409,
                     server=self.n2,
                     url=self.n2.url('api_1_0.locker_prevent'))
        ], e.exception.responses)

    @aioresponses()
    def test_lock_unlock_lock_with_server_error_on_preventing(self, m):
        m.post(self.n1.url('api_1_0.locker_prevent'),
               status=200,
               payload={'message': 'Preventing lock acquired'})
        m.post(self.n2.url('api_1_0.locker_prevent'),
               status=500,
               body="Error message")

        with self.assertRaises(errors.LockError) as e:
            ret = lock_unlock('L',
                              Scope.ORCHESTRATION, [self.n1, self.n2],
                              identity=ROOT)

        self.assertEqual(Scope.ORCHESTRATION, e.exception.scope)
        self.assertListEqual([
            Response("Error message",
                     code=500,
                     server=self.n2,
                     url=self.n2.url('api_1_0.locker_prevent'))
        ], e.exception.responses)

    @aioresponses()
    def test_lock_unlock_lock_with_connection_error(self, m):
        m.post(self.n1.url('api_1_0.locker_prevent'),
               status=200,
               payload={'message': 'Preventing lock acquired'})
        m.post(self.n2.url('api_1_0.locker_prevent'),
               exception=aiohttp.ClientConnectionError('test'))

        with self.assertRaises(errors.LockError) as e:
            ret = lock_unlock('L',
                              Scope.ORCHESTRATION, [self.n1, self.n2],
                              identity=ROOT)

        self.assertEqual(Scope.ORCHESTRATION, e.exception.scope)
        self.assertEqual(1, len(e.exception.responses))
        response = e.exception.responses[0]
        self.assertIsNone(response.msg)
        self.assertIsNone(response.code)
        self.assertEqual(self.n2, response.server)
        self.assertIsInstance(response.exception,
                              aiohttp.ClientConnectionError)
        self.assertTupleEqual(('test', ), response.exception.args)

    @aioresponses()
    def test_lock_unlock_lock_error_on_lock(self, m):
        m.post(self.n1.url('api_1_0.locker_prevent'),
               status=200,
               payload={'message': 'Preventing lock acquired'})
        m.post(self.n2.url('api_1_0.locker_prevent'),
               status=200,
               payload={'message': 'Preventing lock acquired'})
        m.post(self.n1.url('api_1_0.locker_lock'),
               status=200,
               payload={'message': 'Locked'})
        m.post(self.n2.url('api_1_0.locker_lock'),
               status=409,
               payload={'error': 'Unable to lock'})

        with self.assertRaises(errors.LockError) as e:
            ret = lock_unlock('L',
                              Scope.ORCHESTRATION, [self.n1, self.n2],
                              identity=ROOT)

        self.assertEqual(Scope.ORCHESTRATION, e.exception.scope)
        self.assertListEqual([
            Response(msg={'error': 'Unable to lock'},
                     code=409,
                     server=self.n2,
                     url=self.n2.url('api_1_0.locker_lock'))
        ], e.exception.responses)

    @aioresponses()
    def test_lock_unlock_unlock(self, m):
        def callback_unlock(url, **kwargs):
            self.assertDictEqual(
                kwargs['json'], {
                    'scope': 'ORCHESTRATION',
                    'applicant': [str(self.n1.id),
                                  str(self.n2.id)]
                })
            return CallbackResult(payload={'message': 'UnLocked'}, status=200)

        m.post(self.n1.url('api_1_0.locker_unlock'), callback=callback_unlock)
        m.post(self.n2.url('api_1_0.locker_unlock'), callback=callback_unlock)

        ret = lock_unlock('U',
                          Scope.ORCHESTRATION, [self.n1, self.n2],
                          identity=ROOT)

        self.assertIsNone(ret)

    @aioresponses()
    def test_lock_unlock_unlock_with_error(self, m):
        m.post(self.n2.url('api_1_0.locker_unlock'),
               status=200,
               payload={'message': 'UnLocked'})
        m.post(self.n1.url('api_1_0.locker_unlock'),
               status=409,
               payload={'error': 'Unable to unlock.'})

        with self.assertRaises(errors.LockError) as e:
            lock_unlock('U',
                        Scope.ORCHESTRATION, [self.n1, self.n2],
                        [str(self.n1.id), str(self.n2.id)],
                        identity=ROOT)

        self.assertEqual(Scope.ORCHESTRATION, e.exception.scope)
        self.assertListEqual([
            Response(msg={'error': 'Unable to unlock.'},
                     code=409,
                     server=self.n1,
                     url=self.n1.url('api_1_0.locker_unlock'))
        ], e.exception.responses)
class TestLogSender(FlaskAppMixin):

    def setUp(self):
        """Create and configure a new app instance for each test."""
        # create the app with common test config
        User.set_initial()
        self.source = Server('source', port=8000, me=True)
        self.dest = Server('dest', port=8000)
        Route(self.dest, cost=0)
        db.session.add_all([self.source, self.dest])
        _PygtailBuffer._fh = mock.MagicMock()

        self.mock_dm = mock.Mock()
        self.log_sender = LogSender(dimensigon=self.mock_dm)

    @patch('dimensigon.use_cases.log_sender.os.walk', autospec=True)
    @patch('dimensigon.use_cases.log_sender.os.path.isfile', autospec=True)
    @patch.object(Pygtail, 'update_offset_file')
    @patch.object(_PygtailBuffer, 'readlines', return_value='content', autospec=True)
    @aioresponses()
    def test_log_sender_file(self, mock_pb_rl, mock_pt_uof, mock_isfile, mock_walk, m):
        def callback(url, **kwargs):
            self.assertDictEqual(
                {"file": '/dimensigon/logs/dimensigon.log',
                 'data': base64.b64encode('content'.encode()).decode('ascii')},
                kwargs['json'])
            return CallbackResult('POST', status=200)

        m.post(self.dest.url('api_1_0.logresource', log_id='aaaaaaaa-1234-5678-1234-56781234aaa1'), callback=callback)

        mock_isfile.return_value = True

        log = Log(id='aaaaaaaa-1234-5678-1234-56781234aaa1', source_server=self.source,
                  target='/var/log/dimensigon.log',
                  destination_server=self.dest, dest_folder='/dimensigon/logs/')
        db.session.add(log)

        run(self.log_sender.send_new_data())

        mock_isfile.assert_called_once()
        mock_walk.assert_not_called()
        mock_pb_rl.assert_called_once()
        mock_pt_uof.assert_called_once()

    @patch('dimensigon.use_cases.log_sender.os.path.isfile', autospec=True)
    @patch.object(Pygtail, 'update_offset_file')
    @patch.object(_PygtailBuffer, 'readlines', return_value='content', autospec=True)
    @aioresponses()
    def test_log_sender_file_no_dest_folder(self, mock_pb_rl, mock_pt_uof, mock_isfile, m):
        def callback(url, **kwargs):
            self.assertDictEqual(
                {"file": '/var/log/dimensigon.log', 'data': base64.b64encode('content'.encode()).decode('ascii')},
                kwargs['json'])
            return CallbackResult('POST', status=200)

        m.post(self.dest.url('api_1_0.logresource', log_id='aaaaaaaa-1234-5678-1234-56781234aaa1'), callback=callback)

        mock_isfile.return_value = True

        log = Log(id='aaaaaaaa-1234-5678-1234-56781234aaa1', source_server=self.source,
                  target='/var/log/dimensigon.log',
                  destination_server=self.dest, dest_folder=None)
        db.session.add(log)

        run(self.log_sender.send_new_data())

        mock_isfile.assert_called_once()
        mock_pb_rl.assert_called_once()
        mock_pt_uof.assert_called_once()

    @async_patch('dimensigon.use_cases.log_sender.async_post', autospec=True)
    @patch('dimensigon.use_cases.log_sender.os.walk', autospec=True)
    @patch('dimensigon.use_cases.log_sender.os.path.isfile', autospec=True)
    @patch.object(Pygtail, 'update_offset_file')
    @patch.object(_PygtailBuffer, 'readlines', side_effect=['content1', 'newcontent2'], autospec=True)
    @aioresponses()
    def test_log_sender_folder(self, mock_pb_rl, mock_pt_uof, mock_isfile, mock_walk, mock_post, m):

        def callback(url, **kwargs):
            if kwargs['json']['file'] == '/dimensigon/logs/log1':
                self.assertDictEqual(
                    {"file": '/dimensigon/logs/log1', 'data': base64.b64encode('content1'.encode()).decode('ascii')},
                    kwargs['json'])
                return CallbackResult('POST', payload={'offset': 8}, status=200)
            elif kwargs['json']['file'] == '/dimensigon/logs/dir1/log2':
                self.assertDictEqual(
                    {"file": '/dimensigon/logs/dir1/log2',
                     'data': base64.b64encode('newcontent2'.encode()).decode('ascii')},
                    kwargs['json'])
                return CallbackResult('POST', payload={'offset': 11}, status=200)
            else:
                raise

        mock_post.side_effect = [({'offset': 8}, 200), ({'offset': 11}, 200), ({'offset': 8}, 200)]

        m.post(self.dest.url('api_1_0.logresource', log_id='aaaaaaaa-1234-5678-1234-56781234aaa1'), callback=callback)
        m.post(self.dest.url('api_1_0.logresource', log_id='aaaaaaaa-1234-5678-1234-56781234aaa1'), callback=callback)
        m.post(self.dest.url('api_1_0.logresource', log_id='aaaaaaaa-1234-5678-1234-56781234aaa1'), callback=callback)

        mock_isfile.return_value = False
        mock_walk.side_effect = [
            [('/var/log', ['dir1'], ['log1', 'file']), ('/var/log/dir1', ['dir2'], ['log2'])],
            [('/var/log', ['dir1'], ['log1', 'file']), ('/var/log/dir1', ['dir2'], [])]
        ]

        log = Log(id='aaaaaaaa-1234-5678-1234-56781234aaa1', source_server=self.source, target='/var/log',
                  destination_server=self.dest, dest_folder='/dimensigon/logs/', include='^(log|dir)', exclude='^dir2',
                  recursive=True)
        db.session.add(log)

        run(self.log_sender.send_new_data())

        mock_isfile.assert_called_once()
        self.assertEqual(2, mock_pb_rl.call_count)
        self.assertEqual(2, mock_pt_uof.call_count)
    def test_upgrade_catalog(self, mock_lock, mock_entities, mock_now,
                             mock_tzlocal):
        mock_lock.return_value.__enter__.return_value = 'applicant'
        mock_entities.return_value = [('ActionTemplate', ActionTemplate),
                                      ('Server', Server), ('Gate', Gate)]
        mock_now.return_value = dt.datetime(2019, 4, 1, tzinfo=dt.timezone.utc)
        mock_tzlocal.return_value = dt.timezone.utc

        at1 = ActionTemplate(id='aaaaaaaa-1234-5678-1234-56781234aaa1',
                             name='mkdir',
                             version=1,
                             action_type=ActionType.SHELL,
                             code='mkdir {dir}',
                             expected_output=None,
                             expected_rc=None,
                             system_kwargs={})
        db.session.add(at1)
        db.session.commit()

        s = Server(id='aaaaaaaa-1234-5678-1234-56781234bbb1',
                   name='server',
                   last_modified_at=dt.datetime(2019,
                                                4,
                                                1,
                                                tzinfo=dt.timezone.utc))
        s_json = s.to_json()
        g = Gate(server=s,
                 port=80,
                 dns='server',
                 last_modified_at=dt.datetime(2019,
                                              4,
                                              1,
                                              tzinfo=dt.timezone.utc))
        g_json = g.to_json()
        Route(s, cost=0)

        at2 = ActionTemplate(id='aaaaaaaa-1234-5678-1234-56781234aaa2',
                             name='rmdir',
                             version=1,
                             action_type=ActionType.SHELL,
                             code='rmdir {dir}',
                             expected_output=None,
                             expected_rc=None,
                             system_kwargs={},
                             last_modified_at=dt.datetime(
                                 2019, 4, 2, tzinfo=dt.timezone.utc))
        at2_json = at2.to_json()
        del at2

        at1_json = at1.to_json()
        del at1
        at1_json['code'] = 'mkdir -p {dir}'
        responses.add(
            method='GET',
            url=re.compile('^' + s.url(
                'api_1_0.catalog', data_mark='12345').replace('12345', '')),
            json={
                "ActionTemplate": [at1_json, at2_json],
                "Server": [s_json],
                "Gate": [g_json]
            })

        upgrade_catalog_from_server(s)

        db.session.expire_all()
        atl = [at.to_json() for at in ActionTemplate.query.all()]

        self.assertListEqual([at1_json, at2_json], atl)

        c = Catalog.query.get('ActionTemplate')
        self.assertEqual(dt.datetime(2019, 4, 2, tzinfo=dt.timezone.utc),
                         c.last_modified_at)

        at1 = ActionTemplate.query.get('aaaaaaaa-1234-5678-1234-56781234aaa1')
        self.assertEqual('mkdir -p {dir}', at.code)
Exemple #9
0
class TestServer(OneNodeMixin, TestCase):
    def set_servers_and_routes(self):
        self.n1 = Server(name='n1', dns_or_ip='1.1.1.1')
        self.n2 = Server(name='n2', dns_or_ip='n2_dns')
        self.n3 = Server(name='n3', port=8000)
        self.r1 = Server(name='r1', dns_or_ip='3.3.3.3')
        self.r2 = Server(name='r2', dns_or_ip='r2_dns')
        db.session.add_all([self.n1, self.n2, self.r1, self.r2])
        db.session.commit()

        Route(destination=self.n1, cost=0)
        Route(destination=self.n2, cost=0)
        Route(destination=self.n3, cost=0)
        Route(destination=self.r1, proxy_server_or_gate=self.n1, cost=1)
        Route(destination=self.r2, proxy_server_or_gate=self.n2, cost=1)

        db.session.commit()

    @mock.patch('dimensigon.domain.entities.route.check_host')
    @mock.patch('dimensigon.domain.entities.server.url_for')
    def test_url(self, mock_url, mock_check_host):
        self.set_servers_and_routes()

        mock_check_host.return_value = True
        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}',
                         self.n1.url())
        self.assertEqual(f'https://n2_dns:{defaults.DEFAULT_PORT}',
                         self.n2.url())
        self.assertEqual(f'https://n3:8000', self.n3.url())
        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}',
                         self.r1.url())
        self.assertEqual(f'https://n2_dns:{defaults.DEFAULT_PORT}',
                         self.r2.url())

        mock_url.return_value = '/'

        self.assertEqual(f'https://1.1.1.1:{defaults.DEFAULT_PORT}/',
                         self.n1.url('api'))

        mock_url.assert_called_once_with('api')

        me = Server(name='me',
                    gates=[('127.0.0.1', 5), ('192.168.1.2', 2)],
                    me=True)
        self.assertEqual(f'https://127.0.0.1:5/', me.url('api'))

        with mock.patch('dimensigon.domain.entities.server.current_app'
                        ) as mock_current_app:
            type(mock_current_app.dm.config).http_config = mock.PropertyMock(
                return_value={'keyfile': 'x'})
            me = Server(name='me', gates=[('192.168.1.2', 2)], me=True)
            self.assertEqual(f'http://192.168.1.2:2/', me.url('api'))

        s = Server('test', port=8000)
        with self.assertRaises(errors.UnreachableDestination):
            s.url()

    def test_get_neighbours(self):
        n1 = Server('n1', port=8000)
        n2 = Server('n2', port=8000)
        n3 = Server('n3', port=8000)
        r1 = Server('r1', port=8000)
        Route(destination=n1, cost=0)
        Route(destination=n2, proxy_server_or_gate=n2.gates[0])
        Route(destination=r1, proxy_server_or_gate=n1, cost=1)

        me = Server('me', port=8000, me=True)
        db.session.add_all([n1, n2, n3, r1, me])

        self.assertListEqual([n1, n2], me.get_neighbours())

        self.assertListEqual([n2], me.get_neighbours(exclude=n1))
        self.assertListEqual([n2], me.get_neighbours(exclude=[n1, n3]))
        self.assertListEqual([n2], me.get_neighbours(exclude=[n1.id, n3.id]))

    def test_get_neighbours_no_route(self):
        n1 = Server('n1', port=8000)
        me = Server('me', port=8000, me=True)

        db.session.add_all([n1, me])

        self.assertListEqual([], me.get_neighbours())

    def test_get_not_neighbours(self):
        n1 = Server('n1', port=8000, id='22cd859d-ee91-4079-a112-000000000001')
        n2 = Server('n2', port=8000, id='22cd859d-ee91-4079-a112-000000000002')
        n3 = Server('n3', port=8000, id='22cd859d-ee91-4079-a112-000000000003')
        n3.route = None
        r1 = Server('r1', port=8000, id='22cd859d-ee91-4079-a112-000000000011')
        Route(destination=n1, cost=0)
        Route(destination=n2, proxy_server_or_gate=n2.gates[0])
        Route(destination=r1, proxy_server_or_gate=n1, cost=1)

        me = Server('me', port=8000, me=True)
        db.session.add_all([n1, n2, n3, r1, me])

        self.assertListEqual([n3, r1], me.get_not_neighbours())

    def test_get_reachable_servers(self):
        n1 = Server('n1', port=8000, id='22cd859d-ee91-4079-a112-000000000001')
        n2 = Server('n2', port=8000, id='22cd859d-ee91-4079-a112-000000000002')
        n3 = Server('n3', port=8000, id='22cd859d-ee91-4079-a112-000000000003')
        n3.route = None
        n4 = Server('n4', port=8000, id='22cd859d-ee91-4079-a112-000000000004')
        r1 = Server('r1', port=8000, id='22cd859d-ee91-4079-a112-000000000011')
        Route(destination=n1, cost=0)
        Route(destination=n2, proxy_server_or_gate=n2.gates[0])
        Route(destination=n4)
        Route(destination=r1, proxy_server_or_gate=n1, cost=1)

        me = Server('me', port=8000, me=True)
        db.session.add_all([n1, n2, n3, n4, r1, me])

        self.assertListEqual([n1, n2, r1], me.get_reachable_servers())

        self.assertListEqual([n2, r1], me.get_reachable_servers(exclude=n1))
        self.assertListEqual([n2, r1], me.get_reachable_servers(exclude=n1.id))

        self.assertListEqual([r1],
                             me.get_reachable_servers(exclude=[n1.id, n2]))