Allow to get a disabled alarm

This change allow to get a disabled alarm.

To do this, it:
* add the ability to query the alarm-list API with the 'enabled' fields.
* change the default visibility of alarm-list API from enabled only to all.

Fixes bug #1231328

Change-Id: I80cd691696f7630d2ac9e9b2a69b5b0ae5ee7968
This commit is contained in:
Mehdi Abaakouk 2013-09-26 11:53:01 +02:00
parent c88d7eb3dd
commit 3cfac4c51a
9 changed files with 61 additions and 16 deletions

View File

@ -209,7 +209,7 @@ class Query(_Base):
def as_dict(self): def as_dict(self):
return self.as_dict_from_keys(['field', 'op', 'type', 'value']) return self.as_dict_from_keys(['field', 'op', 'type', 'value'])
def _get_value_as_type(self): def _get_value_as_type(self, forced_type=None):
"""Convert metadata value to the specified data type. """Convert metadata value to the specified data type.
This method is called during metadata query to help convert the This method is called during metadata query to help convert the
@ -225,9 +225,10 @@ class Query(_Base):
:returns: metadata value converted with the specified data type. :returns: metadata value converted with the specified data type.
""" """
type = forced_type or self.type
try: try:
converted_value = self.value converted_value = self.value
if not self.type: if not type:
try: try:
converted_value = ast.literal_eval(self.value) converted_value = ast.literal_eval(self.value)
except (ValueError, SyntaxError): except (ValueError, SyntaxError):
@ -235,13 +236,13 @@ class Query(_Base):
' automatically') % (self.value) ' automatically') % (self.value)
LOG.debug(msg) LOG.debug(msg)
else: else:
if self.type == 'integer': if type == 'integer':
converted_value = int(self.value) converted_value = int(self.value)
elif self.type == 'float': elif type == 'float':
converted_value = float(self.value) converted_value = float(self.value)
elif self.type == 'boolean': elif type == 'boolean':
converted_value = strutils.bool_from_string(self.value) converted_value = strutils.bool_from_string(self.value)
elif self.type == 'string': elif type == 'string':
converted_value = self.value converted_value = self.value
else: else:
# For now, this method only support integer, float, # For now, this method only support integer, float,
@ -251,17 +252,17 @@ class Query(_Base):
except ValueError: except ValueError:
msg = _('Failed to convert the metadata value %(value)s' msg = _('Failed to convert the metadata value %(value)s'
' to the expected data type %(type)s.') % \ ' to the expected data type %(type)s.') % \
{'value': self.value, 'type': self.type} {'value': self.value, 'type': type}
raise wsme.exc.ClientSideError(unicode(msg)) raise wsme.exc.ClientSideError(unicode(msg))
except TypeError: except TypeError:
msg = _('The data type %s is not supported. The supported' msg = _('The data type %s is not supported. The supported'
' data type list is: integer, float, boolean and' ' data type list is: integer, float, boolean and'
' string.') % (self.type) ' string.') % (type)
raise wsme.exc.ClientSideError(unicode(msg)) raise wsme.exc.ClientSideError(unicode(msg))
except Exception: except Exception:
msg = _('Unexpected exception converting %(value)s to' msg = _('Unexpected exception converting %(value)s to'
' the expected data type %(type)s.') % \ ' the expected data type %(type)s.') % \
{'value': self.value, 'type': self.type} {'value': self.value, 'type': type}
raise wsme.exc.ClientSideError(unicode(msg)) raise wsme.exc.ClientSideError(unicode(msg))
return converted_value return converted_value
@ -323,6 +324,8 @@ def _query_to_kwargs(query, db_func, internal_keys=[], headers=None):
if i.op == 'eq': if i.op == 'eq':
if i.field == 'search_offset': if i.field == 'search_offset':
stamp['search_offset'] = i.value stamp['search_offset'] = i.value
elif i.field == 'enabled':
kwargs[i.field] = i._get_value_as_type('boolean')
elif i.field.startswith('metadata.'): elif i.field.startswith('metadata.'):
metaquery[i.field] = i._get_value_as_type() metaquery[i.field] = i._get_value_as_type()
elif i.field.startswith('resource_metadata.'): elif i.field.startswith('resource_metadata.'):

View File

@ -209,7 +209,7 @@ class Connection(object):
@abc.abstractmethod @abc.abstractmethod
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
""" """

View File

@ -666,7 +666,7 @@ class Connection(base.Connection):
alarm['rule']['query'] = query alarm['rule']['query'] = query
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
:param user: Optional ID for user that owns the resource. :param user: Optional ID for user that owns the resource.
:param project: Optional ID for project that owns the resource. :param project: Optional ID for project that owns the resource.

View File

@ -591,7 +591,7 @@ class Connection(base.Connection):
return results return results
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
raise NotImplementedError('metaquery not implemented') raise NotImplementedError('metaquery not implemented')
""" """

View File

@ -158,7 +158,7 @@ class Connection(base.Connection):
return [] return []
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
""" """
return [] return []

View File

@ -850,7 +850,7 @@ class Connection(base.Connection):
alarm['rule']['query'] = query alarm['rule']['query'] = query
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
:param name: The Alarm name. :param name: The Alarm name.
:param user: Optional ID for user that owns the resource. :param user: Optional ID for user that owns the resource.

View File

@ -597,7 +597,7 @@ class Connection(base.Connection):
repeat_actions=row.repeat_actions) repeat_actions=row.repeat_actions)
def get_alarms(self, name=None, user=None, def get_alarms(self, name=None, user=None,
project=None, enabled=True, alarm_id=None, pagination=None): project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters """Yields a lists of alarms that match filters
:param user: Optional ID for user that owns the resource. :param user: Optional ID for user that owns the resource.
:param project: Optional ID for project that owns the resource. :param project: Optional ID for project that owns the resource.

View File

@ -183,6 +183,33 @@ class TestAlarms(FunctionalTest,
self.assertEqual(one['alarm_id'], alarms[0]['alarm_id']) self.assertEqual(one['alarm_id'], alarms[0]['alarm_id'])
self.assertEqual(one['repeat_actions'], alarms[0]['repeat_actions']) self.assertEqual(one['repeat_actions'], alarms[0]['repeat_actions'])
def test_get_alarm_disabled(self):
alarm = Alarm(name='disabled',
type='combination',
enabled=False,
alarm_id='d',
description='d',
state='insufficient data',
state_timestamp=None,
timestamp=None,
ok_actions=[],
insufficient_data_actions=[],
alarm_actions=[],
repeat_actions=False,
user_id=self.auth_headers['X-User-Id'],
project_id=self.auth_headers['X-Project-Id'],
rule=dict(alarm_ids=['a', 'b'], operator='or'))
self.conn.update_alarm(alarm)
alarms = self.get_json('/alarms',
q=[{'field': 'enabled',
'value': 'False'}])
self.assertEqual(len(alarms), 1)
self.assertEqual(alarms[0]['name'], 'disabled')
one = self.get_json('/alarms/%s' % alarms[0]['alarm_id'])
self.assertEqual(one['name'], 'disabled')
def test_get_alarm_combination(self): def test_get_alarm_combination(self):
alarms = self.get_json('/alarms', alarms = self.get_json('/alarms',
q=[{'field': 'name', q=[{'field': 'name',

View File

@ -1903,7 +1903,7 @@ class AlarmTestBase(DBTestBase):
'type': 'string'}]), 'type': 'string'}]),
), ),
models.Alarm(alarm_id='y3ll0w', models.Alarm(alarm_id='y3ll0w',
enabled=True, enabled=False,
type='threshold', type='threshold',
name='yellow-alert', name='yellow-alert',
description='yellow', description='yellow',
@ -1944,6 +1944,21 @@ class AlarmTest(AlarmTestBase,
alarms = list(self.conn.get_alarms()) alarms = list(self.conn.get_alarms())
self.assertEqual([], alarms) self.assertEqual([], alarms)
def test_list(self):
self.add_some_alarms()
alarms = list(self.conn.get_alarms())
self.assertEqual(len(alarms), 3)
def test_list_enabled(self):
self.add_some_alarms()
alarms = list(self.conn.get_alarms(enabled=True))
self.assertEqual(len(alarms), 2)
def test_list_disabled(self):
self.add_some_alarms()
alarms = list(self.conn.get_alarms(enabled=False))
self.assertEqual(len(alarms), 1)
def test_add(self): def test_add(self):
self.add_some_alarms() self.add_some_alarms()
alarms = list(self.conn.get_alarms()) alarms = list(self.conn.get_alarms())