add alarm show backend
Change-Id: Ia675c6d74ec947729d4520007eac1423cdf58ce9 Implements: blueprint add-alarm-show-api
This commit is contained in:
parent
4ff1908d1b
commit
387a3d5b11
@ -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_``.
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user