Merge "add alarm show backend"

This commit is contained in:
Zuul 2018-01-03 13:25:03 +00:00 committed by Gerrit Code Review
commit b5fbd9862b
7 changed files with 111 additions and 37 deletions

View File

@ -0,0 +1,4 @@
---
features:
- Created a new API to show all alarm properties, with a mandatory parameter
vitrage_id of the alarm. The path for the api is ``/v1/alarm/_id_``.

View File

@ -35,11 +35,9 @@ class AlarmsController(RootRestController):
count = count.CountsController() count = count.CountsController()
@pecan.expose('json') @pecan.expose('json')
def index(self, vitrage_id, all_tenants=False): def get_all(self, **kwargs):
return self.get(vitrage_id, all_tenants) vitrage_id = kwargs.get('vitrage_id')
all_tenants = kwargs.get('all_tenants', False)
@pecan.expose('json')
def get(self, vitrage_id, all_tenants=False):
all_tenants = bool_from_string(all_tenants) all_tenants = bool_from_string(all_tenants)
if all_tenants: if all_tenants:
enforce("list alarms:all_tenants", pecan.request.headers, enforce("list alarms:all_tenants", pecan.request.headers,
@ -73,3 +71,35 @@ class AlarmsController(RootRestController):
to_unicode = encodeutils.exception_to_unicode(e) to_unicode = encodeutils.exception_to_unicode(e)
LOG.exception('failed to open file %s ', to_unicode) LOG.exception('failed to open file %s ', to_unicode)
abort(404, to_unicode) abort(404, to_unicode)
@pecan.expose('json')
def get(self, vitrage_id):
enforce("get alarm",
pecan.request.headers,
pecan.request.enforcer,
{})
LOG.info('returns show alarm with vitrage id %s', vitrage_id)
try:
return self._show_alarm(vitrage_id)
except Exception as e:
to_unicode = encodeutils.exception_to_unicode(e)
LOG.exception('failed to load json %s ', to_unicode)
abort(404, to_unicode)
@staticmethod
def _show_alarm(vitrage_id):
alarm_json = pecan.request.client.call(pecan.request.context,
'show_alarm',
vitrage_id=vitrage_id)
LOG.info(alarm_json)
try:
alarms_list = json.loads(alarm_json)
return alarms_list
except Exception as e:
to_unicode = encodeutils.exception_to_unicode(e)
LOG.exception('failed to load json %s ', to_unicode)
abort(404, to_unicode)

View File

@ -19,7 +19,7 @@ from osprofiler import profiler
from vitrage.api_handler.apis.base import ALARM_QUERY from vitrage.api_handler.apis.base import ALARM_QUERY
from vitrage.api_handler.apis.base import ALARMS_ALL_QUERY from vitrage.api_handler.apis.base import ALARMS_ALL_QUERY
from vitrage.api_handler.apis.base import EntityGraphApisBase from vitrage.api_handler.apis.base import EntityGraphApisBase
from vitrage.common.constants import EntityCategory from vitrage.common.constants import EntityCategory as ECategory
from vitrage.common.constants import VertexProperties as VProps from vitrage.common.constants import VertexProperties as VProps
from vitrage.entity_graph.mappings.operational_alarm_severity import \ from vitrage.entity_graph.mappings.operational_alarm_severity import \
OperationalAlarmSeverity OperationalAlarmSeverity
@ -53,13 +53,30 @@ class AlarmApis(EntityGraphApisBase):
is_admin_project) is_admin_project)
alarms = set(alarms) alarms = set(alarms)
else: else:
query = {VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, query = {VProps.VITRAGE_CATEGORY: ECategory.ALARM,
VProps.VITRAGE_IS_DELETED: False} VProps.VITRAGE_IS_DELETED: False}
alarms = self.entity_graph.neighbors(vitrage_id, alarms = self.entity_graph.neighbors(vitrage_id,
vertex_attr_filter=query) vertex_attr_filter=query)
return json.dumps({'alarms': [v.properties for v in alarms]}) return json.dumps({'alarms': [v.properties for v in alarms]})
def show_alarm(self, ctx, vitrage_id):
LOG.debug('Show alarm with vitrage_id: %s', vitrage_id)
alarm = self.entity_graph.get_vertex(vitrage_id)
if not alarm or alarm.get(VProps.VITRAGE_CATEGORY) != ECategory.ALARM:
LOG.warning('Alarm show - not found (%s)', vitrage_id)
return None
is_admin = ctx.get(self.IS_ADMIN_PROJECT_PROPERTY, False)
curr_project = ctx.get(self.TENANT_PROPERTY, None)
alarm_project = alarm.get(VProps.PROJECT_ID)
if not is_admin and curr_project != alarm_project:
LOG.warning('Authorization failed for alarm (%s)', vitrage_id)
return None
return json.dumps(alarm.properties)
def get_alarm_counts(self, ctx, all_tenants): def get_alarm_counts(self, ctx, all_tenants):
LOG.debug("AlarmApis get_alarm_counts - all_tenants=%s", all_tenants) LOG.debug("AlarmApis get_alarm_counts - all_tenants=%s", all_tenants)
@ -99,7 +116,7 @@ class AlarmApis(EntityGraphApisBase):
:rtype: list :rtype: list
""" """
alarm_query = self._get_query_with_project(EntityCategory.ALARM, alarm_query = self._get_query_with_project(ECategory.ALARM,
project_id, project_id,
is_admin_project) is_admin_project)
alarms = self.entity_graph.get_vertices(query_dict=alarm_query) alarms = self.entity_graph.get_vertices(query_dict=alarm_query)
@ -117,7 +134,7 @@ class AlarmApis(EntityGraphApisBase):
:rtype: list :rtype: list
""" """
resource_query = self._get_query_with_project(EntityCategory.RESOURCE, resource_query = self._get_query_with_project(ECategory.RESOURCE,
project_id, project_id,
is_admin_project) is_admin_project)

View File

@ -58,23 +58,19 @@ class ResourceApis(EntityGraphApisBase):
for resource in resources]}) for resource in resources]})
def show_resource(self, ctx, vitrage_id): 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)
LOG.debug('Show resource with vitrage_id: %s', vitrage_id)
resource = self.entity_graph.get_vertex(vitrage_id) resource = self.entity_graph.get_vertex(vitrage_id)
if resource: if not resource or resource.get(VProps.VITRAGE_CATEGORY) != \
project = resource.get(VProps.PROJECT_ID) EntityCategory.RESOURCE:
if is_admin_project: LOG.warning('Resource show - not found (%s)', vitrage_id)
return json.dumps(resource.properties) return None
else:
if project and project_id == project: is_admin = ctx.get(self.IS_ADMIN_PROJECT_PROPERTY, False)
return json.dumps(resource.properties) curr_project = ctx.get(self.TENANT_PROPERTY, None)
LOG.warning( resource_project = resource.get(VProps.PROJECT_ID)
'Have no authority to get resource with vitrage_id(%s)', if not is_admin and curr_project != resource_project:
str(vitrage_id)) LOG.warning('Authorization failed for resource (%s)', vitrage_id)
else: return None
LOG.warning('Can not find the resource with vitrage_id(%s)',
str(vitrage_id)) return json.dumps(resource.properties)
return None

View File

@ -15,6 +15,17 @@ from oslo_policy import policy
from vitrage.common.policies import base from vitrage.common.policies import base
rules = [ rules = [
policy.DocumentedRuleDefault(
name='get alarm',
check_str=base.UNPROTECTED,
description='Show the details of specified alarm',
operations=[
{
'path': '/alarm',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='list alarms', name='list alarms',
check_str=base.UNPROTECTED, check_str=base.UNPROTECTED,

View File

@ -67,11 +67,19 @@ class NoAuthTest(FunctionalTest):
with mock.patch('pecan.request') as request: with mock.patch('pecan.request') as request:
request.client.call.return_value = '{"alarms": []}' request.client.call.return_value = '{"alarms": []}'
params = dict(vitrage_id='all', all_tenants=False) params = dict(vitrage_id='all', all_tenants=False)
resp = self.post_json('/alarm/', params=params) data = self.get_json('/alarm/', params=params)
self.assertEqual(1, request.client.call.call_count) self.assertEqual(1, request.client.call.call_count)
self.assertEqual('200 OK', resp.status) self.assertEqual([], data)
self.assertEqual([], resp.json)
def test_noauth_mode_show_alarm(self):
with mock.patch('pecan.request') as request:
request.client.call.return_value = '{}'
data = self.get_json('/alarm/1234')
self.assertEqual(1, request.client.call.call_count)
self.assertEqual({}, data)
def test_noauth_mode_show_alarm_count(self): def test_noauth_mode_show_alarm_count(self):
with mock.patch('pecan.request') as request: with mock.patch('pecan.request') as request:
@ -97,8 +105,7 @@ class NoAuthTest(FunctionalTest):
with mock.patch('pecan.request') as request: with mock.patch('pecan.request') as request:
request.client.call.return_value = '{}' request.client.call.return_value = '{}'
params = dict(resource_type='all', all_tenants=False) data = self.get_json('/resources/1234')
data = self.get_json('/resources/1234', params=params)
self.assertEqual(1, request.client.call.call_count) self.assertEqual(1, request.client.call.call_count)
self.assertEqual({}, data) self.assertEqual({}, data)

View File

@ -179,7 +179,7 @@ class TestResource(BaseVitrageTempest):
sorted_cli_resources = sorted( sorted_cli_resources = sorted(
json.loads(cli_resources), json.loads(cli_resources),
key=lambda resource: resource["vitrage_id"]) key=lambda resource: resource["ID"])
sorted_api_resources = sorted( sorted_api_resources = sorted(
api_resources, api_resources,
key=lambda resource: resource["vitrage_id"]) key=lambda resource: resource["vitrage_id"])
@ -190,10 +190,19 @@ class TestResource(BaseVitrageTempest):
for cli_resource, api_resource in \ for cli_resource, api_resource in \
zip(sorted_cli_resources, sorted_api_resources): zip(sorted_cli_resources, sorted_api_resources):
for item in self.properties:
self.assertEqual(cli_resource.get(item).lower(), self.assertEqual(
api_resource.get(item).lower(), cli_resource.get("ID").lower(),
'for item %s' % item) api_resource.get(VProps.VITRAGE_ID).lower())
self.assertEqual(
cli_resource.get("Type").lower(),
api_resource.get(VProps.VITRAGE_TYPE).lower())
self.assertEqual(
cli_resource.get("Data Source ID").lower(),
api_resource.get(VProps.ID).lower())
self.assertEqual(
cli_resource.get("State").lower(),
api_resource.get(VProps.VITRAGE_OPERATIONAL_STATE).lower())
def _compare_resource_show(self, api_resource_show, def _compare_resource_show(self, api_resource_show,
cli_resource_show): cli_resource_show):