diff --git a/doc/source/command-objects/volume-snapshot.rst b/doc/source/command-objects/volume-snapshot.rst index 37a5088a59..3cf46ad552 100644 --- a/doc/source/command-objects/volume-snapshot.rst +++ b/doc/source/command-objects/volume-snapshot.rst @@ -82,6 +82,7 @@ List volume snapshots openstack volume snapshot list [--all-projects] + [--project [--project-domain ]] [--long] [--limit ] [--marker ] @@ -93,6 +94,20 @@ List volume snapshots Include all projects (admin only) +.. option:: --project + + Filter results by project (name or ID) (admin only) + + *Volume version 2 only* + +.. option:: --project-domain + + Domain the project belongs to (name or ID). + + This can be used in case collisions between project names exist. + + *Volume version 2 only* + .. option:: --long List additional fields in output diff --git a/openstackclient/tests/unit/volume/v2/test_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py index 8ce356aea8..12d1e3906d 100644 --- a/openstackclient/tests/unit/volume/v2/test_snapshot.py +++ b/openstackclient/tests/unit/volume/v2/test_snapshot.py @@ -19,6 +19,7 @@ from mock import call from osc_lib import exceptions from osc_lib import utils +from openstackclient.tests.unit.identity.v3 import fakes as project_fakes from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import volume_snapshot @@ -32,6 +33,8 @@ class TestSnapshot(volume_fakes.TestVolume): self.snapshots_mock.reset_mock() self.volumes_mock = self.app.client_manager.volume.volumes self.volumes_mock.reset_mock() + self.project_mock = self.app.client_manager.identity.projects + self.project_mock.reset_mock() class TestSnapshotCreate(TestSnapshot): @@ -278,6 +281,7 @@ class TestSnapshotDelete(TestSnapshot): class TestSnapshotList(TestSnapshot): volume = volume_fakes.FakeVolume.create_one_volume() + project = project_fakes.FakeProject.create_one_project() snapshots = volume_fakes.FakeSnapshot.create_snapshots( attrs={'volume_id': volume.name}, count=3) @@ -321,6 +325,7 @@ class TestSnapshotList(TestSnapshot): self.volumes_mock.list.return_value = [self.volume] self.volumes_mock.get.return_value = self.volume + self.project_mock.get.return_value = self.project self.snapshots_mock.list.return_value = self.snapshots # Get the command to test self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None) @@ -341,6 +346,7 @@ class TestSnapshotList(TestSnapshot): 'all_tenants': False, 'name': None, 'status': None, + 'project_id': None, 'volume_id': None } ) @@ -351,11 +357,13 @@ class TestSnapshotList(TestSnapshot): arglist = [ "--long", "--limit", "2", + "--project", self.project.id, "--marker", self.snapshots[0].id, ] verifylist = [ ("long", True), ("limit", 2), + ("project", self.project.id), ("marker", self.snapshots[0].id), ('all_projects', False), ] @@ -367,7 +375,8 @@ class TestSnapshotList(TestSnapshot): limit=2, marker=self.snapshots[0].id, search_opts={ - 'all_tenants': False, + 'all_tenants': True, + 'project_id': self.project.id, 'name': None, 'status': None, 'volume_id': None @@ -394,6 +403,7 @@ class TestSnapshotList(TestSnapshot): 'all_tenants': True, 'name': None, 'status': None, + 'project_id': None, 'volume_id': None } ) @@ -419,6 +429,7 @@ class TestSnapshotList(TestSnapshot): 'all_tenants': False, 'name': self.snapshots[0].name, 'status': None, + 'project_id': None, 'volume_id': None } ) @@ -444,6 +455,7 @@ class TestSnapshotList(TestSnapshot): 'all_tenants': False, 'name': None, 'status': self.snapshots[0].status, + 'project_id': None, 'volume_id': None } ) @@ -469,6 +481,7 @@ class TestSnapshotList(TestSnapshot): 'all_tenants': False, 'name': None, 'status': None, + 'project_id': None, 'volume_id': self.volume.id } ) diff --git a/openstackclient/volume/v2/volume_snapshot.py b/openstackclient/volume/v2/volume_snapshot.py index af29b777dc..3283bb5355 100644 --- a/openstackclient/volume/v2/volume_snapshot.py +++ b/openstackclient/volume/v2/volume_snapshot.py @@ -24,6 +24,7 @@ from osc_lib import utils import six from openstackclient.i18n import _ +from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) @@ -165,6 +166,12 @@ class ListVolumeSnapshot(command.Lister): default=False, help=_('Include all projects (admin only)'), ) + parser.add_argument( + '--project', + metavar='', + help=_('Filter results by project (name or ID) (admin only)') + ) + identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( '--long', action='store_true', @@ -208,6 +215,7 @@ class ListVolumeSnapshot(command.Lister): def take_action(self, parsed_args): volume_client = self.app.client_manager.volume + identity_client = self.app.client_manager.identity def _format_volume_id(volume_id): """Return a volume name if available @@ -245,8 +253,20 @@ class ListVolumeSnapshot(command.Lister): volume_id = utils.find_resource( volume_client.volumes, parsed_args.volume).id + project_id = None + if parsed_args.project: + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain).id + + # set value of 'all_tenants' when using project option + all_projects = True if parsed_args.project else \ + parsed_args.all_projects + search_opts = { - 'all_tenants': parsed_args.all_projects, + 'all_tenants': all_projects, + 'project_id': project_id, 'name': parsed_args.name, 'status': parsed_args.status, 'volume_id': volume_id, diff --git a/releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml b/releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml new file mode 100644 index 0000000000..6cedb545f1 --- /dev/null +++ b/releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--project`` and ``--project-domain`` option to + ``volume snapshot list`` command, in order to filter list result + by different project.