Пример #1
0
    def start_udp(self):
        address_family = socket.AF_INET
        if netutils.is_valid_ipv6(cfg.CONF.collector.udp_address):
            address_family = socket.AF_INET6
        udp = socket.socket(address_family, socket.SOCK_DGRAM)
        udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        udp.bind((cfg.CONF.collector.udp_address,
                  cfg.CONF.collector.udp_port))

        self.udp_run = True
        while self.udp_run:
            # NOTE(jd) Arbitrary limit of 64K because that ought to be
            # enough for anybody.
            data, source = udp.recvfrom(64 * units.Ki)
            try:
                sample = msgpack.loads(data, encoding='utf-8')
            except Exception:
                LOG.warning(_("UDP: Cannot decode data sent by %s"), source)
            else:
                if publisher_utils.verify_signature(
                        sample, cfg.CONF.publisher.telemetry_secret):
                    try:
                        LOG.debug("UDP: Storing %s", sample)
                        self.meter_manager.map_method(
                            'record_metering_data', sample)
                    except Exception:
                        LOG.exception(_("UDP: Unable to store meter"))
                else:
                    LOG.warning(_LW('sample signature invalid, '
                                    'discarding: %s'), sample)
Пример #2
0
    def record_metering_data(self, data):
        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(
                "metering data %(counter_name)s " "for %(resource_id)s @ %(timestamp)s: %(counter_volume)s",
                {
                    "counter_name": meter["counter_name"],
                    "resource_id": meter["resource_id"],
                    "timestamp": meter.get("timestamp", "NO TIMESTAMP"),
                    "counter_volume": meter["counter_volume"],
                },
            )
            if publisher_utils.verify_signature(meter, self.conf.publisher.telemetry_secret):
                try:
                    # Convert the timestamp to a datetime instance.
                    # Storage engines are responsible for converting
                    # that value to something they can store.
                    if meter.get("timestamp"):
                        ts = timeutils.parse_isotime(meter["timestamp"])
                        meter["timestamp"] = timeutils.normalize_time(ts)
                    self.meter_conn.record_metering_data(meter)
                except Exception as err:
                    LOG.exception(_LE("Failed to record metering data: %s"), err)
                    # raise the exception to propagate it up in the chain.
                    raise
            else:
                LOG.warning(_LW("message signature invalid, discarding message: %r"), meter)
Пример #3
0
    def record_metering_data(self, data):
        if self.target == "":
            # if the target was not set, do not do anything
            LOG.error(
                _(
                    "Dispatcher target was not set, no meter will "
                    "be posted. Set the target in the ceilometer.conf "
                    "file"
                )
            )
            return

        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(
                "metering data %(counter_name)s " "for %(resource_id)s @ %(timestamp)s: %(counter_volume)s",
                {
                    "counter_name": meter["counter_name"],
                    "resource_id": meter["resource_id"],
                    "timestamp": meter.get("timestamp", "NO TIMESTAMP"),
                    "counter_volume": meter["counter_volume"],
                },
            )
            if publisher_utils.verify_signature(meter, self.conf.publisher.telemetry_secret):
                try:
                    # Every meter should be posted to the target
                    res = requests.post(self.target, data=json.dumps(meter), headers=self.headers, timeout=self.timeout)
                    LOG.debug("Message posting finished with status code " "%d.", res.status_code)
                except Exception as err:
                    LOG.exception(_("Failed to record metering data: %s"), err)
            else:
                LOG.warning(_("message signature invalid, discarding message: %r"), meter)
Пример #4
0
    def record_metering_data(self, data):
        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(_(
                'metering data %(counter_name)s '
                'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s')
                % ({'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']}))
            if publisher_utils.verify_signature(
                    meter, self.conf.publisher.telemetry_secret):
                try:
                    # Convert the timestamp to a datetime instance.
                    # Storage engines are responsible for converting
                    # that value to something they can store.
                    if meter.get('timestamp'):
                        ts = timeutils.parse_isotime(meter['timestamp'])
                        meter['timestamp'] = timeutils.normalize_time(ts)
                    self.meter_conn.record_metering_data(meter)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'),
                                  err)
                    # raise the exception to propagate it up in the chain.
                    raise
            else:
                LOG.warning(_(
                    'message signature invalid, discarding message: %r'),
                    meter)
Пример #5
0
    def record_metering_data(self, data):
        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(
                _('metering data %(counter_name)s '
                  'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s') %
                ({
                    'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']
                }))
            if publisher_utils.verify_signature(
                    meter, self.conf.publisher.metering_secret):
                try:
                    # Convert the timestamp to a datetime instance.
                    # Storage engines are responsible for converting
                    # that value to something they can store.
                    if meter.get('timestamp'):
                        ts = timeutils.parse_isotime(meter['timestamp'])
                        meter['timestamp'] = timeutils.normalize_time(ts)
                    self.storage_conn.record_metering_data(meter)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'), err)
            else:
                LOG.warning(
                    _('message signature invalid, discarding message: %r'),
                    meter)
Пример #6
0
 def test_udp_receive_valid_encoding(self):
     self._setup_messaging(False)
     mock_dispatcher = self._setup_fake_dispatcher()
     self.data_sent = []
     with mock.patch("socket.socket", return_value=self._make_fake_socket(self.utf8_msg)):
         self.srv.start()
         self.assertTrue(utils.verify_signature(mock_dispatcher.method_calls[0][1][0], "not-so-secret"))
Пример #7
0
    def start_udp(self):
        address_family = socket.AF_INET
        if netutils.is_valid_ipv6(cfg.CONF.collector.udp_address):
            address_family = socket.AF_INET6
        udp = socket.socket(address_family, socket.SOCK_DGRAM)
        udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        udp.bind((cfg.CONF.collector.udp_address, cfg.CONF.collector.udp_port))

        self.udp_run = True
        while self.udp_run:
            # NOTE(jd) Arbitrary limit of 64K because that ought to be
            # enough for anybody.
            data, source = udp.recvfrom(64 * units.Ki)
            try:
                sample = msgpack.loads(data, encoding='utf-8')
            except Exception:
                LOG.warning(_("UDP: Cannot decode data sent by %s"), source)
            else:
                if publisher_utils.verify_signature(
                        sample, cfg.CONF.publisher.telemetry_secret):
                    try:
                        LOG.debug("UDP: Storing %s", sample)
                        self.meter_manager.map_method('record_metering_data',
                                                      sample)
                    except Exception:
                        LOG.exception(_("UDP: Unable to store meter"))
                else:
                    LOG.warning(
                        _LW('sample signature invalid, '
                            'discarding: %s'), sample)
Пример #8
0
    def record_events(self, events):
        if not isinstance(events, list):
            events = [events]

        event_list = []
        for ev in events:
            if publisher_utils.verify_signature(
                    ev, self.conf.publisher.telemetry_secret):
                try:
                    event_list.append(
                        models.Event(
                            message_id=ev['message_id'],
                            event_type=ev['event_type'],
                            generated=timeutils.normalize_time(
                                timeutils.parse_isotime(ev['generated'])),
                            traits=[models.Trait(
                                    name, dtype,
                                    models.Trait.convert_value(dtype, value))
                                    for name, dtype, value in ev['traits']],
                            raw=ev.get('raw', {}))
                    )
                except Exception:
                    LOG.exception(_LE("Error processing event and it will be "
                                      "dropped: %s"), ev)
            else:
                LOG.warning(_LW(
                    'event signature invalid, discarding event: %s'), ev)
        self.event_conn.record_events(event_list)
Пример #9
0
 def sample(self, messages):
     events = chain.from_iterable(m["payload"] for m in messages)
     events = [
         models.Event(message_id=ev['message_id'],
                      event_type=ev['event_type'],
                      generated=timeutils.normalize_time(
                          timeutils.parse_isotime(ev['generated'])),
                      traits=[
                          models.Trait(
                              name, dtype,
                              models.Trait.convert_value(dtype, value))
                          for name, dtype, value in ev['traits']
                      ],
                      raw=ev.get('raw', {})) for ev in events
         if publisher_utils.verify_signature(
             ev, self.conf.publisher.telemetry_secret)
     ]
     try:
         with self.publish_context as p:
             p(events)
     except Exception:
         if not self.conf.notification.ack_on_event_error:
             return oslo_messaging.NotificationResult.REQUEUE
         raise
     return oslo_messaging.NotificationResult.HANDLED
Пример #10
0
 def test_verify_unicode_symbols(self):
     data = {u'a\xe9\u0437': 'A',
             'b': u'B\xe9\u0437'
             }
     data['message_signature'] = utils.compute_signature(
         data,
         'not-so-secret')
     jsondata = json.loads(json.dumps(data))
     self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
Пример #11
0
 def test_verify_unicode_symbols(self):
     data = {u'a\xe9\u0437': 'A',
             'b': u'B\xe9\u0437'
             }
     data['message_signature'] = utils.compute_signature(
         data,
         'not-so-secret')
     jsondata = jsonutils.loads(jsonutils.dumps(data))
     self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
Пример #12
0
 def test_udp_receive_valid_encoding(self):
     self._setup_messaging(False)
     mock_dispatcher = self._setup_fake_dispatcher()
     self.data_sent = []
     with mock.patch('socket.socket',
                     return_value=self._make_fake_socket(self.utf8_msg)):
         self.srv.start()
         self.assertTrue(
             utils.verify_signature(mock_dispatcher.method_calls[0][1][0],
                                    "not-so-secret"))
Пример #13
0
 def verify_and_record_events(self, events):
     """Verify event signature and record them."""
     goods = []
     for event in events:
         if utils.verify_signature(
                 event, self.conf.publisher.telemetry_secret):
             goods.append(event)
         else:
             LOG.warning(_LW(
                 'event signature invalid, discarding event: %s'), event)
     return self.record_events(goods)
Пример #14
0
 def test_verify_signature_nested(self):
     data = {'a': 'A',
             'b': 'B',
             'nested': {'a': 'A',
                        'b': 'B',
                        },
             }
     data['message_signature'] = utils.compute_signature(
         data,
         'not-so-secret')
     self.assertTrue(utils.verify_signature(data, 'not-so-secret'))
Пример #15
0
 def test_udp_receive_valid_encoding(self):
     self.data_sent = []
     with mock.patch('socket.socket',
                     return_value=self._make_fake_socket(self.utf8_msg)):
         self.srv.rpc_server = mock.MagicMock()
         mock_dispatcher = mock.MagicMock()
         self.srv.dispatcher_manager = \
             self._make_test_manager(mock_dispatcher)
         self.srv.start_udp()
         self.assertTrue(utils.verify_signature(
             mock_dispatcher.method_calls[0][1][0],
             "not-so-secret"))
Пример #16
0
 def test_udp_receive_valid_encoding(self):
     self.data_sent = []
     with mock.patch('socket.socket',
                     return_value=self._make_fake_socket(self.utf8_msg)):
         self.srv.rpc_server = mock.MagicMock()
         mock_dispatcher = mock.MagicMock()
         self.srv.dispatcher_manager = \
             self._make_test_manager(mock_dispatcher)
         self.srv.start_udp()
         self.assertTrue(
             utils.verify_signature(mock_dispatcher.method_calls[0][1][0],
                                    "not-so-secret"))
Пример #17
0
 def test_udp_receive_valid_encoding(self):
     self._setup_messaging(False)
     mock_dispatcher = self._setup_fake_dispatcher()
     self.data_sent = []
     with mock.patch('socket.socket',
                     return_value=self._make_fake_socket(self.utf8_msg)):
         self.srv.run()
         self.addCleanup(self.srv.terminate)
         self.srv.udp_thread.join(5)
         self.assertFalse(self.srv.udp_thread.is_alive())
         self.assertTrue(utils.verify_signature(
             mock_dispatcher.method_calls[0][1][0],
             "not-so-secret"))
Пример #18
0
 def test_udp_receive_valid_encoding(self):
     self._setup_messaging(False)
     self.data_sent = []
     sock = self._make_fake_socket(self.utf8_msg)
     with mock.patch('select.select', return_value=([sock], [], [])):
         with mock.patch('socket.socket', return_value=sock):
             self.srv.run()
             self.addCleanup(self.srv.terminate)
             self.srv.udp_thread.join(5)
             self.assertFalse(self.srv.udp_thread.is_alive())
             self.assertTrue(utils.verify_signature(
                 self.mock_dispatcher.method_calls[0][1][0],
                 "not-so-secret"))
Пример #19
0
    def record_metering_data(self, data):
        if self.target == '':
            # if the target was not set, do not do anything
            LOG.error(
                _('Dispatcher target was not set, no meter will '
                  'be posted. Set the target in the ceilometer.conf '
                  'file'))
            return

        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(
                _('metering data %(counter_name)s '
                  'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s') %
                ({
                    'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']
                }))
            if publisher_utils.verify_signature(
                    meter, self.conf.publisher.telemetry_secret):
                try:
                    if self.cadf_only:
                        # Only cadf messages are being wanted.
                        req_data = meter.get('resource_metadata',
                                             {}).get('request')
                        if req_data and 'CADF_EVENT' in req_data:
                            data = req_data['CADF_EVENT']
                        else:
                            continue
                    else:
                        # Every meter should be posted to the target
                        data = meter
                    res = requests.post(self.target,
                                        data=json.dumps(data),
                                        headers=self.headers,
                                        timeout=self.timeout)
                    LOG.debug(
                        _('Message posting finished with status code '
                          '%d.') % res.status_code)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'), err)
            else:
                LOG.warning(
                    _('message signature invalid, discarding message: %r'),
                    meter)
Пример #20
0
 def test_verify_signature_nested_json(self):
     data = {'a': 'A',
             'b': 'B',
             'nested': {'a': 'A',
                        'b': 'B',
                        'c': ('c',),
                        'd': ['d']
                        },
             }
     data['message_signature'] = utils.compute_signature(
         data,
         'not-so-secret')
     jsondata = jsonutils.loads(jsonutils.dumps(data))
     self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
Пример #21
0
    def verify_and_record_metering_data(self, datapoints):
        """Verify metering data's signature and record valid ones."""
        if not isinstance(datapoints, list):
            datapoints = [datapoints]

        valid_datapoints = []
        for datapoint in datapoints:
            if utils.verify_signature(datapoint,
                                      self.conf.publisher.telemetry_secret):
                valid_datapoints.append(datapoint)
            else:
                LOG.warning(_LW('Message signature is invalid, discarding '
                                'it: <%r>.'), datapoint)
        return self.record_metering_data(valid_datapoints)
Пример #22
0
    def record_metering_data(self, data):
        if self.target == '':
            # if the target was not set, do not do anything
            LOG.error(_('Dispatcher target was not set, no meter will '
                        'be posted. Set the target in the ceilometer.conf '
                        'file'))
            return

        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(_(
                'metering data %(counter_name)s '
                'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s')
                % ({'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']}))
            if publisher_utils.verify_signature(
                    meter,
                    self.conf.publisher.metering_secret):
                try:
                    if self.cadf_only:
                        # Only cadf messages are being wanted.
                        req_data = meter.get('resource_metadata',
                                             {}).get('request')
                        if req_data and 'CADF_EVENT' in req_data:
                            data = req_data['CADF_EVENT']
                        else:
                            continue
                    else:
                        # Every meter should be posted to the target
                        data = meter
                    res = requests.post(self.target,
                                        data=json.dumps(data),
                                        headers=self.headers,
                                        timeout=self.timeout)
                    LOG.debug(_('Message posting finished with status code '
                                '%d.') % res.status_code)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'),
                                  err)
            else:
                LOG.warning(_(
                    'message signature invalid, discarding message: %r'),
                    meter)
Пример #23
0
 def sample(self, ctxt, publisher_id, event_type, payload, metadata):
     events = [
         models.Event(
             message_id=ev['message_id'],
             event_type=ev['event_type'],
             generated=timeutils.normalize_time(
                 timeutils.parse_isotime(ev['generated'])),
             traits=[models.Trait(name, dtype,
                                  models.Trait.convert_value(dtype, value))
                     for name, dtype, value in ev['traits']],
             raw=ev.get('raw', {}))
         for ev in payload if publisher_utils.verify_signature(
             ev, cfg.CONF.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(events)
Пример #24
0
 def sample(self, ctxt, publisher_id, event_type, payload, metadata):
     events = [
         models.Event(
             message_id=ev['message_id'],
             event_type=ev['event_type'],
             generated=timeutils.normalize_time(
                 timeutils.parse_isotime(ev['generated'])),
             traits=[models.Trait(name, dtype,
                                  models.Trait.convert_value(dtype, value))
                     for name, dtype, value in ev['traits']],
             raw=ev.get('raw', {}))
         for ev in payload if publisher_utils.verify_signature(
             ev, cfg.CONF.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(events)
Пример #25
0
 def sample(self, ctxt, publisher_id, event_type, payload, metadata):
     samples = [
         sample_util.Sample(name=s['counter_name'],
                            type=s['counter_type'],
                            unit=s['counter_unit'],
                            volume=s['counter_volume'],
                            user_id=s['user_id'],
                            project_id=s['project_id'],
                            resource_id=s['resource_id'],
                            timestamp=s['timestamp'],
                            resource_metadata=s['resource_metadata'],
                            source=s.get('source')) for s in payload
         if publisher_utils.verify_signature(
             s, cfg.CONF.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(samples)
Пример #26
0
 def sample(self, ctxt, publisher_id, event_type, payload, metadata):
     samples = [
         sample_util.Sample(name=s['counter_name'],
                            type=s['counter_type'],
                            unit=s['counter_unit'],
                            volume=s['counter_volume'],
                            user_id=s['user_id'],
                            project_id=s['project_id'],
                            resource_id=s['resource_id'],
                            timestamp=s['timestamp'],
                            resource_metadata=s['resource_metadata'],
                            source=s.get('source'))
         for s in payload if publisher_utils.verify_signature(
             s, cfg.CONF.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(samples)
Пример #27
0
 def sample(self, messages):
     samples = chain.from_iterable(m["payload"] for m in messages)
     samples = [
         sample_util.Sample(name=s['counter_name'],
                            type=s['counter_type'],
                            unit=s['counter_unit'],
                            volume=s['counter_volume'],
                            user_id=s['user_id'],
                            project_id=s['project_id'],
                            resource_id=s['resource_id'],
                            timestamp=s['timestamp'],
                            resource_metadata=s['resource_metadata'],
                            source=s.get('source')) for s in samples
         if publisher_utils.verify_signature(
             s, self.conf.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(sorted(samples, key=methodcaller('get_iso_timestamp')))
Пример #28
0
 def sample(self, messages):
     samples = chain.from_iterable(m["payload"] for m in messages)
     samples = [
         sample_util.Sample(name=s['counter_name'],
                            type=s['counter_type'],
                            unit=s['counter_unit'],
                            volume=s['counter_volume'],
                            user_id=s['user_id'],
                            project_id=s['project_id'],
                            resource_id=s['resource_id'],
                            timestamp=s['timestamp'],
                            resource_metadata=s['resource_metadata'],
                            source=s.get('source'))
         for s in samples if publisher_utils.verify_signature(
             s, self.conf.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(sorted(samples, key=methodcaller('get_iso_timestamp')))
Пример #29
0
    def record_events(self, events):
        if not isinstance(events, list):
            events = [events]

        for event in events:
            if publisher_utils.verify_signature(event, self.conf.publisher.telemetry_secret):
                res = None
                try:
                    res = requests.post(self.event_target, data=event, headers=self.headers, timeout=self.timeout)
                    res.raise_for_status()
                except Exception:
                    error_code = res.status_code if res else "unknown"
                    LOG.exception(
                        _LE("Status Code: %{code}s. Failed to" "dispatch event: %{event}s"),
                        {"code": error_code, "event": event},
                    )
            else:
                LOG.warning(_LW("event signature invalid, discarding event: %s"), event)
Пример #30
0
    def sample(self, messages):
        """RPC endpoint for notification messages

        When another service sends a notification over the message
        bus, this method receives it.
        """
        goods = []
        for sample in chain.from_iterable(m["payload"] for m in messages):
            if publisher_utils.verify_signature(sample, self.secret):
                goods.append(sample)
            else:
                LOG.warning(_LW('notification signature invalid, '
                                'discarding: %s'), sample)
        try:
            self.dispatcher_manager.map_method(self.method, goods)
        except Exception:
            LOG.exception(_LE("Dispatcher failed to handle the notification, "
                              "re-queuing it."))
            return oslo_messaging.NotificationResult.REQUEUE
Пример #31
0
    def start_udp(self):
        address_family = socket.AF_INET
        if netutils.is_valid_ipv6(self.conf.collector.udp_address):
            address_family = socket.AF_INET6
        udp = socket.socket(address_family, socket.SOCK_DGRAM)
        udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            # NOTE(zhengwei): linux kernel >= 3.9
            udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        except Exception:
            LOG.warning(
                _LW("System does not support socket.SO_REUSEPORT "
                    "option. Only one worker will be able to process "
                    "incoming data."))
        udp.bind(
            (self.conf.collector.udp_address, self.conf.collector.udp_port))

        self.udp_run = True
        while self.udp_run:
            # NOTE(sileht): return every 10 seconds to allow
            # clear shutdown
            if not select.select([udp], [], [], 10.0)[0]:
                continue
            # NOTE(jd) Arbitrary limit of 64K because that ought to be
            # enough for anybody.
            data, source = udp.recvfrom(64 * units.Ki)
            try:
                sample = msgpack.loads(data, encoding='utf-8')
            except Exception:
                LOG.warning(_("UDP: Cannot decode data sent by %s"), source)
            else:
                if publisher_utils.verify_signature(
                        sample, self.conf.publisher.telemetry_secret):
                    try:
                        LOG.debug("UDP: Storing %s", sample)
                        self.meter_manager.map_method('record_metering_data',
                                                      sample)
                    except Exception:
                        LOG.exception(_("UDP: Unable to store meter"))
                else:
                    LOG.warning(
                        _LW('sample signature invalid, '
                            'discarding: %s'), sample)
Пример #32
0
 def sample(self, messages):
     samples = chain.from_iterable(m["payload"] for m in messages)
     samples = [
         sample_util.Sample(
             name=s["counter_name"],
             type=s["counter_type"],
             unit=s["counter_unit"],
             volume=s["counter_volume"],
             user_id=s["user_id"],
             project_id=s["project_id"],
             resource_id=s["resource_id"],
             timestamp=s["timestamp"],
             resource_metadata=s["resource_metadata"],
             source=s.get("source"),
         )
         for s in samples
         if publisher_utils.verify_signature(s, cfg.CONF.publisher.telemetry_secret)
     ]
     with self.publish_context as p:
         p(samples)
Пример #33
0
    def sample(self, messages):
        """RPC endpoint for notification messages

        When another service sends a notification over the message
        bus, this method receives it.
        """
        goods = []
        for sample in chain.from_iterable(m["payload"] for m in messages):
            if publisher_utils.verify_signature(sample, self.secret):
                goods.append(sample)
            else:
                LOG.warning(
                    'notification signature invalid, '
                    'discarding: %s', sample)
        try:
            self.dispatcher_manager.map_method(self.method, goods)
        except Exception:
            LOG.exception("Dispatcher failed to handle the notification, "
                          "re-queuing it.")
            return oslo_messaging.NotificationResult.REQUEUE
Пример #34
0
    def start_udp(self):
        address_family = socket.AF_INET
        if netutils.is_valid_ipv6(self.conf.collector.udp_address):
            address_family = socket.AF_INET6
        udp = socket.socket(address_family, socket.SOCK_DGRAM)
        udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            # NOTE(zhengwei): linux kernel >= 3.9
            udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        except Exception:
            LOG.warning(_LW("System does not support socket.SO_REUSEPORT "
                            "option. Only one worker will be able to process "
                            "incoming data."))
        udp.bind((self.conf.collector.udp_address,
                  self.conf.collector.udp_port))

        self.udp_run = True
        while self.udp_run:
            # NOTE(sileht): return every 10 seconds to allow
            # clear shutdown
            if not select.select([udp], [], [], 10.0)[0]:
                continue
            # NOTE(jd) Arbitrary limit of 64K because that ought to be
            # enough for anybody.
            data, source = udp.recvfrom(64 * units.Ki)
            try:
                sample = msgpack.loads(data, encoding='utf-8')
            except Exception:
                LOG.warning(_("UDP: Cannot decode data sent by %s"), source)
            else:
                if publisher_utils.verify_signature(
                        sample, self.conf.publisher.telemetry_secret):
                    try:
                        LOG.debug("UDP: Storing %s", sample)
                        self.meter_manager.map_method(
                            'record_metering_data', sample)
                    except Exception:
                        LOG.exception(_("UDP: Unable to store meter"))
                else:
                    LOG.warning(_LW('sample signature invalid, '
                                    'discarding: %s'), sample)
Пример #35
0
    def record_events(self, events):
        if not isinstance(events, list):
            events = [events]

        for event in events:
            if publisher_utils.verify_signature(
                    event, self.conf.publisher.telemetry_secret):
                res = None
                try:
                    res = requests.post(self.event_target, data=event,
                                        headers=self.headers,
                                        timeout=self.timeout)
                    res.raise_for_status()
                except Exception:
                    error_code = res.status_code if res else 'unknown'
                    LOG.exception(_LE('Status Code: %{code}s. Failed to'
                                      'dispatch event: %{event}s'),
                                  {'code': error_code, 'event': event})
            else:
                LOG.warning(_LW(
                    'event signature invalid, discarding event: %s'), event)
Пример #36
0
 def process_notifications(self, priority, notifications):
     samples = chain.from_iterable(m["payload"] for m in notifications)
     samples = [
         sample_util.Sample(name=s['counter_name'],
                            type=s['counter_type'],
                            unit=s['counter_unit'],
                            volume=s['counter_volume'],
                            user_id=s['user_id'],
                            project_id=s['project_id'],
                            resource_id=s['resource_id'],
                            timestamp=s['timestamp'],
                            resource_metadata=s['resource_metadata'],
                            source=s.get('source'),
                            # NOTE(sileht): May come from an older node,
                            # Put None in this case.
                            monotonic_time=s.get('monotonic_time'))
         for s in samples if publisher_utils.verify_signature(
             s, self.conf.publisher.telemetry_secret)
     ]
     with self.publisher as p:
         p(sorted(samples, key=methodcaller('get_iso_timestamp')))
Пример #37
0
 def sample(self, ctxt, publisher_id, event_type, payload, metadata):
     events = [
         models.Event(
             message_id=ev['message_id'],
             event_type=ev['event_type'],
             generated=timeutils.normalize_time(
                 timeutils.parse_isotime(ev['generated'])),
             traits=[models.Trait(name, dtype,
                                  models.Trait.convert_value(dtype, value))
                     for name, dtype, value in ev['traits']],
             raw=ev.get('raw', {}))
         for ev in payload if publisher_utils.verify_signature(
             ev, cfg.CONF.publisher.telemetry_secret)
     ]
     try:
         with self.publish_context as p:
             p(events)
     except Exception:
         if not cfg.CONF.notification.ack_on_event_error:
             return oslo_messaging.NotificationResult.REQUEUE
         raise
     return oslo_messaging.NotificationResult.HANDLED
Пример #38
0
    def record_metering_data(self, data):
        if self.target == '':
            # if the target was not set, do not do anything
            LOG.error(_('Dispatcher target was not set, no meter will '
                        'be posted. Set the target in the ceilometer.conf '
                        'file'))
            return

        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(meter)
            if publisher_utils.verify_signature(
                    meter, self.conf.publisher.telemetry_secret):
                try:
                    if self.cadf_only:
                        # Only cadf messages are being wanted.
                        data = meter.get('resource_metadata')
                        if not data:
                            continue
                    else:
                        # Every meter should be posted to the target
                        data = meter
                    res = requests.post(self.target,
                                        data=json.dumps(data),
                                        headers=self.headers,
                                        timeout=self.timeout)
                    LOG.debug('Message posting finished with status code '
                              '%d.', res.status_code)
                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'),
                                  err)
            else:
                LOG.warning(_(
                    'message signature invalid, discarding message: %r'),
                    meter)
Пример #39
0
 def sample(self, messages):
     events = chain.from_iterable(m["payload"] for m in messages)
     events = [
         models.Event(
             message_id=ev["message_id"],
             event_type=ev["event_type"],
             generated=timeutils.normalize_time(timeutils.parse_isotime(ev["generated"])),
             traits=[
                 models.Trait(name, dtype, models.Trait.convert_value(dtype, value))
                 for name, dtype, value in ev["traits"]
             ],
             raw=ev.get("raw", {}),
         )
         for ev in events
         if publisher_utils.verify_signature(ev, cfg.CONF.publisher.telemetry_secret)
     ]
     try:
         with self.publish_context as p:
             p(events)
     except Exception:
         if not cfg.CONF.notification.ack_on_event_error:
             return oslo_messaging.NotificationResult.REQUEUE
         raise
     return oslo_messaging.NotificationResult.HANDLED
Пример #40
0
 def test_verify_no_secret(self):
     data = {'a': 'A', 'b': 'B'}
     self.assertTrue(utils.verify_signature(data, ''))
Пример #41
0
 def test_verify_signature_unsigned(self):
     data = {'a': 'A', 'b': 'B'}
     self.assertFalse(utils.verify_signature(data, 'not-so-secret'))
Пример #42
0
 def test_verify_signature_unicode(self):
     data = {'a': 'A', 'b': 'B',
             'message_signature': u''}
     self.assertFalse(utils.verify_signature(data, 'not-so-secret'))
Пример #43
0
 def test_verify_no_secret(self):
     data = {"a": "A", "b": "B"}
     self.assertTrue(utils.verify_signature(data, ""))
Пример #44
0
 def test_verify_signature_incorrect(self):
     data = {'a': 'A', 'b': 'B',
             'message_signature': 'Not the same'}
     self.assertFalse(utils.verify_signature(data, 'not-so-secret'))
Пример #45
0
    def record_metering_data(self, data):
        # We may have receive only one counter on the wire
        if not isinstance(data, list):
            data = [data]

        for meter in data:
            LOG.debug(
                _('metering data %(counter_name)s '
                  'for %(resource_id)s @ %(timestamp)s: %(counter_volume)s') %
                ({
                    'counter_name': meter['counter_name'],
                    'resource_id': meter['resource_id'],
                    'timestamp': meter.get('timestamp', 'NO TIMESTAMP'),
                    'counter_volume': meter['counter_volume']
                }))
            if publisher_utils.verify_signature(
                    meter, self.conf.publisher.metering_secret):
                try:
                    # Convert the timestamp to a datetime instance.
                    # Storage engines are responsible for converting
                    # that value to something they can store.
                    if meter.get('timestamp'):
                        ts = timeutils.parse_isotime(meter['timestamp'])
                        #meter['timestamp'] = timeutils.normalize_time(ts)

                    if meter.get('resource_metadata'):
                        resource_metadata = meter['resource_metadata']
                        if resource_metadata.get('instance_id'):
                            instance_uuid = resource_metadata['instance_id']
                            meter_name = meter['counter_name']
                            resource_id = meter['resource_id']

                            meter_map = self.instance_map.get(instance_uuid)
                            if meter_map is None:
                                meter_map = {}
                                self.instance_map[instance_uuid] = meter_map

                            resource_set = meter_map.get(meter_name)
                            if resource_set is None:
                                resource_set = set()
                                meter_map[meter_name] = resource_set
                            resource_set.add(resource_id)

                            meter_map_json = json.dumps(meter_map,
                                                        cls=SetJSONEncoder)
                            print meter_map_json
                            self.redis_conn.set("metermeta-" + instance_uuid,
                                                meter_map_json)
                            counter_map = {}
                            counter_map['counter_name'] = meter['counter_name']
                            counter_map['counter_unit'] = meter['counter_unit']
                            counter_map['counter_type'] = meter['counter_type']
                            counter_map['counter_volume'] = meter[
                                'counter_volume']
                            counter_map['timestamp'] = meter['timestamp']

                            counter_map_json = json.dumps(counter_map)
                            print counter_map_json
                            self.redis_conn.set(meter_name + '-' + resource_id,
                                                counter_map_json)

                            print "%s instance: %s, meter_name: %s, volume: %s" %\
                                  (meter['timestamp'], resource_metadata['instance_id'],
                                   meter['counter_name'], meter['counter_volume'])

                        elif resource_metadata.get('hostname'):
                            hostname = resource_metadata['hostname']
                            meter_name = meter['counter_name']
                            resource_id = meter['resource_id']

                            meter_map = self.host_map.get(hostname)
                            if meter_map is None:
                                meter_map = {}
                                self.host_map[hostname] = meter_map

                            resource_set = meter_map.get(meter_name)
                            if resource_set is None:
                                resource_set = set()
                                meter_map[meter_name] = resource_set
                            resource_set.add(resource_id)

                            meter_map_json = json.dumps(meter_map,
                                                        cls=SetJSONEncoder)
                            print meter_map_json
                            self.redis_conn.set("metermeta-" + hostname,
                                                meter_map_json)

                            counter_map = {}
                            counter_map['counter_name'] = meter['counter_name']
                            counter_map['counter_unit'] = meter['counter_unit']
                            counter_map['counter_type'] = meter['counter_type']
                            counter_map['counter_volume'] = meter[
                                'counter_volume']
                            counter_map['timestamp'] = meter['timestamp']

                            counter_map_json = json.dumps(counter_map)
                            print counter_map_json
                            self.redis_conn.set(meter_name + '-' + resource_id,
                                                counter_map_json)

                            print "%s hostname: %s, meter_name: %s, volume: %s" % \
                                  (meter['timestamp'], resource_metadata['hostname'],
                                   meter['counter_name'], meter['counter_volume'])

                except Exception as err:
                    LOG.exception(_('Failed to record metering data: %s'), err)
            else:
                LOG.warning(
                    _('message signature invalid, discarding message: %r'),
                    meter)
Пример #46
0
 def test_verify_signature_invalid_encoding(self):
     data = {'a': 'A', 'b': 'B',
             'message_signature': ''}
     self.assertFalse(utils.verify_signature(data, 'not-so-secret'))
Пример #47
0
 def test_verify_signature_signed(self):
     data = {'a': 'A', 'b': 'B'}
     sig1 = utils.compute_signature(data, 'not-so-secret')
     data['message_signature'] = sig1
     self.assertTrue(utils.verify_signature(data, 'not-so-secret'))