Update legacy code depending on Nova V2 API plugin
Blazar-Nova uses Nova API plugin frameworks. The V2 API was removed in Nova commit a31d917af0cc5ecb55424598e7b812e02afbf28c. However, some lines of V2 dependent code were still included in Blazar-Nova. This patch updates the V2 dependent code to V2.1. NOTE: This commit fixes unit tests in order to unblock the gate, but doesn't restore instance reservation functionality due to major changes in support for Nova API extensions. Change-Id: Ie8252a350bd739845ee92e17c85f32385a7ddeb4 Closes-Bug: #1644680
This commit is contained in:
parent
7a525b6d78
commit
97a4a7e89f
@ -25,11 +25,13 @@ import json
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import compute
|
||||
from nova import utils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from webob import exc
|
||||
|
||||
|
||||
reservation_opts = [
|
||||
cfg.StrOpt('reservation_start_date',
|
||||
default='now',
|
||||
@ -49,12 +51,15 @@ CONF = cfg.CONF
|
||||
CONF.register_opts(reservation_opts)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
authorize = extensions.extension_authorizer('compute', 'default_reservation')
|
||||
|
||||
|
||||
class DefaultReservationController(wsgi.Controller):
|
||||
"""Add default reservation flags to every VM started."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DefaultReservationController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.extends
|
||||
def create(self, req, body):
|
||||
"""Add additional hints to the create server request.
|
||||
@ -65,9 +70,7 @@ class DefaultReservationController(wsgi.Controller):
|
||||
if not self.is_valid_body(body, 'server'):
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
if 'server' in body:
|
||||
scheduler_hints = body['server'].get('scheduler_hints', {})
|
||||
elif 'os:scheduler_hints' in body:
|
||||
if 'os:scheduler_hints' in body:
|
||||
scheduler_hints = body['os:scheduler_hints']
|
||||
else:
|
||||
scheduler_hints = body.get('OS-SCH-HNT:scheduler_hints', {})
|
||||
@ -94,29 +97,27 @@ class DefaultReservationController(wsgi.Controller):
|
||||
|
||||
default_hints = {'lease_params': json.dumps(lease_params)}
|
||||
|
||||
if 'server' in body:
|
||||
if 'scheduler_hints' in body['server']:
|
||||
body['server']['scheduler_hints'].update(default_hints)
|
||||
else:
|
||||
body['server']['scheduler_hints'] = default_hints
|
||||
else:
|
||||
attr = 'OS-SCH-HNT:scheduler_hints'
|
||||
if 'os:scheduler_hints' in body:
|
||||
body['os:scheduler_hints'].update(default_hints)
|
||||
elif attr in body and 'lease_params' not in body[attr]:
|
||||
body[attr].update(default_hints)
|
||||
yield
|
||||
elif 'OS-SCH-HNT:scheduler_hints' in body:
|
||||
body['OS-SCH-HNT:scheduler_hints'].update(default_hints)
|
||||
else:
|
||||
body['os:scheduler_hints'] = default_hints
|
||||
|
||||
|
||||
class Default_reservation(extensions.ExtensionDescriptor):
|
||||
class Default_reservation(extensions.V21APIExtensionBase):
|
||||
"""Instance reservation system."""
|
||||
|
||||
name = "DefaultReservation"
|
||||
alias = "os-default-instance-reservation"
|
||||
updated = "2015-09-29T00:00:00Z"
|
||||
namespace = "blazarnova"
|
||||
updated = "2016-11-30T00:00:00Z"
|
||||
version = 1
|
||||
|
||||
def get_controller_extensions(self):
|
||||
return []
|
||||
|
||||
def get_resources(self):
|
||||
controller = DefaultReservationController()
|
||||
extension = extensions.ControllerExtension(self, 'servers', controller)
|
||||
extension = extensions.ResourceExtension(
|
||||
self.alias, controller, member_actions={"action": "POST"})
|
||||
return [extension]
|
||||
|
@ -29,7 +29,6 @@ except ImportError:
|
||||
blazar_client = None
|
||||
|
||||
from blazarnova.i18n import _ # noqa
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import compute
|
||||
@ -38,7 +37,6 @@ from oslo_log import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
authorize = extensions.extension_authorizer('compute', 'reservation')
|
||||
|
||||
|
||||
class ReservationController(wsgi.Controller):
|
||||
@ -51,8 +49,12 @@ class ReservationController(wsgi.Controller):
|
||||
def create(self, req, resp_obj, body):
|
||||
"""Support Blazar usage for Nova VMs."""
|
||||
|
||||
scheduler_hints = body.get('server', {}).get('scheduler_hints', {})
|
||||
lease_params = scheduler_hints.get('lease_params')
|
||||
if 'os:scheduler_hints' in body:
|
||||
scheduler_hints = body['os:scheduler_hints']
|
||||
else:
|
||||
scheduler_hints = body.get('OS-SCH-HNT:scheduler_hints', {})
|
||||
|
||||
lease_params = scheduler_hints.get('lease_params', {})
|
||||
|
||||
if lease_params:
|
||||
try:
|
||||
@ -172,15 +174,18 @@ class LeaseTransaction(object):
|
||||
self.nova_ctx = nova_ctx
|
||||
|
||||
|
||||
class Reservation(extensions.ExtensionDescriptor):
|
||||
class Reservation(extensions.V21APIExtensionBase):
|
||||
"""Instance reservation system."""
|
||||
|
||||
name = "Reservation"
|
||||
alias = "os-instance-reservation"
|
||||
updated = "2015-09-29T00:00:00Z"
|
||||
namespace = "blazarnova"
|
||||
updated = "2016-11-30T00:00:00Z"
|
||||
version = 1
|
||||
|
||||
def get_controller_extensions(self):
|
||||
controller = ReservationController()
|
||||
extension = extensions.ControllerExtension(self, 'servers', controller)
|
||||
return [extension]
|
||||
|
||||
def get_resources(self):
|
||||
return []
|
||||
|
@ -15,21 +15,19 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from nova.tests.unit.api.openstack import fakes
|
||||
|
||||
import mock
|
||||
|
||||
from nova.api.openstack import compute
|
||||
from nova.compute import api as compute_api
|
||||
from nova import context
|
||||
from nova import test
|
||||
from nova.tests.unit.api.openstack import fakes
|
||||
from nova import utils
|
||||
from oslo_config import cfg
|
||||
|
||||
|
||||
UUID = fakes.FAKE_UUID
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('osapi_compute_ext_list',
|
||||
'nova.api.openstack.compute.legacy_v2.contrib')
|
||||
CONF.import_opt('reservation_start_date',
|
||||
'blazarnova.api.extensions.default_reservation')
|
||||
CONF.import_opt('reservation_length_hours',
|
||||
@ -59,22 +57,12 @@ class BaseExtensionTestCase(test.TestCase):
|
||||
"""Set up testing environment."""
|
||||
super(BaseExtensionTestCase, self).setUp()
|
||||
self.fake_instance = fakes.stub_instance(1, uuid=UUID)
|
||||
self.flags(
|
||||
osapi_compute_extension=[
|
||||
'nova.api.openstack.compute.legacy_v2.contrib.'
|
||||
'select_extensions',
|
||||
'blazarnova.api.extensions.default_reservation.'
|
||||
'Default_reservation',
|
||||
'blazarnova.api.extensions.reservation.Reservation'
|
||||
],
|
||||
osapi_compute_ext_list=['Scheduler_hints'])
|
||||
|
||||
self.lease_controller = mock.MagicMock()
|
||||
self.lease_controller.create = mock.MagicMock()
|
||||
self.mock_client = mock.MagicMock()
|
||||
self.mock_client.lease = self.lease_controller
|
||||
|
||||
self.req = fakes.HTTPRequest.blank('/fake/servers')
|
||||
self.req = fakes.HTTPRequestV21.blank('/fake/servers')
|
||||
self.req.method = 'POST'
|
||||
self.req.content_type = 'application/json'
|
||||
self.req.environ.update({
|
||||
@ -86,9 +74,8 @@ class BaseExtensionTestCase(test.TestCase):
|
||||
})
|
||||
|
||||
self.l_name = 'lease_123'
|
||||
self.app = compute.APIRouter(init_only=('servers',))
|
||||
self.app = compute.APIRouterV21()
|
||||
self.stubs.Set(utils, 'generate_uid', lambda name, size: self.l_name)
|
||||
self.stubs.Set(compute_api.API, 'create', self._fake_create)
|
||||
self.stubs.Set(compute_api.API, 'get', self._fake_get)
|
||||
self.stubs.Set(compute_api.API, 'shelve', self._fake_shelve)
|
||||
|
||||
@ -101,9 +88,6 @@ class BaseExtensionTestCase(test.TestCase):
|
||||
self.default_lease_end = lease_end.strftime('%Y-%m-%d %H:%M')
|
||||
self.default_lease_start = 'now'
|
||||
|
||||
def _fake_create(self, *args, **kwargs):
|
||||
return [self.fake_instance], ''
|
||||
|
||||
def _fake_get(self, *args, **kwargs):
|
||||
self.fake_instance['vm_state'] = 'active'
|
||||
return InstanceWrapper(self.fake_instance)
|
||||
|
@ -14,9 +14,12 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from blazarnova.api.extensions import default_reservation
|
||||
from blazarnova.api.extensions import reservation
|
||||
from blazarnova.tests.api import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
||||
class BlazarDefaultReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
@ -30,6 +33,9 @@ class BlazarDefaultReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
def setUp(self):
|
||||
"""Set up testing environment."""
|
||||
super(BlazarDefaultReservationTestCase, self).setUp()
|
||||
self.rsrv_controller = reservation.ReservationController()
|
||||
self.default_rsrv_controller = default_reservation\
|
||||
.DefaultReservationController()
|
||||
|
||||
@mock.patch('blazarnova.api.extensions.reservation.blazar_client')
|
||||
def test_create_with_default(self, mock_module):
|
||||
@ -48,20 +54,21 @@ class BlazarDefaultReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
}
|
||||
|
||||
self.req.body = jsonutils.dumps(body)
|
||||
res = self.req.get_response(self.app)
|
||||
self.default_rsrv_controller.create(self.req, body)
|
||||
resp_obj = wsgi.ResponseObject({'server': {'id': 'fakeId'}})
|
||||
self.rsrv_controller.create(self.req, resp_obj, body)
|
||||
|
||||
mock_module.Client.assert_called_once_with(climate_url='fake',
|
||||
auth_token='fake_token')
|
||||
|
||||
self.lease_controller.create.assert_called_once_with(
|
||||
reservations=[
|
||||
{'resource_type': 'virtual:instance',
|
||||
'resource_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}],
|
||||
'resource_id': 'fakeId'}],
|
||||
end=self.default_lease_end,
|
||||
events=[],
|
||||
start='now',
|
||||
name='lease_123')
|
||||
|
||||
self.assertEqual(202, res.status_int)
|
||||
name=self.l_name)
|
||||
|
||||
@mock.patch('blazarnova.api.extensions.reservation.blazar_client')
|
||||
def test_create_with_passed_args(self, mock_module):
|
||||
@ -82,17 +89,18 @@ class BlazarDefaultReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
}
|
||||
|
||||
self.req.body = jsonutils.dumps(body)
|
||||
res = self.req.get_response(self.app)
|
||||
self.default_rsrv_controller.create(self.req, body)
|
||||
resp_obj = wsgi.ResponseObject({'server': {'id': 'fakeId'}})
|
||||
self.rsrv_controller.create(self.req, resp_obj, body)
|
||||
|
||||
mock_module.Client.assert_called_once_with(climate_url='fake',
|
||||
auth_token='fake_token')
|
||||
|
||||
self.lease_controller.create.assert_called_once_with(
|
||||
reservations=[
|
||||
{'resource_type': 'virtual:instance',
|
||||
'resource_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}],
|
||||
'resource_id': 'fakeId'}],
|
||||
end=self.default_lease_end,
|
||||
events=[],
|
||||
start='now',
|
||||
name='other_name')
|
||||
|
||||
self.assertEqual(202, res.status_int)
|
||||
|
@ -14,15 +14,17 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from blazarnova.api.extensions import reservation
|
||||
from blazarnova.tests.api import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
||||
class BlazarReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
"""Blazar API extensions test case.
|
||||
|
||||
This test case provides tests for Default_reservation extension working
|
||||
This test case provides tests for Reservation extension working
|
||||
together with Reservation extension passing hints to Nova and
|
||||
sending lease creation request to Blazar.
|
||||
"""
|
||||
@ -30,13 +32,7 @@ class BlazarReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
def setUp(self):
|
||||
"""Set up testing environment."""
|
||||
super(BlazarReservationTestCase, self).setUp()
|
||||
self.flags(
|
||||
osapi_compute_extension=[
|
||||
'nova.api.openstack.compute.legacy_v2.contrib.'
|
||||
'select_extensions',
|
||||
'blazarnova.api.extensions.reservation.Reservation'
|
||||
],
|
||||
osapi_compute_ext_list=['Scheduler_hints'])
|
||||
self.controller = reservation.ReservationController()
|
||||
|
||||
@mock.patch('blazarnova.api.extensions.reservation.blazar_client')
|
||||
def test_create(self, mock_module):
|
||||
@ -57,17 +53,17 @@ class BlazarReservationTestCase(extensions.BaseExtensionTestCase):
|
||||
}
|
||||
|
||||
self.req.body = jsonutils.dumps(body)
|
||||
res = self.req.get_response(self.app)
|
||||
resp_obj = wsgi.ResponseObject({'server': {'id': 'fakeId'}})
|
||||
self.controller.create(self.req, resp_obj, body)
|
||||
|
||||
mock_module.Client.assert_called_once_with(climate_url='fake',
|
||||
auth_token='fake_token')
|
||||
|
||||
self.lease_controller.create.assert_called_once_with(
|
||||
reservations=[
|
||||
{'resource_type': 'virtual:instance',
|
||||
'resource_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'}],
|
||||
'resource_id': 'fakeId'}],
|
||||
end='2014-02-10 12:00',
|
||||
events=[],
|
||||
start='2014-02-09 12:00',
|
||||
name='some_name')
|
||||
|
||||
self.assertEqual(202, res.status_int)
|
||||
|
@ -1,3 +1,4 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
kombu>=3.0.25,<4.0.0 # BSD
|
||||
|
Loading…
Reference in New Issue
Block a user