Add 'connection_info' to attachment object
There are some issues around new attach/detach API/CLI,
fix them step by step. This patch added attribute
'connection_info' to attachment object, also add related
testcases in API unit testcases.
Depends-On: 87982a5677
Closes-Bug: #1681297
Change-Id: Idbc1049e8adf1d5b955bda01d58bb6b89fc6c5c7
This commit is contained in:
parent
ff2cba6a4f
commit
8031fb1e98
@ -32,7 +32,7 @@ class ViewBuilder(object):
|
||||
attached_at=cls._normalize(attachment.attach_time),
|
||||
detached_at=cls._normalize(attachment.detach_time),
|
||||
attach_mode=attachment.attach_mode,
|
||||
connection_info=getattr(attachment, 'connection_info', None),)
|
||||
connection_info=attachment.connection_info)
|
||||
if flat:
|
||||
return result
|
||||
return {'attachment': result}
|
||||
|
@ -0,0 +1,22 @@
|
||||
# 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 sqlalchemy import MetaData, Table, Column, Text
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData(migrate_engine)
|
||||
|
||||
# Add connection_info column to attachment table
|
||||
attachment = Table('volume_attachment', meta, autoload=True)
|
||||
connection_info = Column('connection_info', Text)
|
||||
attachment.create_column(connection_info)
|
@ -354,6 +354,7 @@ class VolumeAttachment(BASE, CinderBase):
|
||||
detach_time = Column(DateTime)
|
||||
attach_status = Column(String(255))
|
||||
attach_mode = Column(String(255))
|
||||
connection_info = Column(Text)
|
||||
|
||||
|
||||
class VolumeTypes(BASE, CinderBase):
|
||||
|
@ -130,6 +130,7 @@ OBJ_VERSIONS.add('1.21', {'ManageableSnapshot': '1.0',
|
||||
'ManageableVolumeList': '1.0',
|
||||
'ManageableSnapshotList': '1.0'})
|
||||
OBJ_VERSIONS.add('1.22', {'Snapshot': '1.4'})
|
||||
OBJ_VERSIONS.add('1.23', {'VolumeAttachment': '1.2'})
|
||||
|
||||
|
||||
class CinderObjectRegistry(base.VersionedObjectRegistry):
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_versionedobjects import fields
|
||||
|
||||
from cinder import db
|
||||
@ -28,7 +29,8 @@ class VolumeAttachment(base.CinderPersistentObject, base.CinderObject,
|
||||
base.CinderComparableObject):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added volume relationship
|
||||
VERSION = '1.1'
|
||||
# Version 1.2: Added connection_info attribute
|
||||
VERSION = '1.2'
|
||||
|
||||
OPTIONAL_FIELDS = ['volume']
|
||||
obj_extra_fields = ['project_id', 'volume_host']
|
||||
@ -47,6 +49,7 @@ class VolumeAttachment(base.CinderPersistentObject, base.CinderObject,
|
||||
'attach_mode': fields.StringField(nullable=True),
|
||||
|
||||
'volume': fields.ObjectField('Volume', nullable=False),
|
||||
'connection_info': fields.DictOfNullableStringsField(nullable=True)
|
||||
}
|
||||
|
||||
@property
|
||||
@ -73,8 +76,11 @@ class VolumeAttachment(base.CinderPersistentObject, base.CinderObject,
|
||||
value = db_attachment.get(name)
|
||||
if isinstance(field, fields.IntegerField):
|
||||
value = value or 0
|
||||
attachment[name] = value
|
||||
|
||||
if name == 'connection_info':
|
||||
attachment.connection_info = jsonutils.loads(
|
||||
value) if value else None
|
||||
else:
|
||||
attachment[name] = value
|
||||
if 'volume' in expected_attrs:
|
||||
db_volume = db_attachment.get('volume')
|
||||
if db_volume:
|
||||
@ -100,9 +106,17 @@ class VolumeAttachment(base.CinderPersistentObject, base.CinderObject,
|
||||
|
||||
self.obj_reset_changes(fields=[attrname])
|
||||
|
||||
@staticmethod
|
||||
def _convert_connection_info_to_db_format(updates):
|
||||
properties = updates.pop('connection_info', None)
|
||||
if properties is not None:
|
||||
updates['connection_info'] = jsonutils.dumps(properties)
|
||||
|
||||
def save(self):
|
||||
updates = self.cinder_obj_get_changes()
|
||||
if updates:
|
||||
if 'connection_info' in updates:
|
||||
self._convert_connection_info_to_db_format(updates)
|
||||
if 'volume' in updates:
|
||||
raise exception.ObjectActionError(action='save',
|
||||
reason=_('volume changed'))
|
||||
|
@ -61,17 +61,22 @@ class AttachmentManagerTestCase(test.TestCase):
|
||||
mock_policy):
|
||||
"""Test attachment_create with connector."""
|
||||
volume_params = {'status': 'available'}
|
||||
connection_info = {'fake_key': 'fake_value'}
|
||||
mock_rpc_attachment_update.return_value = connection_info
|
||||
|
||||
vref = tests_utils.create_volume(self.context, **volume_params)
|
||||
connector = {'fake': 'connector'}
|
||||
self.volume_api.attachment_create(self.context,
|
||||
vref,
|
||||
fake.UUID2,
|
||||
connector)
|
||||
attachment = self.volume_api.attachment_create(self.context,
|
||||
vref,
|
||||
fake.UUID2,
|
||||
connector)
|
||||
mock_rpc_attachment_update.assert_called_once_with(self.context,
|
||||
mock.ANY,
|
||||
connector,
|
||||
mock.ANY)
|
||||
new_attachment = objects.VolumeAttachment.get_by_id(self.context,
|
||||
attachment.id)
|
||||
self.assertEqual(connection_info, new_attachment.connection_info)
|
||||
|
||||
@mock.patch('cinder.volume.api.check_policy')
|
||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.attachment_delete')
|
||||
@ -106,6 +111,8 @@ class AttachmentManagerTestCase(test.TestCase):
|
||||
mock_policy):
|
||||
"""Test attachment_delete."""
|
||||
volume_params = {'status': 'available'}
|
||||
connection_info = {'fake_key': 'fake_value'}
|
||||
mock_rpc_attachment_update.return_value = connection_info
|
||||
|
||||
vref = tests_utils.create_volume(self.context, **volume_params)
|
||||
aref = self.volume_api.attachment_create(self.context,
|
||||
@ -120,6 +127,9 @@ class AttachmentManagerTestCase(test.TestCase):
|
||||
self.volume_api.attachment_update(self.context,
|
||||
aref,
|
||||
connector)
|
||||
aref = objects.VolumeAttachment.get_by_id(self.context,
|
||||
aref.id)
|
||||
self.assertEqual(connection_info, aref.connection_info)
|
||||
# We mock the actual call that updates the status
|
||||
# so force it here
|
||||
values = {'volume_id': vref.id,
|
||||
|
@ -47,7 +47,7 @@ object_data = {
|
||||
'SnapshotList': '1.0-15ecf022a68ddbb8c2a6739cfc9f8f5e',
|
||||
'Volume': '1.6-7d3bc8577839d5725670d55e480fe95f',
|
||||
'VolumeList': '1.1-15ecf022a68ddbb8c2a6739cfc9f8f5e',
|
||||
'VolumeAttachment': '1.1-ed82a5fdd56655e14d9f86396c130aea',
|
||||
'VolumeAttachment': '1.2-b68b357a1756582b706006ea9de40c9a',
|
||||
'VolumeAttachmentList': '1.1-15ecf022a68ddbb8c2a6739cfc9f8f5e',
|
||||
'VolumeProperties': '1.1-cadac86b2bdc11eb79d1dcea988ff9e8',
|
||||
'VolumeType': '1.3-a5d8c3473db9bc3bbcdbab9313acf4d1',
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added attribute ``connection_info`` to attachment object.
|
Loading…
Reference in New Issue
Block a user