summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/server.py41
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py172
2 files changed, 212 insertions, 1 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index fb7596a9..414abb62 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -446,6 +446,21 @@ class AddServerVolume(command.Command):
metavar='<device>',
help=_('Server internal device name for volume'),
)
+ termination_group = parser.add_mutually_exclusive_group()
+ termination_group.add_argument(
+ '--enable-delete-on-termination',
+ action='store_true',
+ help=_("Specify if the attached volume should be deleted when "
+ "the server is destroyed. (Supported with "
+ "``--os-compute-api-version`` 2.79 or greater.)"),
+ )
+ termination_group.add_argument(
+ '--disable-delete-on-termination',
+ action='store_true',
+ help=_("Specify if the attached volume should not be deleted "
+ "when the server is destroyed. (Supported with "
+ "``--os-compute-api-version`` 2.79 or greater.)"),
+ )
return parser
def take_action(self, parsed_args):
@@ -461,10 +476,34 @@ class AddServerVolume(command.Command):
parsed_args.volume,
)
+ support_set_delete_on_termination = (compute_client.api_version >=
+ api_versions.APIVersion('2.79'))
+
+ if not support_set_delete_on_termination:
+ if parsed_args.enable_delete_on_termination:
+ msg = _('--os-compute-api-version 2.79 or greater '
+ 'is required to support the '
+ '--enable-delete-on-termination option.')
+ raise exceptions.CommandError(msg)
+ if parsed_args.disable_delete_on_termination:
+ msg = _('--os-compute-api-version 2.79 or greater '
+ 'is required to support the '
+ '--disable-delete-on-termination option.')
+ raise exceptions.CommandError(msg)
+
+ kwargs = {
+ "device": parsed_args.device
+ }
+
+ if parsed_args.enable_delete_on_termination:
+ kwargs['delete_on_termination'] = True
+ if parsed_args.disable_delete_on_termination:
+ kwargs['delete_on_termination'] = False
+
compute_client.volumes.create_server_volume(
server.id,
volume.id,
- parsed_args.device,
+ **kwargs
)
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 5c98188a..c70d6d72 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -43,6 +43,10 @@ class TestServer(compute_fakes.TestComputev2):
self.servers_mock = self.app.client_manager.compute.servers
self.servers_mock.reset_mock()
+ # Get a shortcut to the compute client volumeManager Mock
+ self.servers_volumes_mock = self.app.client_manager.compute.volumes
+ self.servers_volumes_mock.reset_mock()
+
# Get a shortcut to the compute client FlavorManager Mock
self.flavors_mock = self.app.client_manager.compute.flavors
self.flavors_mock.reset_mock()
@@ -457,6 +461,174 @@ class TestServerAddPort(TestServer):
self.find_port.assert_not_called()
+class TestServerVolume(TestServer):
+
+ def setUp(self):
+ super(TestServerVolume, self).setUp()
+
+ self.volume = volume_fakes.FakeVolume.create_one_volume()
+ self.volumes_mock.get.return_value = self.volume
+
+ self.methods = {
+ 'create_server_volume': None,
+ }
+
+ # Get the command object to test
+ self.cmd = server.AddServerVolume(self.app, None)
+
+ def test_server_add_volume(self):
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ '--device', '/dev/sdb',
+ servers[0].id,
+ self.volume.id,
+ ]
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('device', '/dev/sdb'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_volumes_mock.create_server_volume.assert_called_once_with(
+ servers[0].id, self.volume.id, device='/dev/sdb')
+ self.assertIsNone(result)
+
+
+class TestServerVolumeV279(TestServerVolume):
+
+ def test_server_add_volume_with_enable_delete_on_termination(self):
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.79')
+
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ '--enable-delete-on-termination',
+ '--device', '/dev/sdb',
+ servers[0].id,
+ self.volume.id,
+ ]
+
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('device', '/dev/sdb'),
+ ('enable_delete_on_termination', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_volumes_mock.create_server_volume.assert_called_once_with(
+ servers[0].id, self.volume.id,
+ device='/dev/sdb', delete_on_termination=True)
+ self.assertIsNone(result)
+
+ def test_server_add_volume_with_disable_delete_on_termination(self):
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.79')
+
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ '--disable-delete-on-termination',
+ '--device', '/dev/sdb',
+ servers[0].id,
+ self.volume.id,
+ ]
+
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('device', '/dev/sdb'),
+ ('disable_delete_on_termination', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.servers_volumes_mock.create_server_volume.assert_called_once_with(
+ servers[0].id, self.volume.id,
+ device='/dev/sdb', delete_on_termination=False)
+ self.assertIsNone(result)
+
+ def test_server_add_volume_with_enable_delete_on_termination_pre_v279(
+ self):
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.78')
+
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ servers[0].id,
+ self.volume.id,
+ '--enable-delete-on-termination',
+ ]
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('enable_delete_on_termination', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ ex = self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn('--os-compute-api-version 2.79 or greater is required',
+ str(ex))
+
+ def test_server_add_volume_with_disable_delete_on_termination_pre_v279(
+ self):
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.78')
+
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ servers[0].id,
+ self.volume.id,
+ '--disable-delete-on-termination',
+ ]
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('disable_delete_on_termination', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ ex = self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn('--os-compute-api-version 2.79 or greater is required',
+ str(ex))
+
+ def test_server_add_volume_with_disable_and_enable_delete_on_termination(
+ self):
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.79')
+
+ servers = self.setup_servers_mock(count=1)
+ arglist = [
+ '--enable-delete-on-termination',
+ '--disable-delete-on-termination',
+ '--device', '/dev/sdb',
+ servers[0].id,
+ self.volume.id,
+ ]
+
+ verifylist = [
+ ('server', servers[0].id),
+ ('volume', self.volume.id),
+ ('device', '/dev/sdb'),
+ ('enable_delete_on_termination', True),
+ ('disable_delete_on_termination', True),
+ ]
+ ex = self.assertRaises(utils.ParserException,
+ self.check_parser,
+ self.cmd, arglist, verifylist)
+ self.assertIn('Argument parse failed', str(ex))
+
+
class TestServerAddNetwork(TestServer):
def setUp(self):