[microversions] Enable 2.21
2.21 - The os-instance-actions API now returns information from deleted instances. Change-Id: Iff514e4fa9135207c6f8e32e444d45b1b61d8c7c
This commit is contained in:
parent
ca5b06f6ae
commit
cd88097ff5
@ -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.20")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.21")
|
||||
|
@ -308,7 +308,8 @@ class ClientTestBase(testtools.TestCase):
|
||||
|
||||
raise ValueError("Unable to find value for column '%s'.")
|
||||
|
||||
def _create_server(self, name=None, with_network=True, **kwargs):
|
||||
def _create_server(self, name=None, with_network=True, add_cleanup=True,
|
||||
**kwargs):
|
||||
name = name or self.name_generate(prefix='server')
|
||||
if with_network:
|
||||
nics = [{"net-id": self.network.id}]
|
||||
@ -316,7 +317,8 @@ class ClientTestBase(testtools.TestCase):
|
||||
nics = None
|
||||
server = self.client.servers.create(name, self.image, self.flavor,
|
||||
nics=nics, **kwargs)
|
||||
self.addCleanup(server.delete)
|
||||
if add_cleanup:
|
||||
self.addCleanup(server.delete)
|
||||
novaclient.v2.shell._poll_for_status(
|
||||
self.client.servers.get, server.id,
|
||||
'building', ['active'])
|
||||
|
60
novaclient/tests/functional/v2/test_instance_action.py
Normal file
60
novaclient/tests/functional/v2/test_instance_action.py
Normal file
@ -0,0 +1,60 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import uuid
|
||||
|
||||
import six
|
||||
from tempest_lib import exceptions
|
||||
|
||||
from novaclient.tests.functional import base
|
||||
|
||||
|
||||
class TestInstanceActionCLI(base.ClientTestBase):
|
||||
|
||||
COMPUTE_API_VERSION = "2.21"
|
||||
|
||||
def _test_cmd_with_not_existing_instance(self, cmd, args):
|
||||
try:
|
||||
self.nova("%s %s" % (cmd, args))
|
||||
except exceptions.CommandFailed as e:
|
||||
self.assertIn("ERROR (NotFound):", six.text_type(e))
|
||||
else:
|
||||
self.fail("%s is not failed on non existing instance." % cmd)
|
||||
|
||||
def test_show_action_with_not_existing_instance(self):
|
||||
name_or_uuid = str(uuid.uuid4())
|
||||
request_id = str(uuid.uuid4())
|
||||
self._test_cmd_with_not_existing_instance(
|
||||
"instance-action", "%s %s" % (name_or_uuid, request_id))
|
||||
|
||||
def test_list_actions_with_not_existing_instance(self):
|
||||
name_or_uuid = str(uuid.uuid4())
|
||||
self._test_cmd_with_not_existing_instance("instance-action-list",
|
||||
name_or_uuid)
|
||||
|
||||
def test_show_and_list_actions_on_deleted_instance(self):
|
||||
server = self._create_server(add_cleanup=False)
|
||||
server.delete()
|
||||
self.wait_for_resource_delete(server, self.client.servers)
|
||||
|
||||
output = self.nova("instance-action-list %s" % server.id)
|
||||
# NOTE(andreykurilin): output is not a single row table, so we can
|
||||
# obtain just "create" action. It should be enough for testing
|
||||
# "nova instance-action <server> <request-id>" command
|
||||
request_id = self._get_column_value_from_single_row_table(
|
||||
output, "Request_ID")
|
||||
|
||||
output = self.nova("instance-action %s %s" % (server.id, request_id))
|
||||
|
||||
# ensure that obtained action is "create".
|
||||
self.assertEqual("create",
|
||||
self._get_value_from_the_table(output, "action"))
|
@ -158,6 +158,15 @@ class FindResourceTestCase(test_utils.TestCase):
|
||||
output = utils.find_resource(alphanum_manager, '01234')
|
||||
self.assertEqual(output, alphanum_manager.get('01234'))
|
||||
|
||||
def test_find_without_wrapping_exception(self):
|
||||
alphanum_manager = FakeManager(True)
|
||||
self.assertRaises(exceptions.NotFound, utils.find_resource,
|
||||
alphanum_manager, 'not_exist', wrap_exception=False)
|
||||
res = alphanum_manager.resources[0]
|
||||
alphanum_manager.resources.append(res)
|
||||
self.assertRaises(exceptions.NoUniqueMatch, utils.find_resource,
|
||||
alphanum_manager, res.name, wrap_exception=False)
|
||||
|
||||
|
||||
class _FakeResult(object):
|
||||
def __init__(self, name, value):
|
||||
|
@ -273,7 +273,7 @@ def print_dict(d, dict_property="Property", dict_value="Value", wrap=0):
|
||||
print(result)
|
||||
|
||||
|
||||
def find_resource(manager, name_or_id, **find_args):
|
||||
def find_resource(manager, name_or_id, wrap_exception=True, **find_args):
|
||||
"""Helper for the _find_* methods."""
|
||||
# for str id which is not uuid (for Flavor, Keypair and hypervsior in cells
|
||||
# environments search currently)
|
||||
@ -316,7 +316,9 @@ def find_resource(manager, name_or_id, **find_args):
|
||||
"to be more specific.") %
|
||||
{'class': manager.resource_class.__name__.lower(),
|
||||
'name': name_or_id})
|
||||
raise exceptions.CommandError(msg)
|
||||
if wrap_exception:
|
||||
raise exceptions.CommandError(msg)
|
||||
raise exceptions.NoUniqueMatch(msg)
|
||||
|
||||
# finally try to get entity as integer id
|
||||
try:
|
||||
@ -325,7 +327,9 @@ def find_resource(manager, name_or_id, **find_args):
|
||||
msg = (_("No %(class)s with a name or ID of '%(name)s' exists.") %
|
||||
{'class': manager.resource_class.__name__.lower(),
|
||||
'name': name_or_id})
|
||||
raise exceptions.CommandError(msg)
|
||||
if wrap_exception:
|
||||
raise exceptions.CommandError(msg)
|
||||
raise exceptions.NotFound(404, msg)
|
||||
|
||||
|
||||
def _format_servers_list_networks(server):
|
||||
|
@ -15,7 +15,11 @@
|
||||
|
||||
import pprint
|
||||
|
||||
import six
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient import base
|
||||
from novaclient import exceptions
|
||||
from novaclient.i18n import _
|
||||
from novaclient.openstack.common import cliutils
|
||||
from novaclient import utils
|
||||
@ -41,17 +45,41 @@ class InstanceActionManager(base.ManagerWithFind):
|
||||
base.getid(server), 'instanceActions')
|
||||
|
||||
|
||||
@api_versions.wraps("2.0", "2.20")
|
||||
def _find_server(cs, args):
|
||||
return utils.find_resource(cs.servers, args.server)
|
||||
|
||||
|
||||
@api_versions.wraps("2.21")
|
||||
def _find_server(cs, args):
|
||||
try:
|
||||
return utils.find_resource(cs.servers, args.server,
|
||||
wrap_exception=False)
|
||||
except exceptions.NoUniqueMatch as e:
|
||||
raise exceptions.CommandError(six.text_type(e))
|
||||
except exceptions.NotFound:
|
||||
# The server can be deleted
|
||||
return args.server
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'server',
|
||||
metavar='<server>',
|
||||
help=_('Name or UUID of the server to show an action for.'))
|
||||
help=_('Name or UUID of the server to show actions for.'),
|
||||
start_version="2.0", end_version="2.20")
|
||||
@cliutils.arg(
|
||||
'server',
|
||||
metavar='<server>',
|
||||
help=_('Name or UUID of the server to show actions for. Only UUID can be '
|
||||
'used to show actions for a deleted server.'),
|
||||
start_version="2.21")
|
||||
@cliutils.arg(
|
||||
'request_id',
|
||||
metavar='<request_id>',
|
||||
help=_('Request ID of the action to get.'))
|
||||
def do_instance_action(cs, args):
|
||||
"""Show an action."""
|
||||
server = utils.find_resource(cs.servers, args.server)
|
||||
server = _find_server(cs, args)
|
||||
action_resource = cs.instance_action.get(server, args.request_id)
|
||||
action = action_resource._info
|
||||
if 'events' in action:
|
||||
@ -62,10 +90,17 @@ def do_instance_action(cs, args):
|
||||
@cliutils.arg(
|
||||
'server',
|
||||
metavar='<server>',
|
||||
help=_('Name or UUID of the server to list actions for.'))
|
||||
help=_('Name or UUID of the server to list actions for.'),
|
||||
start_version="2.0", end_version="2.20")
|
||||
@cliutils.arg(
|
||||
'server',
|
||||
metavar='<server>',
|
||||
help=_('Name or UUID of the server to list actions for. Only UUID can be '
|
||||
'used to list actions on a deleted server.'),
|
||||
start_version="2.21")
|
||||
def do_instance_action_list(cs, args):
|
||||
"""List actions on a server."""
|
||||
server = utils.find_resource(cs.servers, args.server)
|
||||
server = _find_server(cs, args)
|
||||
actions = cs.instance_action.list(server)
|
||||
utils.print_list(actions,
|
||||
['Action', 'Request_ID', 'Message', 'Start_Time'],
|
||||
|
Loading…
Reference in New Issue
Block a user