add resource show API

Implement: blueprint resource-show-API

Change-Id: If888554105e28726b721a7d881a25ff87607435b
Signed-off-by: dongwenjuan <dong.wenjuan@zte.com.cn>
This commit is contained in:
dongwenjuan 2017-04-19 17:59:10 +08:00
parent 4e1855c6f2
commit fc6f076c2a
4 changed files with 193 additions and 5 deletions

View File

@ -25,7 +25,7 @@ LOG = log.getLogger(__name__)
class ResourcesController(RootRestController):
@pecan.expose('json')
def get(self, **kwargs):
def get_all(self, **kwargs):
LOG.info('get list resource with args: %s', kwargs)
resource_type = kwargs.get('resource_type', None)
@ -43,7 +43,7 @@ class ResourcesController(RootRestController):
try:
return self._get_resources(resource_type, all_tenants)
except Exception as e:
LOG.exception('failed to get resources %s', e)
LOG.exception('failed to list resources %s', e)
abort(404, str(e))
@staticmethod
@ -62,3 +62,34 @@ class ResourcesController(RootRestController):
except Exception as e:
LOG.exception('failed to get resources %s ', e)
abort(404, str(e))
@pecan.expose('json')
def get(self, vitrage_id):
LOG.info('get resource show with vitrage_id: %s', vitrage_id)
enforce("get resource",
pecan.request.headers,
pecan.request.enforcer,
{})
try:
return self._show_resource(vitrage_id)
except Exception as e:
LOG.exception('failed to show resource %s, %s' % vitrage_id, e)
abort(404, str(e))
@staticmethod
def _show_resource(vitrage_id):
try:
resource = pecan.request.client.call(
pecan.request.context,
'show_resource',
vitrage_id=vitrage_id)
LOG.info(resource)
return json.loads(resource)
except Exception as e:
LOG.exception('failed to show resource with vitrage_id(%s),'
'Exception: %s',
vitrage_id, e)
abort(404, str(e))

View File

@ -53,3 +53,24 @@ class ResourceApis(EntityGraphApisBase):
resources = self.entity_graph.get_vertices(query_dict=query)
return json.dumps({'resources': [resource.properties
for resource in resources]})
def show_resource(self, ctx, vitrage_id):
LOG.debug('Show resource with vitrage_id: %s', str(vitrage_id))
project_id = ctx.get(self.TENANT_PROPERTY, None)
is_admin_project = ctx.get(self.IS_ADMIN_PROJECT_PROPERTY, False)
resource = self.entity_graph.get_vertex(vitrage_id)
if resource:
project = resource.get(VProps.PROJECT_ID)
if is_admin_project:
return json.dumps(resource.properties)
else:
if project and project_id == project:
return json.dumps(resource.properties)
LOG.warn('Have no authority to get resource with vitrage_id(%s)',
str(vitrage_id))
else:
LOG.warn('Can not find the resource with vitrage_id(%s)',
str(vitrage_id))
return None

View File

@ -274,6 +274,93 @@ class TestApis(TestEntityGraphUnitBase):
# Test assertions
self.assertEqual(7, len(resources))
def test_resource_show_with_admin_and_no_project_resource(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_1', 'is_admin': True}
# Action
resource = apis.show_resource(ctx, 'zone_1')
resource = json.loads(resource)
# Test assertions
self.assertIsNotNone(resource)
self._check_resource_propeties(resource, 'zone_1',
NOVA_ZONE_DATASOURCE)
def test_resource_show_with_not_admin_and_no_project_resource(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_1', 'is_admin': False}
# Action
resource = apis.show_resource(ctx, 'zone_1')
# Test assertions
self.assertIsNone(resource)
def test_resource_show_with_not_admin_and_resource_in_project(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_1', 'is_admin': False}
# Action
resource = apis.show_resource(ctx, 'instance_2')
resource = json.loads(resource)
# Test assertions
self.assertIsNotNone(resource)
self._check_resource_propeties(resource, 'instance_2',
NOVA_INSTANCE_DATASOURCE,
project_id='project_1')
def test_resource_show_with_not_admin_and_resource_in_other_project(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_2', 'is_admin': False}
# Action
resource = apis.show_resource(ctx, 'instance_2')
# Test assertions
self.assertIsNone(resource)
def test_resource_show_with_admin_and_resource_in_project(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_1', 'is_admin': True}
# Action
resource = apis.show_resource(ctx, 'instance_2')
resource = json.loads(resource)
# Test assertions
self.assertIsNotNone(resource)
self._check_resource_propeties(resource, 'instance_2',
NOVA_INSTANCE_DATASOURCE,
project_id='project_1')
def test_resource_show_with_admin_and_resource_in_other_project(self):
# Setup
graph = self._create_graph()
apis = ResourceApis(graph, None)
ctx = {'tenant': 'project_2', 'is_admin': True}
# Action
resource = apis.show_resource(ctx, 'instance_2')
resource = json.loads(resource)
# Test assertions
self.assertIsNotNone(resource)
self._check_resource_propeties(resource, 'instance_2',
NOVA_INSTANCE_DATASOURCE,
project_id='project_1')
def _check_projects_entities(self,
alarms,
project_id,
@ -289,6 +376,18 @@ class TestApis(TestEntityGraphUnitBase):
(tmp_project_id and tmp_project_id == project_id))
self.assertEqual(True, condition)
def _check_resource_propeties(self, resource, vitrage_id,
resource_type, project_id=None):
self.assertEqual(resource[VProps.VITRAGE_ID], vitrage_id)
self.assertEqual(resource[VProps.ID], vitrage_id)
self.assertEqual(resource[VProps.CATEGORY], EntityCategory.RESOURCE)
self.assertEqual(resource[VProps.TYPE], resource_type)
self.assertEqual(resource[VProps.STATE], 'active')
self.assertFalse(resource[VProps.IS_DELETED])
self.assertFalse(resource[VProps.IS_PLACEHOLDER])
if project_id:
self.assertEqual(resource[VProps.PROJECT_ID], project_id)
def _create_graph(self):
graph = NXGraph('Multi tenancy graph')

View File

@ -28,6 +28,8 @@ LOG = logging.getLogger(__name__)
class TestResource(BaseApiTest):
"""Test class for Vitrage resource API tests."""
properties = ('vitrage_id', 'type', 'id', 'state', 'aggregated_state')
@classmethod
def setUpClass(cls):
super(TestResource, cls).setUpClass()
@ -129,6 +131,32 @@ class TestResource(BaseApiTest):
finally:
self._delete_instances()
def test_compare_resource_show(self):
"""resource_show test"""
resource_list = self.vitrage_client.resource.list()
self.assertNotEqual(len(resource_list), 0)
for resource in resource_list:
api_resource_show = \
self.vitrage_client.resource.show(resource['vitrage_id'])
cli_resource_show = utils.run_vitrage_command(
'vitrage resource show ' + resource['vitrage_id'], self.conf)
self._compare_resource_show(
api_resource_show, cli_resource_show)
def test_resource_show_with_no_existing_resource(self):
"""resource_show test no existing resource"""
try:
resource = \
self.vitrage_client.resource.show('test_for_no_existing')
self.assertIsNone(resource)
except Exception as e:
LOG.exception(e)
traceback.print_exc()
raise
finally:
self._delete_instances()
def _compare_resources(self, api_resources, cli_resources):
self.assertNotEqual(len(api_resources), 0,
'The resources taken from rest api is empty')
@ -145,10 +173,19 @@ class TestResource(BaseApiTest):
self.assertEqual(len(sorted_cli_resources),
len(sorted_api_resources))
properties = ('vitrage_id', 'type', 'id', 'state',
'aggregated_state', 'operational_state')
for cli_resource, api_resource in \
zip(sorted_cli_resources, sorted_api_resources):
for item in properties:
for item in self.properties:
self.assertEqual(cli_resource.get(item),
api_resource.get(item))
def _compare_resource_show(self, api_resource_show,
cli_resource_show):
self.assertIsNotNone(api_resource_show,
'The resource show taken from rest api is empty')
self.assertIsNotNone(cli_resource_show,
'The resource show taken from terminal is empty')
for item in self.properties:
self.assertEqual(api_resource_show.get(item),
cli_resource_show.get(item))