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 v1
Volume v1, v2
volume create
-------------

View File

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

View File

@ -495,6 +495,220 @@ class TestVolumeCreate(TestVolume):
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):
def setUp(self):
super(TestVolumeShow, self).setUp()

View File

@ -14,9 +14,12 @@
"""Volume V2 Volume action implementations"""
import copy
import logging
import os
from cliff import command
from cliff import lister
from cliff import show
import six
@ -189,6 +192,112 @@ class DeleteVolume(command.Command):
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):
"""Set volume properties"""

View File

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