Add support for node.resource_class
This adds support for the node.resource_class field, introduced in API 1.21. It can be modified on an existing node or passed when creating a node, or used as a filter when fetching a list of nodes. Change-Id: Id494a8b735a3532db84d90ba21da173f7e33ed1d Depends-On: I936f2e7b2f4d26e01354e826e5595ff021c3a55c Partial-Bug: #1604916
This commit is contained in:
parent
b3c77f4d3b
commit
22888e9759
@ -156,6 +156,10 @@ class CreateBaremetalNode(show.ShowOne):
|
|||||||
metavar='<network_interface>',
|
metavar='<network_interface>',
|
||||||
help='Network interface used for switching node to '
|
help='Network interface used for switching node to '
|
||||||
'cleaning/provisioning networks.')
|
'cleaning/provisioning networks.')
|
||||||
|
parser.add_argument(
|
||||||
|
'--resource-class',
|
||||||
|
metavar='<resource_class>',
|
||||||
|
help='Resource class for mapping nodes to Nova flavors')
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -166,7 +170,7 @@ class CreateBaremetalNode(show.ShowOne):
|
|||||||
|
|
||||||
field_list = ['chassis_uuid', 'driver', 'driver_info',
|
field_list = ['chassis_uuid', 'driver', 'driver_info',
|
||||||
'properties', 'extra', 'uuid', 'name',
|
'properties', 'extra', 'uuid', 'name',
|
||||||
'network_interface']
|
'network_interface', 'resource_class']
|
||||||
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
|
fields = dict((k, v) for (k, v) in vars(parsed_args).items()
|
||||||
if k in field_list and not (v is None))
|
if k in field_list and not (v is None))
|
||||||
fields = utils.args_array_to_dict(fields, 'driver_info')
|
fields = utils.args_array_to_dict(fields, 'driver_info')
|
||||||
@ -326,6 +330,11 @@ class ListBaremetalNode(lister.Lister):
|
|||||||
choices=self.PROVISION_STATES,
|
choices=self.PROVISION_STATES,
|
||||||
help="Limit list to nodes in <provision state>. One of %s." % (
|
help="Limit list to nodes in <provision state>. One of %s." % (
|
||||||
", ".join(self.PROVISION_STATES)))
|
", ".join(self.PROVISION_STATES)))
|
||||||
|
parser.add_argument(
|
||||||
|
'--resource-class',
|
||||||
|
dest='resource_class',
|
||||||
|
metavar='<resource class>',
|
||||||
|
help="Limit list to nodes with resource class <resource class>")
|
||||||
display_group = parser.add_mutually_exclusive_group(required=False)
|
display_group = parser.add_mutually_exclusive_group(required=False)
|
||||||
display_group.add_argument(
|
display_group.add_argument(
|
||||||
'--long',
|
'--long',
|
||||||
@ -365,6 +374,8 @@ class ListBaremetalNode(lister.Lister):
|
|||||||
params['maintenance'] = parsed_args.maintenance
|
params['maintenance'] = parsed_args.maintenance
|
||||||
if parsed_args.provision_state:
|
if parsed_args.provision_state:
|
||||||
params['provision_state'] = parsed_args.provision_state
|
params['provision_state'] = parsed_args.provision_state
|
||||||
|
if parsed_args.resource_class:
|
||||||
|
params['resource_class'] = parsed_args.resource_class
|
||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
params['detail'] = parsed_args.long
|
params['detail'] = parsed_args.long
|
||||||
columns = res_fields.NODE_DETAILED_RESOURCE.fields
|
columns = res_fields.NODE_DETAILED_RESOURCE.fields
|
||||||
@ -565,6 +576,11 @@ class SetBaremetalNode(command.Command):
|
|||||||
metavar='<network_interface>',
|
metavar='<network_interface>',
|
||||||
help='Set the network interface for the node',
|
help='Set the network interface for the node',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--resource-class',
|
||||||
|
metavar='<resource_class>',
|
||||||
|
help='Set the resource class for the node',
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--property",
|
"--property",
|
||||||
metavar="<key=value>",
|
metavar="<key=value>",
|
||||||
@ -619,6 +635,11 @@ class SetBaremetalNode(command.Command):
|
|||||||
"network_interface=%s" % parsed_args.network_interface]
|
"network_interface=%s" % parsed_args.network_interface]
|
||||||
properties.extend(utils.args_array_to_patch(
|
properties.extend(utils.args_array_to_patch(
|
||||||
'add', network_interface))
|
'add', network_interface))
|
||||||
|
if parsed_args.resource_class:
|
||||||
|
resource_class = [
|
||||||
|
"resource_class=%s" % parsed_args.resource_class]
|
||||||
|
properties.extend(utils.args_array_to_patch(
|
||||||
|
'add', resource_class))
|
||||||
if parsed_args.property:
|
if parsed_args.property:
|
||||||
properties.extend(utils.args_array_to_patch(
|
properties.extend(utils.args_array_to_patch(
|
||||||
'add', ['properties/' + x for x in parsed_args.property]))
|
'add', ['properties/' + x for x in parsed_args.property]))
|
||||||
@ -744,6 +765,12 @@ class UnsetBaremetalNode(command.Command):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help="Unset the name of the node",
|
help="Unset the name of the node",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--resource-class",
|
||||||
|
dest='resource_class',
|
||||||
|
action='store_true',
|
||||||
|
help="Unset the resource class of the node",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--property',
|
'--property',
|
||||||
metavar='<key>',
|
metavar='<key>',
|
||||||
@ -787,6 +814,9 @@ class UnsetBaremetalNode(command.Command):
|
|||||||
if parsed_args.name:
|
if parsed_args.name:
|
||||||
properties.extend(utils.args_array_to_patch('remove',
|
properties.extend(utils.args_array_to_patch('remove',
|
||||||
['name']))
|
['name']))
|
||||||
|
if parsed_args.resource_class:
|
||||||
|
properties.extend(utils.args_array_to_patch('remove',
|
||||||
|
['resource_class']))
|
||||||
if parsed_args.property:
|
if parsed_args.property:
|
||||||
properties.extend(utils.args_array_to_patch('remove',
|
properties.extend(utils.args_array_to_patch('remove',
|
||||||
['properties/' + x
|
['properties/' + x
|
||||||
|
@ -167,6 +167,11 @@ class TestBaremetalCreate(TestBaremetal):
|
|||||||
[('network_interface', 'neutron')],
|
[('network_interface', 'neutron')],
|
||||||
{'network_interface': 'neutron'})
|
{'network_interface': 'neutron'})
|
||||||
|
|
||||||
|
def test_baremetal_create_with_resource_class(self):
|
||||||
|
self.check_with_options(['--resource-class', 'foo'],
|
||||||
|
[('resource_class', 'foo')],
|
||||||
|
{'resource_class': 'foo'})
|
||||||
|
|
||||||
|
|
||||||
class TestBaremetalDelete(TestBaremetal):
|
class TestBaremetalDelete(TestBaremetal):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -317,6 +322,7 @@ class TestBaremetalList(TestBaremetal):
|
|||||||
'Maintenance Reason', 'Power State', 'Properties',
|
'Maintenance Reason', 'Power State', 'Properties',
|
||||||
'Provisioning State', 'Provision Updated At',
|
'Provisioning State', 'Provision Updated At',
|
||||||
'Current RAID configuration', 'Reservation',
|
'Current RAID configuration', 'Reservation',
|
||||||
|
'Resource Class',
|
||||||
'Target Power State', 'Target Provision State',
|
'Target Power State', 'Target Provision State',
|
||||||
'Target RAID configuration',
|
'Target RAID configuration',
|
||||||
'Updated At', 'Inspection Finished At',
|
'Updated At', 'Inspection Finished At',
|
||||||
@ -349,6 +355,7 @@ class TestBaremetalList(TestBaremetal):
|
|||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
'',
|
||||||
baremetal_fakes.baremetal_uuid,
|
baremetal_fakes.baremetal_uuid,
|
||||||
baremetal_fakes.baremetal_name,
|
baremetal_fakes.baremetal_name,
|
||||||
'',
|
'',
|
||||||
@ -439,6 +446,30 @@ class TestBaremetalList(TestBaremetal):
|
|||||||
self.check_parser,
|
self.check_parser,
|
||||||
self.cmd, arglist, verifylist)
|
self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
def test_baremetal_list_resource_class(self):
|
||||||
|
arglist = [
|
||||||
|
'--resource-class', 'foo',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('resource_class', 'foo'),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
# DisplayCommandBase.take_action() returns two tuples
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
# Set expected values
|
||||||
|
kwargs = {
|
||||||
|
'marker': None,
|
||||||
|
'limit': None,
|
||||||
|
'resource_class': 'foo'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.baremetal_mock.node.list.assert_called_with(
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
def test_baremetal_list_fields(self):
|
def test_baremetal_list_fields(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--fields', 'uuid', 'name',
|
'--fields', 'uuid', 'name',
|
||||||
@ -827,6 +858,25 @@ class TestBaremetalSet(TestBaremetal):
|
|||||||
[{'path': '/network_interface', 'value': 'xxxxx', 'op': 'add'}]
|
[{'path': '/network_interface', 'value': 'xxxxx', 'op': 'add'}]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_baremetal_set_resource_class(self):
|
||||||
|
arglist = [
|
||||||
|
'node_uuid',
|
||||||
|
'--resource-class', 'foo',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('node', 'node_uuid'),
|
||||||
|
('resource_class', 'foo')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.baremetal_mock.node.update.assert_called_once_with(
|
||||||
|
'node_uuid',
|
||||||
|
[{'path': '/resource_class', 'value': 'foo', 'op': 'add'}]
|
||||||
|
)
|
||||||
|
|
||||||
def test_baremetal_set_extra(self):
|
def test_baremetal_set_extra(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'node_uuid',
|
'node_uuid',
|
||||||
@ -1124,6 +1174,25 @@ class TestBaremetalUnset(TestBaremetal):
|
|||||||
[{'path': '/name', 'op': 'remove'}]
|
[{'path': '/name', 'op': 'remove'}]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_baremetal_unset_resource_class(self):
|
||||||
|
arglist = [
|
||||||
|
'node_uuid',
|
||||||
|
'--resource-class',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('node', 'node_uuid'),
|
||||||
|
('resource_class', True)
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.baremetal_mock.node.update.assert_called_once_with(
|
||||||
|
'node_uuid',
|
||||||
|
[{'path': '/resource_class', 'op': 'remove'}]
|
||||||
|
)
|
||||||
|
|
||||||
def test_baremetal_unset_extra(self):
|
def test_baremetal_unset_extra(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'node_uuid',
|
'node_uuid',
|
||||||
|
@ -38,6 +38,7 @@ NODE1 = {'id': 123,
|
|||||||
'driver_info': {'user': 'foo', 'password': 'bar'},
|
'driver_info': {'user': 'foo', 'password': 'bar'},
|
||||||
'properties': {'num_cpu': 4},
|
'properties': {'num_cpu': 4},
|
||||||
'name': 'fake-node-1',
|
'name': 'fake-node-1',
|
||||||
|
'resource_class': 'foo',
|
||||||
'extra': {}}
|
'extra': {}}
|
||||||
NODE2 = {'id': 456,
|
NODE2 = {'id': 456,
|
||||||
'uuid': '66666666-7777-8888-9999-111111111111',
|
'uuid': '66666666-7777-8888-9999-111111111111',
|
||||||
@ -47,6 +48,7 @@ NODE2 = {'id': 456,
|
|||||||
'driver': 'fake too',
|
'driver': 'fake too',
|
||||||
'driver_info': {'user': 'foo', 'password': 'bar'},
|
'driver_info': {'user': 'foo', 'password': 'bar'},
|
||||||
'properties': {'num_cpu': 4},
|
'properties': {'num_cpu': 4},
|
||||||
|
'resource_class': 'bar',
|
||||||
'extra': {}}
|
'extra': {}}
|
||||||
PORT = {'id': 456,
|
PORT = {'id': 456,
|
||||||
'uuid': '11111111-2222-3333-4444-555555555555',
|
'uuid': '11111111-2222-3333-4444-555555555555',
|
||||||
@ -171,6 +173,13 @@ fake_responses = {
|
|||||||
{"nodes": [NODE1]},
|
{"nodes": [NODE1]},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
'/v1/nodes/?resource_class=foo':
|
||||||
|
{
|
||||||
|
'GET': (
|
||||||
|
{},
|
||||||
|
{"nodes": [NODE1]},
|
||||||
|
)
|
||||||
|
},
|
||||||
'/v1/nodes/detail?instance_uuid=%s' % NODE2['instance_uuid']:
|
'/v1/nodes/detail?instance_uuid=%s' % NODE2['instance_uuid']:
|
||||||
{
|
{
|
||||||
'GET': (
|
'GET': (
|
||||||
@ -548,6 +557,15 @@ class NodeManagerTest(testtools.TestCase):
|
|||||||
self.assertThat(nodes, HasLength(1))
|
self.assertThat(nodes, HasLength(1))
|
||||||
self.assertEqual(NODE1['uuid'], getattr(nodes[0], 'uuid'))
|
self.assertEqual(NODE1['uuid'], getattr(nodes[0], 'uuid'))
|
||||||
|
|
||||||
|
def test_node_list_resource_class(self):
|
||||||
|
nodes = self.mgr.list(resource_class="foo")
|
||||||
|
expect = [
|
||||||
|
('GET', '/v1/nodes/?resource_class=foo', {}, None),
|
||||||
|
]
|
||||||
|
self.assertEqual(expect, self.api.calls)
|
||||||
|
self.assertThat(nodes, HasLength(1))
|
||||||
|
self.assertEqual(NODE1['uuid'], getattr(nodes[0], 'uuid'))
|
||||||
|
|
||||||
def test_node_list_no_maintenance(self):
|
def test_node_list_no_maintenance(self):
|
||||||
nodes = self.mgr.list(maintenance=False)
|
nodes = self.mgr.list(maintenance=False)
|
||||||
expect = [
|
expect = [
|
||||||
|
@ -52,6 +52,7 @@ class NodeShellTest(utils.BaseTestCase):
|
|||||||
'provision_state',
|
'provision_state',
|
||||||
'provision_updated_at',
|
'provision_updated_at',
|
||||||
'reservation',
|
'reservation',
|
||||||
|
'resource_class',
|
||||||
'target_power_state',
|
'target_power_state',
|
||||||
'target_provision_state',
|
'target_provision_state',
|
||||||
'updated_at',
|
'updated_at',
|
||||||
@ -749,7 +750,7 @@ class NodeShellTest(utils.BaseTestCase):
|
|||||||
maintenance=None, marker=None, limit=None,
|
maintenance=None, marker=None, limit=None,
|
||||||
sort_dir=None, sort_key=None, detail=False,
|
sort_dir=None, sort_key=None, detail=False,
|
||||||
fields=None, provision_state=None, driver=None,
|
fields=None, provision_state=None, driver=None,
|
||||||
json=False):
|
json=False, resource_class=None):
|
||||||
args = mock.MagicMock()
|
args = mock.MagicMock()
|
||||||
args.node = node
|
args.node = node
|
||||||
args.associated = associated
|
args.associated = associated
|
||||||
@ -763,6 +764,7 @@ class NodeShellTest(utils.BaseTestCase):
|
|||||||
args.fields = fields
|
args.fields = fields
|
||||||
args.driver = driver
|
args.driver = driver
|
||||||
args.json = json
|
args.json = json
|
||||||
|
args.resource_class = resource_class
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
@ -818,6 +820,24 @@ class NodeShellTest(utils.BaseTestCase):
|
|||||||
client_mock.node.list.assert_called_once_with(driver='fake',
|
client_mock.node.list.assert_called_once_with(driver='fake',
|
||||||
detail=True)
|
detail=True)
|
||||||
|
|
||||||
|
def test_do_node_list_resource_class(self):
|
||||||
|
client_mock = mock.MagicMock()
|
||||||
|
args = self._get_client_mock_args(resource_class='foo',
|
||||||
|
detail=False)
|
||||||
|
|
||||||
|
n_shell.do_node_list(client_mock, args)
|
||||||
|
client_mock.node.list.assert_called_once_with(resource_class='foo',
|
||||||
|
detail=False)
|
||||||
|
|
||||||
|
def test_do_node_list_detail_resource_class(self):
|
||||||
|
client_mock = mock.MagicMock()
|
||||||
|
args = self._get_client_mock_args(resource_class='foo',
|
||||||
|
detail=True)
|
||||||
|
|
||||||
|
n_shell.do_node_list(client_mock, args)
|
||||||
|
client_mock.node.list.assert_called_once_with(resource_class='foo',
|
||||||
|
detail=True)
|
||||||
|
|
||||||
def test_do_node_list_sort_key(self):
|
def test_do_node_list_sort_key(self):
|
||||||
client_mock = mock.MagicMock()
|
client_mock = mock.MagicMock()
|
||||||
args = self._get_client_mock_args(sort_key='created_at',
|
args = self._get_client_mock_args(sort_key='created_at',
|
||||||
|
@ -38,12 +38,12 @@ class NodeManager(base.CreateManager):
|
|||||||
resource_class = Node
|
resource_class = Node
|
||||||
_creation_attributes = ['chassis_uuid', 'driver', 'driver_info',
|
_creation_attributes = ['chassis_uuid', 'driver', 'driver_info',
|
||||||
'extra', 'uuid', 'properties', 'name',
|
'extra', 'uuid', 'properties', 'name',
|
||||||
'network_interface']
|
'network_interface', 'resource_class']
|
||||||
_resource_name = 'nodes'
|
_resource_name = 'nodes'
|
||||||
|
|
||||||
def list(self, associated=None, maintenance=None, marker=None, limit=None,
|
def list(self, associated=None, maintenance=None, marker=None, limit=None,
|
||||||
detail=False, sort_key=None, sort_dir=None, fields=None,
|
detail=False, sort_key=None, sort_dir=None, fields=None,
|
||||||
provision_state=None, driver=None):
|
provision_state=None, driver=None, resource_class=None):
|
||||||
"""Retrieve a list of nodes.
|
"""Retrieve a list of nodes.
|
||||||
|
|
||||||
:param associated: Optional. Either a Boolean or a string
|
:param associated: Optional. Either a Boolean or a string
|
||||||
@ -84,6 +84,9 @@ class NodeManager(base.CreateManager):
|
|||||||
:param driver: Optional. String value to get only nodes using that
|
:param driver: Optional. String value to get only nodes using that
|
||||||
driver.
|
driver.
|
||||||
|
|
||||||
|
:param resource_class: Optional. String value to get only nodes
|
||||||
|
with the given resource class set.
|
||||||
|
|
||||||
:returns: A list of nodes.
|
:returns: A list of nodes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -104,6 +107,8 @@ class NodeManager(base.CreateManager):
|
|||||||
filters.append('provision_state=%s' % provision_state)
|
filters.append('provision_state=%s' % provision_state)
|
||||||
if driver is not None:
|
if driver is not None:
|
||||||
filters.append('driver=%s' % driver)
|
filters.append('driver=%s' % driver)
|
||||||
|
if resource_class is not None:
|
||||||
|
filters.append('resource_class=%s' % resource_class)
|
||||||
|
|
||||||
path = ''
|
path = ''
|
||||||
if detail:
|
if detail:
|
||||||
|
@ -117,6 +117,11 @@ def do_node_show(cc, args):
|
|||||||
default=[],
|
default=[],
|
||||||
help="One or more node fields. Only these fields will be fetched from "
|
help="One or more node fields. Only these fields will be fetched from "
|
||||||
"the server. Can not be used when '--detail' is specified.")
|
"the server. Can not be used when '--detail' is specified.")
|
||||||
|
@cliutils.arg(
|
||||||
|
'--resource-class',
|
||||||
|
dest='resource_class',
|
||||||
|
metavar='<resource class>',
|
||||||
|
help="List nodes using specified resource class.")
|
||||||
def do_node_list(cc, args):
|
def do_node_list(cc, args):
|
||||||
"""List the nodes which are registered with the Ironic service."""
|
"""List the nodes which are registered with the Ironic service."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -132,6 +137,9 @@ def do_node_list(cc, args):
|
|||||||
if args.driver is not None:
|
if args.driver is not None:
|
||||||
params['driver'] = args.driver
|
params['driver'] = args.driver
|
||||||
|
|
||||||
|
if args.resource_class is not None:
|
||||||
|
params['resource_class'] = args.resource_class
|
||||||
|
|
||||||
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
|
||||||
@ -207,11 +215,16 @@ def do_node_list(cc, args):
|
|||||||
metavar='<network_interface>',
|
metavar='<network_interface>',
|
||||||
help='Network interface used for switching node to cleaning/provisioning '
|
help='Network interface used for switching node to cleaning/provisioning '
|
||||||
'networks.')
|
'networks.')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--resource-class',
|
||||||
|
metavar='<resource_class>',
|
||||||
|
help='Resource class for classifying or grouping nodes. Used, for '
|
||||||
|
'example, to classify nodes in Nova\'s placement engine.')
|
||||||
def do_node_create(cc, args):
|
def do_node_create(cc, args):
|
||||||
"""Register a new node with the Ironic service."""
|
"""Register a new node with the Ironic service."""
|
||||||
field_list = ['chassis_uuid', 'driver', 'driver_info',
|
field_list = ['chassis_uuid', 'driver', 'driver_info',
|
||||||
'properties', 'extra', 'uuid', 'name',
|
'properties', 'extra', 'uuid', 'name',
|
||||||
'network_interface']
|
'network_interface', 'resource_class']
|
||||||
fields = dict((k, v) for (k, v) in vars(args).items()
|
fields = dict((k, v) for (k, v) in vars(args).items()
|
||||||
if k in field_list and not (v is None))
|
if k in field_list and not (v is None))
|
||||||
fields = utils.args_array_to_dict(fields, 'driver_info')
|
fields = utils.args_array_to_dict(fields, 'driver_info')
|
||||||
|
@ -59,6 +59,7 @@ class Resource(object):
|
|||||||
'provision_updated_at': 'Provision Updated At',
|
'provision_updated_at': 'Provision Updated At',
|
||||||
'raid_config': 'Current RAID configuration',
|
'raid_config': 'Current RAID configuration',
|
||||||
'reservation': 'Reservation',
|
'reservation': 'Reservation',
|
||||||
|
'resource_class': 'Resource Class',
|
||||||
'target_power_state': 'Target Power State',
|
'target_power_state': 'Target Power State',
|
||||||
'target_provision_state': 'Target Provision State',
|
'target_provision_state': 'Target Provision State',
|
||||||
'target_raid_config': 'Target RAID configuration',
|
'target_raid_config': 'Target RAID configuration',
|
||||||
@ -146,6 +147,7 @@ NODE_DETAILED_RESOURCE = Resource(
|
|||||||
'provision_updated_at',
|
'provision_updated_at',
|
||||||
'raid_config',
|
'raid_config',
|
||||||
'reservation',
|
'reservation',
|
||||||
|
'resource_class',
|
||||||
'target_power_state',
|
'target_power_state',
|
||||||
'target_provision_state',
|
'target_provision_state',
|
||||||
'target_raid_config',
|
'target_raid_config',
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Adds support for the new ``node.resource_class`` field,
|
||||||
|
which was introduced in API version 1.21.
|
Loading…
Reference in New Issue
Block a user