Convert eDeploy data so that rules can process it

eDeploy's return format is a list of lists, in order to use it with
introspection rules we must convert it to dictionary format. This patch
detects if the data is in eDeploy's format and will convert it storing
the new data in introspection_data['extra']. introspection_data['data']
is assumed unusable by introspection rules and will always be removed
from introspection_data after the data is stored in swift.

Change-Id: I25c7ef1f3d3122b80ea98e4d0e64ea20e2eec618
Closes-Bug: #1495649
This commit is contained in:
Sam Betts 2015-09-18 13:55:59 +01:00
parent 4c6c350447
commit 973dd160b3
2 changed files with 76 additions and 4 deletions

View File

@ -29,8 +29,8 @@ from ironic_inspector.plugins import base
CONF = cfg.CONF
LOG = log.getLogger('ironic_inspector.plugins.extra_hardware')
EDEPLOY_ITEM_SIZE = 4
class ExtraHardwareHook(base.ProcessingHook):
@ -54,10 +54,46 @@ class ExtraHardwareHook(base.ProcessingHook):
LOG.warning(_LW('No extra hardware information was received from '
'the ramdisk'))
return
data = introspection_data['data']
name = 'extra_hardware-%s' % node_info.uuid
self._store_extra_hardware(name,
json.dumps(introspection_data['data']))
self._store_extra_hardware(name, json.dumps(data))
# NOTE(sambetts) If data is edeploy format, convert to dicts for rules
# processing, store converted data in introspection_data['extra'].
# Delete introspection_data['data'], it is assumed unusable
# by rules.
if self._is_edeploy_data(data):
LOG.debug('Extra hardware data is in eDeploy format, '
'converting to usable format.')
introspection_data['extra'] = self._convert_edeploy_data(data)
else:
LOG.warning(_LW('Extra hardware data was not in a recognised '
'format (eDeploy), and will not be forwarded to '
'introspection rules.'))
LOG.debug('Deleting \"data\" key from introspection data as it is '
'assumed unusable by introspection rules. Raw data is '
'stored in swift.')
del introspection_data['data']
node_info.patch([{'op': 'add', 'path': '/extra/hardware_swift_object',
'value': name}])
def _is_edeploy_data(self, data):
return all(isinstance(item, list) and len(item) == EDEPLOY_ITEM_SIZE
for item in data)
def _convert_edeploy_data(self, data):
converted = {}
for item in data:
converted_0 = converted.setdefault(item[0], {})
converted_1 = converted_0.setdefault(item[1], {})
try:
item[3] = int(item[3])
except ValueError:
pass
converted_1[item[2]] = item[3]
return converted

View File

@ -30,17 +30,53 @@ class TestExtraHardware(test_base.NodeTest):
'data': [['memory', 'total', 'size', '4294967296'],
['cpu', 'physical', 'number', '1'],
['cpu', 'logical', 'number', '1']]}
data = json.dumps(introspection_data['data'])
self.hook.before_processing(introspection_data)
self.hook.before_update(introspection_data, self.node_info)
swift_conn = swift_mock.return_value
name = 'extra_hardware-%s' % self.uuid
data = json.dumps(introspection_data['data'])
swift_conn.create_object.assert_called_once_with(name, data)
patch_mock.assert_called_once_with(
[{'op': 'add', 'path': '/extra/hardware_swift_object',
'value': name}])
expected = {
'memory': {
'total': {
'size': 4294967296
}
},
'cpu': {
'physical': {
'number': 1
},
'logical': {
'number': 1
},
}
}
self.assertEqual(expected, introspection_data['extra'])
def test_data_not_in_edeploy_format(self, patch_mock, swift_mock):
introspection_data = {
'data': [['memory', 'total', 'size', '4294967296'],
['cpu', 'physical', 'number', '1'],
{'interface': 'eth1'}]}
data = json.dumps(introspection_data['data'])
self.hook.before_processing(introspection_data)
self.hook.before_update(introspection_data, self.node_info)
swift_conn = swift_mock.return_value
name = 'extra_hardware-%s' % self.uuid
swift_conn.create_object.assert_called_once_with(name, data)
patch_mock.assert_called_once_with(
[{'op': 'add', 'path': '/extra/hardware_swift_object',
'value': name}])
self.assertFalse('data' in introspection_data)
def test_no_data_recieved(self, patch_mock, swift_mock):
introspection_data = {'cats': 'meow'}
swift_conn = swift_mock.return_value