From 79577681d88e4851d4d32482e80d43ed9aa0f521 Mon Sep 17 00:00:00 2001 From: Mohammed Naser Date: Tue, 20 Mar 2018 11:31:50 -0400 Subject: [PATCH] Add support to list image members The OpenStack client presently has support to add or remove members from an image, but no way to list image members. This patch addreses this issue. Change-Id: Ie85c5de23c6beb21fd6b4c04c83ddf2a116606ef --- doc/source/cli/command-objects/image.rst | 16 +++++++ doc/source/cli/commands.rst | 1 + openstackclient/image/v2/image.py | 33 +++++++++++++ .../tests/unit/image/v2/test_image.py | 46 +++++++++++++++++++ ...dd-image-member-list-1630ead5988348c2.yaml | 4 ++ setup.cfg | 1 + 6 files changed, 101 insertions(+) create mode 100644 releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml diff --git a/doc/source/cli/command-objects/image.rst b/doc/source/cli/command-objects/image.rst index e2257bbbba..f0b5bfaade 100644 --- a/doc/source/cli/command-objects/image.rst +++ b/doc/source/cli/command-objects/image.rst @@ -266,6 +266,22 @@ List available images *Image version 2 only* +image member list +----------------- + +List projects associated with image + +.. program:: image member list +.. code:: bash + + openstack image member list + + +.. _image_member_list-image: +.. describe:: + + Image(s) to view members for (name or ID) + image remove project -------------------- diff --git a/doc/source/cli/commands.rst b/doc/source/cli/commands.rst index d840549c3f..76126a7475 100644 --- a/doc/source/cli/commands.rst +++ b/doc/source/cli/commands.rst @@ -104,6 +104,7 @@ referring to both Compute and Volume quotas. * ``hypervisor stats``: (**Compute**) hypervisor statistics over all compute nodes * ``identity provider``: (**Identity**) a source of users and authentication * ``image``: (**Image**) a disk image +* ``image member``: (**Image**) a project that is a member of an Image * ``ip availability``: (**Network**) - details of IP usage of a network * ``ip fixed``: (**Compute**, **Network**) - an internal IP address assigned to a server * ``ip floating``: (**Compute**, **Network**) - a public IP address that can be mapped to a server diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py index 7e6a7aa178..9407e665d2 100644 --- a/openstackclient/image/v2/image.py +++ b/openstackclient/image/v2/image.py @@ -592,6 +592,39 @@ class ListImage(command.Lister): ) +class ListImageProjects(command.Lister): + _description = _("List projects associated with image") + + def get_parser(self, prog_name): + parser = super(ListImageProjects, self).get_parser(prog_name) + parser.add_argument( + "image", + metavar="", + help=_("Image (name or ID)"), + ) + common.add_project_domain_option_to_parser(parser) + return parser + + def take_action(self, parsed_args): + image_client = self.app.client_manager.image + columns = ( + "Image ID", + "Member ID", + "Status" + ) + + image_id = utils.find_resource( + image_client.images, + parsed_args.image).id + + data = image_client.image_members.list(image_id) + + return (columns, + (utils.get_item_properties( + s, columns, + ) for s in data)) + + class RemoveProjectImage(command.Command): _description = _("Disassociate project with image") diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py index e1a79d13ce..301cd0377e 100644 --- a/openstackclient/tests/unit/image/v2/test_image.py +++ b/openstackclient/tests/unit/image/v2/test_image.py @@ -780,6 +780,52 @@ class TestImageList(TestImage): ) +class TestListImageProjects(TestImage): + + project = identity_fakes.FakeProject.create_one_project() + _image = image_fakes.FakeImage.create_one_image() + member = image_fakes.FakeImage.create_one_image_member( + attrs={'image_id': _image.id, + 'member_id': project.id} + ) + + columns = ( + "Image ID", + "Member ID", + "Status" + ) + + datalist = (( + _image.id, + member.member_id, + member.status, + )) + + def setUp(self): + super(TestListImageProjects, self).setUp() + + self.images_mock.get.return_value = self._image + self.image_members_mock.list.return_value = self.datalist + + self.cmd = image.ListImageProjects(self.app, None) + + def test_image_member_list(self): + arglist = [ + self._image.id + ] + verifylist = [ + ('image', self._image.id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.image_members_mock.list.assert_called_with(self._image.id) + + self.assertEqual(self.columns, columns) + self.assertEqual(len(self.datalist), len(tuple(data))) + + class TestRemoveProjectImage(TestImage): project = identity_fakes.FakeProject.create_one_project() diff --git a/releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml b/releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml new file mode 100644 index 0000000000..f939a2fd86 --- /dev/null +++ b/releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml @@ -0,0 +1,4 @@ +--- +features: + - The OpenStack client now has the ability to list all members of an image + in order to faciliate management of member projects for images. diff --git a/setup.cfg b/setup.cfg index b031cc5f6c..a78dc31b71 100644 --- a/setup.cfg +++ b/setup.cfg @@ -353,6 +353,7 @@ openstack.image.v2 = image_create = openstackclient.image.v2.image:CreateImage image_delete = openstackclient.image.v2.image:DeleteImage image_list = openstackclient.image.v2.image:ListImage + image_member_list = openstackclient.image.v2.image:ListImageProjects image_remove_project = openstackclient.image.v2.image:RemoveProjectImage image_save = openstackclient.image.v2.image:SaveImage image_show = openstackclient.image.v2.image:ShowImage