Merge "Add CellMapping object"
This commit is contained in:
commit
b9beb69b27
|
@ -1857,3 +1857,7 @@ class ImageCPUPinningForbidden(Forbidden):
|
||||||
|
|
||||||
class UnsupportedPolicyException(Invalid):
|
class UnsupportedPolicyException(Invalid):
|
||||||
msg_fmt = _("ServerGroup policy is not supported: %(reason)s")
|
msg_fmt = _("ServerGroup policy is not supported: %(reason)s")
|
||||||
|
|
||||||
|
|
||||||
|
class CellMappingNotFound(NotFound):
|
||||||
|
msg_fmt = _("Cell %(uuid)s has no mapping.")
|
||||||
|
|
|
@ -28,6 +28,7 @@ def register_all():
|
||||||
__import__('nova.objects.aggregate')
|
__import__('nova.objects.aggregate')
|
||||||
__import__('nova.objects.bandwidth_usage')
|
__import__('nova.objects.bandwidth_usage')
|
||||||
__import__('nova.objects.block_device')
|
__import__('nova.objects.block_device')
|
||||||
|
__import__('nova.objects.cell_mapping')
|
||||||
__import__('nova.objects.compute_node')
|
__import__('nova.objects.compute_node')
|
||||||
__import__('nova.objects.dns_domain')
|
__import__('nova.objects.dns_domain')
|
||||||
__import__('nova.objects.ec2')
|
__import__('nova.objects.ec2')
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
# 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.db.sqlalchemy import api as db_api
|
||||||
|
from nova.db.sqlalchemy import api_models
|
||||||
|
from nova import exception
|
||||||
|
from nova.objects import base
|
||||||
|
from nova.objects import fields
|
||||||
|
|
||||||
|
|
||||||
|
class CellMapping(base.NovaTimestampObject, base.NovaObject):
|
||||||
|
# Version 1.0: Initial version
|
||||||
|
VERSION = '1.0'
|
||||||
|
|
||||||
|
fields = {
|
||||||
|
'id': fields.IntegerField(read_only=True),
|
||||||
|
'uuid': fields.UUIDField(),
|
||||||
|
'name': fields.StringField(nullable=True),
|
||||||
|
'transport_url': fields.StringField(),
|
||||||
|
'database_connection': fields.StringField(),
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_db_object(context, cell_mapping, db_cell_mapping):
|
||||||
|
for key in cell_mapping.fields:
|
||||||
|
setattr(cell_mapping, key, db_cell_mapping[key])
|
||||||
|
cell_mapping.obj_reset_changes()
|
||||||
|
cell_mapping._context = context
|
||||||
|
return cell_mapping
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_by_uuid_from_db(context, uuid):
|
||||||
|
session = db_api.get_api_session()
|
||||||
|
|
||||||
|
with session.begin():
|
||||||
|
db_mapping = session.query(api_models.CellMapping).filter_by(
|
||||||
|
uuid=uuid).first()
|
||||||
|
if not db_mapping:
|
||||||
|
raise exception.CellMappingNotFound(uuid=uuid)
|
||||||
|
|
||||||
|
return db_mapping
|
||||||
|
|
||||||
|
@base.remotable_classmethod
|
||||||
|
def get_by_uuid(cls, context, uuid):
|
||||||
|
db_mapping = cls._get_by_uuid_from_db(context, uuid)
|
||||||
|
|
||||||
|
return cls._from_db_object(context, cls(), db_mapping)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_in_db(context, updates):
|
||||||
|
session = db_api.get_api_session()
|
||||||
|
|
||||||
|
db_mapping = api_models.CellMapping()
|
||||||
|
db_mapping.update(updates)
|
||||||
|
db_mapping.save(session)
|
||||||
|
return db_mapping
|
||||||
|
|
||||||
|
@base.remotable
|
||||||
|
def create(self):
|
||||||
|
db_mapping = self._create_in_db(self._context, self.obj_get_changes())
|
||||||
|
self._from_db_object(self._context, self, db_mapping)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _save_in_db(context, uuid, updates):
|
||||||
|
session = db_api.get_api_session()
|
||||||
|
|
||||||
|
with session.begin():
|
||||||
|
db_mapping = session.query(
|
||||||
|
api_models.CellMapping).filter_by(uuid=uuid).first()
|
||||||
|
if not db_mapping:
|
||||||
|
raise exception.CellMappingNotFound(uuid=uuid)
|
||||||
|
|
||||||
|
db_mapping.update(updates)
|
||||||
|
session.add(db_mapping)
|
||||||
|
return db_mapping
|
||||||
|
|
||||||
|
@base.remotable
|
||||||
|
def save(self):
|
||||||
|
changes = self.obj_get_changes()
|
||||||
|
db_mapping = self._save_in_db(self._context, self.uuid, changes)
|
||||||
|
self._from_db_object(self._context, self, db_mapping)
|
||||||
|
self.obj_reset_changes()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _destroy_in_db(context, uuid):
|
||||||
|
session = db_api.get_api_session()
|
||||||
|
|
||||||
|
with session.begin():
|
||||||
|
result = session.query(api_models.CellMapping).filter_by(
|
||||||
|
uuid=uuid).delete()
|
||||||
|
if not result:
|
||||||
|
raise exception.CellMappingNotFound(uuid=uuid)
|
||||||
|
|
||||||
|
@base.remotable
|
||||||
|
def destroy(self):
|
||||||
|
self._destroy_in_db(self._context, self.uuid)
|
|
@ -0,0 +1,74 @@
|
||||||
|
# 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 oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from nova import context
|
||||||
|
from nova import exception
|
||||||
|
from nova.objects import cell_mapping
|
||||||
|
from nova import test
|
||||||
|
from nova.tests import fixtures
|
||||||
|
|
||||||
|
|
||||||
|
class CellMappingTestCase(test.NoDBTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(CellMappingTestCase, self).setUp()
|
||||||
|
self.useFixture(fixtures.Database(database='api'))
|
||||||
|
self.context = context.RequestContext('fake-user', 'fake-project')
|
||||||
|
self.mapping_obj = cell_mapping.CellMapping()
|
||||||
|
self.uuid = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
sample_mapping = {'uuid': '',
|
||||||
|
'name': 'fake-cell',
|
||||||
|
'transport_url': 'rabbit:///',
|
||||||
|
'database_connection': 'mysql:///'}
|
||||||
|
|
||||||
|
def _create_mapping(self, **kwargs):
|
||||||
|
args = self.sample_mapping.copy()
|
||||||
|
if 'uuid' not in kwargs:
|
||||||
|
args['uuid'] = self.uuid
|
||||||
|
args.update(kwargs)
|
||||||
|
return self.mapping_obj._create_in_db(self.context, args)
|
||||||
|
|
||||||
|
def test_get_by_uuid(self):
|
||||||
|
mapping = self._create_mapping()
|
||||||
|
db_mapping = self.mapping_obj._get_by_uuid_from_db(self.context,
|
||||||
|
mapping['uuid'])
|
||||||
|
for key in self.mapping_obj.fields.keys():
|
||||||
|
self.assertEqual(db_mapping[key], mapping[key])
|
||||||
|
|
||||||
|
def test_get_by_uuid_not_found(self):
|
||||||
|
self.assertRaises(exception.CellMappingNotFound,
|
||||||
|
self.mapping_obj._get_by_uuid_from_db, self.context, self.uuid)
|
||||||
|
|
||||||
|
def test_save_in_db(self):
|
||||||
|
mapping = self._create_mapping()
|
||||||
|
self.mapping_obj._save_in_db(self.context, mapping['uuid'],
|
||||||
|
{'name': 'meow'})
|
||||||
|
db_mapping = self.mapping_obj._get_by_uuid_from_db(self.context,
|
||||||
|
mapping['uuid'])
|
||||||
|
self.assertNotEqual(db_mapping['name'], mapping['name'])
|
||||||
|
for key in [key for key in self.mapping_obj.fields.keys()
|
||||||
|
if key not in ['name', 'updated_at']]:
|
||||||
|
self.assertEqual(db_mapping[key], mapping[key])
|
||||||
|
|
||||||
|
def test_destroy_in_db(self):
|
||||||
|
mapping = self._create_mapping()
|
||||||
|
self.mapping_obj._get_by_uuid_from_db(self.context, mapping['uuid'])
|
||||||
|
self.mapping_obj._destroy_in_db(self.context, mapping['uuid'])
|
||||||
|
self.assertRaises(exception.CellMappingNotFound,
|
||||||
|
self.mapping_obj._get_by_uuid_from_db, self.context,
|
||||||
|
mapping['uuid'])
|
||||||
|
|
||||||
|
def test_destroy_in_db_not_found(self):
|
||||||
|
self.assertRaises(exception.CellMappingNotFound,
|
||||||
|
self.mapping_obj._destroy_in_db, self.context, self.uuid)
|
|
@ -0,0 +1,97 @@
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from nova import objects
|
||||||
|
from nova.objects import cell_mapping
|
||||||
|
from nova.tests.unit.objects import test_objects
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_mapping(**updates):
|
||||||
|
db_mapping = {
|
||||||
|
'id': 1,
|
||||||
|
'uuid': uuidutils.generate_uuid(),
|
||||||
|
'name': 'cell1',
|
||||||
|
'transport_url': 'rabbit://',
|
||||||
|
'database_connection': 'sqlite:///',
|
||||||
|
'created_at': None,
|
||||||
|
'updated_at': None,
|
||||||
|
}
|
||||||
|
db_mapping.update(updates)
|
||||||
|
return db_mapping
|
||||||
|
|
||||||
|
|
||||||
|
class _TestCellMappingObject(object):
|
||||||
|
@mock.patch.object(cell_mapping.CellMapping, '_get_by_uuid_from_db')
|
||||||
|
def test_get_by_uuid(self, uuid_from_db):
|
||||||
|
db_mapping = get_db_mapping()
|
||||||
|
uuid_from_db.return_value = db_mapping
|
||||||
|
|
||||||
|
mapping_obj = objects.CellMapping().get_by_uuid(self.context,
|
||||||
|
db_mapping['uuid'])
|
||||||
|
uuid_from_db.assert_called_once_with(self.context, db_mapping['uuid'])
|
||||||
|
self.compare_obj(mapping_obj, db_mapping)
|
||||||
|
|
||||||
|
@mock.patch.object(cell_mapping.CellMapping, '_create_in_db')
|
||||||
|
def test_create(self, create_in_db):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
db_mapping = get_db_mapping(uuid=uuid, name='test',
|
||||||
|
database_connection='mysql:///')
|
||||||
|
create_in_db.return_value = db_mapping
|
||||||
|
mapping_obj = objects.CellMapping(self.context)
|
||||||
|
mapping_obj.uuid = uuid
|
||||||
|
mapping_obj.name = 'test'
|
||||||
|
mapping_obj.database_connection = 'mysql:///'
|
||||||
|
|
||||||
|
mapping_obj.create()
|
||||||
|
create_in_db.assert_called_once_with(self.context,
|
||||||
|
{'uuid': uuid,
|
||||||
|
'name': 'test',
|
||||||
|
'database_connection': 'mysql:///'})
|
||||||
|
self.compare_obj(mapping_obj, db_mapping)
|
||||||
|
|
||||||
|
@mock.patch.object(cell_mapping.CellMapping, '_save_in_db')
|
||||||
|
def test_save(self, save_in_db):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
db_mapping = get_db_mapping(database_connection='mysql:///')
|
||||||
|
save_in_db.return_value = db_mapping
|
||||||
|
mapping_obj = objects.CellMapping(self.context)
|
||||||
|
mapping_obj.uuid = uuid
|
||||||
|
mapping_obj.database_connection = 'mysql:///'
|
||||||
|
|
||||||
|
mapping_obj.save()
|
||||||
|
save_in_db.assert_called_once_with(self.context, uuid,
|
||||||
|
{'uuid': uuid,
|
||||||
|
'database_connection': 'mysql:///'})
|
||||||
|
self.compare_obj(mapping_obj, db_mapping)
|
||||||
|
|
||||||
|
@mock.patch.object(cell_mapping.CellMapping, '_destroy_in_db')
|
||||||
|
def test_destroy(self, destroy_in_db):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
mapping_obj = objects.CellMapping(self.context)
|
||||||
|
mapping_obj.uuid = uuid
|
||||||
|
|
||||||
|
mapping_obj.destroy()
|
||||||
|
destroy_in_db.assert_called_once_with(self.context, uuid)
|
||||||
|
|
||||||
|
|
||||||
|
class TestCellMappingObject(test_objects._LocalTest,
|
||||||
|
_TestCellMappingObject):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestRemoteCellMappingObject(test_objects._RemoteTest,
|
||||||
|
_TestCellMappingObject):
|
||||||
|
pass
|
|
@ -1183,6 +1183,7 @@ object_data = {
|
||||||
'BandwidthUsageList': '1.2-5b564cbfd5ae6e106443c086938e7602',
|
'BandwidthUsageList': '1.2-5b564cbfd5ae6e106443c086938e7602',
|
||||||
'BlockDeviceMapping': '1.8-c87e9c7e5cfd6a402f32727aa74aca95',
|
'BlockDeviceMapping': '1.8-c87e9c7e5cfd6a402f32727aa74aca95',
|
||||||
'BlockDeviceMappingList': '1.9-0faaeebdca213010c791bc37a22546e3',
|
'BlockDeviceMappingList': '1.9-0faaeebdca213010c791bc37a22546e3',
|
||||||
|
'CellMapping': '1.0-4b1616970814c3c819e10c7ef6b9c3d5',
|
||||||
'ComputeNode': '1.10-5f8cd6948ad98fcc0c39b79d49acc4b6',
|
'ComputeNode': '1.10-5f8cd6948ad98fcc0c39b79d49acc4b6',
|
||||||
'ComputeNodeList': '1.10-4ae1f844c247029fbcdb5fdccbe9e619',
|
'ComputeNodeList': '1.10-4ae1f844c247029fbcdb5fdccbe9e619',
|
||||||
'DNSDomain': '1.0-5bdc288d7c3b723ce86ede998fd5c9ba',
|
'DNSDomain': '1.0-5bdc288d7c3b723ce86ede998fd5c9ba',
|
||||||
|
|
Loading…
Reference in New Issue