Fix None for instance_uuid label

In some envs the `instance_uuid` can be `None`, if this happens
we will override using `node_uuid`.

Change-Id: Ie26d42bc3842f2446d1ddc9704f5df431306aa46
Story: #2007302
Task: #38779
(cherry picked from commit 09f802160e)
This commit is contained in:
Iury Gregory Melo Ferreira 2020-02-06 19:12:59 +01:00 committed by Iury Gregory Melo Ferreira
parent 212e553f50
commit 4a6d6131d7
11 changed files with 2549 additions and 3 deletions

View File

@ -14,6 +14,7 @@ from datetime import datetime
from prometheus_client import Gauge
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import descriptions
@ -33,4 +34,5 @@ def timestamp_registry(node_information, ipmi_metric_registry):
metric, desc, labelnames=labels,
registry=ipmi_metric_registry)
g.labels(**labels).set(value)
valid_labels = ipe_utils.update_instance_uuid(labels)
g.labels(**valid_labels).set(value)

View File

@ -17,6 +17,7 @@ import re
from prometheus_client import Gauge
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import descriptions
@ -230,7 +231,8 @@ def prometheus_format(category_info, ipmi_metric_registry, available_metrics):
for e in entries:
if values[e] is None:
continue
g.labels(**labels[e]).set(values[e])
valid_labels = ipe_utils.update_instance_uuid(labels[e])
g.labels(**valid_labels).set(values[e])
def category_registry(node_message, ipmi_metric_registry):

View File

@ -15,6 +15,7 @@ import logging
from prometheus_client import Gauge
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import descriptions
@ -261,4 +262,5 @@ def category_registry(node_message, metrics_registry):
registry=metrics_registry)
for value, labels in details:
gauge.labels(**labels).set(value)
valid_labels = ipe_utils.update_instance_uuid(labels)
gauge.labels(**valid_labels).set(value)

View File

@ -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":null ,
"node_uuid": "6d85703a-565d-469a-96ce-30b6de53079d",
"event_type": "hardware.redfish.metrics.update",
"timestamp": "2019-03-29T20:12:22.989020",
"node_name": "knilab-master-u9",
"message_id": "85d6b2c8-fe57-432d-868a-330e0e28cf34",
"payload": {
}
},
"message_id": "2c0da1e8-1958-484f-9bdd-9117d717f7fa"
}

View File

@ -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": null,
"node_uuid": "c2bd00b9-9881-4179-8b7b-bf786ec3696b",
"event_type": "hardware.redfish.metrics.update",
"timestamp": "2019-03-29T20:12:22.989020",
"node_name": "knilab-master-u9",
"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"
}

View File

@ -15,6 +15,7 @@ import os
import unittest
import ironic_prometheus_exporter
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import header
from prometheus_client import CollectorRegistry
@ -46,3 +47,21 @@ class TestPayloadsParser(unittest.TestCase):
'node_uuid': self.node_uuid,
'instance_uuid': self.instance_uuid}
))
def test_none_for_instance_uuid(self):
sample_file_2 = os.path.join(
os.path.dirname(ironic_prometheus_exporter.__file__),
'tests', 'json_samples', 'notification-header-with-none.json')
msg2 = json.load(open(sample_file_2))
self.assertIsNone(msg2['payload']['instance_uuid'])
valid_labels = ipe_utils.update_instance_uuid(msg2['payload'])
self.assertEqual(valid_labels['instance_uuid'],
msg2['payload']['node_uuid'])
header.timestamp_registry(msg2['payload'], self.metric_registry)
self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
'baremetal_last_payload_timestamp_seconds',
{'node_name': msg2['payload']['node_name'],
'node_uuid': msg2['payload']['node_uuid'],
'instance_uuid': msg2['payload']['node_uuid']}
))

View File

@ -15,6 +15,7 @@ import os
import unittest
import ironic_prometheus_exporter
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import ipmi
from prometheus_client import CollectorRegistry
@ -920,3 +921,37 @@ class TestPayloadsParser(unittest.TestCase):
'instance_uuid': self.instance_uuid,
'sensor_id': 'Pfault Fail Safe (0x74)'}
))
def test_none_instance_uuid(self):
sample_file2 = os.path.join(
os.path.dirname(ironic_prometheus_exporter.__file__),
'tests', 'json_samples',
'notification-ipmi-none-instance_uuid.json')
msg2 = json.load(open(sample_file2))
self.assertIsNone(msg2['payload']['instance_uuid'])
valid_labels = ipe_utils.update_instance_uuid(msg2['payload'])
self.assertEqual(valid_labels['instance_uuid'],
msg2['payload']['node_uuid'])
management_category_info = ipmi.CATEGORY_PARAMS['management'].copy()
management_category_info['data'] = \
msg2['payload']['payload']['Management'].copy()
management_category_info['node_name'] = msg2['payload']['node_name']
management_category_info['node_uuid'] = msg2['payload']['node_uuid']
management_category_info['instance_uuid'] = \
msg2['payload']['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_name': 'knilab-master-u9',
'node_uuid': msg2['payload']['node_uuid'],
'instance_uuid': msg2['payload']['node_uuid'],
'entity_id': '7.1 (System Board)',
'sensor_id': 'Front LED Panel (0x23)'}))

View File

@ -3,6 +3,7 @@ import os
import unittest
import ironic_prometheus_exporter
from ironic_prometheus_exporter import utils as ipe_utils
from ironic_prometheus_exporter.parsers import redfish
from prometheus_client import CollectorRegistry
@ -119,3 +120,34 @@ class TestPayloadsParser(unittest.TestCase):
'baremetal_drive_status', label)
self.assertEqual(0, sensor_value)
def test_none_instance_uuid(self):
sample_file2 = os.path.join(
os.path.dirname(ironic_prometheus_exporter.__file__),
'tests', 'json_samples',
'notification-redfish-none-instance_uuid.json')
msg2 = json.load(open(sample_file2))
self.assertIsNone(msg2['payload']['instance_uuid'])
valid_labels = ipe_utils.update_instance_uuid(msg2['payload'])
self.assertEqual(valid_labels['instance_uuid'],
msg2['payload']['node_uuid'])
metrics = redfish.build_power_metrics(msg2['payload'])
expected_metric = 'baremetal_power_status'
self.assertIn(expected_metric, metrics)
self.assertEqual(0, metrics[expected_metric][0][0])
expected_labels = {
'entity_id': 'PSU',
'instance_uuid': 'c2bd00b9-9881-4179-8b7b-bf786ec3696b',
'node_name': 'knilab-master-u9',
'node_uuid': 'c2bd00b9-9881-4179-8b7b-bf786ec3696b',
'sensor_id': '0:Power@ZZZ-YYY-XXX'
}
self.assertEqual(
expected_labels, metrics[expected_metric][0][1])

View File

@ -0,0 +1,17 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
def update_instance_uuid(labels):
if labels['instance_uuid'] is None and labels['node_uuid']:
labels['instance_uuid'] = labels.get('node_uuid')
return labels

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes the value for `instance_uuid` field when the value is `None` in all
parsers, we will use the same value of `node_uuid` in `instance_uuid`.