Microversion 2.79: Add delete_on_termination to volume-attach API
Support add 'delete_on_termination' field to the voume attach API to support configuring whether to delete the data volume when the server is destroyed. * Updating the ``nova volume-attachments`` command to show the ``delete_on_termination`` value if 2.79 or greater is used. * The '--delete-on-termination' option is added to the `nova volume-attach` CLI. Depends-On: https://review.opendev.org/#/c/673133/ Part of blueprint support-delete-on-termination-in-server-attach-volume Change-Id: I8dcf2fd21a2fd99ca4e05bd953fbbe026be3a619
This commit is contained in:
parent
aae95dcc7a
commit
cd396b8b61
@ -3849,7 +3849,8 @@ nova volume-attach
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
usage: nova volume-attach [--tag <tag>] <server> <volume> [<device>]
|
||||
usage: nova volume-attach [--delete-on-termination] [--tag <tag>]
|
||||
<server> <volume> [<device>]
|
||||
|
||||
Attach a volume to a server.
|
||||
|
||||
@ -3870,6 +3871,11 @@ Attach a volume to a server.
|
||||
``--tag <tag>``
|
||||
Tag for the attached volume. (Supported by API versions '2.49' - '2.latest')
|
||||
|
||||
``--delete-on-termination``
|
||||
Specify if the attached volume sholud be deleted when the server is
|
||||
destroyed. By default the attached volume is not deleted when the server is
|
||||
destroyed. (Supported by API versions '2.79' - '2.latest')
|
||||
|
||||
.. _nova_volume-attachments:
|
||||
|
||||
nova volume-attachments
|
||||
|
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.78")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.79")
|
||||
|
@ -2115,6 +2115,11 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
if self.api_version >= api_versions.APIVersion('2.70'):
|
||||
# Include the "tag" field in the response.
|
||||
attachment['tag'] = 'test-tag'
|
||||
|
||||
if self.api_version >= api_versions.APIVersion('2.79'):
|
||||
# Include the "delete_on_termination" field in the
|
||||
# response.
|
||||
attachment['delete_on_termination'] = True
|
||||
return (200, FAKE_RESPONSE_HEADERS, {"volumeAttachment": attachment})
|
||||
|
||||
def put_servers_1234_os_volume_attachments_Work(self, **kw):
|
||||
@ -2139,6 +2144,12 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
# Include the "tag" field in each attachment.
|
||||
for attachment in attachments['volumeAttachments']:
|
||||
attachment['tag'] = 'test-tag'
|
||||
|
||||
if self.api_version >= api_versions.APIVersion('2.79'):
|
||||
# Include the "delete_on_termination" field in each
|
||||
# attachment.
|
||||
for attachment in attachments['volumeAttachments']:
|
||||
attachment['delete_on_termination'] = True
|
||||
return (200, FAKE_RESPONSE_HEADERS, attachments)
|
||||
|
||||
def get_servers_1234_os_volume_attachments_Work(self, **kw):
|
||||
|
@ -3825,6 +3825,42 @@ class ShellTest(utils.TestCase):
|
||||
'tag': 'test-tag'}})
|
||||
self.assertIn('test-tag', out)
|
||||
|
||||
def test_volume_attachments_pre_v2_79(self):
|
||||
out = self.run_command(
|
||||
'volume-attachments 1234', api_version='2.78')[0]
|
||||
self.assert_called('GET', '/servers/1234/os-volume_attachments')
|
||||
self.assertNotIn('DELETE ON TERMINATION', out)
|
||||
|
||||
def test_volume_attachments_v2_79(self):
|
||||
out = self.run_command(
|
||||
'volume-attachments 1234', api_version='2.79')[0]
|
||||
self.assert_called('GET', '/servers/1234/os-volume_attachments')
|
||||
self.assertIn('DELETE ON TERMINATION', out)
|
||||
|
||||
def test_volume_attach_with_delete_on_termination_pre_v2_79(self):
|
||||
self.assertRaises(
|
||||
SystemExit, self.run_command,
|
||||
'volume-attach --delete-on-termination sample-server '
|
||||
'Work /dev/vdb', api_version='2.78')
|
||||
|
||||
def test_volume_attach_with_delete_on_termination_v2_79(self):
|
||||
out = self.run_command(
|
||||
'volume-attach --delete-on-termination sample-server '
|
||||
'2 /dev/vdb', api_version='2.79')[0]
|
||||
self.assert_called('POST', '/servers/1234/os-volume_attachments',
|
||||
{'volumeAttachment':
|
||||
{'device': '/dev/vdb',
|
||||
'volumeId': '2',
|
||||
'delete_on_termination': True}})
|
||||
self.assertIn('delete_on_termination', out)
|
||||
|
||||
def test_volume_attach_without_delete_on_termination(self):
|
||||
self.run_command('volume-attach sample-server Work',
|
||||
api_version='2.79')
|
||||
self.assert_called('POST', '/servers/1234/os-volume_attachments',
|
||||
{'volumeAttachment':
|
||||
{'volumeId': 'Work'}})
|
||||
|
||||
def test_volume_update(self):
|
||||
self.run_command('volume-update sample-server Work Work')
|
||||
self.assert_called('PUT', '/servers/1234/os-volume_attachments/Work',
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import six
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient.tests.unit import utils
|
||||
@ -126,3 +127,33 @@ class VolumesV249Test(VolumesTest):
|
||||
volume_id=None,
|
||||
attachment_id="Work")
|
||||
mock_warn.assert_called_once()
|
||||
|
||||
|
||||
class VolumesV279Test(VolumesV249Test):
|
||||
api_version = "2.79"
|
||||
|
||||
def test_create_server_volume_with_delete_on_termination(self):
|
||||
v = self.cs.volumes.create_server_volume(
|
||||
server_id=1234,
|
||||
volume_id='15e59938-07d5-11e1-90e3-e3dffe0c5983',
|
||||
device='/dev/vdb',
|
||||
tag='tag1',
|
||||
delete_on_termination=True
|
||||
)
|
||||
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called(
|
||||
'POST', '/servers/1234/os-volume_attachments',
|
||||
{'volumeAttachment': {
|
||||
'volumeId': '15e59938-07d5-11e1-90e3-e3dffe0c5983',
|
||||
'device': '/dev/vdb',
|
||||
'tag': 'tag1',
|
||||
'delete_on_termination': True}})
|
||||
self.assertIsInstance(v, volumes.Volume)
|
||||
|
||||
def test_create_server_volume_with_delete_on_termination_pre_v279(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.78')
|
||||
ex = self.assertRaises(
|
||||
TypeError, self.cs.volumes.create_server_volume, "1234",
|
||||
volume_id='15e59938-07d5-11e1-90e3-e3dffe0c5983',
|
||||
delete_on_termination=True)
|
||||
self.assertIn('delete_on_termination', six.text_type(ex))
|
||||
|
@ -2633,6 +2633,13 @@ def _translate_volume_attachments_keys(collection):
|
||||
default=None,
|
||||
help=_('Tag for the attached volume.'),
|
||||
start_version="2.49")
|
||||
@utils.arg(
|
||||
'--delete-on-termination',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Specify if the attached volume should be deleted '
|
||||
'when the server is destroyed.'),
|
||||
start_version="2.79")
|
||||
def do_volume_attach(cs, args):
|
||||
"""Attach a volume to a server."""
|
||||
if args.device == 'auto':
|
||||
@ -2642,6 +2649,9 @@ def do_volume_attach(cs, args):
|
||||
if 'tag' in args and args.tag:
|
||||
update_kwargs['tag'] = args.tag
|
||||
|
||||
if 'delete_on_termination' in args and args.delete_on_termination:
|
||||
update_kwargs['delete_on_termination'] = args.delete_on_termination
|
||||
|
||||
volume = cs.volumes.create_server_volume(_find_server(cs, args.server).id,
|
||||
args.volume,
|
||||
args.device,
|
||||
@ -2699,6 +2709,9 @@ def do_volume_attachments(cs, args):
|
||||
fields = ['ID', 'DEVICE', 'SERVER ID', 'VOLUME ID']
|
||||
if cs.api_version >= api_versions.APIVersion('2.70'):
|
||||
fields.append('TAG')
|
||||
# Microversion >= 2.79 returns the delete_on_termination value.
|
||||
if cs.api_version >= api_versions.APIVersion('2.79'):
|
||||
fields.append('DELETE ON TERMINATION')
|
||||
utils.print_list(volumes, fields)
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ class VolumeManager(base.Manager):
|
||||
return self._create("/servers/%s/os-volume_attachments" % server_id,
|
||||
body, "volumeAttachment")
|
||||
|
||||
@api_versions.wraps("2.49")
|
||||
@api_versions.wraps("2.49", "2.78")
|
||||
def create_server_volume(self, server_id, volume_id, device=None,
|
||||
tag=None):
|
||||
"""
|
||||
@ -75,6 +75,34 @@ class VolumeManager(base.Manager):
|
||||
return self._create("/servers/%s/os-volume_attachments" % server_id,
|
||||
body, "volumeAttachment")
|
||||
|
||||
@api_versions.wraps("2.79")
|
||||
def create_server_volume(self, server_id, volume_id, device=None,
|
||||
tag=None, delete_on_termination=False):
|
||||
"""
|
||||
Attach a volume identified by the volume ID to the given server ID
|
||||
|
||||
:param server_id: The ID of the server.
|
||||
:param volume_id: The ID of the volume to attach.
|
||||
:param device: The device name (optional).
|
||||
:param tag: The tag (optional).
|
||||
:param delete_on_termination: Marked whether to delete the attached
|
||||
volume when the server is deleted
|
||||
(optional).
|
||||
:rtype: :class:`Volume`
|
||||
"""
|
||||
# TODO(mriedem): Move this body construction into a private common
|
||||
# helper method for all versions of create_server_volume to use.
|
||||
body = {'volumeAttachment': {'volumeId': volume_id}}
|
||||
if device is not None:
|
||||
body['volumeAttachment']['device'] = device
|
||||
if tag is not None:
|
||||
body['volumeAttachment']['tag'] = tag
|
||||
if delete_on_termination:
|
||||
body['volumeAttachment']['delete_on_termination'] = (
|
||||
delete_on_termination)
|
||||
return self._create("/servers/%s/os-volume_attachments" % server_id,
|
||||
body, "volumeAttachment")
|
||||
|
||||
def update_server_volume(self, server_id, src_volid, dest_volid):
|
||||
"""
|
||||
Swaps the existing volume attachment to point to a new volume.
|
||||
|
16
releasenotes/notes/microversion-v2_79-f13bc0414743dc16.yaml
Normal file
16
releasenotes/notes/microversion-v2_79-f13bc0414743dc16.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for `microversion 2.79`_ which includes the following
|
||||
changes:
|
||||
|
||||
- The ``--delete-on-termination`` option is added to the
|
||||
``nova volume-attach`` CLI.
|
||||
- A ``DELETE ON TERMINATION`` column is added to the
|
||||
``nova volume-attachments`` table.
|
||||
- New kwarg called ``delete_on_termination`` added to the python API
|
||||
binding:
|
||||
|
||||
- ``novaclient.v2.volumes.VolumeManager.create_server_volume()``
|
||||
|
||||
.. _microversion 2.79: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id71
|
Loading…
Reference in New Issue
Block a user