Пример #1
0
def main() -> int:
    """Runs a oslo_messaging notification listener for k2hr3.

    You can configure the listener by the config file.

    Simple usage:

    $ k2hr3_osnl -c etc/k2hr3_osnl.config

    :returns:
        0 if success, otherwise 1.
    :rtype:
        int
    """
    parser = argparse.ArgumentParser(
        description='An oslo.messaging notification listener for k2hr3.')
    parser.add_argument('-c',
                        '--config-file',
                        dest='config_file',
                        default='/etc/k2hr3/k2hr3_osnl.conf',
                        help='config file path')
    parser.add_argument(
        '-d',
        dest='debug_level',
        choices=('debug', 'info', 'warn', 'error', 'critical'),
        help='debug level. default: defined in the config_file')
    parser.add_argument(
        '-l',
        dest='libs_debug_level',
        choices=('debug', 'info', 'warn', 'error', 'critical'),
        help='dependent libraries loglevel. default: defined in the config_file'
    )
    parser.add_argument(
        '-f',
        dest='log_file',
        help='log file path. default: defined in the config_file')
    parser.add_argument('-v',
                        action='version',
                        version='%(prog)s ' + __version__)
    args = parser.parse_args()

    try:
        conf = K2hr3Conf(Path(args.config_file))
        _configure_logger(args, conf)  # logger configured by args and conf.
        endpoints = [K2hr3NotificationEndpoint(conf)]
        sys.exit(listen(endpoints))
    except K2hr3Error as error:
        LOG.error('K2hr3Error error, %s', error)
        raise K2hr3Error("K2hr3 RuntimeError") from error
    except Exception as error:
        LOG.error('Unknown error, %s', error)
        raise RuntimeError("Unknown RuntimeError") from error
Пример #2
0
    def test_k2hr3_osnl_listen(self):
        """Executes the k2hr3_osnl main function."""
        sys.argv[0] = 'me'
        sys.argv[1] = '-c'
        sys.argv.append(str(conf_file_path))

        # Ensure k2hr3_osnl.listen called.
        with patch.object(oslo_messaging.get_notification_listener,
                          'start',
                          return_value=None,
                          side_effect=Exception('skip listening')):
            conf = K2hr3Conf(conf_file_path)
            endpoint = K2hr3NotificationEndpoint(conf)
            with self.assertRaises(Exception):
                k2hr3_osnl.listen(endpoint)
Пример #3
0
    def test_notification_endpoint_info_r3api_failed(self):
        """Checks if info works correctly.

        NotificationEndpoint::info returns HANDLED if __call_r3api returns HANDLED.
        __call_r3api internally callses _K2hr3UserAgent::send() to call the R3 API.
        We mock the method to return False without having access to the API.
        """
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        endpoint = K2hr3NotificationEndpoint(conf)
        _K2hr3UserAgent.send = MagicMock(return_value=False)
        with open(src_dir + '/tools/data/notifications_neutron.json') as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, HANDLED)
Пример #4
0
    def test_notification_endpoint_call_r3api_exception_raise(self):
        """Checks if call_r3api works correctly.

        __call_r3api calls the _K2hr3UserAgent::send() to call the R3 API.
        We mock _K2hr3UserAgent::send() to throws an unknown exception.
        Then the function raises the exception again.
        K2hr3NotificationEndpoint::info() method will catch all exceptions
        then it returns HANDLED to the dispatcher.
        """
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        _K2hr3UserAgent.send = MagicMock(side_effect=Exception('error'))
        endpoint = K2hr3NotificationEndpoint(conf)
        with open(src_dir + '/tools/data/notifications_neutron.json') as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, HANDLED)
Пример #5
0
    def test_notification_endpoint_info_call_r3api_exception(self):
        """Checks if info works correctly.

        NotificationEndpoint::info returns HANDLED if the __call_r3api
        method throws other than K2hr3NotificationEndpointError excetion.
        """
        payload = {
            "instance_id": "12345678-1234-5678-1234-567812345678",
        }
        with patch.object(K2hr3NotificationEndpoint,
                          '_K2hr3NotificationEndpoint__call_r3api',
                          side_effect=Exception('__call_r3api error')):
            conf = K2hr3Conf(conf_file_path)
            endpoint = K2hr3NotificationEndpoint(conf)
            result = endpoint.info(context={},
                                   publisher_id='',
                                   event_type='',
                                   payload=payload,
                                   metadata={})
        # Ensucre the result of info is HANDLED.
        self.assertEqual(result, HANDLED)
Пример #6
0
    def test_notification_endpoint_info_r3api_failed_requeue(self):
        """Checks if info works correctly.

        NotificationEndpoint::info returns HANDLED if __call_r3api returns HANDLED.
        __call_r3api internally callses _K2hr3UserAgent::send() to call the R3 API.
        We mock the method to return False without having access to the API.
        """
        # Expected return_value is REQUEUE in this case.
        self.mock_method.return_value = REQUEUE
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        conf.k2hr3.requeue_on_error = True
        endpoint = K2hr3NotificationEndpoint(conf)
        _K2hr3UserAgent.send = MagicMock(return_value=False)

        with open(src_dir + '/tools/data/notifications_neutron.json') as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, REQUEUE)
        # Reset it. Default return_value is HANDLED.
        self.mock_method.return_value = HANDLED
Пример #7
0
    def test_neutron_payload_to_params(self):
        """Checks if _payload_to_params() works correctly.

        The payload pattern is a neutron notification message.
        """
        # Ensure values are as expected at runtime.
        self.patcher_call_r3api = patch.object(
            K2hr3NotificationEndpoint,
            '_K2hr3NotificationEndpoint__call_r3api')
        self.mock_method = self.patcher_call_r3api.start()
        self.mock_method.return_value = HANDLED
        self.addCleanup(self.patcher_call_r3api.stop)
        # input --- payload
        payload = {
            "port": {
                "device_id":
                "12345678-1234-5678-1234-567812345678",
                "fixed_ips": [{
                    "ip_address": "127.0.0.1",
                }, {
                    "ip_address": "127.0.0.2",
                }]
            }
        }
        # output --- params
        expect_params = {
            'cuk': '12345678-1234-5678-1234-567812345678',
            'ips': ['127.0.0.1', '127.0.0.2']
        }
        conf = K2hr3Conf(conf_file_path)
        endpoint = K2hr3NotificationEndpoint(conf)
        result = endpoint.info(context={},
                               publisher_id='',
                               event_type='',
                               payload=payload,
                               metadata={})
        self.mock_method.assert_called_once_with(expect_params)
        # Ensucre the result of info is HANDLED.
        self.assertEqual(result, HANDLED)
Пример #8
0
    def test_notification_endpoint_call_r3api_exception_raise(self):
        """Checks if call_r3api works correctly.

        __call_r3api calls the _K2hr3UserAgent::send() to call the R3 API.
        We mock _K2hr3UserAgent::send() to throws an unknown exception.
        Then the function raises the exception again.
        K2hr3NotificationEndpoint::info() method will catch all exceptions
        then it returns HANDLED to the dispatcher.
        """
        _K2hr3UserAgent.send = MagicMock(side_effect=Exception('error'))

        conf = K2hr3Conf(conf_file_path)
        endpoint = K2hr3NotificationEndpoint(conf)
        json_file_path = Path(
            os.sep.join(
                [here, '..', 'tools', 'data',
                 'notifications_neutron.json'])).resolve()
        with json_file_path.open() as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, HANDLED)
Пример #9
0
    def test_compute_payload_to_params(self):
        """Checks if _payload_to_params() works correctly.

        The payload pattern is a compute notification message.
        """
        # input --- payload
        payload = {
            "instance_id": "12345678-1234-5678-1234-567812345678",
        }
        # output --- params
        expect_params = {'cuk': '12345678-1234-5678-1234-567812345678'}
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        endpoint = K2hr3NotificationEndpoint(conf)
        result = endpoint.info(
            context={},
            publisher_id='',
            event_type='',
            payload=payload,
            metadata={})
        # Ensure values are as expected at runtime.
        self.mock_method.assert_called_once_with(expect_params)
        # Ensucre the result of info is HANDLED.
        self.assertEqual(result, HANDLED)
Пример #10
0
    def test_notification_endpoint_call_r3api_requeue_on_exception(self):
        """Checks if call_r3api works correctly.

        __call_r3api calls the _K2hr3UserAgent::send() to call the R3 API.
        We mock _K2hr3UserAgent::send() to throws a _K2hr3UserAgentError.
        If requeue_on_error is true, then the function returns HANDLED.
        """
        # Expected return_value is REQUEUE in this case.
        self.mock_method.return_value = REQUEUE
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        conf.k2hr3.requeue_on_error = True
        _K2hr3UserAgent.send = MagicMock(
            side_effect=_K2hr3UserAgentError('error'))
        endpoint = K2hr3NotificationEndpoint(conf)
        with open(src_dir + '/tools/data/notifications_neutron.json') as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, REQUEUE)

        # Reset it. Default return_value is HANDLED.
        self.mock_method.return_value = HANDLED
Пример #11
0
    def test_notification_endpoint_info__payload_to_params_exception(self):
        """Checks if info works correctly.

        NotificationEndpoint::info returns HANDLED if the _payload_to_params
        method throws other than K2hr3NotificationEndpointError excetion.
        """
        payload = {
            "instance_id": "12345678-1234-5678-1234-567812345678",
        }
        with patch.object(
                K2hr3NotificationEndpoint,
                '_payload_to_params',
                side_effect=Exception('_payload_to_params error')):
            conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
            endpoint = K2hr3NotificationEndpoint(conf)
            result = endpoint.info(
                context={},
                publisher_id='',
                event_type='',
                payload=payload,
                metadata={})
        # Ensucre the result of info is HANDLED.
        self.assertEqual(result, HANDLED)
Пример #12
0
    def test_payload_to_params_error_no_instance_id(self):
        """Checks if _payload_to_params() works correctly.

        The payload has no instance_id.
        """
        # input --- payload
        payload = {
            "invalid_named": "12345678-1234-5678-1234-567812345678",
        }
        # __call_r3api is mocked! no http request will send.
        conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
        endpoint = K2hr3NotificationEndpoint(conf)
        result = endpoint.info(
            context={},
            publisher_id='',
            event_type='',
            payload=payload,
            metadata={})

        # Ensure the__call_r3api is not called.
        self.mock_method.mock_call_r3api.assert_not_called()
        # Ensucre the result of info is HANDLED.
        self.assertEqual(result, HANDLED)
Пример #13
0
    def test_notification_endpoint_call_r3api_requeue_on_exception(self):
        """Checks if call_r3api works correctly.

        __call_r3api calls the _K2hr3UserAgent::send() to call the R3 API.
        We mock _K2hr3UserAgent::send() to throws a _K2hr3UserAgentError.
        If requeue_on_error is true, then the function returns HANDLED.
        """
        # Expected return_value is REQUEUE in this case.
        _K2hr3UserAgent.send = MagicMock(
            side_effect=_K2hr3UserAgentError('error'))

        conf = K2hr3Conf(conf_file_path)
        conf.k2hr3.requeue_on_error = True  # overwrites it True.
        endpoint = K2hr3NotificationEndpoint(conf)
        json_file_path = Path(
            os.sep.join(
                [here, '..', 'tools', 'data',
                 'notifications_neutron.json'])).resolve()
        with json_file_path.open() as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, REQUEUE)
Пример #14
0
    def test_notification_endpoint_info_r3api_failed(self):
        """Checks if info works correctly.

        NotificationEndpoint::__call_r3api returns HANDLED in this case.

        NotificationEndpoint::info()
        --> NotificationEndpoint::__call_r3api()
        --> _K2hr3UserAgent::send()                # we mock this method.
        """
        # Expected return_value of _K2hr3UserAgent::send() is False
        _K2hr3UserAgent.send = MagicMock(return_value=False)

        conf = K2hr3Conf(conf_file_path)
        endpoint = K2hr3NotificationEndpoint(conf)
        json_file_path = Path(
            os.sep.join(
                [here, '..', 'tools', 'data',
                 'notifications_neutron.json'])).resolve()
        with json_file_path.open() as fp:
            data = json.load(fp)
            result = endpoint.info(data['ctxt'], data['publisher_id'],
                                   data['event_type'], data['payload'],
                                   data['metadata'])
        self.assertEqual(result, HANDLED)
Пример #15
0
 def test_notification_endpoint_conf(self):
     """Checks if conf is readable."""
     conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
     endpoint = K2hr3NotificationEndpoint(conf)
     self.assertIsInstance(endpoint, K2hr3NotificationEndpoint)
     self.assertEqual(endpoint.conf, conf)
Пример #16
0
 def test_notification_endpoint_construct(self):
     """Creates a NotificationEndpoint instance."""
     conf = K2hr3Conf(src_dir + '/etc/k2hr3_osnl.conf.sample')
     endpoint = K2hr3NotificationEndpoint(conf)
     self.assertIsInstance(endpoint, K2hr3NotificationEndpoint)
Пример #17
0
 def test_notification_endpoint_construct(self):
     """Creates a NotificationEndpoint instance."""
     conf = K2hr3Conf(conf_file_path)
     endpoint = K2hr3NotificationEndpoint(conf)
     self.assertIsInstance(endpoint, K2hr3NotificationEndpoint)
Пример #18
0
 def test_notification_endpoint_conf(self):
     """Checks if conf is readable."""
     conf = K2hr3Conf(conf_file_path)
     endpoint = K2hr3NotificationEndpoint(conf)
     self.assertIsInstance(endpoint, K2hr3NotificationEndpoint)
     self.assertEqual(endpoint.conf, conf)