Merge "Add list feature to volume v2"

This commit is contained in:
Jenkins 2015-08-07 04:56:16 +00:00 committed by Gerrit Code Review
commit 8affa0d1c3
5 changed files with 330 additions and 2 deletions

View File

@ -2,7 +2,7 @@
volume volume
====== ======
Volume v1 Volume v1, v2
volume create volume create
------------- -------------

View File

@ -15,11 +15,15 @@
import copy import copy
import mock import mock
from openstackclient.tests.compute.v2 import fakes as compute_fakes
from openstackclient.tests import fakes from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
from openstackclient.tests.image.v2 import fakes as image_fakes from openstackclient.tests.image.v2 import fakes as image_fakes
from openstackclient.tests import utils from openstackclient.tests import utils
volume_attachment_server = copy.deepcopy(compute_fakes.SERVER)
volume_attachment_server['device'] = 'device'
volume_id = "ce26708d-a7f8-4b4b-9861-4a80256615a6" volume_id = "ce26708d-a7f8-4b4b-9861-4a80256615a6"
volume_name = "fake_volume" volume_name = "fake_volume"
volume_description = "fake description" volume_description = "fake description"
@ -34,7 +38,7 @@ volume_metadata = {
volume_metadata_str = "Alpha='a', Beta='b', Gamma='g'" volume_metadata_str = "Alpha='a', Beta='b', Gamma='g'"
volume_snapshot_id = 1 volume_snapshot_id = 1
volume_availability_zone = "nova" volume_availability_zone = "nova"
volume_attachments = ["fake_attachments"] volume_attachments = [volume_attachment_server]
VOLUME = { VOLUME = {
"id": volume_id, "id": volume_id,

View File

@ -495,6 +495,220 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(datalist, data) self.assertEqual(datalist, data)
class TestVolumeList(TestVolume):
def setUp(self):
super(TestVolumeList, self).setUp()
self.volumes_mock.list.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(volume_fakes.VOLUME),
loaded=True,
),
]
self.users_mock.get.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(identity_fakes.USER),
loaded=True,
),
]
self.projects_mock.get.return_value = [
fakes.FakeResource(
None,
copy.deepcopy(identity_fakes.PROJECT),
loaded=True,
),
]
# Get the command object to test
self.cmd = volume.ListVolume(self.app, None)
def test_volume_list_no_options(self):
arglist = []
verifylist = [
('long', False),
('all_projects', False),
('name', None),
('status', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
collist = [
'ID',
'Display Name',
'Status',
'Size',
'Attached to',
]
self.assertEqual(collist, columns)
server = volume_fakes.volume_attachment_server['id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
volume_fakes.volume_status,
volume_fakes.volume_size,
msg,
), )
self.assertEqual(datalist, tuple(data))
def test_volume_list_all_projects_option(self):
arglist = [
'--all-projects',
]
verifylist = [
('long', False),
('all_projects', True),
('name', None),
('status', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
collist = [
'ID',
'Display Name',
'Status',
'Size',
'Attached to',
]
self.assertEqual(collist, columns)
server = volume_fakes.volume_attachment_server['id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
volume_fakes.volume_status,
volume_fakes.volume_size,
msg,
), )
self.assertEqual(datalist, tuple(data))
def test_volume_list_name(self):
arglist = [
'--name', volume_fakes.volume_name,
]
verifylist = [
('long', False),
('all_projects', False),
('name', volume_fakes.volume_name),
('status', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
collist = (
'ID',
'Display Name',
'Status',
'Size',
'Attached to',
)
self.assertEqual(collist, tuple(columns))
server = volume_fakes.volume_attachment_server['id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
volume_fakes.volume_status,
volume_fakes.volume_size,
msg,
), )
self.assertEqual(datalist, tuple(data))
def test_volume_list_status(self):
arglist = [
'--status', volume_fakes.volume_status,
]
verifylist = [
('long', False),
('all_projects', False),
('name', None),
('status', volume_fakes.volume_status),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
collist = (
'ID',
'Display Name',
'Status',
'Size',
'Attached to',
)
self.assertEqual(collist, tuple(columns))
server = volume_fakes.volume_attachment_server['id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
volume_fakes.volume_status,
volume_fakes.volume_size,
msg,
), )
self.assertEqual(datalist, tuple(data))
def test_volume_list_long(self):
arglist = [
'--long',
]
verifylist = [
('long', True),
('all_projects', False),
('name', None),
('status', None),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
collist = [
'ID',
'Display Name',
'Status',
'Size',
'Type',
'Bootable',
'Attached to',
'Properties',
]
self.assertEqual(collist, columns)
server = volume_fakes.volume_attachment_server['id']
device = volume_fakes.volume_attachment_server['device']
msg = 'Attached to %s on %s ' % (server, device)
datalist = ((
volume_fakes.volume_id,
volume_fakes.volume_name,
volume_fakes.volume_status,
volume_fakes.volume_size,
volume_fakes.volume_type,
'',
msg,
"Alpha='a', Beta='b', Gamma='g'",
), )
self.assertEqual(datalist, tuple(data))
class TestVolumeShow(TestVolume): class TestVolumeShow(TestVolume):
def setUp(self): def setUp(self):
super(TestVolumeShow, self).setUp() super(TestVolumeShow, self).setUp()

View File

@ -14,9 +14,12 @@
"""Volume V2 Volume action implementations""" """Volume V2 Volume action implementations"""
import copy
import logging import logging
import os
from cliff import command from cliff import command
from cliff import lister
from cliff import show from cliff import show
import six import six
@ -189,6 +192,112 @@ class DeleteVolume(command.Command):
return return
class ListVolume(lister.Lister):
"""List volumes"""
log = logging.getLogger(__name__ + '.ListVolume')
def get_parser(self, prog_name):
parser = super(ListVolume, self).get_parser(prog_name)
parser.add_argument(
'--all-projects',
action='store_true',
default=bool(int(os.environ.get("ALL_PROJECTS", 0))),
help='Include all projects (admin only)',
)
parser.add_argument(
'--long',
action='store_true',
default=False,
help='List additional fields in output',
)
parser.add_argument(
'--name',
metavar='<name>',
help='Filter results by name',
)
parser.add_argument(
'--status',
metavar='<status>',
help='Filter results by status',
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
volume_client = self.app.client_manager.volume
compute_client = self.app.client_manager.compute
def _format_attach(attachments):
"""Return a formatted string of a volume's attached instances
:param volume: a volume.attachments field
:rtype: a string of formatted instances
"""
msg = ''
for attachment in attachments:
server = attachment['id']
if server in server_cache:
server = server_cache[server].name
device = attachment['device']
msg += 'Attached to %s on %s ' % (server, device)
return msg
if parsed_args.long:
columns = [
'ID',
'Name',
'Status',
'Size',
'Volume Type',
'Bootable',
'Attachments',
'Metadata',
]
column_headers = copy.deepcopy(columns)
column_headers[1] = 'Display Name'
column_headers[4] = 'Type'
column_headers[6] = 'Attached to'
column_headers[7] = 'Properties'
else:
columns = [
'ID',
'Name',
'Status',
'Size',
'Attachments',
]
column_headers = copy.deepcopy(columns)
column_headers[1] = 'Display Name'
column_headers[4] = 'Attached to'
# Cache the server list
server_cache = {}
try:
for s in compute_client.servers.list():
server_cache[s.id] = s
except Exception:
# Just forget it if there's any trouble
pass
search_opts = {
'all_projects': parsed_args.all_projects,
'display_name': parsed_args.name,
'status': parsed_args.status,
}
data = volume_client.volumes.list(search_opts=search_opts)
return (column_headers,
(utils.get_item_properties(
s, columns,
formatters={'Metadata': utils.format_dict,
'Attachments': _format_attach},
) for s in data))
class SetVolume(show.ShowOne): class SetVolume(show.ShowOne):
"""Set volume properties""" """Set volume properties"""

View File

@ -393,6 +393,7 @@ openstack.volume.v2 =
snapshot_show = openstackclient.volume.v2.snapshot:ShowSnapshot snapshot_show = openstackclient.volume.v2.snapshot:ShowSnapshot
snapshot_unset = openstackclient.volume.v2.snapshot:UnsetSnapshot snapshot_unset = openstackclient.volume.v2.snapshot:UnsetSnapshot
volume_list = openstackclient.volume.v2.volume:ListVolume
volume_create = openstackclient.volume.v2.volume:CreateVolume volume_create = openstackclient.volume.v2.volume:CreateVolume
volume_delete = openstackclient.volume.v2.volume:DeleteVolume volume_delete = openstackclient.volume.v2.volume:DeleteVolume
volume_set = openstackclient.volume.v2.volume:SetVolume volume_set = openstackclient.volume.v2.volume:SetVolume