diff --git a/doc/source/cli/nova.rst b/doc/source/cli/nova.rst index 35799551d..899a0e0bf 100644 --- a/doc/source/cli/nova.rst +++ b/doc/source/cli/nova.rst @@ -1923,6 +1923,7 @@ nova instance-action-list usage: nova instance-action-list [--marker ] [--limit ] [--changes-since ] + [--changes-before ] List actions on a server. @@ -1947,10 +1948,15 @@ List actions on a server. in the server. (Supported by API versions '2.58' - '2.latest') ``--changes-since `` - List only instance actions changed after a certain point of time. - The provided time should be an ISO 8061 formatted time. + List only instance actions changed later or equal to a certain + point of time. The provided time should be an ISO 8061 formatted time. e.g. 2016-03-04T06:27:59Z. (Supported by API versions '2.58' - '2.latest') +``--changes-before `` + List only instance actions changed earlier or equal to a certain + point of time. The provided time should be an ISO 8061 formatted time. + e.g. 2016-03-04T06:27:59Z. (Supported by API versions '2.66' - '2.latest') + .. _nova_interface-attach: nova interface-attach @@ -2154,6 +2160,7 @@ nova list [--user []] [--deleted] [--fields ] [--minimal] [--sort [:]] [--marker ] [--limit ] [--changes-since ] + [--changes-before ] [--tags ] [--tags-any ] [--not-tags ] [--not-tags-any ] @@ -2233,11 +2240,18 @@ List servers. used instead. ``--changes-since `` - List only servers changed after a certain - point of time.The provided time should be an - ISO 8061 formatted time.ex + List only servers changed later or equal to a + certain point of time. The provided time should + be an ISO 8061 formatted time. e.g. 2016-03-04T06:27:59Z . +``--changes-before `` + List only servers changed earlier or equal to a + certain point of time. The provided time should + be an ISO 8061 formatted time. e.g. + 2016-03-05T06:27:59Z . (Supported by API versions + '2.66' - '2.latest') + ``--tags `` The given tags must all be present for a server to be included in the list result. @@ -2443,6 +2457,7 @@ nova migration-list usage: nova migration-list [--instance-uuid ] [--host ] [--status ] [--marker ] [--limit ] [--changes-since ] + [--changes-before ] Print a list of migrations. @@ -2469,10 +2484,15 @@ Print a list of migrations. (Supported by API versions '2.59' - '2.latest') ``--changes-since `` - List only migrations changed after a certain point of time. - The provided time should be an ISO 8061 formatted time. + List only migrations changed later or equal to a certain + point of time. The provided time should be an ISO 8061 formatted time. e.g. 2016-03-04T06:27:59Z . (Supported by API versions '2.59' - '2.latest') +``--changes-before `` + List only migrations changed earlier or equal to a certain + point of time. The provided time should be an ISO 8061 formatted time. + e.g. 2016-03-04T06:27:59Z . (Supported by API versions '2.66' - '2.latest') + .. _nova_pause: nova pause diff --git a/novaclient/__init__.py b/novaclient/__init__.py index e4f84779d..49bd667d7 100644 --- a/novaclient/__init__.py +++ b/novaclient/__init__.py @@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1") # when client supported the max version, and bumped sequentially, otherwise # the client may break due to server side new version may include some # backward incompatible change. -API_MAX_VERSION = api_versions.APIVersion("2.65") +API_MAX_VERSION = api_versions.APIVersion("2.66") diff --git a/novaclient/tests/functional/v2/test_instance_action.py b/novaclient/tests/functional/v2/test_instance_action.py index 9ea15c284..968c12d6b 100644 --- a/novaclient/tests/functional/v2/test_instance_action.py +++ b/novaclient/tests/functional/v2/test_instance_action.py @@ -151,3 +151,39 @@ class TestInstanceActionCLIV262(TestInstanceActionCLIV258, output = self.nova("instance-action %s %s" % (server_id, request_id)) self.assertIn("'host'", output) self.assertIn("'hostId'", output) + + +class TestInstanceActionCLIV266(TestInstanceActionCLIV258, + base.TenantTestBase): + """Instance action functional tests for v2.66 nova-api microversion.""" + + COMPUTE_API_VERSION = "2.66" + expect_event_hostId_field = True + + def test_list_instance_action_with_changes_before(self): + # Ignore microseconds to make this a deterministic test. + server = self._create_server() + end_create = timeutils.utcnow().replace(microsecond=0).isoformat() + time.sleep(2) + server.stop() + end_stop = timeutils.utcnow().replace(microsecond=0).isoformat() + + stop_output = self.nova( + "instance-action-list %s --changes-before %s" % + (server.id, end_stop)) + action = self._get_list_of_values_from_single_column_table( + stop_output, "Action") + # The actions are sorted by created_at in descending order. + self.assertEqual(action, ['create', 'stop']) + + create_output = self.nova( + "instance-action-list %s --changes-before %s" % + (server.id, end_create)) + action = self._get_list_of_values_from_single_column_table( + create_output, "Action") + # Provide detailed debug information if this fails. + self.assertEqual(action, ['create'], + 'Expected to find the create action with ' + '--changes-before=%s but got: %s\n\n' + 'First instance-action-list output: %s' % + (end_create, create_output, stop_output)) diff --git a/novaclient/tests/unit/v2/test_instance_actions.py b/novaclient/tests/unit/v2/test_instance_actions.py index e26bf7a50..e2da9d03a 100644 --- a/novaclient/tests/unit/v2/test_instance_actions.py +++ b/novaclient/tests/unit/v2/test_instance_actions.py @@ -61,3 +61,23 @@ class InstanceActionExtensionV258Tests(InstanceActionExtensionTests): 'marker=%s' % (server_uuid, '2016-02-29T06%3A23%3A22', marker)) for ia in ias: self.assertIsInstance(ia, instance_action.InstanceAction) + + +class InstanceActionExtensionV266Tests(InstanceActionExtensionV258Tests): + def setUp(self): + super(InstanceActionExtensionV266Tests, self).setUp() + self.cs.api_version = api_versions.APIVersion("2.66") + + def test_list_instance_actions_with_changes_before(self): + server_uuid = '1234' + + ias = self.cs.instance_action.list( + server_uuid, marker=None, limit=None, changes_since=None, + changes_before='2016-02-29T06:23:22') + self.assert_request_id(ias, fakes.FAKE_REQUEST_ID_LIST) + self.cs.assert_called( + 'GET', + '/servers/%s/os-instance-actions?changes-before=%s' % + (server_uuid, '2016-02-29T06%3A23%3A22')) + for ia in ias: + self.assertIsInstance(ia, instance_action.InstanceAction) diff --git a/novaclient/tests/unit/v2/test_migrations.py b/novaclient/tests/unit/v2/test_migrations.py index 4efa3cb44..fcafa6d29 100644 --- a/novaclient/tests/unit/v2/test_migrations.py +++ b/novaclient/tests/unit/v2/test_migrations.py @@ -95,3 +95,20 @@ class MigrationsV259Test(MigrationsV223Test): % ('2012-02-29T06%3A23%3A22', marker)) for m in ms: self.assertIsInstance(m, migrations.Migration) + + +class MigrationsV266Test(MigrationsV259Test): + def setUp(self): + super(MigrationsV266Test, self).setUp() + self.cs.api_version = api_versions.APIVersion("2.66") + + def test_list_migrations_with_changes_before(self): + params = {'changes_before': '2012-02-29T06:23:22'} + ms = self.cs.migrations.list(**params) + self.assert_request_id(ms, fakes.FAKE_REQUEST_ID_LIST) + self.cs.assert_called('GET', + '/os-migrations?' + 'changes-before=%s' % + '2012-02-29T06%3A23%3A22') + for m in ms: + self.assertIsInstance(m, migrations.Migration) diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index c5492514f..7bde8cd3d 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -1597,6 +1597,23 @@ class ShellTest(utils.TestCase): self.assertRaises(exceptions.CommandError, self.run_command, 'list --changes-since 0123456789') + def test_list_with_changes_before(self): + self.run_command('list --changes-before 2016-02-29T06:23:22', + api_version='2.66') + self.assert_called( + 'GET', '/servers/detail?changes-before=2016-02-29T06%3A23%3A22') + + def test_list_with_changes_before_invalid_value(self): + ex = self.assertRaises(exceptions.CommandError, self.run_command, + 'list --changes-before 0123456789', + api_version='2.66') + self.assertIn('Invalid changes-before value', six.text_type(ex)) + + def test_list_with_changes_before_pre_v266_not_allowed(self): + self.assertRaises(SystemExit, self.run_command, + 'list --changes-before 2016-02-29T06:23:22', + api_version='2.65') + def test_list_fields_redundant(self): output, _err = self.run_command('list --fields id,status,status') header = output.splitlines()[1] @@ -3487,6 +3504,28 @@ class ShellTest(utils.TestCase): api_version='2.58') self.assertIn('Invalid changes-since value', six.text_type(ex)) + def test_instance_action_list_changes_before_pre_v266_not_allowed(self): + cmd = 'instance-action-list sample-server --changes-before ' \ + '2016-02-29T06:23:22' + self.assertRaises(SystemExit, self.run_command, + cmd, api_version='2.65') + + def test_instance_action_list_with_changes_before_v266(self): + self.run_command('instance-action-list sample-server ' + '--changes-before 2016-02-29T06:23:22', + api_version='2.66') + self.assert_called( + 'GET', + '/servers/1234/os-instance-actions?' + 'changes-before=2016-02-29T06%3A23%3A22') + + def test_instance_action_list_with_changes_before_invalid_value_v266(self): + ex = self.assertRaises( + exceptions.CommandError, self.run_command, + 'instance-action-list sample-server --changes-before 0123456789', + api_version='2.66') + self.assertIn('Invalid changes-before value', six.text_type(ex)) + def test_instance_usage_audit_log(self): self.run_command('instance-usage-audit-log') self.assert_called('GET', '/os-instance_usage_audit_log') @@ -3564,6 +3603,23 @@ class ShellTest(utils.TestCase): api_version='2.59') self.assertIn('Invalid changes-since value', six.text_type(ex)) + def test_migration_list_with_changes_before_v266(self): + self.run_command('migration-list --changes-before 2016-02-29T06:23:22', + api_version='2.66') + self.assert_called( + 'GET', '/os-migrations?changes-before=2016-02-29T06%3A23%3A22') + + def test_migration_list_with_changes_before_invalid_value_v266(self): + ex = self.assertRaises(exceptions.CommandError, self.run_command, + 'migration-list --changes-before 0123456789', + api_version='2.66') + self.assertIn('Invalid changes-before value', six.text_type(ex)) + + def test_migration_list_with_changes_before_pre_v266_not_allowed(self): + cmd = 'migration-list --changes-before 2016-02-29T06:23:22' + self.assertRaises(SystemExit, self.run_command, cmd, + api_version='2.65') + @mock.patch('novaclient.v2.shell._find_server') @mock.patch('os.system') def test_ssh(self, mock_system, mock_find_server): diff --git a/novaclient/v2/instance_action.py b/novaclient/v2/instance_action.py index b8316c2d7..79f1b6173 100644 --- a/novaclient/v2/instance_action.py +++ b/novaclient/v2/instance_action.py @@ -43,7 +43,7 @@ class InstanceActionManager(base.ManagerWithFind): return self._list('/servers/%s/os-instance-actions' % base.getid(server), 'instanceActions') - @api_versions.wraps("2.58") + @api_versions.wraps("2.58", "2.65") def list(self, server, marker=None, limit=None, changes_since=None): """ Get a list of actions performed on a server. @@ -53,10 +53,10 @@ class InstanceActionManager(base.ManagerWithFind): list than that represented by this action request id (optional). :param limit: Maximum number of actions to return. (optional). - :param changes_since: List only instance actions changed after a - certain point of time. The provided time should - be an ISO 8061 formatted time. ex - 2016-03-04T06:27:59Z . (optional). + :param changes_since: List only instance actions changed later or + equal to a certain point of time. The provided + time should be an ISO 8061 formatted time. + e.g. 2016-03-04T06:27:59Z . (optional). """ opts = {} if marker: @@ -67,3 +67,35 @@ class InstanceActionManager(base.ManagerWithFind): opts['changes-since'] = changes_since return self._list('/servers/%s/os-instance-actions' % base.getid(server), 'instanceActions', filters=opts) + + @api_versions.wraps("2.66") + def list(self, server, marker=None, limit=None, changes_since=None, + changes_before=None): + """ + Get a list of actions performed on a server. + + :param server: The :class:`Server` (or its ID) + :param marker: Begin returning actions that appear later in the action + list than that represented by this action request id + (optional). + :param limit: Maximum number of actions to return. (optional). + :param changes_since: List only instance actions changed later or + equal to a certain point of time. The provided + time should be an ISO 8061 formatted time. + e.g. 2016-03-04T06:27:59Z . (optional). + :param changes_before: List only instance actions changed earlier or + equal to a certain point of time. The provided + time should be an ISO 8061 formatted time. + e.g. 2016-03-05T06:27:59Z . (optional). + """ + opts = {} + if marker: + opts['marker'] = marker + if limit: + opts['limit'] = limit + if changes_since: + opts['changes-since'] = changes_since + if changes_before: + opts['changes-before'] = changes_before + return self._list('/servers/%s/os-instance-actions' % + base.getid(server), 'instanceActions', filters=opts) diff --git a/novaclient/v2/migrations.py b/novaclient/v2/migrations.py index 00eb6d110..f1954f1ab 100644 --- a/novaclient/v2/migrations.py +++ b/novaclient/v2/migrations.py @@ -27,7 +27,8 @@ class MigrationManager(base.ManagerWithFind): resource_class = Migration def _list_base(self, host=None, status=None, instance_uuid=None, - marker=None, limit=None, changes_since=None): + marker=None, limit=None, changes_since=None, + changes_before=None): opts = {} if host: opts['host'] = host @@ -41,6 +42,8 @@ class MigrationManager(base.ManagerWithFind): opts['limit'] = limit if changes_since: opts['changes-since'] = changes_since + if changes_before: + opts['changes-before'] = changes_before return self._list("/os-migrations", "migrations", filters=opts) @@ -55,7 +58,7 @@ class MigrationManager(base.ManagerWithFind): return self._list_base(host=host, status=status, instance_uuid=instance_uuid) - @api_versions.wraps("2.59") + @api_versions.wraps("2.59", "2.65") def list(self, host=None, status=None, instance_uuid=None, marker=None, limit=None, changes_since=None): """ @@ -67,11 +70,37 @@ class MigrationManager(base.ManagerWithFind): migrations list than that represented by this migration UUID (optional). :param limit: maximum number of migrations to return (optional). - :param changes_since: only return migrations updated after. The - provided time should be an ISO 8061 formatted time. ex - 2016-03-04T06:27:59Z . (optional). + :param changes_since: only return migrations changed later or equal + to a certain point of time. The provided time should be an ISO 8061 + formatted time. e.g. 2016-03-04T06:27:59Z . (optional). """ return self._list_base(host=host, status=status, instance_uuid=instance_uuid, marker=marker, limit=limit, changes_since=changes_since) + + @api_versions.wraps("2.66") + def list(self, host=None, status=None, instance_uuid=None, + marker=None, limit=None, changes_since=None, + changes_before=None): + """ + Get a list of migrations. + :param host: filter migrations by host name (optional). + :param status: filter migrations by status (optional). + :param instance_uuid: filter migrations by instance uuid (optional). + :param marker: Begin returning migrations that appear later in the + migrations list than that represented by this migration UUID + (optional). + :param limit: maximum number of migrations to return (optional). + :param changes_since: Only return migrations changed later or equal + to a certain point of time. The provided time should be an ISO 8061 + formatted time. e.g. 2016-03-04T06:27:59Z . (optional). + :param changes_before: Only return migrations changed earlier or + equal to a certain point of time. The provided time should be an ISO + 8061 formatted time. e.g. 2016-03-05T06:27:59Z . (optional). + """ + return self._list_base(host=host, status=status, + instance_uuid=instance_uuid, + marker=marker, limit=limit, + changes_since=changes_since, + changes_before=changes_before) diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py index 0bf6da8ee..7ddc5323e 100644 --- a/novaclient/v2/shell.py +++ b/novaclient/v2/shell.py @@ -1475,9 +1475,18 @@ def _print_flavor(flavor): dest='changes_since', metavar='', default=None, - help=_("List only servers changed after a certain point of time. " - "The provided time should be an ISO 8061 formatted time. " - "ex 2016-03-04T06:27:59Z .")) + help=_("List only servers changed later or equal to a certain point of " + "time. The provided time should be an ISO 8061 formatted time. " + "e.g. 2016-03-04T06:27:59Z .")) +@utils.arg( + '--changes-before', + dest='changes_before', + metavar='', + default=None, + help=_("List only servers changed earlier or equal to a certain point of " + "time. The provided time should be an ISO 8061 formatted time. " + "e.g. 2016-03-04T06:27:59Z ."), + start_version="2.66") @utils.arg( '--tags', dest='tags', @@ -1582,6 +1591,18 @@ def do_list(cs, args): raise exceptions.CommandError(_('Invalid changes-since value: %s') % search_opts['changes-since']) + # In microversion 2.66 we added ``changes-before`` option + # in server details. + have_added_changes_before = ( + cs.api_version >= api_versions.APIVersion('2.66')) + if have_added_changes_before and args.changes_before: + search_opts['changes-before'] = args.changes_before + try: + timeutils.parse_isotime(search_opts['changes-before']) + except ValueError: + raise exceptions.CommandError(_('Invalid changes-before value: %s') + % search_opts['changes-before']) + servers = cs.servers.list(detailed=detailed, search_opts=search_opts, sort_keys=sort_keys, @@ -1629,7 +1650,7 @@ def do_list(cs, args): # Tenant ID as well if search_opts['all_tenants']: columns.insert(2, 'Tenant ID') - if search_opts['changes-since']: + if search_opts['changes-since'] or search_opts.get('changes-before'): columns.append('Updated') formatters['Networks'] = utils.format_servers_list_networks sortby_index = 1 @@ -5023,7 +5044,7 @@ def do_instance_action_list(cs, args): sortby_index=3) -@api_versions.wraps("2.58") +@api_versions.wraps("2.58", "2.65") @utils.arg( 'server', metavar='', @@ -5051,9 +5072,9 @@ def do_instance_action_list(cs, args): dest='changes_since', metavar='', default=None, - help=_('List only instance actions changed after a certain point of ' - 'time. The provided time should be an ISO 8061 formatted time. ' - 'e.g. 2016-03-04T06:27:59Z.')) + help=_('List only instance actions changed later or equal to a certain ' + 'point of time. The provided time should be an ISO 8061 formatted ' + 'time. e.g. 2016-03-04T06:27:59Z.')) def do_instance_action_list(cs, args): """List actions on a server.""" server = _find_server(cs, args.server, raise_if_notfound=False) @@ -5073,6 +5094,75 @@ def do_instance_action_list(cs, args): sortby_index=3) +@api_versions.wraps("2.66") +@utils.arg( + 'server', + metavar='', + help=_('Name or UUID of the server to list actions for. Only UUID can be ' + 'used to list actions on a deleted server.')) +@utils.arg( + '--marker', + dest='marker', + metavar='', + default=None, + help=_('The last instance action of the previous page; displays list of ' + 'actions after "marker".')) +@utils.arg( + '--limit', + dest='limit', + metavar='', + type=int, + default=None, + help=_('Maximum number of instance actions to display. Note that there ' + 'is a configurable max limit on the server, and the limit that is ' + 'used will be the minimum of what is requested here and what ' + 'is configured in the server.')) +@utils.arg( + '--changes-since', + dest='changes_since', + metavar='', + default=None, + help=_('List only instance actions changed later or equal to a certain ' + 'point of time. The provided time should be an ISO 8061 formatted ' + 'time. e.g. 2016-03-04T06:27:59Z.')) +@utils.arg( + '--changes-before', + dest='changes_before', + metavar='', + default=None, + help=_('List only instance actions changed earlier or equal to a certain ' + 'point of time. The provided time should be an ISO 8061 formatted ' + 'time. e.g. 2016-03-04T06:27:59Z.'), + start_version="2.66") +def do_instance_action_list(cs, args): + """List actions on a server.""" + server = _find_server(cs, args.server, raise_if_notfound=False) + if args.changes_since: + try: + timeutils.parse_isotime(args.changes_since) + except ValueError: + raise exceptions.CommandError(_('Invalid changes-since value: %s') + % args.changes_since) + + # In microversion 2.66 we added ``changes-before`` option + # in instance actions. + if args.changes_before: + try: + timeutils.parse_isotime(args.changes_before) + except ValueError: + raise exceptions.CommandError(_('Invalid changes-before value: %s') + % args.changes_before) + + actions = cs.instance_action.list(server, marker=args.marker, + limit=args.limit, + changes_since=args.changes_since, + changes_before=args.changes_before) + utils.print_list(actions, + ['Action', 'Request_ID', 'Message', 'Start_Time', + 'Updated_At'], + sortby_index=3) + + def do_list_extensions(cs, _args): """ List all the os-api extensions that are available. @@ -5165,7 +5255,7 @@ def do_migration_list(cs, args): _print_migrations(cs, migrations) -@api_versions.wraps("2.59") +@api_versions.wraps("2.59", "2.65") @utils.arg( '--instance-uuid', dest='instance_uuid', @@ -5204,8 +5294,8 @@ def do_migration_list(cs, args): dest='changes_since', metavar='', default=None, - help=_('List only migrations changed after a certain point of time. ' - 'The provided time should be an ISO 8061 formatted time. ' + help=_('List only migrations changed later or equal to a certain point ' + 'of time. The provided time should be an ISO 8061 formatted time. ' 'e.g. 2016-03-04T06:27:59Z .')) def do_migration_list(cs, args): """Print a list of migrations.""" @@ -5224,6 +5314,81 @@ def do_migration_list(cs, args): _print_migrations(cs, migrations) +@api_versions.wraps("2.66") +@utils.arg( + '--instance-uuid', + dest='instance_uuid', + metavar='', + help=_('Fetch migrations for the given instance.')) +@utils.arg( + '--host', + dest='host', + metavar='', + help=_('Fetch migrations for the given host.')) +@utils.arg( + '--status', + dest='status', + metavar='', + help=_('Fetch migrations for the given status.')) +@utils.arg( + '--marker', + dest='marker', + metavar='', + default=None, + help=_('The last migration of the previous page; displays list of ' + 'migrations after "marker". Note that the marker is the ' + 'migration UUID.')) +@utils.arg( + '--limit', + dest='limit', + metavar='', + type=int, + default=None, + help=_('Maximum number of migrations to display. Note that there is a ' + 'configurable max limit on the server, and the limit that is used ' + 'will be the minimum of what is requested here and what ' + 'is configured in the server.')) +@utils.arg( + '--changes-since', + dest='changes_since', + metavar='', + default=None, + help=_('List only migrations changed later or equal to a certain point ' + 'of time. The provided time should be an ISO 8061 formatted time. ' + 'e.g. 2016-03-04T06:27:59Z .')) +@utils.arg( + '--changes-before', + dest='changes_before', + metavar='', + default=None, + help=_('List only migrations changed earlier or equal to a certain point ' + 'of time. The provided time should be an ISO 8061 formatted time. ' + 'e.g. 2016-03-04T06:27:59Z .'), + start_version="2.66") +def do_migration_list(cs, args): + """Print a list of migrations.""" + if args.changes_since: + try: + timeutils.parse_isotime(args.changes_since) + except ValueError: + raise exceptions.CommandError(_('Invalid changes-since value: %s') + % args.changes_since) + + if args.changes_before: + try: + timeutils.parse_isotime(args.changes_before) + except ValueError: + raise exceptions.CommandError(_('Invalid changes-before value: %s') + % args.changes_before) + + migrations = cs.migrations.list(args.host, args.status, + instance_uuid=args.instance_uuid, + marker=args.marker, limit=args.limit, + changes_since=args.changes_since, + changes_before=args.changes_before) + _print_migrations(cs, migrations) + + @utils.arg( '--before', dest='before', diff --git a/releasenotes/notes/microversion-v2_66-cda5d6dc31b56b46.yaml b/releasenotes/notes/microversion-v2_66-cda5d6dc31b56b46.yaml new file mode 100644 index 000000000..69c649521 --- /dev/null +++ b/releasenotes/notes/microversion-v2_66-cda5d6dc31b56b46.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + Added support for `microversion 2.66`_ which adds ``changes-before`` + parameter to the servers, os-instance-actions or os-migrations APIs. + + * This parameter (``changes-before``) does not change any read-deleted + behavior in the os-instance-actions or os-migrations APIs. + * Like the ``changes-since`` filter, the ``changes-before`` filter will + also return deleted servers. + * The ``--changes-before`` options is added to the ``nova list``, + ``nova instance-action-list`` and ``nova migration-list`` CLIs. + + .. _microversion 2.66: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id59