summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwhoami-rajat <rajatdhasmana@gmail.com>2023-02-06 23:09:03 +0530
committerwhoami-rajat <rajatdhasmana@gmail.com>2023-02-17 12:17:22 +0000
commitec01268ea93141439542fb162a6a12bc2bf533fe (patch)
tree6f73657981480a52d5cc6261c4ea07e01cefe5f9
parent73b4ce88eb3e71568cf5330d6c0a8a4e92287d89 (diff)
downloadpython-openstackclient-ec01268ea93141439542fb162a6a12bc2bf533fe.tar.gz
Add options to create volume group from source6.1.0
This patch adds ``--source-group`` and ``--group-snapshot`` options to the ``volume group create`` command to allow creating group from a source group or a group snapshot. Change-Id: I87482a5dd43c519dfdcf981635aa879914a70a5c
-rw-r--r--doc/source/cli/data/cinder.csv2
-rw-r--r--openstackclient/tests/unit/volume/v3/test_volume_group.py131
-rw-r--r--openstackclient/volume/v3/volume_group.py117
-rw-r--r--releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml6
4 files changed, 226 insertions, 30 deletions
diff --git a/doc/source/cli/data/cinder.csv b/doc/source/cli/data/cinder.csv
index d5dc42c1..84ea409e 100644
--- a/doc/source/cli/data/cinder.csv
+++ b/doc/source/cli/data/cinder.csv
@@ -45,7 +45,7 @@ freeze-host,volume host set --disable,Freeze and disable the specified cinder-vo
get-capabilities,volume backend capability show,Show capabilities of a volume backend. Admin only.
get-pools,volume backend pool list,Show pool information for backends. Admin only.
group-create,volume group create,Creates a group. (Supported by API versions 3.13 - 3.latest)
-group-create-from-src,,Creates a group from a group snapshot or a source group. (Supported by API versions 3.14 - 3.latest)
+group-create-from-src,volume group create [--source-group|--group-snapshot],Creates a group from a group snapshot or a source group. (Supported by API versions 3.14 - 3.latest)
group-delete,volume group delete,Removes one or more groups. (Supported by API versions 3.13 - 3.latest)
group-disable-replication,volume group set --disable-replication,Disables replication for group. (Supported by API versions 3.38 - 3.latest)
group-enable-replication,volume group set --enable-replication,Enables replication for group. (Supported by API versions 3.38 - 3.latest)
diff --git a/openstackclient/tests/unit/volume/v3/test_volume_group.py b/openstackclient/tests/unit/volume/v3/test_volume_group.py
index 96079a08..a8338a80 100644
--- a/openstackclient/tests/unit/volume/v3/test_volume_group.py
+++ b/openstackclient/tests/unit/volume/v3/test_volume_group.py
@@ -10,9 +10,12 @@
# License for the specific language governing permissions and limitations
# under the License.
+from unittest import mock
+
from cinderclient import api_versions
from osc_lib import exceptions
+from openstackclient.tests.unit import utils as tests_utils
from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
from openstackclient.volume.v3 import volume_group
@@ -32,6 +35,10 @@ class TestVolumeGroup(volume_fakes.TestVolume):
self.volume_types_mock = self.app.client_manager.volume.volume_types
self.volume_types_mock.reset_mock()
+ self.volume_group_snapshots_mock = \
+ self.app.client_manager.volume.group_snapshots
+ self.volume_group_snapshots_mock.reset_mock()
+
class TestVolumeGroupCreate(TestVolumeGroup):
@@ -43,6 +50,8 @@ class TestVolumeGroupCreate(TestVolumeGroup):
'volume_types': [fake_volume_type.id],
},
)
+ fake_volume_group_snapshot = \
+ volume_fakes.create_one_volume_group_snapshot()
columns = (
'ID',
@@ -79,6 +88,10 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.fake_volume_group_type
self.volume_groups_mock.create.return_value = self.fake_volume_group
self.volume_groups_mock.get.return_value = self.fake_volume_group
+ self.volume_groups_mock.create_from_src.return_value = \
+ self.fake_volume_group
+ self.volume_group_snapshots_mock.get.return_value = \
+ self.fake_volume_group_snapshot
self.cmd = volume_group.CreateVolumeGroup(self.app, None)
@@ -115,6 +128,29 @@ class TestVolumeGroupCreate(TestVolumeGroup):
self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data)
+ def test_volume_group_create_no_volume_type(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.13')
+
+ arglist = [
+ self.fake_volume_group_type.id
+ ]
+ verifylist = [
+ ('volume_group_type', self.fake_volume_group_type.id),
+ ('name', None),
+ ('description', None),
+ ('availability_zone', None),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '<volume_types> is a required argument',
+ str(exc))
+
def test_volume_group_create_with_options(self):
self.app.client_manager.volume.api_version = \
api_versions.APIVersion('3.13')
@@ -176,6 +212,101 @@ class TestVolumeGroupCreate(TestVolumeGroup):
'--os-volume-api-version 3.13 or greater is required',
str(exc))
+ def test_volume_group_create_from_source_group(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.14')
+
+ arglist = [
+ '--source-group', self.fake_volume_group.id,
+ ]
+ verifylist = [
+ ('source_group', self.fake_volume_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volume_groups_mock.get.assert_has_calls(
+ [mock.call(self.fake_volume_group.id),
+ mock.call(self.fake_volume_group.id)])
+ self.volume_groups_mock.create_from_src.assert_called_once_with(
+ None,
+ self.fake_volume_group.id,
+ None,
+ None,
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertCountEqual(self.data, data)
+
+ def test_volume_group_create_from_group_snapshot(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.14')
+
+ arglist = [
+ '--group-snapshot', self.fake_volume_group_snapshot.id,
+ ]
+ verifylist = [
+ ('group_snapshot', self.fake_volume_group_snapshot.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volume_group_snapshots_mock.get.assert_called_once_with(
+ self.fake_volume_group_snapshot.id)
+ self.volume_groups_mock.get.assert_called_once_with(
+ self.fake_volume_group.id)
+ self.volume_groups_mock.create_from_src.assert_called_once_with(
+ self.fake_volume_group_snapshot.id,
+ None,
+ None,
+ None,
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertCountEqual(self.data, data)
+
+ def test_volume_group_create_from_src_pre_v314(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.13')
+
+ arglist = [
+ '--source-group', self.fake_volume_group.id,
+ ]
+ verifylist = [
+ ('source_group', self.fake_volume_group.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ exc = self.assertRaises(
+ exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
+ self.assertIn(
+ '--os-volume-api-version 3.14 or greater is required',
+ str(exc))
+
+ def test_volume_group_create_from_src_source_group_group_snapshot(self):
+ self.app.client_manager.volume.api_version = \
+ api_versions.APIVersion('3.14')
+
+ arglist = [
+ '--source-group', self.fake_volume_group.id,
+ '--group-snapshot', self.fake_volume_group_snapshot.id,
+ ]
+ verifylist = [
+ ('source_group', self.fake_volume_group.id),
+ ('group_snapshot', self.fake_volume_group_snapshot.id),
+ ]
+
+ exc = self.assertRaises(tests_utils.ParserException,
+ self.check_parser,
+ self.cmd,
+ arglist,
+ verifylist)
+ self.assertIn(
+ '--group-snapshot: not allowed with argument --source-group',
+ str(exc))
+
class TestVolumeGroupDelete(TestVolumeGroup):
diff --git a/openstackclient/volume/v3/volume_group.py b/openstackclient/volume/v3/volume_group.py
index db4e9a94..69b18ceb 100644
--- a/openstackclient/volume/v3/volume_group.py
+++ b/openstackclient/volume/v3/volume_group.py
@@ -82,15 +82,17 @@ class CreateVolumeGroup(command.ShowOne):
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
- parser.add_argument(
+ source_parser = parser.add_mutually_exclusive_group()
+ source_parser.add_argument(
'volume_group_type',
metavar='<volume_group_type>',
+ nargs='?',
help=_('Name or ID of volume group type to use.'),
)
parser.add_argument(
'volume_types',
metavar='<volume_type>',
- nargs='+',
+ nargs='*',
default=[],
help=_('Name or ID of volume type(s) to use.'),
)
@@ -107,44 +109,101 @@ class CreateVolumeGroup(command.ShowOne):
parser.add_argument(
'--availability-zone',
metavar='<availability-zone>',
- help=_('Availability zone for volume group.'),
+ help=_('Availability zone for volume group. '
+ '(not available if creating group from source)'),
+ )
+ source_parser.add_argument(
+ '--source-group',
+ metavar='<source-group>',
+ help=_('Existing volume group (name or ID) '
+ '(supported by --os-volume-api-version 3.14 or later)'),
+ )
+ source_parser.add_argument(
+ '--group-snapshot',
+ metavar='<group-snapshot>',
+ help=_('Existing group snapshot (name or ID) '
+ '(supported by --os-volume-api-version 3.14 or later)'),
)
return parser
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
- if volume_client.api_version < api_versions.APIVersion('3.13'):
- msg = _(
- "--os-volume-api-version 3.13 or greater is required to "
- "support the 'volume group create' command"
- )
- raise exceptions.CommandError(msg)
-
- volume_group_type = utils.find_resource(
- volume_client.group_types,
- parsed_args.volume_group_type,
- )
-
- volume_types = []
- for volume_type in parsed_args.volume_types:
- volume_types.append(
- utils.find_resource(
- volume_client.volume_types,
- volume_type,
+ if parsed_args.volume_group_type:
+ if volume_client.api_version < api_versions.APIVersion('3.13'):
+ msg = _(
+ "--os-volume-api-version 3.13 or greater is required to "
+ "support the 'volume group create' command"
)
+ raise exceptions.CommandError(msg)
+ if not parsed_args.volume_types:
+ msg = _(
+ "<volume_types> is a required argument when creating a "
+ "group from group type."
+ )
+ raise exceptions.CommandError(msg)
+
+ volume_group_type = utils.find_resource(
+ volume_client.group_types,
+ parsed_args.volume_group_type,
)
+ volume_types = []
+ for volume_type in parsed_args.volume_types:
+ volume_types.append(
+ utils.find_resource(
+ volume_client.volume_types,
+ volume_type,
+ )
+ )
- group = volume_client.groups.create(
- volume_group_type.id,
- ','.join(x.id for x in volume_types),
- parsed_args.name,
- parsed_args.description,
- availability_zone=parsed_args.availability_zone)
+ group = volume_client.groups.create(
+ volume_group_type.id,
+ ','.join(x.id for x in volume_types),
+ parsed_args.name,
+ parsed_args.description,
+ availability_zone=parsed_args.availability_zone)
- group = volume_client.groups.get(group.id)
+ group = volume_client.groups.get(group.id)
+ return _format_group(group)
- return _format_group(group)
+ else:
+ if volume_client.api_version < api_versions.APIVersion('3.14'):
+ msg = _(
+ "--os-volume-api-version 3.14 or greater is required to "
+ "support the 'volume group create "
+ "[--source-group|--group-snapshot]' command"
+ )
+ raise exceptions.CommandError(msg)
+ if (parsed_args.source_group is None and
+ parsed_args.group_snapshot is None):
+ msg = _(
+ "Either --source-group <source_group> or "
+ "'--group-snapshot <group_snapshot>' needs to be "
+ "provided to run the 'volume group create "
+ "[--source-group|--group-snapshot]' command"
+ )
+ raise exceptions.CommandError(msg)
+ if parsed_args.availability_zone:
+ msg = _("'--availability-zone' option will not work "
+ "if creating group from source.")
+ LOG.warning(msg)
+
+ source_group = None
+ if parsed_args.source_group:
+ source_group = utils.find_resource(volume_client.groups,
+ parsed_args.source_group)
+ group_snapshot = None
+ if parsed_args.group_snapshot:
+ group_snapshot = utils.find_resource(
+ volume_client.group_snapshots,
+ parsed_args.group_snapshot)
+ group = volume_client.groups.create_from_src(
+ group_snapshot.id if group_snapshot else None,
+ source_group.id if source_group else None,
+ parsed_args.name,
+ parsed_args.description)
+ group = volume_client.groups.get(group.id)
+ return _format_group(group)
class DeleteVolumeGroup(command.Command):
diff --git a/releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml b/releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml
new file mode 100644
index 00000000..9a4f1cb3
--- /dev/null
+++ b/releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Added ``--source-group`` and ``--group-snapshot`` options to the
+ ``volume group create`` command to allow creating group from
+ a source group or a group snapshot.