diff --git a/ironic_inspector/plugins/introspection_data.py b/ironic_inspector/plugins/introspection_data.py index e0d8d6ac2..6f51d6b7b 100644 --- a/ironic_inspector/plugins/introspection_data.py +++ b/ironic_inspector/plugins/introspection_data.py @@ -42,10 +42,10 @@ def _filter_data_excluded_keys(data): class BaseStorageBackend(object): @abc.abstractmethod - def get(self, node_id, processed=True, get_json=False): + def get(self, node_uuid, processed=True, get_json=False): """Get introspected data from storage backend. - :param node_id: node UUID or name. + :param node_uuid: node UUID. :param processed: Specify whether the data to be retrieved is processed or not. :param get_json: Specify whether return the introspection data in json @@ -55,10 +55,10 @@ class BaseStorageBackend(object): """ @abc.abstractmethod - def save(self, node_info, data, processed=True): + def save(self, node_uuid, data, processed=True): """Save introspected data to storage backend. - :param node_info: a NodeInfo object. + :param node_uuid: node UUID. :param data: the introspected data to be saved, in dict format. :param processed: Specify whether the data to be saved is processed or not. @@ -67,57 +67,62 @@ class BaseStorageBackend(object): class NoStore(BaseStorageBackend): - def get(self, node_id, processed=True, get_json=False): + def get(self, node_uuid, processed=True, get_json=False): raise utils.IntrospectionDataStoreDisabled( 'Introspection data storage is disabled') - def save(self, node_info, data, processed=True): + def save(self, node_uuid, data, processed=True): LOG.debug('Introspection data storage is disabled, the data will not ' - 'be saved', node_info=node_info) + 'be saved for node %(node)s', {'node': node_uuid}) class SwiftStore(object): - def get(self, node_id, processed=True, get_json=False): + def get(self, node_uuid, processed=True, get_json=False): suffix = None if processed else _UNPROCESSED_DATA_STORE_SUFFIX - LOG.debug('Fetching introspection data from Swift for %s', node_id) - data = swift.get_introspection_data(node_id, suffix=suffix) + LOG.debug('Fetching introspection data from Swift for %s', node_uuid) + data = swift.get_introspection_data(node_uuid, suffix=suffix) if get_json: return json.loads(data) return data - def save(self, node_info, data, processed=True): + def save(self, node_uuid, data, processed=True): suffix = None if processed else _UNPROCESSED_DATA_STORE_SUFFIX swift_object_name = swift.store_introspection_data( _filter_data_excluded_keys(data), - node_info.uuid, + node_uuid, suffix=suffix ) - LOG.info('Introspection data was stored in Swift object %s', - swift_object_name, node_info=node_info) + LOG.info('Introspection data was stored for node %(node)s in Swift ' + 'object %(obj_name)s', {'node': node_uuid, + 'obj_name': swift_object_name}) if CONF.processing.store_data_location: + node_info = node_cache.get_node(node_uuid) + # TODO(kaifeng) node_info is not synced back, while we are not + # using extra in the processing logic, it looks fine at the moment, + # but we should consider refactor in a later time. node_info.patch([{'op': 'add', 'path': '/extra/%s' % CONF.processing.store_data_location, 'value': swift_object_name}]) class DatabaseStore(object): - def get(self, node_id, processed=True, get_json=False): + def get(self, node_uuid, processed=True, get_json=False): LOG.debug('Fetching introspection data from database for %(node)s', - {'node': node_id}) - data = node_cache.get_introspection_data(node_id, processed) + {'node': node_uuid}) + data = node_cache.get_introspection_data(node_uuid, processed) if get_json: return data return json.dumps(data) - def save(self, node_info, data, processed=True): + def save(self, node_uuid, data, processed=True): introspection_data = _filter_data_excluded_keys(data) try: - node_cache.store_introspection_data(node_info.uuid, + node_cache.store_introspection_data(node_uuid, introspection_data, processed) except Exception as e: with excutils.save_and_reraise_exception(): LOG.exception('Failed to store introspection data in ' 'database: %(exc)s', {'exc': e}) else: - LOG.info('Introspection data was stored in database', - node_info=node_info) + LOG.info('Introspection data was stored in database for node ' + '%(node)s', {'node': node_uuid}) diff --git a/ironic_inspector/process.py b/ironic_inspector/process.py index d41a76196..29673423c 100644 --- a/ironic_inspector/process.py +++ b/ironic_inspector/process.py @@ -140,21 +140,20 @@ def _filter_data_excluded_keys(data): if k not in _STORAGE_EXCLUDED_KEYS} -def _store_data(node_info, data, processed=True): +def _store_data(node_uuid, data, processed=True): introspection_data_manager = plugins_base.introspection_data_manager() store = CONF.processing.store_data ext = introspection_data_manager[store].obj - ext.save(node_info, data, processed) + ext.save(node_uuid, data, processed) -def _store_unprocessed_data(node_info, data): +def _store_unprocessed_data(node_uuid, data): # runs in background try: - _store_data(node_info, data, processed=False) + _store_data(node_uuid, data, processed=False) except Exception: LOG.exception('Encountered exception saving unprocessed ' - 'introspection data', node_info=node_info, - data=data) + 'introspection data for node %s', node_uuid, data=data) def get_introspection_data(uuid, processed=True, get_json=False): @@ -198,7 +197,7 @@ def process(introspection_data): # Note(mkovacik): store data now when we're sure that a background # thread won't race with other process() or introspect.abort() # call - utils.executor().submit(_store_unprocessed_data, node_info, + utils.executor().submit(_store_unprocessed_data, node_info.uuid, unprocessed_data) try: @@ -243,7 +242,7 @@ def _process_node(node_info, node, introspection_data): # NOTE(dtantsur): repeat the check in case something changed ir_utils.check_provision_state(node) _run_post_hooks(node_info, introspection_data) - _store_data(node_info, introspection_data) + _store_data(node_info.uuid, introspection_data) ironic = ir_utils.get_client() pxe_filter.driver().sync(ironic) @@ -351,6 +350,6 @@ def _reapply_with_data(node_info, introspection_data): '\n'.join(failures), node_info=node_info) _run_post_hooks(node_info, introspection_data) - _store_data(node_info, introspection_data) + _store_data(node_info.uuid, introspection_data) node_info.invalidate_cache() rules.apply(node_info, introspection_data) diff --git a/ironic_inspector/test/unit/test_plugins_introspection_data.py b/ironic_inspector/test/unit/test_plugins_introspection_data.py index c2b74d508..61c9d9ba4 100644 --- a/ironic_inspector/test/unit/test_plugins_introspection_data.py +++ b/ironic_inspector/test/unit/test_plugins_introspection_data.py @@ -72,16 +72,23 @@ class TestSwiftStore(BaseTest): swift_conn.create_object.assert_called_once_with(name, json.dumps(data)) + def _create_node(self): + session = db.get_writer_session() + with session.begin(): + db.Node(uuid=self.node_info.uuid, + state=istate.States.starting).save(session) + def test_store_data_location(self, swift_mock): CONF.set_override('store_data_location', 'inspector_data_object', 'processing') + self._create_node() swift_conn = swift_mock.return_value name = 'inspector_data-%s' % self.uuid patch = [{'path': '/extra/inspector_data_object', 'value': name, 'op': 'add'}] expected = self.data - self.driver.save(self.node_info, self.data) + self.driver.save(self.node_info.uuid, self.data) data = introspection_data._filter_data_excluded_keys(self.data) swift_conn.create_object.assert_called_once_with(name, @@ -101,7 +108,7 @@ class TestDatabaseStore(BaseTest): state=istate.States.starting).save(session) def test_store_and_get_data(self): - self.driver.save(self.node_info, self.data) + self.driver.save(self.node_info.uuid, self.data) res_data = self.driver.get(self.node_info.uuid)