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