def _populate_and_retrieve_violations(self, mock_get_utc_now): fake_datetime = datetime.datetime(2010, 8, 28, 10, 20, 30, 0) mock_get_utc_now.return_value = fake_datetime scanner_index_id = self.populate_db(inv_index_id=self.inv_index_id2) violations = self.violation_access.list( scanner_index_id=scanner_index_id) violations_as_dict = [] for violation in violations: violations_as_dict.append( scanner_dao.convert_sqlalchemy_object_to_dict(violation)) violations_as_dict = notifier.convert_to_timestamp(violations_as_dict) return violations_as_dict
def test_convert_sqlalchemy_object_to_dict(self, mock_violation_hash): mock_violation_hash.side_effect = [ scanner_base_db.FAKE_VIOLATION_HASH, scanner_base_db.FAKE_VIOLATION_HASH ] scanner_index_id = self.populate_db(inv_index_id=self.inv_index_id1) saved_violations = self.violation_access.list( scanner_index_id=scanner_index_id) converted_violations_as_dict = [] for violation in saved_violations: converted_violations_as_dict.append( scanner_dao.convert_sqlalchemy_object_to_dict(violation)) expected_violations_as_dict = [{ 'full_name': u'full_name_111', 'id': 1, 'resource_name': 'fw-tag-match_111', 'resource_data': u'inventory_data_111', 'scanner_index_id': scanner_index_id, 'resource_id': u'fake_firewall_111', 'resource_type': u'firewall_rule', 'rule_index': 111, 'rule_name': u'disallow_all_ports_111', 'violation_data': (u'{"policy_names": ["fw-tag-match_111"], ' '"recommended_actions": {"DELETE_FIREWALL_RULES": ' '["fw-tag-match_111"]}}'), 'violation_type': u'FIREWALL_BLACKLIST_VIOLATION_111', 'violation_hash': scanner_base_db.FAKE_VIOLATION_HASH, }, { 'full_name': u'full_name_222', 'id': 2, 'resource_name': 'fw-tag-match_222', 'resource_data': u'inventory_data_222', 'scanner_index_id': scanner_index_id, 'resource_id': u'fake_firewall_222', 'resource_type': u'firewall_rule', 'rule_index': 222, 'rule_name': u'disallow_all_ports_222', 'violation_data': (u'{"policy_names": ["fw-tag-match_222"], ' '"recommended_actions": {"DELETE_FIREWALL_RULES": ' '["fw-tag-match_222"]}}'), 'violation_type': u'FIREWALL_BLACKLIST_VIOLATION_222', 'violation_hash': scanner_base_db.FAKE_VIOLATION_HASH, }] # It's useless testing 'created_at_datetime' as we can't mock datetime # and we only care about its type and not its value. for violation in converted_violations_as_dict: del violation['created_at_datetime'] self.assertEqual(expected_violations_as_dict, converted_violations_as_dict) self.assertEqual(mock_violation_hash.call_count, len(scanner_base_db.FAKE_VIOLATIONS))
def run(inventory_index_id, scanner_index_id, progress_queue, service_config=None): """Run the notifier. Entry point when the notifier is run as a library. Args: inventory_index_id (int64): Inventory index id. scanner_index_id (int64): Scanner index id. progress_queue (Queue): The progress queue. service_config (ServiceConfig): Forseti 2.0 service configs. Returns: int: Status code. """ # pylint: disable=too-many-locals global_configs = service_config.get_global_config() notifier_configs = service_config.get_notifier_config() with service_config.scoped_session() as session: if scanner_index_id: inventory_index_id = ( DataAccess.get_inventory_index_id_by_scanner_index_id( session, scanner_index_id)) else: if not inventory_index_id: inventory_index_id = ( DataAccess.get_latest_inventory_index_id(session)) scanner_index_id = scanner_dao.get_latest_scanner_index_id( session, inventory_index_id) if not scanner_index_id: LOGGER.error( 'No success or partial success scanner index found for ' 'inventory index: "%s".', str(inventory_index_id)) else: # get violations violation_access = scanner_dao.ViolationAccess(session) violations = violation_access.list( scanner_index_id=scanner_index_id) violations_as_dict = [] for violation in violations: violations_as_dict.append( scanner_dao.convert_sqlalchemy_object_to_dict(violation)) violations_as_dict = convert_to_timestamp(violations_as_dict) violation_map = scanner_dao.map_by_resource(violations_as_dict) for retrieved_v in violation_map: log_message = ( 'Retrieved {} violations for resource \'{}\''.format( len(violation_map[retrieved_v]), retrieved_v)) LOGGER.info(log_message) progress_queue.put(log_message) # build notification notifiers notifiers = [] for resource in notifier_configs['resources']: if violation_map.get(resource['resource']) is None: log_message = 'Resource \'{}\' has no violations'.format( resource['resource']) progress_queue.put(log_message) LOGGER.info(log_message) continue if not resource['should_notify']: LOGGER.debug('Not notifying for: %s', resource['resource']) continue for notifier in resource['notifiers']: log_message = ( 'Running \'{}\' notifier for resource \'{}\''.format( notifier['name'], resource['resource'])) progress_queue.put(log_message) LOGGER.info(log_message) chosen_pipeline = find_notifiers(notifier['name']) notifiers.append(chosen_pipeline( resource['resource'], inventory_index_id, violation_map[resource['resource']], global_configs, notifier_configs, notifier.get('configuration'))) # Run the notifiers. for notifier in notifiers: notifier.run() # Run the CSCC notifier. violation_configs = notifier_configs.get('violation') if violation_configs: if violation_configs.get('cscc').get('enabled'): source_id = violation_configs.get('cscc').get('source_id') if source_id: # beta mode LOGGER.debug( 'Running CSCC notifier with beta API. source_id: ' '%s', source_id) (cscc_notifier.CsccNotifier(inventory_index_id) .run(violations_as_dict, source_id=source_id)) else: # alpha mode LOGGER.debug('Running CSCC notifier with alpha API.') gcs_path = ( violation_configs.get('cscc').get('gcs_path')) mode = violation_configs.get('cscc').get('mode') organization_id = ( violation_configs.get('cscc').get( 'organization_id')) (cscc_notifier.CsccNotifier(inventory_index_id) .run(violations_as_dict, gcs_path, mode, organization_id)) InventorySummary(service_config, inventory_index_id).run() log_message = 'Notification completed!' progress_queue.put(log_message) progress_queue.put(None) LOGGER.info(log_message) return 0