summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulia Kreger <juliaashleykreger@gmail.com>2021-11-30 15:10:43 -0800
committerJulia Kreger <juliaashleykreger@gmail.com>2021-12-01 07:24:27 -0800
commit2e0cef2cb0b1297788dc187fc61816408060c616 (patch)
tree6ca5ad2d59dbcc1aefd4ff179d88efbfb9d21a80
parent4ce3c4ebf2601beacc31b1e35c804fcab912bbf9 (diff)
downloadpython-ironicclient-2e0cef2cb0b1297788dc187fc61816408060c616.tar.gz
Add node history support
Adds support for rest API version 1.78, which covers the node history feature. Story: 2002980 Task: 43319 Change-Id: I6edbc38353a4b2f7b0a758108bc91cc9fb72a29d
-rw-r--r--ironicclient/common/http.py2
-rwxr-xr-xironicclient/osc/v1/baremetal_node.py74
-rw-r--r--ironicclient/tests/unit/osc/v1/fakes.py12
-rw-r--r--ironicclient/tests/unit/osc/v1/test_baremetal_node.py56
-rw-r--r--ironicclient/v1/node.py53
-rw-r--r--ironicclient/v1/resource_fields.py22
-rw-r--r--releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml9
-rw-r--r--setup.cfg2
8 files changed, 229 insertions, 1 deletions
diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py
index b449599..0608e3a 100644
--- a/ironicclient/common/http.py
+++ b/ironicclient/common/http.py
@@ -37,7 +37,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 = 77
+LAST_KNOWN_API_VERSION = 78
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 1f1b947..3fe329a 100755
--- a/ironicclient/osc/v1/baremetal_node.py
+++ b/ironicclient/osc/v1/baremetal_node.py
@@ -2131,3 +2131,77 @@ class BIOSSettingShowBaremetalNode(command.ShowOne):
parsed_args.node, parsed_args.setting_name)
setting.pop("links", None)
return self.dict2columns(setting)
+
+
+class NodeHistoryList(command.Lister):
+ """Get history events for a baremetal node."""
+
+ log = logging.getLogger(__name__ + ".NodeHistoryList")
+
+ def get_parser(self, prog_name):
+ parser = super(NodeHistoryList, self).get_parser(prog_name)
+
+ parser.add_argument(
+ 'node',
+ metavar='<node>',
+ help=_("Name or UUID of the node.")
+ )
+ parser.add_argument(
+ '--long',
+ default=False,
+ help=_("Show detailed information about the BIOS settings."),
+ action='store_true')
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action(%s)", parsed_args)
+
+ baremetal_client = self.app.client_manager.baremetal
+ if parsed_args.long:
+ labels = res_fields.NODE_HISTORY_DETAILED_RESOURCE.labels
+ fields = res_fields.NODE_HISTORY_DETAILED_RESOURCE.fields
+ else:
+ labels = res_fields.NODE_HISTORY_RESOURCE.labels
+ fields = res_fields.NODE_HISTORY_RESOURCE.fields
+
+ data = baremetal_client.node.get_history_list(
+ parsed_args.node,
+ parsed_args.long)
+
+ return (labels,
+ (oscutils.get_dict_properties(s, fields) for s in data))
+
+
+class NodeHistoryEventGet(command.ShowOne):
+ """Get history event for a baremetal node."""
+
+ log = logging.getLogger(__name__ + ".NodeHistoryEventGet")
+
+ def get_parser(self, prog_name):
+ parser = super(NodeHistoryEventGet, self).get_parser(prog_name)
+
+ parser.add_argument(
+ 'node',
+ metavar='<node>',
+ help=_("Name or UUID of the node.")
+ )
+
+ parser.add_argument(
+ 'event',
+ metavar='<event>',
+ help=_("UUID of the event.")
+ )
+
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action(%s)", parsed_args)
+
+ baremetal_client = self.app.client_manager.baremetal
+
+ data = baremetal_client.node.get_history_event(
+ parsed_args.node,
+ parsed_args.event)
+ data.pop('links')
+
+ return self.dict2columns(data)
diff --git a/ironicclient/tests/unit/osc/v1/fakes.py b/ironicclient/tests/unit/osc/v1/fakes.py
index 111fd7f..5745998 100644
--- a/ironicclient/tests/unit/osc/v1/fakes.py
+++ b/ironicclient/tests/unit/osc/v1/fakes.py
@@ -229,6 +229,18 @@ DEPLOY_TEMPLATE = {
'steps': baremetal_deploy_template_steps,
'extra': baremetal_deploy_template_extra,
}
+NODE_HISTORY = [
+ {
+ 'uuid': 'abcdef1',
+ 'created_at': 'time',
+ 'severity': 'info',
+ 'event': 'meow',
+ 'event_type': 'purring',
+ 'conductor': 'lap-conductor',
+ 'user': '0191',
+ 'links': {'href': 'url', 'rel': 'self'},
+ }
+]
class TestBaremetal(utils.TestCommand):
diff --git a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
index 5a1b2fe..6426eef 100644
--- a/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
+++ b/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
@@ -4188,3 +4188,59 @@ class TestBIOSSettingShow(TestBaremetal):
'node_uuid', 'bios_name_1')
expected_data = ('bios_name_1', 'bios_value_1')
self.assertEqual(expected_data, tuple(data))
+
+
+class TestNodeHistoryEventList(TestBaremetal):
+ def setUp(self):
+ super(TestNodeHistoryEventList, self).setUp()
+
+ self.baremetal_mock.node.get_history_list.return_value = (
+ baremetal_fakes.NODE_HISTORY)
+
+ # Get the command object to test
+ self.cmd = baremetal_node.NodeHistoryList(self.app, None)
+
+ def test_baremetal_node_history_list(self):
+ arglist = ['node_uuid', '--long']
+ verifylist = [('node', 'node_uuid'), ('long', True)]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.baremetal_mock.node.get_history_list.assert_called_once_with(
+ 'node_uuid', True)
+ expected_columns = ('UUID', 'Created At', 'Severity',
+ 'Event Origin Type', 'Description of the event',
+ 'Conductor', 'User')
+ expected_data = (('abcdef1', 'time', 'info', 'purring', 'meow',
+ 'lap-conductor', '0191'),)
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, tuple(data))
+
+
+class TestNodeHistoryEventGet(TestBaremetal):
+ def setUp(self):
+ super(TestNodeHistoryEventGet, self).setUp()
+
+ self.baremetal_mock.node.get_history_event.return_value = (
+ baremetal_fakes.NODE_HISTORY[0])
+
+ # Get the command object to test
+ self.cmd = baremetal_node.NodeHistoryEventGet(self.app, None)
+
+ def test_baremetal_node_history_list(self):
+ arglist = ['node_uuid', 'event_uuid']
+ verifylist = [('node', 'node_uuid'), ('event', 'event_uuid')]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.baremetal_mock.node.get_history_event.assert_called_once_with(
+ 'node_uuid', 'event_uuid')
+ expected_columns = ('conductor', 'created_at', 'event', 'event_type',
+ 'severity', 'user', 'uuid')
+ expected_data = ('lap-conductor', 'time', 'meow', 'purring', 'info',
+ '0191', 'abcdef1')
+
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, tuple(data))
diff --git a/ironicclient/v1/node.py b/ironicclient/v1/node.py
index d438d0e..84def25 100644
--- a/ironicclient/v1/node.py
+++ b/ironicclient/v1/node.py
@@ -1008,3 +1008,56 @@ class NodeManager(base.CreateManager):
'%(state)s, the current state is %(actual)s',
{'node': node_ident, 'state': expected_state,
'actual': node.provision_state})
+
+ def get_history_list(self,
+ node_ident,
+ detail=False,
+ os_ironic_api_version=None,
+ global_request_id=None):
+ """Get node history event list.
+
+ Provides the ability to query a node event history list from
+ the API and return the API response to the caller.
+
+ Requires API version 1.78.
+
+ :param node_ident: The name or UUID of the node.
+ :param detail: If detailed data should be returned in the
+ event list entry. Default False.
+ :param os_ironic_api_version: String version (e.g. "1.35") to use for
+ the request. If not specified, the client's default is used.
+ :param global_request_id: String containing global request ID header
+ value (in form "req-<UUID>") to use for the request.
+ """
+ path = "%s/history" % node_ident
+
+ if detail:
+ path = path + '/detail'
+
+ return self._list_primitives(
+ self._path(path), 'history',
+ os_ironic_api_version=os_ironic_api_version,
+ global_request_id=global_request_id)
+
+ def get_history_event(self,
+ node_ident,
+ event,
+ os_ironic_api_version=None,
+ global_request_id=None):
+ """Get a single event record for a node.
+
+ Provides the ability to request, and return
+ a node's single vent hisotyr entry.
+
+ :param node_ident: The name or UUID of the node.
+ :param event: The UUID of the event entry as listed
+ in the node event history list.
+ :param os_ironic_api_version: String version (e.g. "1.35") to use for
+ the request. If not specified, the client's default is used.
+ :param global_request_id: String containing global request ID header
+ value (in form "req-<UUID>") to use for the request.
+ """
+ path = "%s/history/%s" % (node_ident, event)
+ return self._get_as_dict(
+ path, os_ironic_api_version=os_ironic_api_version,
+ global_request_id=global_request_id)
diff --git a/ironicclient/v1/resource_fields.py b/ironicclient/v1/resource_fields.py
index 76cfaca..1c9aebe 100644
--- a/ironicclient/v1/resource_fields.py
+++ b/ironicclient/v1/resource_fields.py
@@ -79,6 +79,8 @@ class Resource(object):
'enabled_storage_interfaces': 'Enabled Storage Interfaces',
'enabled_vendor_interfaces': 'Enabled Vendor Interfaces',
'extra': 'Extra',
+ 'event': 'Description of the event',
+ 'event_type': 'Event Origin Type',
'hostname': 'Hostname',
'hosts': 'Active host(s)',
'http_methods': 'Supported HTTP methods',
@@ -140,8 +142,10 @@ class Resource(object):
'raid_interface': 'RAID Interface',
'rescue_interface': 'Rescue Interface',
'storage_interface': 'Storage Interface',
+ 'severity': 'Severity',
'unique': 'Unique',
'upper_bound': 'Upper Bound',
+ 'user': 'User',
'vendor_interface': 'Vendor Interface',
'standalone_ports_supported': 'Standalone Ports Supported',
'physical_network': 'Physical Network',
@@ -570,3 +574,21 @@ DEPLOY_TEMPLATE_RESOURCE = Resource(
'name',
],
)
+
+
+NODE_HISTORY_RESOURCE = Resource(
+ ['uuid',
+ 'created_at',
+ 'severity',
+ 'event']
+)
+
+NODE_HISTORY_DETAILED_RESOURCE = Resource(
+ ['uuid',
+ 'created_at',
+ 'severity',
+ 'event_type',
+ 'event',
+ 'conductor',
+ 'user']
+)
diff --git a/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml b/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml
new file mode 100644
index 0000000..dcdc202
--- /dev/null
+++ b/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml
@@ -0,0 +1,9 @@
+---
+features:
+ - |
+ Adds support for API version ``1.78`` and "node history" functionality
+ allowing users to query a list of events, and retrieve a single history
+ event from a baremetal node.
+ - Adds ``get_history_list`` and ``get_history_event`` methods to the python
+ client library. These methods allow operators to query recorded node event
+ information from an ironic API, where supported and enabled.
diff --git a/setup.cfg b/setup.cfg
index d8de9bb..b06b87d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -71,6 +71,8 @@ openstack.baremetal.v1 =
baremetal_node_create = ironicclient.osc.v1.baremetal_node:CreateBaremetalNode
baremetal_node_delete = ironicclient.osc.v1.baremetal_node:DeleteBaremetalNode
baremetal_node_deploy = ironicclient.osc.v1.baremetal_node:DeployBaremetalNode
+ baremetal_node_history_list = ironicclient.osc.v1.baremetal_node:NodeHistoryList
+ baremetal_node_history_get = ironicclient.osc.v1.baremetal_node:NodeHistoryEventGet
baremetal_node_inspect = ironicclient.osc.v1.baremetal_node:InspectBaremetalNode
baremetal_node_list = ironicclient.osc.v1.baremetal_node:ListBaremetalNode
baremetal_node_maintenance_set = ironicclient.osc.v1.baremetal_node:MaintenanceSetBaremetalNode