Beispiel #1
0
 def test_restore_nesting(self):
     metadata = {
         'a': 'A',
         'b': 'B',
         'nested:a': 'A',
         'nested:b': 'B',
         'nested:twice:c': 'C',
         'nested:twice:d': 'D',
         'embedded:e': 'E'
     }
     unwound = utils.restore_nesting(metadata)
     expected = {
         'a': 'A',
         'b': 'B',
         'nested': {
             'a': 'A',
             'b': 'B',
             'twice': {
                 'c': 'C',
                 'd': 'D'
             }
         },
         'embedded': {
             'e': 'E'
         }
     }
     self.assertEqual(expected, unwound)
     self.assertIsNot(metadata, unwound)
Beispiel #2
0
 def test_restore_nesting_with_separator(self):
     metadata = {
         'a': 'A',
         'b': 'B',
         'nested.a': 'A',
         'nested.b': 'B',
         'nested.twice.c': 'C',
         'nested.twice.d': 'D',
         'embedded.e': 'E'
     }
     unwound = utils.restore_nesting(metadata, separator='.')
     expected = {
         'a': 'A',
         'b': 'B',
         'nested': {
             'a': 'A',
             'b': 'B',
             'twice': {
                 'c': 'C',
                 'd': 'D'
             }
         },
         'embedded': {
             'e': 'E'
         }
     }
     self.assertEqual(expected, unwound)
     self.assertIsNot(metadata, unwound)
Beispiel #3
0
 def test_restore_nesting_with_separator(self):
     metadata = {'a': 'A', 'b': 'B',
                 'nested.a': 'A',
                 'nested.b': 'B',
                 'nested.twice.c': 'C',
                 'nested.twice.d': 'D',
                 'embedded.e': 'E'}
     unwound = utils.restore_nesting(metadata, separator='.')
     expected = {'a': 'A', 'b': 'B',
                 'nested': {'a': 'A', 'b': 'B',
                            'twice': {'c': 'C', 'd': 'D'}},
                 'embedded': {'e': 'E'}}
     self.assertEqual(expected, unwound)
     self.assertIsNot(metadata, unwound)
Beispiel #4
0
 def test_restore_nesting(self):
     metadata = {'a': 'A', 'b': 'B',
                 'nested:a': 'A',
                 'nested:b': 'B',
                 'nested:twice:c': 'C',
                 'nested:twice:d': 'D',
                 'embedded:e': 'E'}
     unwound = utils.restore_nesting(metadata)
     expected = {'a': 'A', 'b': 'B',
                 'nested': {'a': 'A', 'b': 'B',
                            'twice': {'c': 'C', 'd': 'D'}},
                 'embedded': {'e': 'E'}}
     self.assertEqual(expected, unwound)
     self.assertIsNot(metadata, unwound)
Beispiel #5
0
    def post(self, samples):
        """Post a list of new Samples to Telemetry.

        :param samples: a list of samples within the request body.
        """

        rbac.enforce('create_samples', pecan.request)

        now = timeutils.utcnow()
        auth_project = rbac.get_limited_to_project(pecan.request.headers)
        def_source = pecan.request.cfg.sample_source
        def_project_id = pecan.request.headers.get('X-Project-Id')
        def_user_id = pecan.request.headers.get('X-User-Id')

        published_samples = []
        for s in samples:
            if self.meter_name != s.counter_name:
                raise wsme.exc.InvalidInput('counter_name', s.counter_name,
                                            'should be %s' % self.meter_name)

            if s.message_id:
                raise wsme.exc.InvalidInput('message_id', s.message_id,
                                            'The message_id must not be set')

            if s.counter_type not in sample.TYPES:
                raise wsme.exc.InvalidInput(
                    'counter_type', s.counter_type,
                    'The counter type must be: ' + ', '.join(sample.TYPES))

            s.user_id = (s.user_id or def_user_id)
            s.project_id = (s.project_id or def_project_id)
            s.source = '%s:%s' % (s.project_id, (s.source or def_source))
            s.timestamp = (s.timestamp or now)

            if auth_project and auth_project != s.project_id:
                # non admin user trying to cross post to another project_id
                auth_msg = 'can not post samples to other projects'
                raise wsme.exc.InvalidInput('project_id', s.project_id,
                                            auth_msg)

            published_sample = sample.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.isoformat(),
                resource_metadata=utils.restore_nesting(s.resource_metadata,
                                                        separator='.'),
                source=s.source)
            published_samples.append(published_sample)

            s.message_id = published_sample.id

        with pecan.request.pipeline_manager.publisher(
                context.get_admin_context()) as publisher:
            publisher(published_samples)

        return samples
Beispiel #6
0
    def post(self, direct='', samples=None):
        """Post a list of new Samples to Telemetry.

        :param direct: a flag indicates whether the samples will be posted
                       directly to storage or not.
        :param samples: a list of samples within the request body.
        """
        rbac.enforce('create_samples', pecan.request)

        direct = strutils.bool_from_string(direct)
        if not samples:
            msg = _('Samples should be included in request body')
            raise base.ClientSideError(msg)

        now = timeutils.utcnow()
        auth_project = rbac.get_limited_to_project(pecan.request.headers)
        def_source = pecan.request.cfg.sample_source
        def_project_id = pecan.request.headers.get('X-Project-Id')
        def_user_id = pecan.request.headers.get('X-User-Id')

        published_samples = []
        for s in samples:
            if self.meter_name != s.counter_name:
                raise wsme.exc.InvalidInput('counter_name', s.counter_name,
                                            'should be %s' % self.meter_name)

            if s.message_id:
                raise wsme.exc.InvalidInput('message_id', s.message_id,
                                            'The message_id must not be set')

            if s.counter_type not in sample.TYPES:
                raise wsme.exc.InvalidInput('counter_type', s.counter_type,
                                            'The counter type must be: ' +
                                            ', '.join(sample.TYPES))

            s.user_id = (s.user_id or def_user_id)
            s.project_id = (s.project_id or def_project_id)
            s.source = '%s:%s' % (s.project_id, (s.source or def_source))
            s.timestamp = (s.timestamp or now)

            if auth_project and auth_project != s.project_id:
                # non admin user trying to cross post to another project_id
                auth_msg = 'can not post samples to other projects'
                raise wsme.exc.InvalidInput('project_id', s.project_id,
                                            auth_msg)

            published_sample = sample.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.isoformat(),
                resource_metadata=utils.restore_nesting(s.resource_metadata,
                                                        separator='.'),
                source=s.source)
            s.message_id = published_sample.id

            sample_dict = publisher_utils.meter_message_from_counter(
                published_sample, cfg.CONF.publisher.telemetry_secret)
            if direct:
                ts = timeutils.parse_isotime(sample_dict['timestamp'])
                sample_dict['timestamp'] = timeutils.normalize_time(ts)
                pecan.request.storage_conn.record_metering_data(sample_dict)
            else:
                published_samples.append(sample_dict)
        if not direct:
            ctxt = context.RequestContext(user=def_user_id,
                                          tenant=def_project_id,
                                          is_admin=True)
            notifier = pecan.request.notifier
            notifier.info(ctxt.to_dict(), 'telemetry.api', published_samples)

        return samples
Beispiel #7
0
    def post(self, samples):
        """Post a list of new Samples to Telemetry.

        :param samples: a list of samples within the request body.
        """

        rbac.enforce('create_samples', pecan.request)

        now = timeutils.utcnow()
        auth_project = rbac.get_limited_to_project(pecan.request.headers)
        def_source = pecan.request.cfg.sample_source
        def_project_id = pecan.request.headers.get('X-Project-Id')
        def_user_id = pecan.request.headers.get('X-User-Id')

        published_samples = []
        for s in samples:
            for p in pecan.request.pipeline_manager.pipelines:
                if p.support_meter(s.counter_name):
                    break
            else:
                message = _("The metric %s is not supported by metering "
                            "pipeline configuration.") % s.counter_name
                raise base.ClientSideError(message, status_code=409)

            if self.meter_name != s.counter_name:
                raise wsme.exc.InvalidInput('counter_name', s.counter_name,
                                            'should be %s' % self.meter_name)

            if s.message_id:
                raise wsme.exc.InvalidInput('message_id', s.message_id,
                                            'The message_id must not be set')

            if s.counter_type not in sample.TYPES:
                raise wsme.exc.InvalidInput('counter_type', s.counter_type,
                                            'The counter type must be: ' +
                                            ', '.join(sample.TYPES))

            s.user_id = (s.user_id or def_user_id)
            s.project_id = (s.project_id or def_project_id)
            s.source = '%s:%s' % (s.project_id, (s.source or def_source))
            s.timestamp = (s.timestamp or now)

            if auth_project and auth_project != s.project_id:
                # non admin user trying to cross post to another project_id
                auth_msg = 'can not post samples to other projects'
                raise wsme.exc.InvalidInput('project_id', s.project_id,
                                            auth_msg)

            published_sample = sample.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.isoformat(),
                resource_metadata=utils.restore_nesting(s.resource_metadata,
                                                        separator='.'),
                source=s.source)
            published_samples.append(published_sample)

            s.message_id = published_sample.id

        with pecan.request.pipeline_manager.publisher(
                context.get_admin_context()) as publisher:
            publisher(published_samples)

        return samples
Beispiel #8
0
 def test_restore_nesting_unested(self):
     metadata = {'a': 'A', 'b': 'B'}
     unwound = utils.restore_nesting(metadata)
     self.assertIs(metadata, unwound)
Beispiel #9
0
    def post(self, direct='', samples=None):
        """Post a list of new Samples to Telemetry.

        :param direct: a flag indicates whether the samples will be posted
                       directly to storage or not.
        :param samples: a list of samples within the request body.
        """
        rbac.enforce('create_samples', pecan.request)

        direct = strutils.bool_from_string(direct)
        if not samples:
            msg = _('Samples should be included in request body')
            raise base.ClientSideError(msg)

        now = timeutils.utcnow()
        auth_project = rbac.get_limited_to_project(pecan.request.headers)
        def_source = pecan.request.cfg.sample_source
        def_project_id = pecan.request.headers.get('X-Project-Id')
        def_user_id = pecan.request.headers.get('X-User-Id')

        published_samples = []
        for s in samples:
            if self.meter_name != s.counter_name:
                raise wsme.exc.InvalidInput('counter_name', s.counter_name,
                                            'should be %s' % self.meter_name)

            if s.message_id:
                raise wsme.exc.InvalidInput('message_id', s.message_id,
                                            'The message_id must not be set')

            if s.counter_type not in sample.TYPES:
                raise wsme.exc.InvalidInput(
                    'counter_type', s.counter_type,
                    'The counter type must be: ' + ', '.join(sample.TYPES))

            s.user_id = (s.user_id or def_user_id)
            s.project_id = (s.project_id or def_project_id)
            s.source = '%s:%s' % (s.project_id, (s.source or def_source))
            s.timestamp = (s.timestamp or now)

            if auth_project and auth_project != s.project_id:
                # non admin user trying to cross post to another project_id
                auth_msg = 'can not post samples to other projects'
                raise wsme.exc.InvalidInput('project_id', s.project_id,
                                            auth_msg)

            published_sample = sample.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.isoformat(),
                resource_metadata=utils.restore_nesting(s.resource_metadata,
                                                        separator='.'),
                source=s.source)
            s.message_id = published_sample.id

            sample_dict = publisher_utils.meter_message_from_counter(
                published_sample, cfg.CONF.publisher.telemetry_secret)
            if direct:
                ts = timeutils.parse_isotime(sample_dict['timestamp'])
                sample_dict['timestamp'] = timeutils.normalize_time(ts)
                pecan.request.storage_conn.record_metering_data(sample_dict)
            else:
                published_samples.append(sample_dict)
        if not direct:
            pecan.request.notifier.sample(
                {
                    'user': def_user_id,
                    'tenant': def_project_id,
                    'is_admin': True
                }, 'telemetry.api', {'samples': published_samples})

        return samples
Beispiel #10
0
 def test_restore_nesting_unested(self):
     metadata = {'a': 'A', 'b': 'B'}
     unwound = utils.restore_nesting(metadata)
     self.assertIs(metadata, unwound)
Beispiel #11
0
    def post(self, direct="", samples=None):
        """Post a list of new Samples to Telemetry.

        :param direct: a flag indicates whether the samples will be posted
                       directly to storage or not.
        :param samples: a list of samples within the request body.
        """
        rbac.enforce("create_samples", pecan.request)

        direct = strutils.bool_from_string(direct)
        if not samples:
            msg = _("Samples should be included in request body")
            raise base.ClientSideError(msg)

        now = timeutils.utcnow()
        auth_project = rbac.get_limited_to_project(pecan.request.headers)
        def_source = pecan.request.cfg.sample_source
        def_project_id = pecan.request.headers.get("X-Project-Id")
        def_user_id = pecan.request.headers.get("X-User-Id")

        published_samples = []
        for s in samples:
            if self.meter_name != s.counter_name:
                raise wsme.exc.InvalidInput("counter_name", s.counter_name, "should be %s" % self.meter_name)

            if s.message_id:
                raise wsme.exc.InvalidInput("message_id", s.message_id, "The message_id must not be set")

            if s.counter_type not in sample.TYPES:
                raise wsme.exc.InvalidInput(
                    "counter_type", s.counter_type, "The counter type must be: " + ", ".join(sample.TYPES)
                )

            s.user_id = s.user_id or def_user_id
            s.project_id = s.project_id or def_project_id
            s.source = "%s:%s" % (s.project_id, (s.source or def_source))
            s.timestamp = s.timestamp or now

            if auth_project and auth_project != s.project_id:
                # non admin user trying to cross post to another project_id
                auth_msg = "can not post samples to other projects"
                raise wsme.exc.InvalidInput("project_id", s.project_id, auth_msg)

            published_sample = sample.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.isoformat(),
                resource_metadata=utils.restore_nesting(s.resource_metadata, separator="."),
                source=s.source,
            )
            s.message_id = published_sample.id

            sample_dict = publisher_utils.meter_message_from_counter(
                published_sample, pecan.request.cfg.publisher.telemetry_secret
            )
            if direct:
                ts = timeutils.parse_isotime(sample_dict["timestamp"])
                sample_dict["timestamp"] = timeutils.normalize_time(ts)
                pecan.request.storage_conn.record_metering_data(sample_dict)
            else:
                published_samples.append(sample_dict)
        if not direct:
            pecan.request.notifier.sample(
                {"user": def_user_id, "tenant": def_project_id, "is_admin": True},
                "telemetry.api",
                {"samples": published_samples},
            )

        return samples