From 78902bfd0c56ba08642cd1ec0b21408c19ab2839 Mon Sep 17 00:00:00 2001 From: Kaifeng Wang <kaifeng.w@gmail.com> Date: Tue, 27 Mar 2018 15:52:19 +0800 Subject: [PATCH] Power fault recovery: client support This patch adds codes to support the fault field exposed from ironic API. Querying nodes with specified fault is also supported as well. Story: #1596107 Task: #10469 Partial-Bug: #1596107 Depends-On: https://review.openstack.org/556015/ Change-Id: I429df0ab5ea39140a2b988d5dfdacb24a67b955e --- ironicclient/common/http.py | 2 +- ironicclient/osc/v1/baremetal_node.py | 7 ++++ .../tests/unit/osc/v1/test_baremetal_node.py | 41 +++++++++++++++---- ironicclient/tests/unit/v1/test_node_shell.py | 1 + ironicclient/v1/node.py | 7 +++- ironicclient/v1/resource_fields.py | 2 + .../notes/node-fault-adbe74fd600063ee.yaml | 5 +++ 7 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/node-fault-adbe74fd600063ee.yaml diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py index e8c24f1ea..edf423207 100644 --- a/ironicclient/common/http.py +++ b/ironicclient/common/http.py @@ -43,7 +43,7 @@ from ironicclient import exc # http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa # for full details. DEFAULT_VER = '1.9' -LAST_KNOWN_API_VERSION = 38 +LAST_KNOWN_API_VERSION = 42 LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION) LOG = logging.getLogger(__name__) diff --git a/ironicclient/osc/v1/baremetal_node.py b/ironicclient/osc/v1/baremetal_node.py index e8d801905..244bca1f8 100755 --- a/ironicclient/osc/v1/baremetal_node.py +++ b/ironicclient/osc/v1/baremetal_node.py @@ -555,6 +555,11 @@ class ListBaremetalNode(command.Lister): default=None, help=_("Limit list to nodes not in maintenance mode"), ) + parser.add_argument( + '--fault', + dest='fault', + metavar='<fault>', + help=_("List nodes in specified fault.")) associated_group = parser.add_mutually_exclusive_group() associated_group.add_argument( '--associated', @@ -625,6 +630,8 @@ class ListBaremetalNode(command.Lister): params['associated'] = False if parsed_args.maintenance is not None: params['maintenance'] = parsed_args.maintenance + if parsed_args.fault is not None: + params['fault'] = parsed_args.fault if parsed_args.provision_state: params['provision_state'] = parsed_args.provision_state if parsed_args.driver: diff --git a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py index 33e017e12..6495e5897 100644 --- a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py +++ b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py @@ -592,13 +592,12 @@ class TestBaremetalList(TestBaremetal): 'Console Enabled', 'Driver', 'Driver Info', 'Driver Internal Info', 'Extra', 'Instance Info', 'Instance UUID', 'Last Error', 'Maintenance', - 'Maintenance Reason', 'Power State', 'Properties', - 'Provisioning State', 'Provision Updated At', - 'Current RAID configuration', 'Reservation', - 'Resource Class', - 'Target Power State', 'Target Provision State', - 'Target RAID configuration', 'Traits', - 'Updated At', 'Inspection Finished At', + 'Maintenance Reason', 'Fault', + 'Power State', 'Properties', 'Provisioning State', + 'Provision Updated At', 'Current RAID configuration', + 'Reservation', 'Resource Class', 'Target Power State', + 'Target Provision State', 'Target RAID configuration', + 'Traits', 'Updated At', 'Inspection Finished At', 'Inspection Started At', 'UUID', 'Name', 'Boot Interface', 'Console Interface', 'Deploy Interface', 'Inspect Interface', @@ -621,6 +620,7 @@ class TestBaremetalList(TestBaremetal): '', baremetal_fakes.baremetal_maintenance, '', + '', baremetal_fakes.baremetal_power_state, '', baremetal_fakes.baremetal_provision_state, @@ -713,6 +713,33 @@ class TestBaremetalList(TestBaremetal): self.check_parser, self.cmd, arglist, verifylist) + def test_baremetal_list_fault(self): + arglist = [ + '--maintenance', + '--fault', 'power failure', + ] + verifylist = [ + ('maintenance', True), + ('fault', 'power failure'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'marker': None, + 'limit': None, + 'maintenance': True, + 'fault': 'power failure' + } + + self.baremetal_mock.node.list.assert_called_with( + **kwargs + ) + def test_baremetal_list_associated(self): arglist = [ '--associated', diff --git a/ironicclient/tests/unit/v1/test_node_shell.py b/ironicclient/tests/unit/v1/test_node_shell.py index a8152142e..be0074798 100644 --- a/ironicclient/tests/unit/v1/test_node_shell.py +++ b/ironicclient/tests/unit/v1/test_node_shell.py @@ -46,6 +46,7 @@ class NodeShellTest(utils.BaseTestCase): 'last_error', 'maintenance', 'maintenance_reason', + 'fault', 'name', 'boot_interface', 'console_interface', diff --git a/ironicclient/v1/node.py b/ironicclient/v1/node.py index 9fb59c842..292c5cf78 100644 --- a/ironicclient/v1/node.py +++ b/ironicclient/v1/node.py @@ -58,7 +58,7 @@ class NodeManager(base.CreateManager): def list(self, associated=None, maintenance=None, marker=None, limit=None, detail=False, sort_key=None, sort_dir=None, fields=None, provision_state=None, driver=None, resource_class=None, - chassis=None): + chassis=None, fault=None): """Retrieve a list of nodes. :param associated: Optional. Either a Boolean or a string @@ -105,6 +105,9 @@ class NodeManager(base.CreateManager): :param chassis: Optional, the UUID of a chassis. Used to get only nodes of this chassis. + :param fault: Optional. String value to get only nodes with + specified fault. + :returns: A list of nodes. """ @@ -121,6 +124,8 @@ class NodeManager(base.CreateManager): filters.append('associated=%s' % associated) if maintenance is not None: filters.append('maintenance=%s' % maintenance) + if fault is not None: + filters.append('fault=%s' % fault) if provision_state is not None: filters.append('provision_state=%s' % provision_state) if driver is not None: diff --git a/ironicclient/v1/resource_fields.py b/ironicclient/v1/resource_fields.py index a67383dfe..0b87feda6 100644 --- a/ironicclient/v1/resource_fields.py +++ b/ironicclient/v1/resource_fields.py @@ -76,6 +76,7 @@ class Resource(object): 'last_error': 'Last Error', 'maintenance': 'Maintenance', 'maintenance_reason': 'Maintenance Reason', + 'fault': 'Fault', 'mode': 'Mode', 'name': 'Name', 'node_uuid': 'Node UUID', @@ -204,6 +205,7 @@ NODE_DETAILED_RESOURCE = Resource( 'last_error', 'maintenance', 'maintenance_reason', + 'fault', 'power_state', 'properties', 'provision_state', diff --git a/releasenotes/notes/node-fault-adbe74fd600063ee.yaml b/releasenotes/notes/node-fault-adbe74fd600063ee.yaml new file mode 100644 index 000000000..66f4df6c1 --- /dev/null +++ b/releasenotes/notes/node-fault-adbe74fd600063ee.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Supports the node's ``fault`` field, introduced in the Bare Metal API + version 1.42, including displaying or querying nodes by this field.