diff --git a/aodhclient/tests/functional/test_alarm.py b/aodhclient/tests/functional/test_alarm.py index 1f9194e..fa76540 100644 --- a/aodhclient/tests/functional/test_alarm.py +++ b/aodhclient/tests/functional/test_alarm.py @@ -266,6 +266,46 @@ class AodhClientTest(base.ClientTestBase): if alarm_list["alarm_id"] == ALARM_ID: self.assertEqual('alarm_th', alarm_list['name']) + # LIST WITH PAGINATION + # list with limit + result = self.aodh('alarm', + params="list --limit 1") + alarm_list = self.parser.listing(result) + self.assertEqual(1, len(alarm_list)) + # list with sort with key=name dir=asc + result = self.aodh('alarm', + params="list --sort name:asc") + names = [r['name'] for r in self.parser.listing(result)] + sorted_name = sorted(names) + self.assertEqual(sorted_name, names) + # list with sort with key=name dir=asc and key=alarm_id dir=asc + result = self.aodh(u'alarm', + params=(u"create --type threshold --name alarm_th " + "-m meter_name --threshold 5 " + "--project-id %s" % PROJECT_ID)) + created_alarm_id = self.details_multiple(result)[0]['alarm_id'] + result = self.aodh('alarm', + params="list --sort name:asc --sort alarm_id:asc") + alarm_list = self.parser.listing(result) + ids_with_same_name = [] + names = [] + for alarm in alarm_list: + names.append(['alarm_name']) + if alarm['name'] == 'alarm_th': + ids_with_same_name.append(alarm['alarm_id']) + sorted_ids = sorted(ids_with_same_name) + sorted_names = sorted(names) + self.assertEqual(sorted_names, names) + self.assertEqual(sorted_ids, ids_with_same_name) + # list with sort with key=name dir=desc and with the marker equal to + # the alarm_id of the alarm_th we created for this test. + result = self.aodh('alarm', + params="list --sort name:desc " + "--marker %s" % created_alarm_id) + self.assertIn('alarm_tc', + [r['name'] for r in self.parser.listing(result)]) + self.aodh('alarm', params="delete %s" % created_alarm_id) + # LIST WITH QUERY result = self.aodh('alarm', params=("list --query project_id=%s" % PROJECT_ID)) diff --git a/aodhclient/tests/functional/test_alarm_history.py b/aodhclient/tests/functional/test_alarm_history.py index ad58ba7..08b0588 100644 --- a/aodhclient/tests/functional/test_alarm_history.py +++ b/aodhclient/tests/functional/test_alarm_history.py @@ -40,6 +40,30 @@ class AlarmHistoryTest(base.ClientTestBase): alarm = self.details_multiple(result)[0] ALARM_ID2 = alarm['alarm_id'] + # LIST WITH PAGINATION + # list with limit + result = self.aodh('alarm-history', + params=("show %s --limit 1" % ALARM_ID)) + alarm_list = self.parser.listing(result) + self.assertEqual(1, len(alarm_list)) + # list with sort key=timestamp, dir=asc + result = self.aodh('alarm-history', + params=("show %s --sort timestamp:asc" % ALARM_ID)) + alarm_history_list = self.parser.listing(result) + timestamp = [r['timestamp'] for r in alarm_history_list] + sorted_timestamp = sorted(timestamp) + self.assertEqual(sorted_timestamp, timestamp) + # list with sort key=type dir = desc and key=timestamp, dir=asc + result = self.aodh('alarm-history', + params=("show %s --sort type:desc " + "--sort timestamp:asc" % ALARM_ID)) + alarm_history_list = self.parser.listing(result) + creation = alarm_history_list.pop(-1) + timestamp = [r['timestamp'] for r in alarm_history_list] + sorted_timestamp = sorted(timestamp) + self.assertEqual(sorted_timestamp, timestamp) + self.assertEqual('creation', creation['type']) + # SHOW result = self.aodh( 'alarm-history', params=("show %s" % ALARM_ID)) diff --git a/aodhclient/utils.py b/aodhclient/utils.py index d77f03d..462a603 100644 --- a/aodhclient/utils.py +++ b/aodhclient/utils.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. import re +from six.moves.urllib import parse as urllib_parse import pyparsing as pp @@ -175,6 +176,17 @@ def cli_to_array(cli_query): return opts +def get_pagination_options(limit=None, marker=None, sorts=None): + options = [] + if limit: + options.append("limit=%d" % limit) + if marker: + options.append("marker=%s" % urllib_parse.quote(marker)) + for sort in sorts or []: + options.append("sort=%s" % urllib_parse.quote(sort)) + return "&".join(options) + + def get_client(obj): if hasattr(obj.app, 'client_manager'): # NOTE(liusheng): cliff objects loaded by OSC diff --git a/aodhclient/v2/alarm.py b/aodhclient/v2/alarm.py index 21e5506..77b65dd 100644 --- a/aodhclient/v2/alarm.py +++ b/aodhclient/v2/alarm.py @@ -14,6 +14,7 @@ from debtcollector import removals from oslo_serialization import jsonutils +from aodhclient import utils from aodhclient.v2.alarm_cli import ALARM_TYPES from aodhclient.v2 import base @@ -35,7 +36,8 @@ class AlarmManager(base.Manager): 'is deprecated, and will be removed' 'in python-aodhclient 0.7.0, please ' 'use query() instead.') - def list(self, filters=None, query=None): + def list(self, filters=None, query=None, limit=None, + marker=None, sorts=None): """List alarms. :param filters: A dict includes filters parameters, for example, @@ -47,13 +49,29 @@ class AlarmManager(base.Manager): '{"=":{"type":"threshold"}}', this expression is used to query all the threshold type alarms. :type query: js + :param limit: maximum number of resources to return + :type limit: int + :param marker: the last item of the previous page; we return the next + results after this value. + :type marker: str + :param sorts: list of resource attributes to order by. + :type sorts: list of str """ if query: return query(query) - else: - url = (self.url + '?' + self._filtersdict_to_url(filters) if - filters else self.url) - return self._get(url).json() + + pagination = utils.get_pagination_options(limit, marker, sorts) + filter_string = (self._filtersdict_to_url(filters) if + filters else "") + url = self.url + options = [] + if filter_string: + options.append(filter_string) + if pagination: + options.append(pagination) + if options: + url += "?" + "&".join(options) + return self._get(url).json() def query(self, query=None): """Query alarms. diff --git a/aodhclient/v2/alarm_cli.py b/aodhclient/v2/alarm_cli.py index 2059442..4ca100e 100644 --- a/aodhclient/v2/alarm_cli.py +++ b/aodhclient/v2/alarm_cli.py @@ -61,16 +61,33 @@ class CliAlarmList(lister.Lister): action='append', help='Filter parameters to apply on' ' returned alarms.') + parser.add_argument("--limit", type=int, metavar="", + help="Number of resources to return " + "(Default is server default)") + parser.add_argument("--marker", metavar="", + help="Last item of the previous listing. " + "Return the next results after this value," + "the supported marker is alarm_id.") + parser.add_argument("--sort", action="append", + metavar="", + help="Sort of resource attribute, " + "e.g. name:asc") return parser def take_action(self, parsed_args): if parsed_args.query: + if any([parsed_args.limit, parsed_args.sort, parsed_args.marker]): + raise exceptions.CommandError( + "Query and pagination options are mutually " + "exclusive.") query = jsonutils.dumps( utils.search_query_builder(parsed_args.query)) alarms = utils.get_client(self).alarm.query(query=query) else: filters = dict(parsed_args.filter) if parsed_args.filter else None - alarms = utils.get_client(self).alarm.list(filters=filters) + alarms = utils.get_client(self).alarm.list( + filters=filters, sorts=parsed_args.sort, + limit=parsed_args.limit, marker=parsed_args.marker) return utils.list2cols(ALARM_LIST_COLS, alarms) diff --git a/aodhclient/v2/alarm_history.py b/aodhclient/v2/alarm_history.py index 3cdebe6..e8f7b9f 100644 --- a/aodhclient/v2/alarm_history.py +++ b/aodhclient/v2/alarm_history.py @@ -13,6 +13,7 @@ from oslo_serialization import jsonutils +from aodhclient import utils from aodhclient.v2 import base @@ -20,13 +21,24 @@ class AlarmHistoryManager(base.Manager): url = "v2/alarms/%s/history" - def get(self, alarm_id): + def get(self, alarm_id, limit=None, marker=None, sorts=None): """Get history of an alarm :param alarm_id: ID of the alarm :type alarm_id: str + :param limit: maximum number of resources to return + :type limit: int + :param marker: the last item of the previous page; we return the next + results after this value. + :type marker: str + :param sorts: list of resource attributes to order by. + :type sorts: list of str """ - return self._get(self.url % alarm_id).json() + pagination = utils.get_pagination_options(limit, marker, sorts) + self.url = self.url % alarm_id + if pagination: + self.url = "%s?%s" % (self.url, pagination) + return self._get(self.url).json() def search(self, query=None): """List of history matching corresponding query diff --git a/aodhclient/v2/alarm_history_cli.py b/aodhclient/v2/alarm_history_cli.py index 272822b..0f8a3dc 100644 --- a/aodhclient/v2/alarm_history_cli.py +++ b/aodhclient/v2/alarm_history_cli.py @@ -34,7 +34,8 @@ class CliAlarmHistorySearch(lister.Lister): if parsed_args.query: query = jsonutils.dumps( utils.search_query_builder(parsed_args.query)) - history = utils.get_client(self).alarm_history.search(query=query) + history = utils.get_client(self).alarm_history.search( + query=query) return utils.list2cols(self.COLS, history) @@ -46,9 +47,21 @@ class CliAlarmHistoryShow(lister.Lister): def get_parser(self, prog_name): parser = super(CliAlarmHistoryShow, self).get_parser(prog_name) parser.add_argument("alarm_id", help="ID of an alarm") + parser.add_argument("--limit", type=int, metavar="", + help="Number of resources to return " + "(Default is server default)") + parser.add_argument("--marker", metavar="", + help="Last item of the previous listing. " + "Return the next results after this value," + "the supported marker is event_id.") + parser.add_argument("--sort", action="append", + metavar="", + help="Sort of resource attribute. " + "e.g. timestamp:desc") return parser def take_action(self, parsed_args): history = utils.get_client(self).alarm_history.get( - alarm_id=parsed_args.alarm_id) + alarm_id=parsed_args.alarm_id, sorts=parsed_args.sort, + limit=parsed_args.limit, marker=parsed_args.marker) return utils.list2cols(self.COLS, history) diff --git a/releasenotes/notes/add-pagination-support-fcdf1cef0cfa5ca9.yaml b/releasenotes/notes/add-pagination-support-fcdf1cef0cfa5ca9.yaml new file mode 100644 index 0000000..01017ae --- /dev/null +++ b/releasenotes/notes/add-pagination-support-fcdf1cef0cfa5ca9.yaml @@ -0,0 +1,4 @@ +--- +features: + - Add pagination support for aodhclient, users can now use limit, sort + and marker when list alarms and show alarm histories.