Make os-instance-action read deleted instances.
Add a microversion change to the os-instance-actions API so that we mutate the context to set 'read_deleted="yes"' when looking up the instance. Blueprint: os-instance-actions-read-deleted-instances Change-Id: I607a28bbe06e20e17ee47a283e06b1d42b5c0e84
This commit is contained in:
parent
07573aff23
commit
934a0e4ede
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"instanceActions": [
|
||||||
|
{
|
||||||
|
"action": "resize",
|
||||||
|
"instance_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
|
||||||
|
"message": "",
|
||||||
|
"project_id": "842",
|
||||||
|
"request_id": "req-25517360-b757-47d3-be45-0e8d2a01b36a",
|
||||||
|
"start_time": "2012-12-05T01:00:00.000000",
|
||||||
|
"user_id": "789"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "reboot",
|
||||||
|
"instance_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
|
||||||
|
"message": "",
|
||||||
|
"project_id": "147",
|
||||||
|
"request_id": "req-3293a3f1-b44c-4609-b8d2-d81b105636b8",
|
||||||
|
"start_time": "2012-12-05T00:00:00.000000",
|
||||||
|
"user_id": "789"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
|||||||
* 2.19 - Allow user to set and get the server description
|
* 2.19 - Allow user to set and get the server description
|
||||||
* 2.20 - Add attach and detach volume operations for instances in shelved
|
* 2.20 - Add attach and detach volume operations for instances in shelved
|
||||||
and shelved_offloaded state
|
and shelved_offloaded state
|
||||||
|
* 2.21 - Make os-instance-actions read deleted instances
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
|||||||
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
||||||
# support is fully merged. It does not affect the V2 API.
|
# support is fully merged. It does not affect the V2 API.
|
||||||
_MIN_API_VERSION = "2.1"
|
_MIN_API_VERSION = "2.1"
|
||||||
_MAX_API_VERSION = "2.20"
|
_MAX_API_VERSION = "2.21"
|
||||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from nova.api.openstack import extensions
|
|||||||
from nova.api.openstack import wsgi
|
from nova.api.openstack import wsgi
|
||||||
from nova import compute
|
from nova import compute
|
||||||
from nova.i18n import _
|
from nova.i18n import _
|
||||||
|
from nova import utils
|
||||||
|
|
||||||
ALIAS = "os-instance-actions"
|
ALIAS = "os-instance-actions"
|
||||||
authorize = extensions.os_compute_authorizer(ALIAS)
|
authorize = extensions.os_compute_authorizer(ALIAS)
|
||||||
@ -49,11 +50,20 @@ class InstanceActionsController(wsgi.Controller):
|
|||||||
event[key] = event_raw.get(key)
|
event[key] = event_raw.get(key)
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
@wsgi.Controller.api_version("2.1", "2.20")
|
||||||
|
def _get_instance(self, req, context, server_id):
|
||||||
|
return common.get_instance(self.compute_api, context, server_id)
|
||||||
|
|
||||||
|
@wsgi.Controller.api_version("2.21") # noqa
|
||||||
|
def _get_instance(self, req, context, server_id):
|
||||||
|
with utils.temporary_mutation(context, read_deleted='yes'):
|
||||||
|
return common.get_instance(self.compute_api, context, server_id)
|
||||||
|
|
||||||
@extensions.expected_errors(404)
|
@extensions.expected_errors(404)
|
||||||
def index(self, req, server_id):
|
def index(self, req, server_id):
|
||||||
"""Returns the list of actions recorded for a given instance."""
|
"""Returns the list of actions recorded for a given instance."""
|
||||||
context = req.environ["nova.context"]
|
context = req.environ["nova.context"]
|
||||||
instance = common.get_instance(self.compute_api, context, server_id)
|
instance = self._get_instance(req, context, server_id)
|
||||||
authorize(context, target=instance)
|
authorize(context, target=instance)
|
||||||
actions_raw = self.action_api.actions_get(context, instance)
|
actions_raw = self.action_api.actions_get(context, instance)
|
||||||
actions = [self._format_action(action) for action in actions_raw]
|
actions = [self._format_action(action) for action in actions_raw]
|
||||||
@ -63,7 +73,7 @@ class InstanceActionsController(wsgi.Controller):
|
|||||||
def show(self, req, server_id, id):
|
def show(self, req, server_id, id):
|
||||||
"""Return data about the given instance action."""
|
"""Return data about the given instance action."""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
instance = common.get_instance(self.compute_api, context, server_id)
|
instance = self._get_instance(req, context, server_id)
|
||||||
authorize(context, target=instance)
|
authorize(context, target=instance)
|
||||||
action = self.action_api.action_get_by_request_id(context, instance,
|
action = self.action_api.action_get_by_request_id(context, instance,
|
||||||
id)
|
id)
|
||||||
|
@ -176,6 +176,10 @@ user documentation.
|
|||||||
|
|
||||||
2.20
|
2.20
|
||||||
----
|
----
|
||||||
|
|
||||||
From this version of the API user can call detach and attach volumes for
|
From this version of the API user can call detach and attach volumes for
|
||||||
instances which are in shelved and shelved_offloaded state.
|
instances which are in shelved and shelved_offloaded state.
|
||||||
|
|
||||||
|
2.21
|
||||||
|
----
|
||||||
|
The ``os-instance-actions`` API now returns information from deleted
|
||||||
|
instances.
|
||||||
|
@ -193,8 +193,11 @@ class TestOpenStackClient(object):
|
|||||||
resp.body = jsonutils.loads(response.content)
|
resp.body = jsonutils.loads(response.content)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def api_get(self, relative_uri, **kwargs):
|
def api_get(self, relative_uri, api_version=None, **kwargs):
|
||||||
kwargs.setdefault('check_response_status', [200])
|
kwargs.setdefault('check_response_status', [200])
|
||||||
|
if api_version:
|
||||||
|
headers = kwargs.setdefault('headers', {})
|
||||||
|
headers['X-OpenStack-Nova-API-Version'] = api_version
|
||||||
return APIResponse(self.api_request(relative_uri, **kwargs))
|
return APIResponse(self.api_request(relative_uri, **kwargs))
|
||||||
|
|
||||||
def api_post(self, relative_uri, body, api_version=None, **kwargs):
|
def api_post(self, relative_uri, body, api_version=None, **kwargs):
|
||||||
@ -360,6 +363,6 @@ class TestOpenStackClient(object):
|
|||||||
def delete_server_group(self, group_id):
|
def delete_server_group(self, group_id):
|
||||||
self.api_delete('/os-server-groups/%s' % group_id)
|
self.api_delete('/os-server-groups/%s' % group_id)
|
||||||
|
|
||||||
def get_instance_actions(self, server_id):
|
def get_instance_actions(self, server_id, api_version=None):
|
||||||
return self.api_get('/servers/%s/os-instance-actions' %
|
return self.api_get('/servers/%s/os-instance-actions' %
|
||||||
(server_id)).body['instanceActions']
|
(server_id), api_version).body['instanceActions']
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"instanceAction": {
|
||||||
|
"action": "%(action)s",
|
||||||
|
"instance_uuid": "%(instance_uuid)s",
|
||||||
|
"request_id": "%(request_id)s",
|
||||||
|
"user_id": "%(integer_id)s",
|
||||||
|
"project_id": "%(integer_id)s",
|
||||||
|
"start_time": "%(strtime)s",
|
||||||
|
"message": "",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"event": "%(event)s",
|
||||||
|
"start_time": "%(strtime)s",
|
||||||
|
"finish_time": "%(strtime)s",
|
||||||
|
"result": "%(result)s",
|
||||||
|
"traceback": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event": "%(event)s",
|
||||||
|
"start_time": "%(strtime)s",
|
||||||
|
"finish_time": "%(strtime)s",
|
||||||
|
"result": "%(result)s",
|
||||||
|
"traceback": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"instanceActions": [
|
||||||
|
{
|
||||||
|
"action": "%(action)s",
|
||||||
|
"instance_uuid": "%(uuid)s",
|
||||||
|
"request_id": "%(request_id)s",
|
||||||
|
"user_id": "%(integer_id)s",
|
||||||
|
"project_id": "%(integer_id)s",
|
||||||
|
"start_time": "%(strtime)s",
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "%(action)s",
|
||||||
|
"instance_uuid": "%(uuid)s",
|
||||||
|
"request_id": "%(request_id)s",
|
||||||
|
"user_id": "%(integer_id)s",
|
||||||
|
"project_id": "%(integer_id)s",
|
||||||
|
"start_time": "%(strtime)s",
|
||||||
|
"message": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ CONF.import_opt('osapi_compute_extension',
|
|||||||
|
|
||||||
|
|
||||||
class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
||||||
|
microversion = None
|
||||||
ADMIN_API = True
|
ADMIN_API = True
|
||||||
extension_name = 'os-instance-actions'
|
extension_name = 'os-instance-actions'
|
||||||
|
|
||||||
@ -39,6 +40,11 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
'contrib.instance_actions.Instance_actions')
|
'contrib.instance_actions.Instance_actions')
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
def _fake_get(self, context, instance_uuid, expected_attrs=None,
|
||||||
|
want_objects=True):
|
||||||
|
return fake_instance.fake_instance_obj(
|
||||||
|
None, **{'uuid': instance_uuid})
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(ServerActionsSampleJsonTest, self).setUp()
|
super(ServerActionsSampleJsonTest, self).setUp()
|
||||||
self.actions = fake_server_actions.FAKE_ACTIONS
|
self.actions = fake_server_actions.FAKE_ACTIONS
|
||||||
@ -58,11 +64,6 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
def fake_instance_get_by_uuid(context, instance_id):
|
def fake_instance_get_by_uuid(context, instance_id):
|
||||||
return self.instance
|
return self.instance
|
||||||
|
|
||||||
def fake_get(self, context, instance_uuid, expected_attrs=None,
|
|
||||||
want_objects=True):
|
|
||||||
return fake_instance.fake_instance_obj(
|
|
||||||
None, **{'uuid': instance_uuid})
|
|
||||||
|
|
||||||
self.stub_out('nova.db.action_get_by_request_id',
|
self.stub_out('nova.db.action_get_by_request_id',
|
||||||
fake_instance_action_get_by_request_id)
|
fake_instance_action_get_by_request_id)
|
||||||
self.stub_out('nova.db.actions_get', fake_server_actions_get)
|
self.stub_out('nova.db.actions_get', fake_server_actions_get)
|
||||||
@ -70,7 +71,7 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
fake_instance_action_events_get)
|
fake_instance_action_events_get)
|
||||||
self.stub_out('nova.db.instance_get_by_uuid',
|
self.stub_out('nova.db.instance_get_by_uuid',
|
||||||
fake_instance_get_by_uuid)
|
fake_instance_get_by_uuid)
|
||||||
self.stub_out('nova.compute.api.API.get', fake_get)
|
self.stub_out('nova.compute.api.API.get', self._fake_get)
|
||||||
|
|
||||||
def test_instance_action_get(self):
|
def test_instance_action_get(self):
|
||||||
fake_uuid = fake_server_actions.FAKE_UUID
|
fake_uuid = fake_server_actions.FAKE_UUID
|
||||||
@ -78,7 +79,8 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
fake_action = self.actions[fake_uuid][fake_request_id]
|
fake_action = self.actions[fake_uuid][fake_request_id]
|
||||||
|
|
||||||
response = self._do_get('servers/%s/os-instance-actions/%s' %
|
response = self._do_get('servers/%s/os-instance-actions/%s' %
|
||||||
(fake_uuid, fake_request_id))
|
(fake_uuid, fake_request_id),
|
||||||
|
api_version=self.microversion)
|
||||||
subs = {}
|
subs = {}
|
||||||
subs['action'] = '(reboot)|(resize)'
|
subs['action'] = '(reboot)|(resize)'
|
||||||
subs['instance_uuid'] = fake_uuid
|
subs['instance_uuid'] = fake_uuid
|
||||||
@ -91,7 +93,8 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
|
|
||||||
def test_instance_actions_list(self):
|
def test_instance_actions_list(self):
|
||||||
fake_uuid = fake_server_actions.FAKE_UUID
|
fake_uuid = fake_server_actions.FAKE_UUID
|
||||||
response = self._do_get('servers/%s/os-instance-actions' % (fake_uuid))
|
response = self._do_get('servers/%s/os-instance-actions' % (fake_uuid),
|
||||||
|
api_version=self.microversion)
|
||||||
subs = {}
|
subs = {}
|
||||||
subs['action'] = '(reboot)|(resize)'
|
subs['action'] = '(reboot)|(resize)'
|
||||||
subs['integer_id'] = '[0-9]+'
|
subs['integer_id'] = '[0-9]+'
|
||||||
@ -99,3 +102,14 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
'-[0-9a-f]{4}-[0-9a-f]{12}')
|
'-[0-9a-f]{4}-[0-9a-f]{12}')
|
||||||
self._verify_response('instance-actions-list-resp', subs,
|
self._verify_response('instance-actions-list-resp', subs,
|
||||||
response, 200)
|
response, 200)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerActionsV221SampleJsonTest(ServerActionsSampleJsonTest):
|
||||||
|
microversion = '2.21'
|
||||||
|
scenarios = [('v2_21', {'api_major_version': 'v2.1'})]
|
||||||
|
|
||||||
|
def _fake_get(self, context, instance_uuid, expected_attrs=None,
|
||||||
|
want_objects=True):
|
||||||
|
self.assertEqual('yes', context.read_deleted)
|
||||||
|
return fake_instance.fake_instance_obj(
|
||||||
|
None, **{'uuid': instance_uuid})
|
||||||
|
76
nova/tests/functional/test_instance_actions.py
Normal file
76
nova/tests/functional/test_instance_actions.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Copyright 2016 IBM Corp.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from nova.tests.functional.api import client
|
||||||
|
from nova.tests.functional import test_servers
|
||||||
|
from nova.tests.unit import fake_network
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceActionsTestV2(test_servers.ServersTestBase):
|
||||||
|
"""Tests Instance Actions API"""
|
||||||
|
|
||||||
|
def _create_server(self):
|
||||||
|
"""Creates a minimal test server via the compute API
|
||||||
|
|
||||||
|
Ensures the server is created and can be retrieved from the compute API
|
||||||
|
and waits for it to be ACTIVE.
|
||||||
|
|
||||||
|
:returns: created server (dict)
|
||||||
|
"""
|
||||||
|
# TODO(mriedem): We should pull this up into the parent class so we
|
||||||
|
# don't have so much copy/paste in these functional tests.
|
||||||
|
fake_network.set_stub_network_methods(self)
|
||||||
|
|
||||||
|
# Create a server
|
||||||
|
server = self._build_minimal_create_server_request()
|
||||||
|
created_server = self.api.post_server({'server': server})
|
||||||
|
self.assertTrue(created_server['id'])
|
||||||
|
created_server_id = created_server['id']
|
||||||
|
|
||||||
|
# Check it's there
|
||||||
|
found_server = self.api.get_server(created_server_id)
|
||||||
|
self.assertEqual(created_server_id, found_server['id'])
|
||||||
|
|
||||||
|
found_server = self._wait_for_state_change(found_server, 'BUILD')
|
||||||
|
# It should be available...
|
||||||
|
self.assertEqual('ACTIVE', found_server['status'])
|
||||||
|
return found_server
|
||||||
|
|
||||||
|
def test_get_instance_actions(self):
|
||||||
|
server = self._create_server()
|
||||||
|
actions = self.api.get_instance_actions(server['id'])
|
||||||
|
self.assertEqual('create', actions[0]['action'])
|
||||||
|
|
||||||
|
def test_get_instance_actions_deleted(self):
|
||||||
|
server = self._create_server()
|
||||||
|
self._delete_server(server['id'])
|
||||||
|
self.assertRaises(client.OpenStackApiNotFoundException,
|
||||||
|
self.api.get_instance_actions,
|
||||||
|
server['id'])
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceActionsTestV21(InstanceActionsTestV2):
|
||||||
|
api_major_version = 'v2.1'
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceActionsTestV221(InstanceActionsTestV21):
|
||||||
|
microversion = '2.21'
|
||||||
|
|
||||||
|
def test_get_instance_actions_deleted(self):
|
||||||
|
server = self._create_server()
|
||||||
|
self._delete_server(server['id'])
|
||||||
|
actions = self.api.get_instance_actions(server['id'],
|
||||||
|
api_version=self.microversion)
|
||||||
|
self.assertEqual('delete', actions[0]['action'])
|
||||||
|
self.assertEqual('create', actions[1]['action'])
|
@ -23,6 +23,7 @@ from webob import exc
|
|||||||
from nova.api.openstack.compute import instance_actions as instance_actions_v21
|
from nova.api.openstack.compute import instance_actions as instance_actions_v21
|
||||||
from nova.api.openstack.compute.legacy_v2.contrib import instance_actions \
|
from nova.api.openstack.compute.legacy_v2.contrib import instance_actions \
|
||||||
as instance_actions_v2
|
as instance_actions_v2
|
||||||
|
from nova.api.openstack import wsgi as os_wsgi
|
||||||
from nova.compute import api as compute_api
|
from nova.compute import api as compute_api
|
||||||
from nova.db.sqlalchemy import models
|
from nova.db.sqlalchemy import models
|
||||||
from nova import exception
|
from nova import exception
|
||||||
@ -130,6 +131,11 @@ class InstanceActionsPolicyTestV2(InstanceActionsPolicyTestV21):
|
|||||||
|
|
||||||
class InstanceActionsTestV21(test.NoDBTestCase):
|
class InstanceActionsTestV21(test.NoDBTestCase):
|
||||||
instance_actions = instance_actions_v21
|
instance_actions = instance_actions_v21
|
||||||
|
wsgi_api_version = os_wsgi.DEFAULT_API_VERSION
|
||||||
|
|
||||||
|
def fake_get(self, context, instance_uuid, expected_attrs=None,
|
||||||
|
want_objects=False):
|
||||||
|
return objects.Instance(uuid=instance_uuid)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(InstanceActionsTestV21, self).setUp()
|
super(InstanceActionsTestV21, self).setUp()
|
||||||
@ -137,22 +143,19 @@ class InstanceActionsTestV21(test.NoDBTestCase):
|
|||||||
self.fake_actions = copy.deepcopy(fake_server_actions.FAKE_ACTIONS)
|
self.fake_actions = copy.deepcopy(fake_server_actions.FAKE_ACTIONS)
|
||||||
self.fake_events = copy.deepcopy(fake_server_actions.FAKE_EVENTS)
|
self.fake_events = copy.deepcopy(fake_server_actions.FAKE_EVENTS)
|
||||||
|
|
||||||
def fake_get(self, context, instance_uuid, expected_attrs=None,
|
|
||||||
want_objects=False):
|
|
||||||
return objects.Instance(uuid=instance_uuid)
|
|
||||||
|
|
||||||
def fake_instance_get_by_uuid(context, instance_id, use_slave=False):
|
def fake_instance_get_by_uuid(context, instance_id, use_slave=False):
|
||||||
return fake_instance.fake_instance_obj(None,
|
return fake_instance.fake_instance_obj(None,
|
||||||
**{'name': 'fake', 'project_id': context.project_id})
|
**{'name': 'fake', 'project_id': context.project_id})
|
||||||
|
|
||||||
self.stubs.Set(compute_api.API, 'get', fake_get)
|
self.stubs.Set(compute_api.API, 'get', self.fake_get)
|
||||||
self.stub_out('nova.db.instance_get_by_uuid',
|
self.stub_out('nova.db.instance_get_by_uuid',
|
||||||
fake_instance_get_by_uuid)
|
fake_instance_get_by_uuid)
|
||||||
|
|
||||||
def _get_http_req(self, action, use_admin_context=False):
|
def _get_http_req(self, action, use_admin_context=False):
|
||||||
fake_url = '/123/servers/12/%s' % action
|
fake_url = '/123/servers/12/%s' % action
|
||||||
return fakes.HTTPRequest.blank(fake_url,
|
return fakes.HTTPRequest.blank(fake_url,
|
||||||
use_admin_context=use_admin_context)
|
use_admin_context=use_admin_context,
|
||||||
|
version=self.wsgi_api_version)
|
||||||
|
|
||||||
def _set_policy_rules(self):
|
def _set_policy_rules(self):
|
||||||
rules = {'compute:get': '',
|
rules = {'compute:get': '',
|
||||||
@ -246,6 +249,15 @@ class InstanceActionsTestV21(test.NoDBTestCase):
|
|||||||
FAKE_UUID, 'fake')
|
FAKE_UUID, 'fake')
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceActionsTestV221(InstanceActionsTestV21):
|
||||||
|
wsgi_api_version = "2.21"
|
||||||
|
|
||||||
|
def fake_get(self, context, instance_uuid, expected_attrs=None,
|
||||||
|
want_objects=False):
|
||||||
|
self.assertEqual('yes', context.read_deleted)
|
||||||
|
return objects.Instance(uuid=instance_uuid)
|
||||||
|
|
||||||
|
|
||||||
class InstanceActionsTestV2(InstanceActionsTestV21):
|
class InstanceActionsTestV2(InstanceActionsTestV21):
|
||||||
instance_actions = instance_actions_v2
|
instance_actions = instance_actions_v2
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ EXP_VERSIONS = {
|
|||||||
"v2.1": {
|
"v2.1": {
|
||||||
"id": "v2.1",
|
"id": "v2.1",
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z",
|
"updated": "2013-07-23T11:33:21Z",
|
||||||
"links": [
|
"links": [
|
||||||
@ -128,7 +128,7 @@ class VersionsTestV20(test.NoDBTestCase):
|
|||||||
{
|
{
|
||||||
"id": "v2.1",
|
"id": "v2.1",
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.20",
|
"version": "2.21",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z",
|
"updated": "2013-07-23T11:33:21Z",
|
||||||
"links": [
|
"links": [
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- The os-instance-actions methods now read actions from deleted instances.
|
||||||
|
This means that
|
||||||
|
'GET /v2.1/{tenant-id}/servers/{server-id}/os-instance-actions'
|
||||||
|
and
|
||||||
|
'GET /v2.1/{tenant-id}/servers/{server-id}/os-instance-actions/{req-id}'
|
||||||
|
will return instance-action items even if the instance corresponding to
|
||||||
|
'{server-id}' has been deleted.
|
Loading…
Reference in New Issue
Block a user