def test_convert_req_action(self): self.assertEqual(cadftaxonomy.ACTION_READ, api.convert_req_action('get')) self.assertEqual(cadftaxonomy.ACTION_CREATE, api.convert_req_action('POST')) self.assertEqual(cadftaxonomy.ACTION_DELETE, api.convert_req_action('deLetE'))
def emit_event(self, env, bytes_received, bytes_sent, outcome='success'): if ((env.get('HTTP_X_SERVICE_PROJECT_ID') or env.get('HTTP_X_PROJECT_ID') or env.get('HTTP_X_TENANT_ID')) in self.ignore_projects or env.get('swift.source') is not None): return path = urlparse.quote(env['PATH_INFO']) method = env['REQUEST_METHOD'] headers = {} for header in env: if header.startswith('HTTP_') and env[header]: key = header[5:] if isinstance(env[header], six.text_type): headers[key] = six.text_type(env[header]) else: headers[key] = str(env[header]) try: container = obj = None path = path.replace('/', '', 1) version, account, remainder = path.split('/', 2) except ValueError: try: version, account = path.split('/', 1) remainder = None except ValueError: return try: if not version or not account: raise ValueError('Invalid path: %s' % path) if remainder: if '/' in remainder: container, obj = remainder.split('/', 1) else: container = remainder except ValueError: return now = timeutils.utcnow().isoformat() resource_metadata = { "path": path, "version": version, "container": container, "object": obj, } for header in self.metadata_headers: if header.upper() in headers: resource_metadata['http_header_%s' % header] = headers.get( header.upper()) # build object store details target = cadf_resource.Resource( typeURI='service/storage/object', id=account.partition(self.reseller_prefix)[2] or path) target.metadata = resource_metadata target.action = method.lower() # build user details initiator = cadf_resource.Resource( typeURI='service/security/account/user', id=env.get('HTTP_X_USER_ID')) initiator.project_id = (env.get('HTTP_X_PROJECT_ID') or env.get('HTTP_X_TENANT_ID')) # build notification body event = cadf_event.Event(eventTime=now, outcome=outcome, action=api.convert_req_action(method), initiator=initiator, target=target, observer=cadf_resource.Resource(id='target')) # measurements if bytes_received: event.add_measurement(cadf_measurement.Measurement( result=bytes_received, metric=cadf_metric.Metric( name='storage.objects.incoming.bytes', unit='B'))) if bytes_sent: event.add_measurement(cadf_measurement.Measurement( result=bytes_sent, metric=cadf_metric.Metric( name='storage.objects.outgoing.bytes', unit='B'))) self._notifier.info(context.get_admin_context().to_dict(), 'objectstore.http.request', event.as_dict())
def test_convert_req_action_with_details_invalid(self): detail = 123 self.assertEqual(cadftaxonomy.ACTION_READ, api.convert_req_action('GET', detail)) self.assertEqual(cadftaxonomy.ACTION_DELETE, api.convert_req_action('DELETE', detail))
def test_convert_req_action_with_details(self): detail = 'compute/instance' self.assertEqual(cadftaxonomy.ACTION_READ + '/%s' % detail, api.convert_req_action('GET', detail)) self.assertEqual(cadftaxonomy.ACTION_DELETE + '/%s' % detail, api.convert_req_action('DELETE', detail))
def test_convert_req_action_invalid(self): self.assertEqual(cadftaxonomy.UNKNOWN, api.convert_req_action(124)) self.assertEqual(cadftaxonomy.UNKNOWN, api.convert_req_action('blah'))
def emit_event(self, env, bytes_received, bytes_sent, outcome='success'): if ((env.get('HTTP_X_SERVICE_PROJECT_ID') or env.get('HTTP_X_PROJECT_ID') or env.get('HTTP_X_TENANT_ID')) in self.ignore_projects or env.get('swift.source') is not None): return path = urlparse.quote(env['PATH_INFO']) method = env['REQUEST_METHOD'] headers = {} for header in env: if header.startswith('HTTP_') and env[header]: key = header[5:] if isinstance(env[header], six.text_type): headers[key] = six.text_type(env[header]) else: headers[key] = str(env[header]) try: container = obj = None path = path.replace('/', '', 1) version, account, remainder = path.split('/', 2) except ValueError: try: version, account = path.split('/', 1) remainder = None except ValueError: return try: if not version or not account: raise ValueError('Invalid path: %s' % path) if remainder: if '/' in remainder: container, obj = remainder.split('/', 1) else: container = remainder except ValueError: return now = timeutils.utcnow().isoformat() resource_metadata = { "path": path, "version": version, "container": container, "object": obj, } for header in self.metadata_headers: if header.upper() in headers: resource_metadata['http_header_%s' % header] = headers.get( header.upper()) # build object store details target = cadf_resource.Resource( typeURI='service/storage/object', id=account.partition(self.reseller_prefix)[2] or path) target.metadata = resource_metadata target.action = method.lower() # build user details initiator = cadf_resource.Resource( typeURI='service/security/account/user', id=env.get('HTTP_X_USER_ID')) initiator.project_id = (env.get('HTTP_X_PROJECT_ID') or env.get('HTTP_X_TENANT_ID')) # build notification body event = cadf_event.Event(eventTime=now, outcome=outcome, action=api.convert_req_action(method), initiator=initiator, target=target, observer=cadf_resource.Resource(id='target')) # measurements if bytes_received: event.add_measurement( cadf_measurement.Measurement( result=bytes_received, metric=cadf_metric.Metric( name='storage.objects.incoming.bytes', unit='B'))) if bytes_sent: event.add_measurement( cadf_measurement.Measurement( result=bytes_sent, metric=cadf_metric.Metric( name='storage.objects.outgoing.bytes', unit='B'))) self._notifier.info(context.get_admin_context().to_dict(), 'objectstore.http.request', event.as_dict())