MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / upsert_host

Method upsert_host

db_manager.py:611–808  ·  view source on GitHub ↗

Insert or update a host record. DUPLICATE PREVENTION: - If adding a real MAC for an IP that has a pseudo-MAC, migrates data and deletes pseudo-MAC - If adding a pseudo-MAC for an IP that has a real MAC, uses the real MAC instead - Prevents duplicate

(self, mac: str, ip: str = None, hostname: str = None, 
                   vendor: str = None, ports: str = None, services: str = None,
                   vulnerabilities: str = None, **kwargs)

Source from the content-addressed store, hash-verified

609 "UPDATE hosts SET hostname = ?, updated_at = ? WHERE mac = ?",
610 (sanitized, now, mac)
611 )
612 updated += 1
613
614 if updated:
615 logger.info(f"Sanitized {updated} hostnames with invalid formatting")
616 return updated
617 except Exception as e:
618 logger.error(f"Failed to sanitize existing hostnames: {e}")
619 return 0
620
621 def upsert_host(self, mac: str, ip: str = None, hostname: str = None,
622 vendor: str = None, ports: str = None, services: str = None,
623 vulnerabilities: str = None, **kwargs):
624 """
625 Insert or update a host record.
626
627 DUPLICATE PREVENTION:
628 - If adding a real MAC for an IP that has a pseudo-MAC, migrates data and deletes pseudo-MAC
629 - If adding a pseudo-MAC for an IP that has a real MAC, uses the real MAC instead
630 - Prevents duplicate entries for the same IP with different MACs
631
632 Args:
633 mac: MAC address (primary key)
634 ip: IP address
635 hostname: Hostname
636 vendor: Vendor/manufacturer
637 ports: Comma-separated list of open ports
638 services: JSON string or dict of port->service mappings
639 vulnerabilities: JSON string or dict of vulnerabilities
640 **kwargs: Additional columns (action statuses, notes, etc.)
641
642 Returns:
643 bool: True if successful
644 """
645 if not mac:
646 logger.warning("Cannot upsert host without MAC address")
647 return False
648
649 # Normalize MAC address
650 mac = mac.lower().strip()
651
652 # DUPLICATE PREVENTION: Check for existing entry with same IP but different MAC
653 if ip:
654 existing_host = self.get_host_by_ip(ip)
655 if existing_host and existing_host['mac'] != mac:
656 existing_mac = existing_host['mac']
657 is_new_mac_pseudo = self._is_pseudo_mac(mac)
658 is_existing_mac_pseudo = self._is_pseudo_mac(existing_mac)
659
660 if is_new_mac_pseudo and not is_existing_mac_pseudo:
661 # Trying to add pseudo-MAC when real MAC exists - use real MAC instead
662 logger.info(f"🔄 Real MAC {existing_mac} already exists for IP {ip}, ignoring pseudo-MAC {mac}")
663 mac = existing_mac
664 elif not is_new_mac_pseudo and is_existing_mac_pseudo:
665 # Upgrading from pseudo-MAC to real MAC - migrate data
666 logger.info(f"🔄 Upgrading IP {ip} from pseudo-MAC {existing_mac} to real MAC {mac}")
667
668 # Merge data from old entry with new data, preserving valuable info

Callers 11

_migrate_from_csvMethod · 0.95
db_manager.pyFile · 0.80
_upsert_passive_hostMethod · 0.80
_bg_scanFunction · 0.80
run_arp_scanMethod · 0.80
run_nmap_network_scanMethod · 0.80
update_netkbMethod · 0.80

Calls 15

get_host_by_ipMethod · 0.95
_is_pseudo_macMethod · 0.95
delete_hostMethod · 0.95
get_connectionMethod · 0.95
sanitize_hostnameMethod · 0.95
warningMethod · 0.80
infoMethod · 0.80
debugMethod · 0.80
cursorMethod · 0.80
appendMethod · 0.80
commitMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected