Added tests for multi tenancy
When a different tenant queries the topology, it should not get instances that were created by the default tenant. Change-Id: I239198ee33a8512e607776b3aa98b00c4a81f0e8
This commit is contained in:
@@ -110,6 +110,40 @@ class TestTopology(BaseTopologyTest):
|
||||
finally:
|
||||
self._rollback_to_default()
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_default_graph_for_tenant(self):
|
||||
"""default_graph
|
||||
|
||||
This test validate correctness of default topology graph when queried
|
||||
by another tenant.
|
||||
"""
|
||||
try:
|
||||
# Action - create entities as the default tenant
|
||||
self._create_entities(num_instances=self.NUM_INSTANCE,
|
||||
num_volumes=self.NUM_VOLUME)
|
||||
|
||||
# Calculate expected results for another tenant - the other tenant
|
||||
# should not see instances and volumes of the default tenant.
|
||||
# All it can see is its private network.
|
||||
tenant_client = self.vitrage_client_for_demo_user
|
||||
api_graph = tenant_client.topology.get(all_tenants=False)
|
||||
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||
|
||||
entities = self._entities_validation_data(
|
||||
cluster_entities=0, cluster_edges=0, zone_entities=0,
|
||||
zone_edges=0, host_entities=0, host_edges=0,
|
||||
instance_entities=0, instance_edges=0, volume_entities=0,
|
||||
volume_edges=0)
|
||||
num_entities = self.num_demo_tenant_networks
|
||||
|
||||
# Test Assertions
|
||||
self._validate_graph_correctness(graph, num_entities, 0, entities)
|
||||
except Exception as e:
|
||||
self._handle_exception(e)
|
||||
raise
|
||||
finally:
|
||||
self._rollback_to_default()
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_graph_with_query(self):
|
||||
"""graph_with_query
|
||||
@@ -146,6 +180,38 @@ class TestTopology(BaseTopologyTest):
|
||||
finally:
|
||||
self._rollback_to_default()
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_graph_with_query_for_tenant(self):
|
||||
"""graph_with_query
|
||||
|
||||
This test validate correctness of topology graph
|
||||
with query, when queried by another tenant.
|
||||
"""
|
||||
try:
|
||||
# Action - create entities as the default tenant
|
||||
self._create_entities(num_instances=self.NUM_INSTANCE,
|
||||
num_volumes=self.NUM_VOLUME)
|
||||
|
||||
# Calculate expected results - the other tenant should not see
|
||||
# instances and volumes of the default tenant
|
||||
tenant_client = self.vitrage_client_for_demo_user
|
||||
api_graph = tenant_client.topology.get(query=self._graph_query())
|
||||
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||
|
||||
entities = self._entities_validation_data(
|
||||
cluster_entities=0, cluster_edges=0, zone_entities=0,
|
||||
zone_edges=0, host_entities=0, host_edges=0,
|
||||
instance_entities=0, instance_edges=0, volume_entities=0,
|
||||
volume_edges=0)
|
||||
|
||||
# Test Assertions
|
||||
self._validate_graph_correctness(graph, 0, 0, entities)
|
||||
except Exception as e:
|
||||
self._handle_exception(e)
|
||||
raise
|
||||
finally:
|
||||
self._rollback_to_default()
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_nova_tree(self):
|
||||
"""nova_tree
|
||||
|
||||
@@ -59,6 +59,10 @@ class BaseVitrageTempest(base.BaseTestCase):
|
||||
|
||||
NUM_VERTICES_PER_TYPE = 'num_vertices'
|
||||
NUM_EDGES_PER_TYPE = 'num_edges_per_type'
|
||||
DEMO_USERNAME = 'demo'
|
||||
DEMO_USER_DOMAIN_ID = 'default'
|
||||
DEMO_PROJECT_NAME = 'demo'
|
||||
DEMO_PROJECT_DOMAIN_ID = 'default'
|
||||
|
||||
def assert_list_equal(self, l1, l2):
|
||||
if tuple(sys.version_info)[0:2] < (2, 7):
|
||||
@@ -121,12 +125,17 @@ class BaseVitrageTempest(base.BaseTestCase):
|
||||
cls.conf = service.prepare_service([])
|
||||
TempestClients.class_init(cls.conf)
|
||||
cls.vitrage_client = TempestClients.vitrage()
|
||||
cls.vitrage_client_for_demo_user = \
|
||||
TempestClients.vitrage_client_for_user(
|
||||
cls.DEMO_USERNAME, cls.DEMO_USER_DOMAIN_ID,
|
||||
cls.DEMO_PROJECT_NAME, cls.DEMO_PROJECT_DOMAIN_ID)
|
||||
|
||||
cls.num_default_networks = \
|
||||
len(TempestClients.neutron().list_networks()['networks'])
|
||||
cls.num_default_ports = 0
|
||||
cls.num_default_entities = 3
|
||||
cls.num_default_edges = 2
|
||||
cls.num_demo_tenant_networks = cls._calc_num_demo_tenant_networks()
|
||||
|
||||
def _create_graph_from_graph_dictionary(self, api_graph):
|
||||
self.assertIsNotNone(api_graph)
|
||||
@@ -302,3 +311,20 @@ class BaseVitrageTempest(base.BaseTestCase):
|
||||
traceback.print_exc()
|
||||
LOG.exception(exception)
|
||||
self._print_entity_graph()
|
||||
|
||||
@classmethod
|
||||
def _calc_num_demo_tenant_networks(cls):
|
||||
neutron_client = TempestClients.neutron_client_for_user(
|
||||
cls.DEMO_USERNAME, cls.DEMO_USER_DOMAIN_ID,
|
||||
cls.DEMO_PROJECT_NAME, cls.DEMO_PROJECT_DOMAIN_ID)
|
||||
tenant_networks = neutron_client.list_networks(
|
||||
tenant_id=cls._get_demo_tenant_id())['networks']
|
||||
return len(tenant_networks)
|
||||
|
||||
@classmethod
|
||||
def _get_demo_tenant_id(cls):
|
||||
projects = TempestClients.keystone().projects.list()
|
||||
for project in projects:
|
||||
if cls.DEMO_PROJECT_NAME == project.name:
|
||||
return project.id
|
||||
return None
|
||||
|
||||
@@ -12,8 +12,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from keystoneauth1 import loading as ka_loading
|
||||
from keystoneauth1 import session as ka_session
|
||||
from neutronclient.v2_0 import client as neutron_client
|
||||
from vitrage import keystone_client
|
||||
from vitrage import os_clients
|
||||
from vitrage_tempest_plugin.tests.utils import get_property_value
|
||||
from vitrageclient import client as vc
|
||||
|
||||
|
||||
@@ -30,6 +34,7 @@ class TempestClients(object):
|
||||
cls._heat = None
|
||||
cls._mistral = None
|
||||
cls._aodh = None
|
||||
cls._keystone = None
|
||||
|
||||
@classmethod
|
||||
def vitrage(cls):
|
||||
@@ -42,6 +47,24 @@ class TempestClients(object):
|
||||
'1', session=keystone_client.get_session(cls._conf))
|
||||
return cls._vitrage
|
||||
|
||||
@classmethod
|
||||
def vitrage_client_for_user(cls, username, user_domain_id,
|
||||
project_name, project_domain_id):
|
||||
"""vitrage client for a specific user and tenant
|
||||
|
||||
:rtype: vitrageclient.v1.client.Client
|
||||
"""
|
||||
session = cls._get_session_for_user(
|
||||
username, user_domain_id, project_name, project_domain_id)
|
||||
return vc.Client('1', session=session)
|
||||
|
||||
@classmethod
|
||||
def neutron_client_for_user(cls, username, user_domain_id,
|
||||
project_name, project_domain_id):
|
||||
session = cls._get_session_for_user(
|
||||
username, user_domain_id, project_name, project_domain_id)
|
||||
return neutron_client.Client(session=session)
|
||||
|
||||
@classmethod
|
||||
def ceilometer(cls):
|
||||
"""ceilometer client
|
||||
@@ -121,3 +144,26 @@ class TempestClients(object):
|
||||
if not cls._aodh:
|
||||
cls._aodh = os_clients.aodh_client(cls._conf)
|
||||
return cls._aodh
|
||||
|
||||
@classmethod
|
||||
def keystone(cls):
|
||||
"""keystone client
|
||||
|
||||
:rtype: keystoneclient.v3.client.Client
|
||||
"""
|
||||
if not cls._keystone:
|
||||
cls._keystone = keystone_client.get_client(cls._conf)
|
||||
return cls._keystone
|
||||
|
||||
@classmethod
|
||||
def _get_session_for_user(cls, username, user_domain_id,
|
||||
project_name, project_domain_id):
|
||||
password = get_property_value(
|
||||
'OS_PASSWORD', 'password', 'password', cls._conf)
|
||||
loader = ka_loading.get_plugin_loader('password')
|
||||
auth_plugin = loader.load_from_options(
|
||||
auth_url=cls._conf.service_credentials.auth_url,
|
||||
username=username, password=password, project_name=project_name,
|
||||
project_domain_id=project_domain_id,
|
||||
user_domain_id=user_domain_id)
|
||||
return ka_session.Session(auth=auth_plugin)
|
||||
|
||||
Reference in New Issue
Block a user