async def db_import_cve(cve: str, conn: Connection): """Import missing CVE metadata into database""" # Attempt to get CVE data from VMAAS LOGGER.info("Attempting to get %s data from VMAAS", cve) cve_request_endpoint = format_vmaas_cve_endpoint(cve) cve_page = await vmaas_request(cve_request_endpoint, method="GET") success = True try: cve_data = cve_page["cve_list"][cve] except (KeyError, TypeError): LOGGER.error("Error importing %s from VMAAS", cve) success = False try: async with conn.transaction(): if success: impact_id_map = {} async for row in conn.cursor( "SELECT name, id FROM cve_impact"): impact_name, impact_id = row impact_id_map[impact_name] = impact_id cve_row = construct_cve_row(cve_data, impact_id_map, asyncpg_type=True) inserted = await conn.fetchrow( """INSERT INTO cve_metadata (cve, description, impact_id, public_date, modified_date, cvss3_score, cvss3_metrics, cvss2_score, cvss2_metrics, redhat_url, secondary_url, advisories_list) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) ON CONFLICT (cve) DO UPDATE SET description = EXCLUDED.description, impact_id = EXCLUDED.impact_id, public_date = EXCLUDED.public_date, modified_date = EXCLUDED.modified_date, cvss3_score = EXCLUDED.cvss3_score, cvss3_metrics = EXCLUDED.cvss3_metrics, cvss2_score = EXCLUDED.cvss2_score, cvss2_metrics = EXCLUDED.cvss2_metrics, redhat_url = EXCLUDED.redhat_url, secondary_url = EXCLUDED.secondary_url, advisories_list = EXCLUDED.advisories_list RETURNING id AS inserted""", *cve_row) # if vmaas was not available insert empty cve else: inserted = await conn.fetchrow( """INSERT INTO cve_metadata (cve, description, impact_id) VALUES ($1, $2, $3) ON CONFLICT (cve) DO UPDATE SET cve = $1 RETURNING id AS inserted""", cve, 'unknown', 0) CVES_CACHE[cve] = inserted[0] # pylint: disable=broad-except except Exception: DATABASE_ERROR.inc() LOGGER.exception("Error during inserting CVE: ")
async def db_import_rule_hits(conn: Connection, rh_account_id: int, inventory_id: str, system_id: int, rule_hits: dict) -> None: """Associate rules hits with system""" # pylint: disable=too-many-branches, too-many-statements active_rules = set() rules_playbook_count = {} async for row in conn.cursor( """SELECT ir.id, ir.playbook_count, ir.active FROM insights_rule ir""" ): rule_id, rule_playbook_count, rule_active = row rules_playbook_count[rule_id] = rule_playbook_count if rule_active: active_rules.add(rule_id) to_update = [] rule_hits_cves_ids = tuple(rule_hits.keys()) system_cves = [] async for row in conn.cursor( """SELECT sv.id, sv.cve_id, sv.rule_id, sv.when_mitigated, sv.advisory_available, cm.cve FROM system_vulnerabilities sv JOIN cve_metadata cm ON sv.cve_id = cm.id WHERE system_id = $1 AND rh_account_id = $2""", system_id, rh_account_id): row_id, cve_id, rule_id, when_mitigated, advisory_available, cve = row playbook_count = rules_playbook_count.get( rule_hits.get(cve_id, {}).get('id')) mitigation_reason = rule_hits.get(cve_id, {}).get('mitigation_reason') remediation_type_id = get_available_remediation_type( advisory_available, when_mitigated, mitigation_reason, playbook_count) if cve_id in rule_hits_cves_ids: if 'mitigation_reason' in rule_hits[cve_id]: if rule_hits[cve_id][ 'id'] not in active_rules and not when_mitigated: system_cves.append(cve) to_update.append( (row_id, rh_account_id, rule_hits[cve_id]['id'], None, rule_hits[cve_id]['mitigation_reason'], advisory_available, remediation_type_id)) else: to_update.append( (row_id, rh_account_id, rule_hits[cve_id]['id'], rule_hits[cve_id]['details'], None, advisory_available, remediation_type_id)) if rule_hits[cve_id][ 'id'] in active_rules or not when_mitigated: system_cves.append(cve) del rule_hits[ cve_id] # rule hits become dict of completely new system cves elif rule_id: to_update.append((row_id, rh_account_id, None, None, None, advisory_available, remediation_type_id)) if not when_mitigated: system_cves.append(cve) elif not when_mitigated: system_cves.append(cve) if rule_hits: await insert_new_cves(conn, rh_account_id, system_id, rule_hits, rules_playbook_count) system_cves.extend([ rule_hits[cve]['cve_name'] for cve in rule_hits if rule_hits[cve]['id'] in active_rules and 'details' in rule_hits[cve] ]) if to_update: await update_cves(conn, to_update, rh_account_id) await _update_system(system_id, len(system_cves), conn) send_remediations_update(REMEDIATIONS_PRODUCER, inventory_id, system_cves)