Fix cross-tenant logs submission
* add 'delegate_roles' configuration option Change-Id: If4952b84536ef058d91f6ee2332076dc448d97bd
This commit is contained in:
parent
4b743bcc6c
commit
9bb918197e
|
@ -20,7 +20,9 @@ Create logs.
|
|||
None.
|
||||
|
||||
#### Query Parameters
|
||||
* tenant_id (string, optional, restricted) - Tenant ID to create log on behalf of. Usage of this query parameter requires the `monitoring-delegate` role.
|
||||
* tenant_id (string, optional, restricted) - Tenant ID (project ID) to create
|
||||
log on behalf of. Usage of this query parameter requires the role specified
|
||||
in the configuration option `delegate_roles` .
|
||||
|
||||
#### Request Body
|
||||
JSON object which can have a maximum size of 5 MB. It consists of global
|
||||
|
@ -241,9 +243,6 @@ Example:
|
|||
#### Path Parameters
|
||||
None.
|
||||
|
||||
#### Query Parameters
|
||||
* tenant_id (string, optional, restricted) - Tenant ID to create log on behalf of. Usage of this query parameter requires the `monitoring-delegate` role.
|
||||
|
||||
#### Request Body
|
||||
Consists of a single plain text message or a JSON object which can have a maximum length of 1048576 characters.
|
||||
|
||||
|
|
|
@ -53,3 +53,4 @@ kafka_topics = log
|
|||
path = /v2.0/log,/v3.0/logs
|
||||
default_roles = user,domainuser,domainadmin,monasca-user
|
||||
agent_roles = monasca-agent
|
||||
delegate_roles = admin
|
||||
|
|
|
@ -21,8 +21,6 @@ from monasca_log_api.monitoring import metrics
|
|||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
MONITORING_DELEGATE_ROLE = 'monitoring-delegate'
|
||||
|
||||
|
||||
class LogsApi(object):
|
||||
"""Logs API.
|
||||
|
|
|
@ -31,7 +31,11 @@ role_m_opts = [
|
|||
default=None,
|
||||
help=('List of roles, that if set, mean that request '
|
||||
'comes from agent, thus is authorized in the same '
|
||||
'time'))
|
||||
'time')),
|
||||
cfg.ListOpt(name='delegate_roles',
|
||||
default=['admin'],
|
||||
help=('Roles that are allowed to POST logs on '
|
||||
'behalf of another tenant (project)'))
|
||||
]
|
||||
role_m_group = cfg.OptGroup(name='roles_middleware', title='roles_middleware')
|
||||
|
||||
|
@ -81,12 +85,15 @@ class RoleMiddleware(om.ConfigurableMiddleware):
|
|||
path = /v2.0/log
|
||||
default_roles = monasca-user
|
||||
agent_roles = monasca-log-agent
|
||||
delegate_roles = admin
|
||||
|
||||
Configuration explained:
|
||||
|
||||
* path (list) - path (or list of paths) middleware should be applied
|
||||
* agent_roles (list) - list of roles that identifies tenant as an agent
|
||||
* default_roles (list) - list of roles that should be authorized
|
||||
* delegate_roles (list) - list of roles that are allowed to POST logs on
|
||||
behalf of another tenant (project)
|
||||
|
||||
Note:
|
||||
Being an agent means that tenant is automatically authorized.
|
||||
|
|
|
@ -20,7 +20,6 @@ from oslo_log import log
|
|||
import six
|
||||
|
||||
from monasca_log_api.api import exceptions
|
||||
from monasca_log_api.api import logs_api
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
@ -214,10 +213,12 @@ def validate_payload_size(req):
|
|||
)
|
||||
|
||||
|
||||
def validate_is_delegate(role):
|
||||
if role:
|
||||
role = role.split(',') if isinstance(role, six.string_types) else role
|
||||
return logs_api.MONITORING_DELEGATE_ROLE in role
|
||||
def validate_is_delegate(roles):
|
||||
delegate_roles = CONF.roles_middleware.delegate_roles
|
||||
if roles and delegate_roles:
|
||||
roles = roles.split(',') if isinstance(roles, six.string_types) \
|
||||
else roles
|
||||
return any(x in set(delegate_roles) for x in roles)
|
||||
return False
|
||||
|
||||
|
||||
|
@ -227,7 +228,7 @@ def validate_cross_tenant(tenant_id, cross_tenant_id, roles):
|
|||
if cross_tenant_id:
|
||||
raise falcon.HTTPForbidden(
|
||||
'Permission denied',
|
||||
'Projects %s cannot POST cross tenant metrics' % tenant_id
|
||||
'Projects %s cannot POST cross tenant logs' % tenant_id
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@ class Logs(logs_api.LogsApi):
|
|||
self._logs_size_gauge.send(name=None,
|
||||
value=int(req.content_length))
|
||||
|
||||
tenant_id = (req.project_id if req.project_id
|
||||
else req.cross_project_id)
|
||||
tenant_id = (req.cross_project_id if req.cross_project_id
|
||||
else req.project_id)
|
||||
|
||||
try:
|
||||
self._processor.send_message(
|
||||
|
|
|
@ -20,10 +20,11 @@ import unittest
|
|||
|
||||
from monasca_log_api.api import exceptions as log_api_exceptions
|
||||
from monasca_log_api.api import headers
|
||||
from monasca_log_api.api import logs_api
|
||||
from monasca_log_api.reference.v2 import logs
|
||||
from monasca_log_api.tests import base
|
||||
|
||||
ROLES = 'admin'
|
||||
|
||||
|
||||
def _init_resource(test):
|
||||
resource = logs.Logs()
|
||||
|
@ -121,7 +122,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: 'a:1',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '0'
|
||||
|
@ -147,7 +148,7 @@ class TestLogs(testing.TestBase):
|
|||
method='POST',
|
||||
query_string='tenant_id=1',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: 'a:1',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '0'
|
||||
|
@ -169,7 +170,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '0'
|
||||
|
@ -187,7 +188,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'video/3gpp',
|
||||
'Content-Length': '0'
|
||||
|
@ -208,7 +209,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -229,7 +230,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -250,7 +251,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -267,7 +268,7 @@ class TestLogs(testing.TestBase):
|
|||
'/log/single',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_DIMENSIONS.name: '',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
|
|
@ -16,18 +16,19 @@ import random
|
|||
import string
|
||||
import unittest
|
||||
|
||||
import falcon
|
||||
from falcon import testing
|
||||
import mock
|
||||
import ujson as json
|
||||
|
||||
from monasca_log_api.api import exceptions as log_api_exceptions
|
||||
from monasca_log_api.api import headers
|
||||
from monasca_log_api.api import logs_api
|
||||
from monasca_log_api.reference.v3 import logs
|
||||
from monasca_log_api.tests import base
|
||||
|
||||
ENDPOINT = '/logs'
|
||||
TENANT_ID = 'bob'
|
||||
ROLES = 'admin'
|
||||
|
||||
|
||||
def _init_resource(test):
|
||||
|
@ -101,7 +102,7 @@ class TestLogsMonitoring(testing.TestBase):
|
|||
ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_TENANT_ID.name: TENANT_ID,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -137,7 +138,7 @@ class TestLogsMonitoring(testing.TestBase):
|
|||
ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_TENANT_ID.name: TENANT_ID,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -181,7 +182,7 @@ class TestLogsMonitoring(testing.TestBase):
|
|||
ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: ROLES,
|
||||
headers.X_TENANT_ID.name: TENANT_ID,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
|
@ -204,3 +205,98 @@ class TestLogsMonitoring(testing.TestBase):
|
|||
self.assertEqual(1, size_gauge.call_count)
|
||||
self.assertEqual(content_length,
|
||||
size_gauge.mock_calls[0][2]['value'])
|
||||
|
||||
|
||||
class TestLogs(testing.TestBase):
|
||||
|
||||
api_class = base.MockedAPI
|
||||
|
||||
def before(self):
|
||||
self.conf = base.mock_config(self)
|
||||
|
||||
@mock.patch('monasca_log_api.reference.v3.common.bulk_processor.'
|
||||
'BulkProcessor')
|
||||
def test_should_pass_cross_tenant_id(self, bulk_processor):
|
||||
logs_resource = _init_resource(self)
|
||||
logs_resource._processor = bulk_processor
|
||||
|
||||
v3_body, v3_logs = _generate_v3_payload(1)
|
||||
payload = json.dumps(v3_body)
|
||||
content_length = len(payload)
|
||||
self.simulate_request(
|
||||
'/logs',
|
||||
method='POST',
|
||||
query_string='tenant_id=1',
|
||||
headers={
|
||||
headers.X_ROLES.name: ROLES,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
},
|
||||
body=payload
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
||||
logs_resource._processor.send_message.assert_called_with(
|
||||
logs=v3_logs,
|
||||
global_dimensions=v3_body['dimensions'],
|
||||
log_tenant_id='1')
|
||||
|
||||
@mock.patch('monasca_log_api.reference.v3.common.bulk_processor.'
|
||||
'BulkProcessor')
|
||||
def test_should_fail_not_delegate_ok_cross_tenant_id(self, _):
|
||||
_init_resource(self)
|
||||
self.simulate_request(
|
||||
'/logs',
|
||||
method='POST',
|
||||
query_string='tenant_id=1',
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '0'
|
||||
}
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_403, self.srmock.status)
|
||||
|
||||
@mock.patch('monasca_log_api.reference.v3.common.bulk_processor.'
|
||||
'BulkProcessor')
|
||||
def test_should_pass_empty_cross_tenant_id_wrong_role(self,
|
||||
bulk_processor):
|
||||
logs_resource = _init_resource(self)
|
||||
logs_resource._processor = bulk_processor
|
||||
|
||||
v3_body, _ = _generate_v3_payload(1)
|
||||
payload = json.dumps(v3_body)
|
||||
content_length = len(payload)
|
||||
self.simulate_request(
|
||||
'/logs',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: 'some_role',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
},
|
||||
body=payload
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
||||
self.assertEqual(1, bulk_processor.send_message.call_count)
|
||||
|
||||
@mock.patch('monasca_log_api.reference.v3.common.bulk_processor.'
|
||||
'BulkProcessor')
|
||||
def test_should_pass_empty_cross_tenant_id_ok_role(self,
|
||||
bulk_processor):
|
||||
logs_resource = _init_resource(self)
|
||||
logs_resource._processor = bulk_processor
|
||||
|
||||
v3_body, _ = _generate_v3_payload(1)
|
||||
payload = json.dumps(v3_body)
|
||||
content_length = len(payload)
|
||||
self.simulate_request(
|
||||
'/logs',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: ROLES,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': str(content_length)
|
||||
},
|
||||
body=payload
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_204, self.srmock.status)
|
||||
self.assertEqual(1, bulk_processor.send_message.call_count)
|
||||
|
|
|
@ -22,31 +22,31 @@ import mock
|
|||
from oslotest import base as os_test
|
||||
|
||||
from monasca_log_api.api import exceptions
|
||||
from monasca_log_api.api import logs_api
|
||||
from monasca_log_api.reference.common import validation
|
||||
from monasca_log_api.reference.v2.common import service as common_service
|
||||
from monasca_log_api.tests import base
|
||||
|
||||
|
||||
class IsDelegate(os_test.BaseTestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(IsDelegate, self).__init__(*args, **kwargs)
|
||||
self._conf = None
|
||||
self._roles = ['admin']
|
||||
|
||||
def setUp(self):
|
||||
super(IsDelegate, self).setUp()
|
||||
self._conf = base.mock_config(self)
|
||||
|
||||
def test_is_delegate_ok_role(self):
|
||||
roles = logs_api.MONITORING_DELEGATE_ROLE
|
||||
self.assertTrue(validation.validate_is_delegate(roles))
|
||||
self.assertTrue(validation.validate_is_delegate(self._roles))
|
||||
|
||||
def test_is_delegate_ok_role_in_roles(self):
|
||||
roles = logs_api.MONITORING_DELEGATE_ROLE + ',a_role,b_role'
|
||||
self.assertTrue(validation.validate_is_delegate(roles))
|
||||
self._roles.extend(['a_role', 'b_role'])
|
||||
self.assertTrue(validation.validate_is_delegate(self._roles))
|
||||
|
||||
def test_is_delegate_not_ok_role(self):
|
||||
roles = 'a_role,b_role'
|
||||
self.assertFalse(validation.validate_is_delegate(roles))
|
||||
|
||||
def test_is_delegate_ok_role_as_list(self):
|
||||
roles = {logs_api.MONITORING_DELEGATE_ROLE}
|
||||
self.assertTrue(validation.validate_is_delegate(roles))
|
||||
|
||||
def test_is_delegate_not_ok_role_as_list(self):
|
||||
roles = {'a_role', 'b_role'}
|
||||
roles = ['a_role', 'b_role']
|
||||
self.assertFalse(validation.validate_is_delegate(roles))
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import mock
|
|||
import ujson as json
|
||||
|
||||
from monasca_log_api.api import headers
|
||||
from monasca_log_api.api import logs_api
|
||||
from monasca_log_api.reference.v2 import logs as v2_logs
|
||||
from monasca_log_api.reference.v3 import logs as v3_logs
|
||||
from monasca_log_api.tests import base
|
||||
|
@ -48,6 +47,7 @@ class SameV2V3Output(testing.TestBase):
|
|||
service = 'laas'
|
||||
hostname = 'kornik'
|
||||
tenant_id = 'ironMan'
|
||||
roles = 'admin'
|
||||
|
||||
v2_dimensions = 'hostname:%s,service:%s' % (hostname, service)
|
||||
v3_dimensions = {
|
||||
|
@ -76,7 +76,7 @@ class SameV2V3Output(testing.TestBase):
|
|||
'/v2.0',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: roles,
|
||||
headers.X_DIMENSIONS.name: v2_dimensions,
|
||||
headers.X_APPLICATION_TYPE.name: component,
|
||||
headers.X_TENANT_ID.name: tenant_id,
|
||||
|
@ -90,7 +90,7 @@ class SameV2V3Output(testing.TestBase):
|
|||
'/v3.0',
|
||||
method='POST',
|
||||
headers={
|
||||
headers.X_ROLES.name: logs_api.MONITORING_DELEGATE_ROLE,
|
||||
headers.X_ROLES.name: roles,
|
||||
headers.X_TENANT_ID.name: tenant_id,
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '100'
|
||||
|
|
|
@ -33,7 +33,8 @@ class LogApiV2Client(rest_client.RestClient):
|
|||
|
||||
def send_single_log(self,
|
||||
log,
|
||||
headers=None):
|
||||
headers=None,
|
||||
fields=None):
|
||||
default_headers = {
|
||||
'X-Tenant-Id': 'b4265b0a48ae4fd3bdcee0ad8c2b6012',
|
||||
'X-Roles': 'admin',
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
from oslo_serialization import jsonutils as json
|
||||
from six.moves.urllib.parse import urlencode
|
||||
from tempest.lib.common import rest_client
|
||||
|
||||
|
||||
|
@ -31,15 +32,19 @@ class LogApiV3Client(rest_client.RestClient):
|
|||
resp, response_body = self.send_request('GET', '/')
|
||||
return resp, response_body
|
||||
|
||||
def send_single_log(self, log, headers=None):
|
||||
def send_single_log(self, log, headers=None, fields=None):
|
||||
default_headers = {
|
||||
'X-Tenant-Id': 'b4265b0a48ae4fd3bdcee0ad8c2b6012',
|
||||
'X-Roles': 'admin',
|
||||
}
|
||||
default_headers.update(headers)
|
||||
msg = json.dumps(log)
|
||||
uri = LogApiV3Client._uri
|
||||
|
||||
resp, body = self.post(LogApiV3Client._uri, msg, default_headers)
|
||||
if fields:
|
||||
uri += '?' + urlencode(fields)
|
||||
|
||||
resp, body = self.post(uri, msg, default_headers)
|
||||
|
||||
return resp, body
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ class BaseLogsTestCase(test.BaseTestCase):
|
|||
cls.__name__,
|
||||
identity_version=auth_version)
|
||||
credentials = cred_provider.get_creds_by_roles(
|
||||
['monasca-user']).credentials
|
||||
['monasca-user', 'admin']).credentials
|
||||
cls.os = clients.Manager(credentials=credentials)
|
||||
|
||||
cls.logs_clients = cls.os.log_api_clients
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
from tempest.lib.common.utils import test_utils
|
||||
from tempest.lib import decorators
|
||||
from testtools import matchers
|
||||
|
||||
from monasca_log_api_tempest.tests import base
|
||||
|
||||
|
@ -23,23 +24,28 @@ _RETRY_WAIT = 2
|
|||
|
||||
class TestSingleLog(base.BaseLogsTestCase):
|
||||
def _run_and_wait(self, key, data, version,
|
||||
content_type='application/json', headers=None):
|
||||
content_type='application/json',
|
||||
headers=None, fields=None):
|
||||
|
||||
headers = base._get_headers(headers, content_type)
|
||||
|
||||
def wait():
|
||||
return self.logs_search_client.count_search_messages(key, headers) > 0
|
||||
return self.logs_search_client.count_search_messages(key,
|
||||
headers) > 0
|
||||
|
||||
self.assertEqual(0, self.logs_search_client.count_search_messages(key, headers),
|
||||
self.assertEqual(0, self.logs_search_client.count_search_messages(key,
|
||||
headers),
|
||||
'Find log message in elasticsearch: {0}'.format(key))
|
||||
|
||||
headers = base._get_headers(headers, content_type)
|
||||
data = base._get_data(data, content_type, version=version)
|
||||
|
||||
response, _ = self.logs_clients[version].send_single_log(data, headers)
|
||||
client = self.logs_clients[version]
|
||||
response, _ = client.send_single_log(data, headers, fields)
|
||||
self.assertEqual(204, response.status)
|
||||
|
||||
test_utils.call_until_true(wait, _RETRY_COUNT * _RETRY_WAIT, _RETRY_WAIT)
|
||||
test_utils.call_until_true(wait, _RETRY_COUNT * _RETRY_WAIT,
|
||||
_RETRY_WAIT)
|
||||
response = self.logs_search_client.search_messages(key, headers)
|
||||
self.assertEqual(1, len(response))
|
||||
|
||||
|
@ -91,12 +97,23 @@ class TestSingleLog(base.BaseLogsTestCase):
|
|||
def test_send_header_dimensions(self):
|
||||
sid, message = base.generate_unique_message()
|
||||
headers = {'X-Dimensions':
|
||||
'server:WebServer01,environment:production'}
|
||||
'server:WebServer01,environment:production'}
|
||||
response = self._run_and_wait(sid, message, headers=headers,
|
||||
version="v2")
|
||||
self.assertEqual('production', response[0]['_source']['environment'])
|
||||
self.assertEqual('WebServer01', response[0]['_source']['server'])
|
||||
|
||||
@decorators.attr(type="gate")
|
||||
def test_send_cross_tenant(self):
|
||||
sid, message = base.generate_small_message()
|
||||
headers = {'X-Roles': 'admin, monitoring-delegate'}
|
||||
cross_tennant_id = '2106b2c8da0eecdb3df4ea84a0b5624b'
|
||||
fields = {'tenant_id': cross_tennant_id}
|
||||
response = self._run_and_wait(sid, message, version="v3",
|
||||
headers=headers, fields=fields)
|
||||
self.assertThat(response[0]['_source']['tenant'],
|
||||
matchers.StartsWith(cross_tennant_id))
|
||||
|
||||
# TODO(trebski) following test not passing - failed to retrieve
|
||||
# big message from elasticsearch
|
||||
|
||||
|
|
Loading…
Reference in New Issue