Merge "Allow specifying a set of fields of the Port and Chasis resources"
This commit is contained in:
commit
66f83811a7
@ -167,10 +167,9 @@ def common_params_for_list(args, fields, field_labels):
|
||||
|
||||
params['detail'] = args.detail
|
||||
|
||||
if hasattr(args, 'fields'):
|
||||
requested_fields = args.fields[0] if args.fields else None
|
||||
if requested_fields is not None:
|
||||
params['fields'] = requested_fields
|
||||
requested_fields = args.fields[0] if args.fields else None
|
||||
if requested_fields is not None:
|
||||
params['fields'] = requested_fields
|
||||
|
||||
return params
|
||||
|
||||
@ -299,7 +298,9 @@ def check_for_invalid_fields(fields, valid_fields):
|
||||
if not fields:
|
||||
return
|
||||
|
||||
invalid_attr = set(fields) - set(valid_fields)
|
||||
if invalid_attr:
|
||||
raise exc.CommandError(_('Invalid field(s): %s') %
|
||||
', '.join(invalid_attr))
|
||||
invalid_fields = set(fields) - set(valid_fields)
|
||||
if invalid_fields:
|
||||
raise exc.CommandError(
|
||||
_('Invalid field(s) requested: %(invalid)s. Valid fields '
|
||||
'are: %(valid)s.') % {'invalid': ', '.join(invalid_fields),
|
||||
'valid': ', '.join(valid_fields)})
|
||||
|
@ -126,7 +126,8 @@ class CommonParamsForListTest(test_utils.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(CommonParamsForListTest, self).setUp()
|
||||
self.args = mock.Mock(marker=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False, spec=True)
|
||||
sort_dir=None, detail=False, fields=None,
|
||||
spec=True)
|
||||
self.expected_params = {'detail': False}
|
||||
|
||||
def test_nothing_set(self):
|
||||
|
@ -18,6 +18,7 @@ import copy
|
||||
import testtools
|
||||
from testtools.matchers import HasLength
|
||||
|
||||
from ironicclient import exc
|
||||
from ironicclient.tests.unit import utils
|
||||
import ironicclient.v1.chassis
|
||||
|
||||
@ -67,6 +68,13 @@ fake_responses = {
|
||||
{"chassis": [CHASSIS]},
|
||||
),
|
||||
},
|
||||
'/v1/chassis/?fields=uuid,extra':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{"chassis": [CHASSIS]},
|
||||
),
|
||||
},
|
||||
'/v1/chassis/%s' % CHASSIS['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
@ -82,6 +90,13 @@ fake_responses = {
|
||||
UPDATED_CHASSIS,
|
||||
),
|
||||
},
|
||||
'/v1/chassis/%s?fields=uuid,description' % CHASSIS['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
CHASSIS,
|
||||
),
|
||||
},
|
||||
'/v1/chassis/%s/nodes' % CHASSIS['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
@ -96,6 +111,13 @@ fake_responses = {
|
||||
{"nodes": [NODE]},
|
||||
),
|
||||
},
|
||||
'/v1/chassis/%s/nodes?fields=uuid,extra' % CHASSIS['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{"nodes": [NODE]},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
fake_responses_pagination = {
|
||||
@ -243,6 +265,18 @@ class ChassisManagerTest(testtools.TestCase):
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(1, len(chassis))
|
||||
|
||||
def test_chassis_list_fields(self):
|
||||
nodes = self.mgr.list(fields=['uuid', 'extra'])
|
||||
expect = [
|
||||
('GET', '/v1/chassis/?fields=uuid,extra', {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(1, len(nodes))
|
||||
|
||||
def test_chassis_list_detail_and_fields_fail(self):
|
||||
self.assertRaises(exc.InvalidAttribute, self.mgr.list,
|
||||
detail=True, fields=['uuid', 'extra'])
|
||||
|
||||
def test_chassis_show(self):
|
||||
chassis = self.mgr.get(CHASSIS['uuid'])
|
||||
expect = [
|
||||
@ -252,6 +286,16 @@ class ChassisManagerTest(testtools.TestCase):
|
||||
self.assertEqual(CHASSIS['uuid'], chassis.uuid)
|
||||
self.assertEqual(CHASSIS['description'], chassis.description)
|
||||
|
||||
def test_chassis_show_fields(self):
|
||||
chassis = self.mgr.get(CHASSIS['uuid'], fields=['uuid', 'description'])
|
||||
expect = [
|
||||
('GET', '/v1/chassis/%s?fields=uuid,description' %
|
||||
CHASSIS['uuid'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(CHASSIS['uuid'], chassis.uuid)
|
||||
self.assertEqual(CHASSIS['description'], chassis.description)
|
||||
|
||||
def test_create(self):
|
||||
chassis = self.mgr.create(**CREATE_CHASSIS)
|
||||
expect = [
|
||||
@ -297,6 +341,20 @@ class ChassisManagerTest(testtools.TestCase):
|
||||
self.assertEqual(1, len(nodes))
|
||||
self.assertEqual(NODE['uuid'], nodes[0].uuid)
|
||||
|
||||
def test_chassis_node_list_fields(self):
|
||||
nodes = self.mgr.list_nodes(CHASSIS['uuid'], fields=['uuid', 'extra'])
|
||||
expect = [
|
||||
('GET', '/v1/chassis/%s/nodes?fields=uuid,extra' %
|
||||
CHASSIS['uuid'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(1, len(nodes))
|
||||
|
||||
def test_chassis_node_list_detail_and_fields_fail(self):
|
||||
self.assertRaises(exc.InvalidAttribute, self.mgr.list_nodes,
|
||||
CHASSIS['uuid'], detail=True,
|
||||
fields=['uuid', 'extra'])
|
||||
|
||||
def test_chassis_node_list_limit(self):
|
||||
self.api = utils.FakeAPI(fake_responses_pagination)
|
||||
self.mgr = ironicclient.v1.chassis.ChassisManager(self.api)
|
||||
|
@ -22,7 +22,8 @@ import ironicclient.v1.chassis_shell as c_shell
|
||||
|
||||
class ChassisShellTest(utils.BaseTestCase):
|
||||
def _get_client_mock_args(self, chassis=None, marker=None, limit=None,
|
||||
sort_dir=None, sort_key=None, detail=False):
|
||||
sort_dir=None, sort_key=None, detail=False,
|
||||
fields=None):
|
||||
args = mock.MagicMock(spec=True)
|
||||
args.chassis = chassis
|
||||
args.marker = marker
|
||||
@ -30,6 +31,7 @@ class ChassisShellTest(utils.BaseTestCase):
|
||||
args.sort_dir = sort_dir
|
||||
args.sort_key = sort_key
|
||||
args.detail = detail
|
||||
args.fields = fields
|
||||
|
||||
return args
|
||||
|
||||
@ -59,6 +61,24 @@ class ChassisShellTest(utils.BaseTestCase):
|
||||
c_shell.do_chassis_show,
|
||||
client_mock, args)
|
||||
|
||||
def test_do_chassis_show_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = mock.MagicMock()
|
||||
args.chassis = 'chassis_uuid'
|
||||
args.fields = [['uuid', 'description']]
|
||||
c_shell.do_chassis_show(client_mock, args)
|
||||
client_mock.chassis.get.assert_called_once_with(
|
||||
'chassis_uuid', fields=['uuid', 'description'])
|
||||
|
||||
def test_do_chassis_show_invalid_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = mock.MagicMock()
|
||||
args.chassis = 'chassis_uuid'
|
||||
args.fields = [['foo', 'bar']]
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
c_shell.do_chassis_show,
|
||||
client_mock, args)
|
||||
|
||||
def test_do_chassis_list(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = self._get_client_mock_args()
|
||||
@ -111,6 +131,20 @@ class ChassisShellTest(utils.BaseTestCase):
|
||||
client_mock, args)
|
||||
self.assertFalse(client_mock.chassis.list.called)
|
||||
|
||||
def test_do_chassis_list_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = self._get_client_mock_args(fields=[['uuid', 'description']])
|
||||
c_shell.do_chassis_list(client_mock, args)
|
||||
client_mock.chassis.list.assert_called_once_with(
|
||||
fields=['uuid', 'description'], detail=False)
|
||||
|
||||
def test_do_chassis_list_invalid_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = self._get_client_mock_args(fields=[['foo', 'bar']])
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
c_shell.do_chassis_list,
|
||||
client_mock, args)
|
||||
|
||||
def test_do_chassis_node_list(self):
|
||||
client_mock = mock.MagicMock()
|
||||
chassis_mock = mock.MagicMock(spec_set=[])
|
||||
@ -128,3 +162,20 @@ class ChassisShellTest(utils.BaseTestCase):
|
||||
c_shell.do_chassis_node_list(client_mock, args)
|
||||
client_mock.chassis.list_nodes.assert_called_once_with(
|
||||
chassis_mock, detail=True)
|
||||
|
||||
def test_do_chassis_node_list_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
chassis_mock = mock.MagicMock(spec_set=[])
|
||||
args = self._get_client_mock_args(chassis=chassis_mock,
|
||||
fields=[['uuid', 'power_state']])
|
||||
c_shell.do_chassis_node_list(client_mock, args)
|
||||
client_mock.chassis.list_nodes.assert_called_once_with(
|
||||
chassis_mock, fields=['uuid', 'power_state'], detail=False)
|
||||
|
||||
def test_do_chassis_node_list_invalid_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
chassis_mock = mock.MagicMock(spec_set=[])
|
||||
args = self._get_client_mock_args(chassis=chassis_mock,
|
||||
fields=[['foo', 'bar']])
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
c_shell.do_chassis_node_list, client_mock, args)
|
||||
|
@ -18,6 +18,7 @@ import copy
|
||||
import testtools
|
||||
from testtools.matchers import HasLength
|
||||
|
||||
from ironicclient import exc
|
||||
from ironicclient.tests.unit import utils
|
||||
import ironicclient.v1.port
|
||||
|
||||
@ -60,6 +61,13 @@ fake_responses = {
|
||||
{"ports": [PORT]},
|
||||
),
|
||||
},
|
||||
'/v1/ports/?fields=uuid,address':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{"ports": [PORT]},
|
||||
),
|
||||
},
|
||||
'/v1/ports/%s' % PORT['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
@ -75,6 +83,13 @@ fake_responses = {
|
||||
UPDATED_PORT,
|
||||
),
|
||||
},
|
||||
'/v1/ports/%s?fields=uuid,address' % PORT['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
PORT,
|
||||
),
|
||||
},
|
||||
'/v1/ports/detail?address=%s' % PORT['address']:
|
||||
{
|
||||
'GET': (
|
||||
@ -173,6 +188,18 @@ class PortManagerTest(testtools.TestCase):
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(1, len(ports))
|
||||
|
||||
def test_port_list_fields(self):
|
||||
ports = self.mgr.list(fields=['uuid', 'address'])
|
||||
expect = [
|
||||
('GET', '/v1/ports/?fields=uuid,address', {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(1, len(ports))
|
||||
|
||||
def test_port_list_detail_and_fields_fail(self):
|
||||
self.assertRaises(exc.InvalidAttribute, self.mgr.list,
|
||||
detail=True, fields=['uuid', 'address'])
|
||||
|
||||
def test_ports_list_limit(self):
|
||||
self.api = utils.FakeAPI(fake_responses_pagination)
|
||||
self.mgr = ironicclient.v1.port.PortManager(self.api)
|
||||
@ -245,6 +272,16 @@ class PortManagerTest(testtools.TestCase):
|
||||
self.assertEqual(PORT['address'], port.address)
|
||||
self.assertEqual(PORT['node_uuid'], port.node_uuid)
|
||||
|
||||
def test_port_show_fields(self):
|
||||
port = self.mgr.get(PORT['uuid'], fields=['uuid', 'address'])
|
||||
expect = [
|
||||
('GET', '/v1/ports/%s?fields=uuid,address' %
|
||||
PORT['uuid'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(PORT['uuid'], port.uuid)
|
||||
self.assertEqual(PORT['address'], port.address)
|
||||
|
||||
def test_create(self):
|
||||
port = self.mgr.create(**CREATE_PORT)
|
||||
expect = [
|
||||
|
@ -39,9 +39,10 @@ class PortShellTest(utils.BaseTestCase):
|
||||
args = mock.MagicMock()
|
||||
args.port = 'port_uuid'
|
||||
args.address = False
|
||||
args.fields = None
|
||||
|
||||
p_shell.do_port_show(client_mock, args)
|
||||
client_mock.port.get.assert_called_once_with('port_uuid')
|
||||
client_mock.port.get.assert_called_once_with('port_uuid', fields=None)
|
||||
# assert get_by_address() wasn't called
|
||||
self.assertFalse(client_mock.port.get_by_address.called)
|
||||
|
||||
@ -68,12 +69,34 @@ class PortShellTest(utils.BaseTestCase):
|
||||
args = mock.MagicMock()
|
||||
args.port = 'port_address'
|
||||
args.address = True
|
||||
args.fields = None
|
||||
|
||||
p_shell.do_port_show(client_mock, args)
|
||||
client_mock.port.get_by_address.assert_called_once_with('port_address')
|
||||
client_mock.port.get_by_address.assert_called_once_with('port_address',
|
||||
fields=None)
|
||||
# assert get() wasn't called
|
||||
self.assertFalse(client_mock.port.get.called)
|
||||
|
||||
def test_do_port_show_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = mock.MagicMock()
|
||||
args.port = 'port_uuid'
|
||||
args.address = False
|
||||
args.fields = [['uuid', 'address']]
|
||||
p_shell.do_port_show(client_mock, args)
|
||||
client_mock.port.get.assert_called_once_with(
|
||||
'port_uuid', fields=['uuid', 'address'])
|
||||
|
||||
def test_do_port_show_invalid_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = mock.MagicMock()
|
||||
args.port = 'port_uuid'
|
||||
args.address = False
|
||||
args.fields = [['foo', 'bar']]
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
p_shell.do_port_show,
|
||||
client_mock, args)
|
||||
|
||||
def test_do_port_update(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = mock.MagicMock()
|
||||
@ -86,7 +109,8 @@ class PortShellTest(utils.BaseTestCase):
|
||||
client_mock.port.update.assert_called_once_with('port_uuid', patch)
|
||||
|
||||
def _get_client_mock_args(self, address=None, marker=None, limit=None,
|
||||
sort_dir=None, sort_key=None, detail=False):
|
||||
sort_dir=None, sort_key=None, detail=False,
|
||||
fields=None):
|
||||
args = mock.MagicMock(spec=True)
|
||||
args.address = address
|
||||
args.marker = marker
|
||||
@ -94,6 +118,7 @@ class PortShellTest(utils.BaseTestCase):
|
||||
args.sort_dir = sort_dir
|
||||
args.sort_key = sort_key
|
||||
args.detail = detail
|
||||
args.fields = fields
|
||||
|
||||
return args
|
||||
|
||||
@ -148,3 +173,18 @@ class PortShellTest(utils.BaseTestCase):
|
||||
p_shell.do_port_list,
|
||||
client_mock, args)
|
||||
self.assertFalse(client_mock.port.list.called)
|
||||
|
||||
def test_do_port_list_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = self._get_client_mock_args(fields=[['uuid', 'address']])
|
||||
|
||||
p_shell.do_port_list(client_mock, args)
|
||||
client_mock.port.list.assert_called_once_with(
|
||||
fields=['uuid', 'address'], detail=False)
|
||||
|
||||
def test_do_port_list_invalid_fields(self):
|
||||
client_mock = mock.MagicMock()
|
||||
args = self._get_client_mock_args(fields=[['foo', 'bar']])
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
p_shell.do_port_list,
|
||||
client_mock, args)
|
||||
|
@ -15,6 +15,7 @@
|
||||
# under the License.
|
||||
|
||||
from ironicclient.common import base
|
||||
from ironicclient.common.i18n import _
|
||||
from ironicclient.common import utils
|
||||
from ironicclient import exc
|
||||
|
||||
@ -35,7 +36,7 @@ class ChassisManager(base.Manager):
|
||||
return '/v1/chassis/%s' % id if id else '/v1/chassis'
|
||||
|
||||
def list(self, marker=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
sort_dir=None, detail=False, fields=None):
|
||||
"""Retrieve a list of chassis.
|
||||
|
||||
:param marker: Optional, the UUID of a chassis, eg the last
|
||||
@ -58,13 +59,22 @@ class ChassisManager(base.Manager):
|
||||
:param detail: Optional, boolean whether to return detailed information
|
||||
about chassis.
|
||||
|
||||
:param fields: Optional, a list with a specified set of fields
|
||||
of the resource to be returned. Can not be used
|
||||
when 'detail' is set.
|
||||
|
||||
:returns: A list of chassis.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
if detail and fields:
|
||||
raise exc.InvalidAttribute(_("Can't fetch a subset of fields "
|
||||
"with 'detail' set"))
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir,
|
||||
fields)
|
||||
|
||||
path = ''
|
||||
if detail:
|
||||
@ -79,7 +89,7 @@ class ChassisManager(base.Manager):
|
||||
limit=limit)
|
||||
|
||||
def list_nodes(self, chassis_id, marker=None, limit=None,
|
||||
sort_key=None, sort_dir=None, detail=False):
|
||||
sort_key=None, sort_dir=None, detail=False, fields=None):
|
||||
"""List all the nodes for a given chassis.
|
||||
|
||||
:param chassis_id: The UUID of the chassis.
|
||||
@ -103,13 +113,22 @@ class ChassisManager(base.Manager):
|
||||
:param detail: Optional, boolean whether to return detailed information
|
||||
about nodes.
|
||||
|
||||
:param fields: Optional, a list with a specified set of fields
|
||||
of the resource to be returned. Can not be used
|
||||
when 'detail' is set.
|
||||
|
||||
:returns: A list of nodes.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
if detail and fields:
|
||||
raise exc.InvalidAttribute(_("Can't fetch a subset of fields "
|
||||
"with 'detail' set"))
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir,
|
||||
fields)
|
||||
|
||||
path = "%s/nodes" % chassis_id
|
||||
if detail:
|
||||
@ -124,7 +143,11 @@ class ChassisManager(base.Manager):
|
||||
return self._list_pagination(self._path(path), "nodes",
|
||||
limit=limit)
|
||||
|
||||
def get(self, chassis_id):
|
||||
def get(self, chassis_id, fields=None):
|
||||
if fields is not None:
|
||||
chassis_id = '%s?fields=' % chassis_id
|
||||
chassis_id += ','.join(fields)
|
||||
|
||||
try:
|
||||
return self._list(self._path(chassis_id))[0]
|
||||
except IndexError:
|
||||
|
@ -18,18 +18,32 @@ from ironicclient.openstack.common import cliutils
|
||||
from ironicclient.v1 import resource_fields as res_fields
|
||||
|
||||
|
||||
def _print_chassis_show(chassis):
|
||||
fields = ['uuid', 'description', 'created_at', 'updated_at', 'extra']
|
||||
def _print_chassis_show(chassis, fields=None):
|
||||
if fields is None:
|
||||
fields = res_fields.CHASSIS_DETAILED_RESOURCE.fields
|
||||
|
||||
data = dict([(f, getattr(chassis, f, '')) for f in fields])
|
||||
cliutils.print_dict(data, wrap=72)
|
||||
|
||||
|
||||
@cliutils.arg('chassis', metavar='<chassis>', help="UUID of the chassis.")
|
||||
@cliutils.arg(
|
||||
'--fields',
|
||||
nargs='+',
|
||||
dest='fields',
|
||||
metavar='<field>',
|
||||
action='append',
|
||||
default=[],
|
||||
help="One or more chassis fields. Only these fields will be fetched from "
|
||||
"the server.")
|
||||
def do_chassis_show(cc, args):
|
||||
"""Show detailed information about a chassis."""
|
||||
utils.check_empty_arg(args.chassis, '<chassis>')
|
||||
chassis = cc.chassis.get(args.chassis)
|
||||
_print_chassis_show(chassis)
|
||||
fields = args.fields[0] if args.fields else None
|
||||
utils.check_for_invalid_fields(
|
||||
fields, res_fields.CHASSIS_DETAILED_RESOURCE.fields)
|
||||
chassis = cc.chassis.get(args.chassis, fields=fields)
|
||||
_print_chassis_show(chassis, fields=fields)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
@ -60,6 +74,15 @@ def do_chassis_show(cc, args):
|
||||
metavar='<direction>',
|
||||
choices=['asc', 'desc'],
|
||||
help='Sort direction: "asc" (the default) or "desc".')
|
||||
@cliutils.arg(
|
||||
'--fields',
|
||||
nargs='+',
|
||||
dest='fields',
|
||||
metavar='<field>',
|
||||
action='append',
|
||||
default=[],
|
||||
help="One or more chassis fields. Only these fields will be fetched from "
|
||||
"the server. Can not be used when '--detail' is specified.")
|
||||
def do_chassis_list(cc, args):
|
||||
"""List the chassis."""
|
||||
if args.detail:
|
||||
@ -67,6 +90,14 @@ def do_chassis_list(cc, args):
|
||||
field_labels = res_fields.CHASSIS_DETAILED_RESOURCE.labels
|
||||
sort_fields = res_fields.CHASSIS_DETAILED_RESOURCE.sort_fields
|
||||
sort_field_labels = res_fields.CHASSIS_DETAILED_RESOURCE.sort_labels
|
||||
elif args.fields:
|
||||
utils.check_for_invalid_fields(
|
||||
args.fields[0], res_fields.CHASSIS_DETAILED_RESOURCE.fields)
|
||||
resource = res_fields.Resource(args.fields[0])
|
||||
fields = resource.fields
|
||||
field_labels = resource.labels
|
||||
sort_fields = res_fields.CHASSIS_DETAILED_RESOURCE.sort_fields
|
||||
sort_field_labels = res_fields.CHASSIS_DETAILED_RESOURCE.sort_labels
|
||||
else:
|
||||
fields = res_fields.CHASSIS_RESOURCE.fields
|
||||
field_labels = res_fields.CHASSIS_RESOURCE.labels
|
||||
@ -166,11 +197,26 @@ def do_chassis_update(cc, args):
|
||||
choices=['asc', 'desc'],
|
||||
help='Sort direction: "asc" (the default) or "desc".')
|
||||
@cliutils.arg('chassis', metavar='<chassis>', help="UUID of the chassis.")
|
||||
@cliutils.arg(
|
||||
'--fields',
|
||||
nargs='+',
|
||||
dest='fields',
|
||||
metavar='<field>',
|
||||
action='append',
|
||||
default=[],
|
||||
help="One or more node fields. Only these fields will be fetched from "
|
||||
"the server. Can not be used when '--detail' is specified.")
|
||||
def do_chassis_node_list(cc, args):
|
||||
"""List the nodes contained in a chassis."""
|
||||
if args.detail:
|
||||
fields = res_fields.NODE_DETAILED_RESOURCE.fields
|
||||
field_labels = res_fields.NODE_DETAILED_RESOURCE.labels
|
||||
elif args.fields:
|
||||
utils.check_for_invalid_fields(
|
||||
args.fields[0], res_fields.NODE_DETAILED_RESOURCE.fields)
|
||||
resource = res_fields.Resource(args.fields[0])
|
||||
fields = resource.fields
|
||||
field_labels = resource.labels
|
||||
else:
|
||||
fields = res_fields.NODE_RESOURCE.fields
|
||||
field_labels = res_fields.NODE_RESOURCE.labels
|
||||
|
@ -15,6 +15,7 @@
|
||||
# under the License.
|
||||
|
||||
from ironicclient.common import base
|
||||
from ironicclient.common.i18n import _
|
||||
from ironicclient.common import utils
|
||||
from ironicclient import exc
|
||||
|
||||
@ -34,7 +35,7 @@ class PortManager(base.Manager):
|
||||
return '/v1/ports/%s' % id if id else '/v1/ports'
|
||||
|
||||
def list(self, address=None, limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
sort_dir=None, detail=False, fields=None):
|
||||
"""Retrieve a list of port.
|
||||
|
||||
:param address: Optional, MAC address of a port, to get
|
||||
@ -59,13 +60,22 @@ class PortManager(base.Manager):
|
||||
:param detail: Optional, boolean whether to return detailed information
|
||||
about ports.
|
||||
|
||||
:param fields: Optional, a list with a specified set of fields
|
||||
of the resource to be returned. Can not be used
|
||||
when 'detail' is set.
|
||||
|
||||
:returns: A list of ports.
|
||||
|
||||
"""
|
||||
if limit is not None:
|
||||
limit = int(limit)
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir)
|
||||
if detail and fields:
|
||||
raise exc.InvalidAttribute(_("Can't fetch a subset of fields "
|
||||
"with 'detail' set"))
|
||||
|
||||
filters = utils.common_filters(marker, limit, sort_key, sort_dir,
|
||||
fields)
|
||||
if address is not None:
|
||||
filters.append('address=%s' % address)
|
||||
|
||||
@ -81,14 +91,23 @@ class PortManager(base.Manager):
|
||||
return self._list_pagination(self._path(path), "ports",
|
||||
limit=limit)
|
||||
|
||||
def get(self, port_id):
|
||||
def get(self, port_id, fields=None):
|
||||
if fields is not None:
|
||||
port_id = '%s?fields=' % port_id
|
||||
port_id += ','.join(fields)
|
||||
|
||||
try:
|
||||
return self._list(self._path(port_id))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def get_by_address(self, address):
|
||||
path = "detail?address=%s" % address
|
||||
def get_by_address(self, address, fields=None):
|
||||
path = '?address=%s' % address
|
||||
if fields is not None:
|
||||
path += '&fields=' + ','.join(fields)
|
||||
else:
|
||||
path = 'detail' + path
|
||||
|
||||
ports = self._list(self._path(path), 'ports')
|
||||
# get all the details of the port assuming that filtering by
|
||||
# address returns a collection of one port if successful.
|
||||
|
@ -18,9 +18,10 @@ from ironicclient.openstack.common import cliutils
|
||||
from ironicclient.v1 import resource_fields as res_fields
|
||||
|
||||
|
||||
def _print_port_show(port):
|
||||
fields = ['address', 'created_at', 'extra', 'node_uuid', 'updated_at',
|
||||
'uuid']
|
||||
def _print_port_show(port, fields=None):
|
||||
if fields is None:
|
||||
fields = res_fields.PORT_DETAILED_RESOURCE.fields
|
||||
|
||||
data = dict([(f, getattr(port, f, '')) for f in fields])
|
||||
cliutils.print_dict(data, wrap=72)
|
||||
|
||||
@ -35,14 +36,26 @@ def _print_port_show(port):
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='<id> is the MAC address (instead of the UUID) of the port.')
|
||||
@cliutils.arg(
|
||||
'--fields',
|
||||
nargs='+',
|
||||
dest='fields',
|
||||
metavar='<field>',
|
||||
action='append',
|
||||
default=[],
|
||||
help="One or more port fields. Only these fields will be fetched from "
|
||||
"the server.")
|
||||
def do_port_show(cc, args):
|
||||
"""Show detailed information about a port."""
|
||||
fields = args.fields[0] if args.fields else None
|
||||
utils.check_for_invalid_fields(
|
||||
fields, res_fields.PORT_DETAILED_RESOURCE.fields)
|
||||
if args.address:
|
||||
port = cc.port.get_by_address(args.port)
|
||||
port = cc.port.get_by_address(args.port, fields=fields)
|
||||
else:
|
||||
utils.check_empty_arg(args.port, '<id>')
|
||||
port = cc.port.get(args.port)
|
||||
_print_port_show(port)
|
||||
port = cc.port.get(args.port, fields=fields)
|
||||
_print_port_show(port, fields=fields)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
@ -76,6 +89,15 @@ def do_port_show(cc, args):
|
||||
metavar='<direction>',
|
||||
choices=['asc', 'desc'],
|
||||
help='Sort direction: "asc" (the default) or "desc".')
|
||||
@cliutils.arg(
|
||||
'--fields',
|
||||
nargs='+',
|
||||
dest='fields',
|
||||
metavar='<field>',
|
||||
action='append',
|
||||
default=[],
|
||||
help="One or more port fields. Only these fields will be fetched from "
|
||||
"the server. Can not be used when '--detail' is specified.")
|
||||
def do_port_list(cc, args):
|
||||
"""List the ports."""
|
||||
params = {}
|
||||
@ -88,6 +110,14 @@ def do_port_list(cc, args):
|
||||
field_labels = res_fields.PORT_DETAILED_RESOURCE.labels
|
||||
sort_fields = res_fields.PORT_DETAILED_RESOURCE.sort_fields
|
||||
sort_field_labels = res_fields.PORT_DETAILED_RESOURCE.sort_labels
|
||||
elif args.fields:
|
||||
utils.check_for_invalid_fields(
|
||||
args.fields[0], res_fields.PORT_DETAILED_RESOURCE.fields)
|
||||
resource = res_fields.Resource(args.fields[0])
|
||||
fields = resource.fields
|
||||
field_labels = resource.labels
|
||||
sort_fields = res_fields.PORT_DETAILED_RESOURCE.sort_fields
|
||||
sort_field_labels = res_fields.PORT_DETAILED_RESOURCE.sort_labels
|
||||
else:
|
||||
fields = res_fields.PORT_RESOURCE.fields
|
||||
field_labels = res_fields.PORT_RESOURCE.labels
|
||||
|
Loading…
Reference in New Issue
Block a user