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
This commit is contained in:
Julia Kreger 2021-11-30 15:10:43 -08:00
parent 4ce3c4ebf2
commit 2e0cef2cb0
8 changed files with 229 additions and 1 deletions

View File

@ -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__)

View File

@ -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)

View File

@ -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):

View File

@ -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))

View File

@ -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)

View File

@ -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']
)

View File

@ -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.

View File

@ -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