diff --git a/ceilometer/alarm/storage/base.py b/ceilometer/alarm/storage/base.py index 60e1d28b23..17945bf063 100644 --- a/ceilometer/alarm/storage/base.py +++ b/ceilometer/alarm/storage/base.py @@ -44,8 +44,20 @@ def upgrade(): @staticmethod def get_alarms(name=None, user=None, state=None, meter=None, - project=None, enabled=None, alarm_id=None, pagination=None): - """Yields a lists of alarms that match filters.""" + project=None, enabled=None, alarm_id=None, pagination=None, + alarm_type=None): + """Yields a lists of alarms that match filters. + + :param name: Optional name for alarm. + :param user: Optional ID for user that owns the resource. + :param state: Optional string for alarm state. + :param meter: Optional string for alarms associated with meter. + :param project: Optional ID for project that owns the resource. + :param enabled: Optional boolean to list disable alarm. + :param alarm_id: Optional alarm_id to return one alarm. + :param pagination: Optional pagination query. + :param alarm_type: Optional alarm type. + """ raise ceilometer.NotImplementedError('Alarms not implemented') @staticmethod @@ -68,7 +80,7 @@ def delete_alarm(alarm_id): @staticmethod def get_alarm_changes(alarm_id, on_behalf_of, - user=None, project=None, type=None, + user=None, project=None, alarm_type=None, start_timestamp=None, start_timestamp_op=None, end_timestamp=None, end_timestamp_op=None): """Yields list of AlarmChanges describing alarm history @@ -88,7 +100,7 @@ def get_alarm_changes(alarm_id, on_behalf_of, administrative user, indicating all projects) :param user: Optional ID of user to return changes for :param project: Optional ID of project to return changes for - :project type: Optional change type + :param alarm_type: Optional change type :param start_timestamp: Optional modified timestamp start range :param start_timestamp_op: Optional timestamp start range operation :param end_timestamp: Optional modified timestamp end range diff --git a/ceilometer/alarm/storage/impl_hbase.py b/ceilometer/alarm/storage/impl_hbase.py index 21c1431d8f..470d1d1a3c 100644 --- a/ceilometer/alarm/storage/impl_hbase.py +++ b/ceilometer/alarm/storage/impl_hbase.py @@ -118,7 +118,8 @@ def delete_alarm(self, alarm_id): alarm_table.delete(alarm_id) def get_alarms(self, name=None, user=None, state=None, meter=None, - project=None, enabled=None, alarm_id=None, pagination=None): + project=None, enabled=None, alarm_id=None, pagination=None, + alarm_type=None): if pagination: raise ceilometer.NotImplementedError('Pagination not implemented') @@ -128,7 +129,8 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, q = hbase_utils.make_query(alarm_id=alarm_id, name=name, enabled=enabled, user_id=user, - project_id=project, state=state) + project_id=project, state=state, + type=alarm_type) with self.conn_pool.connection() as conn: alarm_table = conn.table(self.ALARM_TABLE) @@ -138,11 +140,11 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, yield models.Alarm(**stored_alarm) def get_alarm_changes(self, alarm_id, on_behalf_of, - user=None, project=None, type=None, + user=None, project=None, alarm_type=None, start_timestamp=None, start_timestamp_op=None, end_timestamp=None, end_timestamp_op=None): q = hbase_utils.make_query(alarm_id=alarm_id, - on_behalf_of=on_behalf_of, type=type, + on_behalf_of=on_behalf_of, type=alarm_type, user_id=user, project_id=project) start_row, end_row = hbase_utils.make_timestamp_query( hbase_utils.make_general_rowkey_scan, diff --git a/ceilometer/alarm/storage/impl_log.py b/ceilometer/alarm/storage/impl_log.py index 03c01a360d..0b8675b232 100644 --- a/ceilometer/alarm/storage/impl_log.py +++ b/ceilometer/alarm/storage/impl_log.py @@ -33,7 +33,8 @@ def clear(self): pass def get_alarms(self, name=None, user=None, state=None, meter=None, - project=None, enabled=None, alarm_id=None, pagination=None): + project=None, enabled=None, alarm_id=None, pagination=None, + alarm_type=None): """Yields a lists of alarms that match filters.""" return [] diff --git a/ceilometer/alarm/storage/impl_sqlalchemy.py b/ceilometer/alarm/storage/impl_sqlalchemy.py index ddf856ae3a..133eba89e8 100644 --- a/ceilometer/alarm/storage/impl_sqlalchemy.py +++ b/ceilometer/alarm/storage/impl_sqlalchemy.py @@ -142,9 +142,11 @@ def _retrieve_alarms(self, query): return (self._row_to_alarm_model(x) for x in query.all()) def get_alarms(self, name=None, user=None, state=None, meter=None, - project=None, enabled=None, alarm_id=None, pagination=None): - """Yields a lists of alarms that match filters + project=None, enabled=None, alarm_id=None, pagination=None, + alarm_type=None): + """Yields a lists of alarms that match filters. + :param name: Optional name for alarm. :param user: Optional ID for user that owns the resource. :param state: Optional string for alarm state. :param meter: Optional string for alarms associated with meter. @@ -152,6 +154,7 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, :param enabled: Optional boolean to list disable alarm. :param alarm_id: Optional alarm_id to return one alarm. :param pagination: Optional pagination query. + :param alarm_type: Optional alarm type. """ if pagination: @@ -171,6 +174,8 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, query = query.filter(models.Alarm.alarm_id == alarm_id) if state is not None: query = query.filter(models.Alarm.state == state) + if alarm_type is not None: + query = query.filter(models.Alarm.type == alarm_type) alarms = self._retrieve_alarms(query) @@ -243,7 +248,7 @@ def query_alarm_history(self, filter_expr=None, orderby=None, limit=None): models.AlarmChange) def get_alarm_changes(self, alarm_id, on_behalf_of, - user=None, project=None, type=None, + user=None, project=None, alarm_type=None, start_timestamp=None, start_timestamp_op=None, end_timestamp=None, end_timestamp_op=None): """Yields list of AlarmChanges describing alarm history @@ -263,7 +268,7 @@ def get_alarm_changes(self, alarm_id, on_behalf_of, administrative user, indicating all projects) :param user: Optional ID of user to return changes for :param project: Optional ID of project to return changes for - :project type: Optional change type + :param alarm_type: Optional change type :param start_timestamp: Optional modified timestamp start range :param start_timestamp_op: Optional timestamp start range operation :param end_timestamp: Optional modified timestamp end range @@ -280,8 +285,8 @@ def get_alarm_changes(self, alarm_id, on_behalf_of, query = query.filter(models.AlarmChange.user_id == user) if project is not None: query = query.filter(models.AlarmChange.project_id == project) - if type is not None: - query = query.filter(models.AlarmChange.type == type) + if alarm_type is not None: + query = query.filter(models.AlarmChange.type == alarm_type) if start_timestamp: if start_timestamp_op == 'gt': query = query.filter( diff --git a/ceilometer/alarm/storage/pymongo_base.py b/ceilometer/alarm/storage/pymongo_base.py index b012dd1e1f..b071be7b12 100644 --- a/ceilometer/alarm/storage/pymongo_base.py +++ b/ceilometer/alarm/storage/pymongo_base.py @@ -80,10 +80,11 @@ def record_alarm_change(self, alarm_change): self.db.alarm_history.insert(alarm_change.copy()) def get_alarms(self, name=None, user=None, state=None, meter=None, - project=None, enabled=None, alarm_id=None, pagination=None): - """Yields a lists of alarms that match filters + project=None, enabled=None, alarm_id=None, pagination=None, + alarm_type=None): + """Yields a lists of alarms that match filters. - :param name: The Alarm name. + :param name: Optional name for alarm. :param user: Optional ID for user that owns the resource. :param state: Optional string for alarm state. :param meter: Optional string for alarms associated with meter. @@ -91,6 +92,7 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, :param enabled: Optional boolean to list disable alarm. :param alarm_id: Optional alarm_id to return one alarm. :param pagination: Optional pagination query. + :param alarm_type: Optional alarm type. """ if pagination: raise ceilometer.NotImplementedError('Pagination not implemented') @@ -110,11 +112,13 @@ def get_alarms(self, name=None, user=None, state=None, meter=None, q['state'] = state if meter is not None: q['rule.meter_name'] = meter + if alarm_type is not None: + q['type'] = alarm_type return self._retrieve_alarms(q, [], None) def get_alarm_changes(self, alarm_id, on_behalf_of, - user=None, project=None, type=None, + user=None, project=None, alarm_type=None, start_timestamp=None, start_timestamp_op=None, end_timestamp=None, end_timestamp_op=None): """Yields list of AlarmChanges describing alarm history @@ -134,7 +138,7 @@ def get_alarm_changes(self, alarm_id, on_behalf_of, administrative user, indicating all projects) :param user: Optional ID of user to return changes for :param project: Optional ID of project to return changes for - :project type: Optional change type + :param alarm_type: Optional change type :param start_timestamp: Optional modified timestamp start range :param start_timestamp_op: Optional timestamp start range operation :param end_timestamp: Optional modified timestamp end range @@ -147,8 +151,8 @@ def get_alarm_changes(self, alarm_id, on_behalf_of, q['user_id'] = user if project is not None: q['project_id'] = project - if type is not None: - q['type'] = type + if alarm_type is not None: + q['type'] = alarm_type if start_timestamp or end_timestamp: ts_range = pymongo_utils.make_timestamp_range(start_timestamp, end_timestamp, diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index 96603efcd3..1d74bb71f5 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -420,6 +420,10 @@ def _validate_query(query, db_func, internal_keys=None, _verify_query_segregation(query) valid_keys = inspect.getargspec(db_func)[0] + if 'alarm_type' in valid_keys: + valid_keys.remove('alarm_type') + valid_keys.append('type') + internal_keys.append('self') valid_keys = set(valid_keys) - set(internal_keys) translation = {'user_id': 'user', @@ -515,7 +519,8 @@ def _query_to_kwargs(query, db_func, internal_keys=None, valid_keys = set(inspect.getargspec(db_func)[0]) - set(internal_keys) translation = {'user_id': 'user', 'project_id': 'project', - 'resource_id': 'resource'} + 'resource_id': 'resource', + 'type': 'alarm_type'} stamp = {} metaquery = {} kwargs = {} diff --git a/ceilometer/tests/api/v2/test_alarm_scenarios.py b/ceilometer/tests/api/v2/test_alarm_scenarios.py index 675323eca4..128cdb7d33 100644 --- a/ceilometer/tests/api/v2/test_alarm_scenarios.py +++ b/ceilometer/tests/api/v2/test_alarm_scenarios.py @@ -231,6 +231,15 @@ def test_alarms_query_with_state(self): self.assertEqual(1, len(resp)) self.assertEqual('ok', resp[0]['state']) + def test_list_alarms_by_type(self): + alarms = self.get_json('/alarms', + q=[{'field': 'type', + 'op': 'eq', + 'value': 'threshold'}]) + self.assertEqual(3, len(alarms)) + self.assertEqual(set(['threshold']), + set(alarm['type'] for alarm in alarms)) + def test_get_not_existing_alarm(self): resp = self.get_json('/alarms/alarm-id-3', expect_errors=True) self.assertEqual(404, resp.status_code) diff --git a/ceilometer/tests/storage/test_storage_scenarios.py b/ceilometer/tests/storage/test_storage_scenarios.py index 36890159cd..a951fb637f 100644 --- a/ceilometer/tests/storage/test_storage_scenarios.py +++ b/ceilometer/tests/storage/test_storage_scenarios.py @@ -2418,6 +2418,13 @@ def test_list_disabled(self): alarms = list(self.alarm_conn.get_alarms(enabled=False)) self.assertEqual(len(alarms), 1) + def test_list_by_type(self): + self.add_some_alarms() + alarms = list(self.alarm_conn.get_alarms(alarm_type='threshold')) + self.assertEqual(3, len(alarms)) + alarms = list(self.alarm_conn.get_alarms(alarm_type='combination')) + self.assertEqual(0, len(alarms)) + def test_add(self): self.add_some_alarms() alarms = list(self.alarm_conn.get_alarms())