Merge "Fallback to `node_uuid` if`node_name` is not present" into stable/train
This commit is contained in:
commit
2a3893b058
|
@ -56,9 +56,10 @@ class PrometheusFileDriver(notifier.Driver):
|
||||||
elif event_type == 'hardware.redfish.metrics':
|
elif event_type == 'hardware.redfish.metrics':
|
||||||
redfish.category_registry(node_message, registry)
|
redfish.category_registry(node_message, registry)
|
||||||
|
|
||||||
|
field = (node_message.get('node_name')
|
||||||
|
or node_message.get('node_uuid'))
|
||||||
nodeFile = os.path.join(
|
nodeFile = os.path.join(
|
||||||
self.location,
|
self.location, field + '-' + event_type)
|
||||||
node_message['node_name'] + '-' + event_type)
|
|
||||||
write_to_textfile(nodeFile, registry)
|
write_to_textfile(nodeFile, registry)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -18,11 +18,12 @@ from ironic_prometheus_exporter import utils as ipe_utils
|
||||||
from ironic_prometheus_exporter.parsers import descriptions
|
from ironic_prometheus_exporter.parsers import descriptions
|
||||||
|
|
||||||
|
|
||||||
def timestamp_registry(node_information, ipmi_metric_registry):
|
def timestamp_registry(node_information, metric_registry):
|
||||||
metric = 'baremetal_last_payload_timestamp_seconds'
|
metric = 'baremetal_last_payload_timestamp_seconds'
|
||||||
labels = {'node_name': node_information['node_name'],
|
labels = {'node_uuid': node_information['node_uuid'],
|
||||||
'node_uuid': node_information['node_uuid'],
|
|
||||||
'instance_uuid': node_information['instance_uuid']}
|
'instance_uuid': node_information['instance_uuid']}
|
||||||
|
if node_information['node_name']:
|
||||||
|
labels['node_name'] = node_information['node_name']
|
||||||
dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
|
dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
|
||||||
dt_timestamp = datetime.strptime(node_information['timestamp'],
|
dt_timestamp = datetime.strptime(node_information['timestamp'],
|
||||||
'%Y-%m-%dT%H:%M:%S.%f')
|
'%Y-%m-%dT%H:%M:%S.%f')
|
||||||
|
@ -32,7 +33,7 @@ def timestamp_registry(node_information, ipmi_metric_registry):
|
||||||
|
|
||||||
g = Gauge(
|
g = Gauge(
|
||||||
metric, desc, labelnames=labels,
|
metric, desc, labelnames=labels,
|
||||||
registry=ipmi_metric_registry)
|
registry=metric_registry)
|
||||||
|
|
||||||
valid_labels = ipe_utils.update_instance_uuid(labels)
|
valid_labels = ipe_utils.update_instance_uuid(labels)
|
||||||
g.labels(**valid_labels).set(value)
|
g.labels(**valid_labels).set(value)
|
||||||
|
|
|
@ -163,6 +163,8 @@ def extract_labels(entries, category_info):
|
||||||
'instance_uuid': category_info['instance_uuid'],
|
'instance_uuid': category_info['instance_uuid'],
|
||||||
'entity_id': category_info['data'][entries[0]]['Entity ID'],
|
'entity_id': category_info['data'][entries[0]]['Entity ID'],
|
||||||
'sensor_id': category_info['data'][entries[0]]['Sensor ID']}
|
'sensor_id': category_info['data'][entries[0]]['Sensor ID']}
|
||||||
|
if not category_info['node_name']:
|
||||||
|
del labels['node_name']
|
||||||
if status:
|
if status:
|
||||||
labels['status'] = status
|
labels['status'] = status
|
||||||
return {entries[0]: labels}
|
return {entries[0]: labels}
|
||||||
|
@ -177,6 +179,8 @@ def extract_labels(entries, category_info):
|
||||||
'instance_uuid': category_info['instance_uuid'],
|
'instance_uuid': category_info['instance_uuid'],
|
||||||
'entity_id': entity_id,
|
'entity_id': entity_id,
|
||||||
'sensor_id': sensor_id}
|
'sensor_id': sensor_id}
|
||||||
|
if not category_info['node_name']:
|
||||||
|
del metric_label['node_name']
|
||||||
if status:
|
if status:
|
||||||
metric_label['status'] = status
|
metric_label['status'] = status
|
||||||
entries_labels[entry] = metric_label
|
entries_labels[entry] = metric_label
|
||||||
|
|
|
@ -23,9 +23,11 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _build_labels(node_message):
|
def _build_labels(node_message):
|
||||||
|
fields = ['node_name', 'node_uuid', 'instance_uuid']
|
||||||
|
if not node_message['node_name']:
|
||||||
|
fields.remove('node_name')
|
||||||
return {
|
return {
|
||||||
k: node_message[k]
|
k: node_message[k] for k in fields
|
||||||
for k in ('node_name', 'node_uuid', 'instance_uuid')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"priority": "INFO",
|
||||||
|
"event_type": "hardware.redfish.metrics",
|
||||||
|
"timestamp": "2019-03-29 20:12:26.885347",
|
||||||
|
"publisher_id": "None.localhost.localdomain",
|
||||||
|
"payload": {
|
||||||
|
"instance_uuid":"85d6b2c8-fe57-432d-868a-330e0e28cf34",
|
||||||
|
"node_uuid": "6d85703a-565d-469a-96ce-30b6de53079d",
|
||||||
|
"event_type": "hardware.redfish.metrics.update",
|
||||||
|
"timestamp": "2019-03-29T20:12:22.989020",
|
||||||
|
"node_name": "",
|
||||||
|
"message_id": "330e0e28-fe43-5786-2d8a-85d6b2c8cf34",
|
||||||
|
"payload": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"message_id": "2c0da1e8-1958-484f-9bdd-9117d717f7fa"
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"priority": "INFO",
|
||||||
|
"event_type": "hardware.redfish.metrics",
|
||||||
|
"timestamp": "2019-03-29 20:12:26.885347",
|
||||||
|
"publisher_id": "None.localhost.localdomain",
|
||||||
|
"payload": {
|
||||||
|
"instance_uuid": "85d6b2c8-fe57-432d-868a-330e0e28cf34" ,
|
||||||
|
"node_uuid": "6d85703a-565d-469a-96ce-30b6de53079d",
|
||||||
|
"event_type": "hardware.redfish.metrics.update",
|
||||||
|
"timestamp": "2019-03-29T20:12:22.989020",
|
||||||
|
"node_name": null,
|
||||||
|
"message_id": "85d6b2c8-fe57-432d-868a-330e0e28cf34",
|
||||||
|
"payload": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"message_id": "2c0da1e8-1958-484f-9bdd-9117d717f7fa"
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"priority": "INFO",
|
||||||
|
"event_type": "hardware.redfish.metrics",
|
||||||
|
"timestamp": "2019-03-29 20:12:26.885347",
|
||||||
|
"publisher_id": "None.localhost.localdomain",
|
||||||
|
"payload": {
|
||||||
|
"instance_uuid": "85d6b2c8-fe57-432d-868a-330e0e28cf34",
|
||||||
|
"node_uuid": "c2bd00b9-9881-4179-8b7b-bf786ec3696b",
|
||||||
|
"event_type": "hardware.redfish.metrics.update",
|
||||||
|
"timestamp": "2019-03-29T20:12:22.989020",
|
||||||
|
"node_name": null,
|
||||||
|
"message_id": "85d6b2c8-fe57-432d-868a-330e0e28cf34",
|
||||||
|
"payload": {
|
||||||
|
"Temperature": {
|
||||||
|
"XXX-YYY-ZZZ@ZZZ-YYY-XXX": {
|
||||||
|
"identity": "XXX-YYY-ZZZ",
|
||||||
|
"max_reading_range_temp": 120,
|
||||||
|
"min_reading_range_temp": 0,
|
||||||
|
"physical_context": "CPU",
|
||||||
|
"reading_celsius": 62,
|
||||||
|
"sensor_number": 1,
|
||||||
|
"health": "OK",
|
||||||
|
"state": "enabled"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Power": {
|
||||||
|
"0:Power@ZZZ-YYY-XXX": {
|
||||||
|
"health": "OK",
|
||||||
|
"last_power_output_watts": 650,
|
||||||
|
"line_input_voltage": 220,
|
||||||
|
"maximum_frequency_hz": 63,
|
||||||
|
"maximum_voltage": 250,
|
||||||
|
"minimum_frequency_hz": 47,
|
||||||
|
"minimum_voltage": 185,
|
||||||
|
"output_wattage": 1450,
|
||||||
|
"power_capacity_watts": 1450,
|
||||||
|
"serial_number": "SN010203040506",
|
||||||
|
"state": "enabled"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Fan": {
|
||||||
|
"XXX-YYY-ZZZ@ZZZ-YYY-XXX": {
|
||||||
|
"identity": "XXX-YYY-ZZZ",
|
||||||
|
"max_reading_range": 10000,
|
||||||
|
"min_reading_range": 0,
|
||||||
|
"physical_context": "CPU",
|
||||||
|
"reading": 6000,
|
||||||
|
"reading_units": "RPM",
|
||||||
|
"serial_number": "SN010203040506",
|
||||||
|
"health": "OK",
|
||||||
|
"state": "enabled"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Drive": {
|
||||||
|
"32ADF365C6C1B7BD:XXX-YYY-ZZZ@ZZZ-YYY-XXX": {
|
||||||
|
"capacity_bytes": 3750000000,
|
||||||
|
"failure_predicted": true,
|
||||||
|
"health": "OK",
|
||||||
|
"identity": "32ADF365C6C1B7BD",
|
||||||
|
"model": "IBM 350A",
|
||||||
|
"state": "enabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"message_id": "2c0da1e8-1958-484f-9bdd-9117d717f7fa"
|
||||||
|
}
|
|
@ -65,3 +65,31 @@ class TestPayloadsParser(unittest.TestCase):
|
||||||
'node_uuid': msg2['payload']['node_uuid'],
|
'node_uuid': msg2['payload']['node_uuid'],
|
||||||
'instance_uuid': msg2['payload']['node_uuid']}
|
'instance_uuid': msg2['payload']['node_uuid']}
|
||||||
))
|
))
|
||||||
|
|
||||||
|
def test_none_for_node_name(self):
|
||||||
|
sample_file_2 = os.path.join(
|
||||||
|
os.path.dirname(ironic_prometheus_exporter.__file__),
|
||||||
|
'tests', 'json_samples', 'notification-none-node_name.json')
|
||||||
|
msg2 = json.load(open(sample_file_2))
|
||||||
|
self.assertIsNone(msg2['payload']['node_name'])
|
||||||
|
|
||||||
|
header.timestamp_registry(msg2['payload'], self.metric_registry)
|
||||||
|
self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_last_payload_timestamp_seconds',
|
||||||
|
{'node_uuid': msg2['payload']['node_uuid'],
|
||||||
|
'instance_uuid': msg2['payload']['instance_uuid']}
|
||||||
|
))
|
||||||
|
|
||||||
|
def test_empty_for_node_name(self):
|
||||||
|
sample_file_2 = os.path.join(
|
||||||
|
os.path.dirname(ironic_prometheus_exporter.__file__),
|
||||||
|
'tests', 'json_samples', 'notification-empty-node_name.json')
|
||||||
|
msg2 = json.load(open(sample_file_2))
|
||||||
|
self.assertEqual(msg2['payload']['node_name'], "")
|
||||||
|
|
||||||
|
header.timestamp_registry(msg2['payload'], self.metric_registry)
|
||||||
|
self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_last_payload_timestamp_seconds',
|
||||||
|
{'node_uuid': msg2['payload']['node_uuid'],
|
||||||
|
'instance_uuid': msg2['payload']['instance_uuid']}
|
||||||
|
))
|
||||||
|
|
|
@ -955,3 +955,88 @@ class TestPayloadsParser(unittest.TestCase):
|
||||||
'instance_uuid': msg2['payload']['node_uuid'],
|
'instance_uuid': msg2['payload']['node_uuid'],
|
||||||
'entity_id': '7.1 (System Board)',
|
'entity_id': '7.1 (System Board)',
|
||||||
'sensor_id': 'Front LED Panel (0x23)'}))
|
'sensor_id': 'Front LED Panel (0x23)'}))
|
||||||
|
|
||||||
|
|
||||||
|
class TestPayloadsParserNoneNodeName(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
sample_file = os.path.join(
|
||||||
|
os.path.dirname(ironic_prometheus_exporter.__file__),
|
||||||
|
'tests', 'json_samples',
|
||||||
|
'notification-ipmi-none-node_name.json')
|
||||||
|
msg = json.load(open(sample_file))
|
||||||
|
self.node_message = msg['payload']
|
||||||
|
self.node_name = msg['payload']['node_name']
|
||||||
|
self.node_uuid = msg['payload']['node_uuid']
|
||||||
|
self.instance_uuid = msg['payload']['instance_uuid']
|
||||||
|
self.timestamp = msg['payload']['timestamp']
|
||||||
|
self.payload = msg['payload']['payload']
|
||||||
|
self.metric_registry = CollectorRegistry()
|
||||||
|
|
||||||
|
def test_management_parser(self):
|
||||||
|
management_category_info = ipmi.CATEGORY_PARAMS['management'].copy()
|
||||||
|
management_category_info['data'] = \
|
||||||
|
self.node_message['payload']['Management'].copy()
|
||||||
|
management_category_info['node_name'] = self.node_name
|
||||||
|
management_category_info['node_uuid'] = self.node_uuid
|
||||||
|
management_category_info['instance_uuid'] = self.instance_uuid
|
||||||
|
|
||||||
|
management_metrics_name = ipmi.metric_names(management_category_info)
|
||||||
|
self.assertEqual(len(management_metrics_name), 1)
|
||||||
|
self.assertIn('baremetal_front_led_panel', management_metrics_name)
|
||||||
|
|
||||||
|
ipmi.prometheus_format(management_category_info,
|
||||||
|
self.metric_registry,
|
||||||
|
management_metrics_name)
|
||||||
|
self.assertEqual(0.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_front_led_panel',
|
||||||
|
{'node_uuid': self.node_uuid,
|
||||||
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'entity_id': '7.1 (System Board)',
|
||||||
|
'sensor_id': 'Front LED Panel (0x23)'}))
|
||||||
|
|
||||||
|
def test_temperature_parser(self):
|
||||||
|
temperature_category_info = ipmi.CATEGORY_PARAMS['temperature'].copy()
|
||||||
|
temperature_category_info['data'] = \
|
||||||
|
self.node_message['payload']['Temperature'].copy()
|
||||||
|
temperature_category_info['node_name'] = self.node_name
|
||||||
|
temperature_category_info['node_uuid'] = self.node_uuid
|
||||||
|
temperature_category_info['instance_uuid'] = self.instance_uuid
|
||||||
|
|
||||||
|
temperature_metrics_name = ipmi.metric_names(temperature_category_info)
|
||||||
|
self.assertEqual(len(temperature_metrics_name), 3)
|
||||||
|
self.assertIn('baremetal_temp_celsius', temperature_metrics_name)
|
||||||
|
self.assertIn('baremetal_exhaust_temp_celsius',
|
||||||
|
temperature_metrics_name)
|
||||||
|
self.assertIn('baremetal_inlet_temp_celsius', temperature_metrics_name)
|
||||||
|
|
||||||
|
ipmi.prometheus_format(temperature_category_info,
|
||||||
|
self.metric_registry,
|
||||||
|
temperature_metrics_name)
|
||||||
|
self.assertEqual(21.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_inlet_temp_celsius',
|
||||||
|
{'node_uuid': self.node_uuid,
|
||||||
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'entity_id': '7.1 (System Board)',
|
||||||
|
'sensor_id': 'Inlet Temp (0x5)',
|
||||||
|
'status': 'ok'}
|
||||||
|
))
|
||||||
|
self.assertEqual(36.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_exhaust_temp_celsius',
|
||||||
|
{'node_uuid': self.node_uuid,
|
||||||
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'entity_id': '7.1 (System Board)',
|
||||||
|
'sensor_id': 'Exhaust Temp (0x6)',
|
||||||
|
'status': 'ok'}))
|
||||||
|
self.assertEqual(44.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_temp_celsius', {'sensor_id': 'Temp (0x1)',
|
||||||
|
'node_uuid': self.node_uuid,
|
||||||
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'entity_id': '3.1 (Processor)',
|
||||||
|
'status': 'ok'}))
|
||||||
|
self.assertEqual(43.0, self.metric_registry.get_sample_value(
|
||||||
|
'baremetal_temp_celsius', {'sensor_id': 'Temp (0x2)',
|
||||||
|
'node_uuid': self.node_uuid,
|
||||||
|
'instance_uuid': self.instance_uuid,
|
||||||
|
'entity_id': '3.2 (Processor)',
|
||||||
|
'status': 'ok'}))
|
||||||
|
|
|
@ -151,3 +151,35 @@ class TestPayloadsParser(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
expected_labels, metrics[expected_metric][0][1])
|
expected_labels, metrics[expected_metric][0][1])
|
||||||
|
|
||||||
|
|
||||||
|
class TestPayloadsParserNoneNodeName(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
sample_file_none = os.path.join(
|
||||||
|
os.path.dirname(ironic_prometheus_exporter.__file__),
|
||||||
|
'tests', 'json_samples',
|
||||||
|
'notification-redfish-none-node_name.json')
|
||||||
|
msg = json.load(open(sample_file_none))
|
||||||
|
self.node_message = msg['payload']
|
||||||
|
self.node_uuid = msg['payload']['node_uuid']
|
||||||
|
self.instance_uuid = msg['payload']['instance_uuid']
|
||||||
|
|
||||||
|
def test_build_temperature_metrics(self):
|
||||||
|
metrics = redfish.build_temperature_metrics(self.node_message)
|
||||||
|
|
||||||
|
expected_metric = 'baremetal_temp_cpu_celsius'
|
||||||
|
|
||||||
|
self.assertIn(expected_metric, metrics)
|
||||||
|
|
||||||
|
self.assertEqual(62, metrics[expected_metric][0][0])
|
||||||
|
|
||||||
|
expected_labels = {
|
||||||
|
'entity_id': 'CPU',
|
||||||
|
'instance_uuid': '85d6b2c8-fe57-432d-868a-330e0e28cf34',
|
||||||
|
'node_uuid': 'c2bd00b9-9881-4179-8b7b-bf786ec3696b',
|
||||||
|
'sensor_id': 1
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
expected_labels, metrics[expected_metric][0][1])
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fix an issue where IPE fails if the node does not have `node_name` set
|
2
tox.ini
2
tox.ini
|
@ -53,7 +53,7 @@ deps =
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E129
|
ignore = E129,W503
|
||||||
show-source = True
|
show-source = True
|
||||||
builtins = _
|
builtins = _
|
||||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
||||||
|
|
Loading…
Reference in New Issue