Merge "Add support for volume attachments in compute v2"

This commit is contained in:
Jenkins 2017-04-13 12:07:19 +00:00 committed by Gerrit Code Review
commit 3f2badb9c1
3 changed files with 212 additions and 0 deletions

View File

@ -22,6 +22,7 @@ from openstack.compute.v2 import server_group as _server_group
from openstack.compute.v2 import server_interface as _server_interface
from openstack.compute.v2 import server_ip
from openstack.compute.v2 import service as _service
from openstack.compute.v2 import volume_attachment as _volume_attachment
from openstack import proxy2
from openstack import resource2
@ -1120,3 +1121,126 @@ class Proxy(proxy2.BaseProxy):
"""
return self._list(_service.Service, paginated=False)
def create_volume_attachment(self, server, **attrs):
"""Create a new volume attachment from attributes
:param server: The server can be either the ID of a server or a
:class:`~openstack.compute.v2.server.Server` instance.
:param dict attrs: Keyword arguments which will be used to create a
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`,
comprised of the properties on the VolumeAttachment class.
:returns: The results of volume attachment creation
:rtype:
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
"""
server_id = resource2.Resource._get_id(server)
return self._create(_volume_attachment.VolumeAttachment,
server_id=server_id, **attrs)
def update_volume_attachment(self, volume_attachment, server,
**attrs):
"""update a volume attachment
:param volume_attachment:
The value can be either the ID of a volume attachment or a
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
instance.
:param server: This parameter need to be specified when
VolumeAttachment ID is given as value. It can be
either the ID of a server or a
:class:`~openstack.compute.v2.server.Server`
instance that the attachment belongs to.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the volume attachment does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent volume attachment.
:returns: ``None``
"""
server_id = self._get_uri_attribute(volume_attachment, server,
"server_id")
volume_attachment = resource2.Resource._get_id(volume_attachment)
return self._update(_volume_attachment.VolumeAttachment,
attachment_id=volume_attachment,
server_id=server_id)
def delete_volume_attachment(self, volume_attachment, server,
ignore_missing=True):
"""Delete a volume attachment
:param volume_attachment:
The value can be either the ID of a volume attachment or a
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
instance.
:param server: This parameter need to be specified when
VolumeAttachment ID is given as value. It can be either
the ID of a server or a
:class:`~openstack.compute.v2.server.Server`
instance that the attachment belongs to.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the volume attachment does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent volume attachment.
:returns: ``None``
"""
server_id = self._get_uri_attribute(volume_attachment, server,
"server_id")
volume_attachment = resource2.Resource._get_id(volume_attachment)
self._delete(_volume_attachment.VolumeAttachment,
attachment_id=volume_attachment,
server_id=server_id,
ignore_missing=ignore_missing)
def get_volume_attachment(self, volume_attachment, server,
ignore_missing=True):
"""Get a single volume attachment
:param volume_attachment:
The value can be the ID of a volume attachment or a
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
instance.
:param server: This parameter need to be specified when
VolumeAttachment ID is given as value. It can be either
the ID of a server or a
:class:`~openstack.compute.v2.server.Server`
instance that the attachment belongs to.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the volume attachment does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent volume attachment.
:returns: One
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
server_id = self._get_uri_attribute(volume_attachment, server,
"server_id")
volume_attachment = resource2.Resource._get_id(volume_attachment)
return self._get(_volume_attachment.VolumeAttachment,
server_id=server_id,
attachment_id=volume_attachment,
ignore_missing=ignore_missing)
def volume_attachments(self, server):
"""Return a generator of volume attachments
:param server: The server can be either the ID of a server or a
:class:`~openstack.compute.v2.server.Server`.
:returns: A generator of VolumeAttachment objects
:rtype:
:class:`~openstack.compute.v2.volume_attachment.VolumeAttachment`
"""
server_id = resource2.Resource._get_id(server)
return self._list(_volume_attachment.VolumeAttachment, paginated=False,
server_id=server_id)

View File

@ -0,0 +1,41 @@
# 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 openstack.compute import compute_service
from openstack import resource2
class VolumeAttachment(resource2.Resource):
resource_key = 'volumeAttachment'
resources_key = 'volumeAttachments'
base_path = '/servers/%(server_id)s/os-volume_attachments'
service = compute_service.ComputeService()
# capabilities
allow_create = True
allow_get = True
allow_update = False
allow_delete = True
allow_list = True
_query_mapping = resource2.QueryParameters("limit", "offset")
#: Name of the device such as, /dev/vdb.
device = resource2.Body('device')
#: The ID of the attachment.
id = resource2.Body('id')
#: The ID for the server.
server_id = resource2.URI('server_id')
#: The ID of the attached volume.
volume_id = resource2.Body('volumeId')
#: The ID of the attachment you want to delete or update.
attachment_id = resource2.Body('attachment_id', alternate_id=True)

View File

@ -0,0 +1,47 @@
# 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 testtools
from openstack.compute.v2 import volume_attachment
EXAMPLE = {
'device': '1',
'id': '2',
'volume_id': '3',
}
class TestServerInterface(testtools.TestCase):
def test_basic(self):
sot = volume_attachment.VolumeAttachment()
self.assertEqual('volumeAttachment', sot.resource_key)
self.assertEqual('volumeAttachments', sot.resources_key)
self.assertEqual('/servers/%(server_id)s/os-volume_attachments',
sot.base_path)
self.assertEqual('compute', sot.service.service_type)
self.assertTrue(sot.allow_create)
self.assertTrue(sot.allow_get)
self.assertFalse(sot.allow_update)
self.assertTrue(sot.allow_delete)
self.assertTrue(sot.allow_list)
self.assertDictEqual({"limit": "limit",
"offset": "offset",
"marker": "marker"},
sot._query_mapping._mapping)
def test_make_it(self):
sot = volume_attachment.VolumeAttachment(**EXAMPLE)
self.assertEqual(EXAMPLE['device'], sot.device)
self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(EXAMPLE['volume_id'], sot.volume_id)