Changes V3 server_actions extension into v2.1

This patch changes v3 server_actions API to v2.1, and also share v2.1 and v2
test case.
rename server_actions back to instance_actions.
The differences between v2 and v3 are described on the wiki page
https://wiki.openstack.org/wiki/NovaAPIv2tov3 .
Partially implements blueprint v2-on-v3-api

Change-Id: I8f11dc5f199711e1c98badfbe0035883d9c15573
This commit is contained in:
Eli Qiao 2014-08-19 17:29:06 +08:00
parent 3ab81c9b3e
commit 2ca8b73dd5
12 changed files with 148 additions and 304 deletions

View File

@ -1,5 +1,5 @@
{
"server_action": {
"instanceAction": {
"action": "reboot",
"events": [
{
@ -17,7 +17,7 @@
"traceback": ""
}
],
"server_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"instance_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"message": "",
"project_id": "147",
"request_id": "req-3293a3f1-b44c-4609-b8d2-d81b105636b8",

View File

@ -1,8 +1,8 @@
{
"server_actions": [
"instanceActions": [
{
"action": "resize",
"server_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"instance_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"message": "",
"project_id": "842",
"request_id": "req-25517360-b757-47d3-be45-0e8d2a01b36a",
@ -11,7 +11,7 @@
},
{
"action": "reboot",
"server_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"instance_uuid": "b48316c5-71e8-45e4-9884-6c78055b9b13",
"message": "",
"project_id": "147",
"request_id": "req-3293a3f1-b44c-4609-b8d2-d81b105636b8",

View File

@ -164,10 +164,10 @@
"compute_extension:v3:os-hypervisors:discoverable": "",
"compute_extension:image_size": "",
"compute_extension:instance_actions": "",
"compute_extension:v3:os-server-actions": "",
"compute_extension:v3:os-server-actions:discoverable": "",
"compute_extension:v3:os-instance-actions": "",
"compute_extension:v3:os-instance-actions:discoverable": "",
"compute_extension:instance_actions:events": "rule:admin_api",
"compute_extension:v3:os-server-actions:events": "rule:admin_api",
"compute_extension:v3:os-instance-actions:events": "rule:admin_api",
"compute_extension:instance_usage_audit_log": "rule:admin_api",
"compute_extension:v3:ips:discoverable": "",
"compute_extension:keypairs": "",

View File

@ -21,7 +21,7 @@ from nova.api.openstack import wsgi
from nova import compute
from nova.i18n import _
ALIAS = "os-server-actions"
ALIAS = "os-instance-actions"
authorize_actions = extensions.extension_authorizer('compute',
'v3:' + ALIAS)
authorize_events = extensions.soft_extension_authorizer('compute',
@ -32,20 +32,17 @@ ACTION_KEYS = ['action', 'instance_uuid', 'request_id', 'user_id',
EVENT_KEYS = ['event', 'start_time', 'finish_time', 'result', 'traceback']
class ServerActionsController(wsgi.Controller):
class InstanceActionsController(wsgi.Controller):
def __init__(self):
super(ServerActionsController, self).__init__()
super(InstanceActionsController, self).__init__()
self.compute_api = compute.API()
self.action_api = compute.InstanceActionAPI()
def _format_action(self, action_raw):
action = {}
for key in ACTION_KEYS:
if key == 'instance_uuid':
action['server_uuid'] = action_raw.get(key)
else:
action[key] = action_raw.get(key)
action[key] = action_raw.get(key)
return action
def _format_event(self, event_raw):
@ -62,7 +59,7 @@ class ServerActionsController(wsgi.Controller):
authorize_actions(context, target=instance)
actions_raw = self.action_api.actions_get(context, instance)
actions = [self._format_action(action) for action in actions_raw]
return {'server_actions': actions}
return {'instanceActions': actions}
@extensions.expected_errors(404)
def show(self, req, server_id, id):
@ -82,19 +79,19 @@ class ServerActionsController(wsgi.Controller):
events_raw = self.action_api.action_events_get(context, instance,
action_id)
action['events'] = [self._format_event(evt) for evt in events_raw]
return {'server_action': action}
return {'instanceAction': action}
class ServerActions(extensions.V3APIExtensionBase):
class InstanceActions(extensions.V3APIExtensionBase):
"""View a log of actions and events taken on an instance."""
name = "ServerActions"
name = "InstanceActions"
alias = ALIAS
version = 1
def get_resources(self):
ext = extensions.ResourceExtension('os-server-actions',
ServerActionsController(),
ext = extensions.ResourceExtension(ALIAS,
InstanceActionsController(),
parent=dict(
member_name='server',
collection_name='servers'))

View File

@ -19,7 +19,10 @@ import uuid
from lxml import etree
from webob import exc
from nova.api.openstack.compute.contrib import instance_actions
from nova.api.openstack.compute.contrib import instance_actions \
as instance_actions_v2
from nova.api.openstack.compute.plugins.v3 import instance_actions \
as instance_actions_v21
from nova.compute import api as compute_api
from nova import db
from nova.db.sqlalchemy import models
@ -66,17 +69,26 @@ def format_event(event):
return event
class InstanceActionsPolicyTest(test.NoDBTestCase):
def setUp(self):
super(InstanceActionsPolicyTest, self).setUp()
self.controller = instance_actions.InstanceActionsController()
class InstanceActionsPolicyTestV21(test.NoDBTestCase):
instance_actions = instance_actions_v21
def test_list_actions_restricted_by_project(self):
def setUp(self):
super(InstanceActionsPolicyTestV21, self).setUp()
self.controller = self.instance_actions.InstanceActionsController()
def _get_http_req(self, action):
fake_url = '/servers/12/%s' % action
return fakes.HTTPRequestV3.blank(fake_url)
def _set_policy_rules(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:instance_actions':
'compute_extension:v3:os-instance-actions':
common_policy.parse_rule('project_id:%(project_id)s')}
policy.set_rules(rules)
def test_list_actions_restricted_by_project(self):
self._set_policy_rules()
def fake_instance_get_by_uuid(context, instance_id,
columns_to_join=None,
use_slave=False):
@ -85,15 +97,12 @@ class InstanceActionsPolicyTest(test.NoDBTestCase):
context.project_id})
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
req = fakes.HTTPRequest.blank('/v2/123/servers/12/os-instance-actions')
req = self._get_http_req('os-instance-actions')
self.assertRaises(exception.Forbidden, self.controller.index, req,
str(uuid.uuid4()))
def test_get_action_restricted_by_project(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:instance_actions':
common_policy.parse_rule('project_id:%(project_id)s')}
policy.set_rules(rules)
self._set_policy_rules()
def fake_instance_get_by_uuid(context, instance_id,
columns_to_join=None,
@ -103,16 +112,31 @@ class InstanceActionsPolicyTest(test.NoDBTestCase):
context.project_id})
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
req = fakes.HTTPRequest.blank(
'/v2/123/servers/12/os-instance-actions/1')
req = self._get_http_req('os-instance-actions/1')
self.assertRaises(exception.Forbidden, self.controller.show, req,
str(uuid.uuid4()), '1')
class InstanceActionsTest(test.NoDBTestCase):
class InstanceActionsPolicyTestV2(InstanceActionsPolicyTestV21):
instance_actions = instance_actions_v2
def _get_http_req(self, action):
fake_url = '/123/servers/12/%s' % action
return fakes.HTTPRequest.blank(fake_url)
def _set_policy_rules(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:instance_actions':
common_policy.parse_rule('project_id:%(project_id)s')}
policy.set_rules(rules)
class InstanceActionsTestV21(test.NoDBTestCase):
instance_actions = instance_actions_v21
def setUp(self):
super(InstanceActionsTest, self).setUp()
self.controller = instance_actions.InstanceActionsController()
super(InstanceActionsTestV21, self).setUp()
self.controller = self.instance_actions.InstanceActionsController()
self.fake_actions = copy.deepcopy(fake_server_actions.FAKE_ACTIONS)
self.fake_events = copy.deepcopy(fake_server_actions.FAKE_EVENTS)
@ -126,6 +150,19 @@ class InstanceActionsTest(test.NoDBTestCase):
self.stubs.Set(compute_api.API, 'get', fake_get)
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
def _get_http_req(self, action, use_admin_context=False):
fake_url = '/servers/12/%s' % action
return fakes.HTTPRequestV3.blank(fake_url,
use_admin_context=use_admin_context)
def _set_policy_rules(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:v3:os-instance-actions':
common_policy.parse_rule(''),
'compute_extension:v3:os-instance-actions:events':
common_policy.parse_rule('is_admin:True')}
policy.set_rules(rules)
def test_list_actions(self):
def fake_get_actions(context, uuid):
actions = []
@ -136,7 +173,7 @@ class InstanceActionsTest(test.NoDBTestCase):
return actions
self.stubs.Set(db, 'actions_get', fake_get_actions)
req = fakes.HTTPRequest.blank('/v2/123/servers/12/os-instance-actions')
req = self._get_http_req('os-instance-actions')
res_dict = self.controller.index(req, FAKE_UUID)
for res in res_dict['instanceActions']:
fake_action = self.fake_actions[FAKE_UUID][res['request_id']]
@ -158,8 +195,7 @@ class InstanceActionsTest(test.NoDBTestCase):
self.stubs.Set(db, 'action_get_by_request_id', fake_get_action)
self.stubs.Set(db, 'action_events_get', fake_get_events)
req = fakes.HTTPRequest.blank(
'/v2/123/servers/12/os-instance-actions/1',
req = self._get_http_req('os-instance-actions/1',
use_admin_context=True)
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
@ -177,14 +213,9 @@ class InstanceActionsTest(test.NoDBTestCase):
self.stubs.Set(db, 'action_get_by_request_id', fake_get_action)
self.stubs.Set(db, 'action_events_get', fake_get_events)
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:instance_actions':
common_policy.parse_rule(''),
'compute_extension:instance_actions:events':
common_policy.parse_rule('is_admin:True')}
policy.set_rules(rules)
req = fakes.HTTPRequest.blank(
'/v2/123/servers/12/os-instance-actions/1')
self._set_policy_rules()
req = self._get_http_req('os-instance-actions/1')
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
self.assertEqual(format_action(fake_action),
@ -195,8 +226,7 @@ class InstanceActionsTest(test.NoDBTestCase):
return None
self.stubs.Set(db, 'action_get_by_request_id', fake_no_action)
req = fakes.HTTPRequest.blank(
'/v2/123/servers/12/os-instance-actions/1')
req = self._get_http_req('os-instance-actions/1')
self.assertRaises(exc.HTTPNotFound, self.controller.show, req,
FAKE_UUID, FAKE_REQUEST_ID)
@ -205,7 +235,7 @@ class InstanceActionsTest(test.NoDBTestCase):
want_objects=False):
raise exception.InstanceNotFound(instance_id=instance_uuid)
self.stubs.Set(compute_api.API, 'get', fake_get)
req = fakes.HTTPRequest.blank('/v2/123/servers/12/os-instance-actions')
req = self._get_http_req('os-instance-actions')
self.assertRaises(exc.HTTPNotFound, self.controller.index, req,
FAKE_UUID)
@ -214,15 +244,31 @@ class InstanceActionsTest(test.NoDBTestCase):
want_objects=False):
raise exception.InstanceNotFound(instance_id=instance_uuid)
self.stubs.Set(compute_api.API, 'get', fake_get)
req = fakes.HTTPRequest.blank(
'/v2/123/servers/12/os-instance-actions/fake')
req = self._get_http_req('os-instance-actions/fake')
self.assertRaises(exc.HTTPNotFound, self.controller.show, req,
FAKE_UUID, 'fake')
class InstanceActionsSerializerTest(test.NoDBTestCase):
class InstanceActionsTestV2(InstanceActionsTestV21):
instance_actions = instance_actions_v2
def _get_http_req(self, action, use_admin_context=False):
fake_url = '/123/servers/12/%s' % action
return fakes.HTTPRequest.blank(fake_url,
use_admin_context=use_admin_context)
def _set_policy_rules(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:instance_actions':
common_policy.parse_rule(''),
'compute_extension:instance_actions:events':
common_policy.parse_rule('is_admin:True')}
policy.set_rules(rules)
class InstanceActionsSerializerTestV2(test.NoDBTestCase):
def setUp(self):
super(InstanceActionsSerializerTest, self).setUp()
super(InstanceActionsSerializerTestV2, self).setUp()
self.fake_actions = copy.deepcopy(fake_server_actions.FAKE_ACTIONS)
self.fake_events = copy.deepcopy(fake_server_actions.FAKE_EVENTS)
@ -238,7 +284,7 @@ class InstanceActionsSerializerTest(test.NoDBTestCase):
'%s did not match' % key)
def test_instance_action_serializer(self):
serializer = instance_actions.InstanceActionTemplate()
serializer = instance_actions_v2.InstanceActionTemplate()
action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
text = serializer.serialize({'instanceAction': action})
tree = etree.fromstring(text)
@ -253,7 +299,7 @@ class InstanceActionsSerializerTest(test.NoDBTestCase):
self.assertFalse(found_events)
def test_instance_action_events_serializer(self):
serializer = instance_actions.InstanceActionTemplate()
serializer = instance_actions_v2.InstanceActionTemplate()
action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
event = self.fake_events[action['id']][0]
action['events'] = [dict(event), dict(event)]
@ -274,7 +320,7 @@ class InstanceActionsSerializerTest(test.NoDBTestCase):
self.assertTrue(found_events)
def test_instance_actions_serializer(self):
serializer = instance_actions.InstanceActionsTemplate()
serializer = instance_actions_v2.InstanceActionsTemplate()
action_list = self.fake_actions[FAKE_UUID].values()
text = serializer.serialize({'instanceActions': action_list})
tree = etree.fromstring(text)

View File

@ -1,226 +0,0 @@
# Copyright 2013 Rackspace Hosting
# All Rights Reserved.
#
# 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 copy
import uuid
from webob import exc
from nova.api.openstack.compute.plugins.v3 import server_actions
from nova.compute import api as compute_api
from nova import db
from nova.db.sqlalchemy import models
from nova import exception
from nova.openstack.common import policy as common_policy
from nova import policy
from nova import test
from nova.tests.api.openstack import fakes
from nova.tests import fake_instance
from nova.tests import fake_server_actions
FAKE_UUID = fake_server_actions.FAKE_UUID
FAKE_REQUEST_ID = fake_server_actions.FAKE_REQUEST_ID1
def format_action(action):
'''Remove keys that aren't serialized.'''
to_delete = ('id', 'finish_time', 'created_at', 'updated_at', 'deleted_at',
'deleted')
for key in to_delete:
if key in action:
del(action[key])
if 'start_time' in action:
# NOTE(danms): Without WSGI above us, these will be just stringified,
# and objects will have added a timezone, so strip that for comparison
action['start_time'] = str(action['start_time'].replace(tzinfo=None))
for event in action.get('events', []):
format_event(event)
if 'instance_uuid' in action:
action['server_uuid'] = action.pop('instance_uuid')
return action
def format_event(event):
'''Remove keys that aren't serialized.'''
to_delete = ('id', 'created_at', 'updated_at', 'deleted_at', 'deleted',
'action_id')
for key in to_delete:
if key in event:
del(event[key])
if 'start_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified,
# and objects will have added a timezone, so strip that for comparison
event['start_time'] = str(event['start_time'].replace(tzinfo=None))
if 'finish_time' in event:
# NOTE(danms): Without WSGI above us, these will be just stringified,
# and objects will have added a timezone, so strip that for comparison
event['finish_time'] = str(event['finish_time'].replace(tzinfo=None))
return event
class ServerActionsPolicyTest(test.NoDBTestCase):
def setUp(self):
super(ServerActionsPolicyTest, self).setUp()
self.controller = server_actions.ServerActionsController()
def test_list_actions_restricted_by_project(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:v3:os-server-actions':
common_policy.parse_rule('project_id:%(project_id)s')}
policy.set_rules(rules)
def fake_instance_get_by_uuid(context, instance_id,
columns_to_join=None, use_slave=False):
return fake_instance.fake_db_instance(
**{'name': 'fake', 'project_id': '%s_unequal' %
context.project_id})
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
req = fakes.HTTPRequestV3.blank('/servers/12/os-server-actions')
self.assertRaises(exception.Forbidden, self.controller.index, req,
str(uuid.uuid4()))
def test_get_action_restricted_by_project(self):
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:v3:os-server-actions':
common_policy.parse_rule('project_id:%(project_id)s')}
policy.set_rules(rules)
def fake_instance_get_by_uuid(context, instance_id,
columns_to_join=None, use_slave=False):
return fake_instance.fake_db_instance(
**{'name': 'fake', 'project_id': '%s_unequal' %
context.project_id})
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
req = fakes.HTTPRequestV3.blank(
'/servers/12/os-server-actions/1')
self.assertRaises(exception.Forbidden, self.controller.show, req,
str(uuid.uuid4()), '1')
class ServerActionsTest(test.NoDBTestCase):
def setUp(self):
super(ServerActionsTest, self).setUp()
self.controller = server_actions.ServerActionsController()
self.fake_actions = copy.deepcopy(fake_server_actions.FAKE_ACTIONS)
self.fake_events = copy.deepcopy(fake_server_actions.FAKE_EVENTS)
def fake_get(self, context, instance_uuid, expected_attrs=None,
want_objects=False):
return {'uuid': instance_uuid}
def fake_instance_get_by_uuid(context, instance_id,
columns_to_join=None, use_slave=False):
return fake_instance.fake_db_instance(
**{'name': 'fake', 'project_id': '%s_unequal' %
context.project_id})
self.stubs.Set(compute_api.API, 'get', fake_get)
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
def test_list_actions(self):
def fake_get_actions(context, uuid):
actions = []
for act in self.fake_actions[uuid].itervalues():
action = models.InstanceAction()
action.update(act)
actions.append(action)
return actions
self.stubs.Set(db, 'actions_get', fake_get_actions)
req = fakes.HTTPRequestV3.blank('/servers/12/os-server-actions')
res_dict = self.controller.index(req, FAKE_UUID)
for res in res_dict['server_actions']:
fake_action = self.fake_actions[FAKE_UUID][res['request_id']]
self.assertEqual(format_action(fake_action),
format_action(res))
def test_get_action_with_events_allowed(self):
def fake_get_action(context, uuid, request_id):
action = models.InstanceAction()
action.update(self.fake_actions[uuid][request_id])
return action
def fake_get_events(context, action_id):
events = []
for evt in self.fake_events[action_id]:
event = models.InstanceActionEvent()
event.update(evt)
events.append(event)
return events
self.stubs.Set(db, 'action_get_by_request_id', fake_get_action)
self.stubs.Set(db, 'action_events_get', fake_get_events)
req = fakes.HTTPRequestV3.blank(
'/servers/12/os-server-actions/1',
use_admin_context=True)
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
fake_events = self.fake_events[fake_action['id']]
fake_action['events'] = fake_events
self.assertEqual(format_action(fake_action),
format_action(res_dict['server_action']))
def test_get_action_with_events_not_allowed(self):
def fake_get_action(context, uuid, request_id):
return self.fake_actions[uuid][request_id]
def fake_get_events(context, action_id):
return self.fake_events[action_id]
self.stubs.Set(db, 'action_get_by_request_id', fake_get_action)
self.stubs.Set(db, 'action_events_get', fake_get_events)
rules = {'compute:get': common_policy.parse_rule(''),
'compute_extension:v3:os-server-actions':
common_policy.parse_rule(''),
'compute_extension:v3:os-server-actions:events':
common_policy.parse_rule('is_admin:True')}
policy.set_rules(rules)
req = fakes.HTTPRequestV3.blank(
'/servers/12/os-server-actions/1')
res_dict = self.controller.show(req, FAKE_UUID, FAKE_REQUEST_ID)
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
self.assertEqual(format_action(fake_action),
format_action(res_dict['server_action']))
def test_action_not_found(self):
def fake_no_action(context, uuid, action_id):
return None
self.stubs.Set(db, 'action_get_by_request_id', fake_no_action)
req = fakes.HTTPRequestV3.blank(
'/servers/12/os-server-actions/1')
self.assertRaises(exc.HTTPNotFound, self.controller.show, req,
FAKE_UUID, FAKE_REQUEST_ID)
def test_instance_not_found(self):
def fake_get(self, context, instance_uuid, expected_attrs=None,
want_objects=False):
raise exception.InstanceNotFound(instance_id=instance_uuid)
self.stubs.Set(compute_api.API, 'get', fake_get)
req = fakes.HTTPRequestV3.blank('/servers/12/os-server-actions')
self.assertRaises(exc.HTTPNotFound, self.controller.index, req,
FAKE_UUID)
def test_instance_not_found_in_show(self):
def fake_get(self, context, instance_uuid, expected_attrs=None,
want_objects=False):
raise exception.InstanceNotFound(instance_id=instance_uuid)
self.stubs.Set(compute_api.API, 'get', fake_get)
req = fakes.HTTPRequestV3.blank('/servers/12/os-server-actions/1')
self.assertRaises(exc.HTTPNotFound, self.controller.show, req,
FAKE_UUID, FAKE_REQUEST_ID)

View File

@ -222,9 +222,9 @@ policy_data = """
"compute_extension:v3:os-hypervisors": "rule:admin_api",
"compute_extension:image_size": "",
"compute_extension:instance_actions": "",
"compute_extension:v3:os-server-actions": "",
"compute_extension:v3:os-instance-actions": "",
"compute_extension:instance_actions:events": "is_admin:True",
"compute_extension:v3:os-server-actions:events": "is_admin:True",
"compute_extension:v3:os-instance-actions:events": "is_admin:True",
"compute_extension:instance_usage_audit_log": "",
"compute_extension:keypairs": "",
"compute_extension:keypairs:index": "",

View File

@ -1,7 +1,7 @@
{
"server_action": {
"instanceAction": {
"action": "%(action)s",
"server_uuid": "%(instance_uuid)s",
"instance_uuid": "%(instance_uuid)s",
"request_id": "%(request_id)s",
"user_id": "%(integer_id)s",
"project_id": "%(integer_id)s",

View File

@ -1,8 +1,8 @@
{
"server_actions": [
"instanceActions": [
{
"action": "%(action)s",
"server_uuid": "%(uuid)s",
"instance_uuid": "%(uuid)s",
"request_id": "%(request_id)s",
"user_id": "%(integer_id)s",
"project_id": "%(integer_id)s",
@ -11,7 +11,7 @@
},
{
"action": "%(action)s",
"server_uuid": "%(uuid)s",
"instance_uuid": "%(uuid)s",
"request_id": "%(request_id)s",
"user_id": "%(integer_id)s",
"project_id": "%(integer_id)s",

View File

@ -0,0 +1,27 @@
{
"instanceAction": {
"action": "reboot",
"events": [
{
"event": "schedule",
"finish_time": "2012-12-05T01:02:00.000000",
"result": "Success",
"start_time": "2012-12-05T01:00:02.000000",
"traceback": ""
},
{
"event": "compute_create",
"finish_time": "2012-12-05T01:04:00.000000",
"result": "Success",
"start_time": "2012-12-05T01:03:00.000000",
"traceback": ""
}
],
"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"
}
}

View File

@ -23,7 +23,7 @@ from nova.tests import utils as test_utils
class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
extension_name = 'os-server-actions'
extension_name = 'os-instance-actions'
def setUp(self):
super(ServerActionsSampleJsonTest, self).setUp()
@ -31,14 +31,14 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
self.events = fake_server_actions.FAKE_EVENTS
self.instance = test_utils.get_test_instance()
def fake_server_action_get_by_request_id(context, uuid, request_id):
def fake_instance_action_get_by_request_id(context, uuid, request_id):
return copy.deepcopy(self.actions[uuid][request_id])
def fake_server_actions_get(context, uuid):
return [copy.deepcopy(value) for value in
self.actions[uuid].itervalues()]
def fake_server_action_events_get(context, action_id):
def fake_instance_action_events_get(context, action_id):
return copy.deepcopy(self.events[action_id])
def fake_instance_get_by_uuid(context, instance_id):
@ -48,19 +48,19 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
return {'uuid': instance_uuid}
self.stubs.Set(db, 'action_get_by_request_id',
fake_server_action_get_by_request_id)
fake_instance_action_get_by_request_id)
self.stubs.Set(db, 'actions_get', fake_server_actions_get)
self.stubs.Set(db, 'action_events_get',
fake_server_action_events_get)
fake_instance_action_events_get)
self.stubs.Set(db, 'instance_get_by_uuid', fake_instance_get_by_uuid)
self.stubs.Set(compute_api.API, 'get', fake_get)
def test_server_action_get(self):
def test_instance_action_get(self):
fake_uuid = fake_server_actions.FAKE_UUID
fake_request_id = fake_server_actions.FAKE_REQUEST_ID1
fake_action = self.actions[fake_uuid][fake_request_id]
response = self._do_get('servers/%s/os-server-actions/%s' %
response = self._do_get('servers/%s/os-instance-actions/%s' %
(fake_uuid, fake_request_id))
subs = self._get_regexes()
subs['action'] = '(reboot)|(resize)'
@ -70,15 +70,15 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
subs['start_time'] = fake_action['start_time']
subs['result'] = '(Success)|(Error)'
subs['event'] = '(schedule)|(compute_create)'
self._verify_response('server-action-get-resp', subs, response, 200)
self._verify_response('instance-action-get-resp', subs, response, 200)
def test_server_actions_list(self):
def test_instance_actions_list(self):
fake_uuid = fake_server_actions.FAKE_UUID
response = self._do_get('servers/%s/os-server-actions' % (fake_uuid))
response = self._do_get('servers/%s/os-instance-actions' % (fake_uuid))
subs = self._get_regexes()
subs['action'] = '(reboot)|(resize)'
subs['integer_id'] = '[0-9]+'
subs['request_id'] = ('req-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}'
'-[0-9a-f]{4}-[0-9a-f]{12}')
self._verify_response('server-actions-list-resp', subs,
self._verify_response('instance-actions-list-resp', subs,
response, 200)

View File

@ -86,7 +86,7 @@ nova.api.v3.extensions =
hide_server_addresses = nova.api.openstack.compute.plugins.v3.hide_server_addresses:HideServerAddresses
hosts = nova.api.openstack.compute.plugins.v3.hosts:Hosts
hypervisors = nova.api.openstack.compute.plugins.v3.hypervisors:Hypervisors
server_actions = nova.api.openstack.compute.plugins.v3.server_actions:ServerActions
instance_actions = nova.api.openstack.compute.plugins.v3.instance_actions:InstanceActions
ips = nova.api.openstack.compute.plugins.v3.ips:IPs
keypairs = nova.api.openstack.compute.plugins.v3.keypairs:Keypairs
lock_server = nova.api.openstack.compute.plugins.v3.lock_server:LockServer