# Copyright (C) 2007 Adriano Monteiro Marques
#
# Author: Guilherme Polo <ggpolo@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
from datetime import datetime,timedelta
from umit.db.Utils import log_debug
from umit.db.Connection import ConnectDB
from umit.db.Retrieve import CompositeRetrieve
debug = log_debug('umit.db.Remove')
class ScanRemover(ConnectDB, CompositeRetrieve):
"""
Removes scans from database.
"""
def __init__(self, database):
ConnectDB.__init__(self, database)
CompositeRetrieve.__init__(self, self.conn, self.cursor)
def remove_scan(self, fk_scan):
"""
Removes a scan from database.
"""
# hosts associated with this scan
hosts_ids = self.get_hosts_id_for_scan_from_db(fk_scan)
hosts_ids = [h_id[0] for h_id in hosts_ids]
# remove host data associated with this scan
for h_id in hosts_ids:
self._remove_fingerprint_info(h_id)
self._remove_host_hostname(h_id)
self._remove_host_address(h_id)
self._remove_osmatch(h_id)
self._remove_osclasses(h_id)
self._remove_extraports(h_id)
self._remove_portused(h_id)
self._remove_hostport(h_id)
self._remove_host(h_id)
# remove scan data associated with this scan
self._remove_scaninfo(fk_scan)
self._remove_inventoryscan(fk_scan)
self._remove_scan(fk_scan)
# make changes come true!
self.conn.commit()
def remove_old_umit_scans(self, older_than=None):
"""
Remove scans that aren't in Inventory that are older than N days.
"""
if older_than < 1:
# passed invalid older_than value
return
old_data_date = datetime.now() - timedelta(days=older_than)
# get scans from table scan older than especified days
scans_ids = self.cursor.execute("SELECT pk FROM scan WHERE finish <= ?",
(old_data_date, )).fetchall()
scans_ids = set([s_id[0] for s_id in scans_ids])
# get fk_scans from table _inventory_scan older than especified days
inventory_scans_ids = self.cursor.execute("SELECT fk_scan FROM "
"_inventory_scan JOIN scan ON (_inventory_scan.fk_scan=scan.pk) "
"WHERE scan.finish <= ?", (old_data_date, )).fetchall()
inventory_scans_ids = set([i_id[0] for i_id in inventory_scans_ids])
# get scans that will be removed
to_remove = scans_ids.difference(inventory_scans_ids)
if not to_remove:
# nothing to do
return
debug("Removing UMIT scans older than %d days "
"from database..", older_than)
# remove scans
for scan_id in to_remove:
self.remove_scan(scan_id)
debug("Removal completed")
def remove_old_inventory_scans(self, older_than=None):
"""
Remove Inventory scans that are older than N days. N >= 1
"""
if older_than < 1:
# passed invalid older_than value
return
old_data_date = datetime.now() - timedelta(days=older_than)
# get scans that will be removed
scans_ids = self.cursor.execute("SELECT fk_scan FROM _inventory_scan "
"JOIN scan ON (_inventory_scan.fk_scan=scan.pk) "
"WHERE scan.finish <= ?", (old_data_date, )).fetchall()
scans_ids = [s_id[0] for s_id in scans_ids]
if not scans_ids:
# nothing to do
return
debug("Removing Inventory scans older than %d days "
"from database..", older_than)
# remove scans
for scan_id in scans_ids:
self.remove_scan(scan_id)
# get changes that will be removed
changes_ids = self.cursor.execute("SELECT pk FROM _inventory_changes "
"WHERE entry_date <= ?", (old_data_date, )).fetchall()
changes_ids = [c_id[0] for c_id in changes_ids]
for change_id in changes_ids:
self._remove_inventory_change(change_id)
self.conn.commit()
debug("Removal completed")
def _remove_fingerprint_info(self, fk_host):
"""
Remove fingerprint_info associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM fingerprint_info WHERE fk_host=?",
(fk_host, ))
def _remove_host_hostname(self, fk_host):
"""
Remove hostnames associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM _host_hostname WHERE fk_host=?",
(fk_host, ))
def _remove_host_address(self, fk_host):
"""
Remove addresses associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM _host_address WHERE fk_host=?",
(fk_host, ))
def _remove_osmatch(self, fk_host):
"""
Remove osmatch associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM osmatch WHERE fk_host=?", (fk_host, ))
def _remove_osclasses(self, fk_host):
"""
Remove osclasses associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM osclass WHERE fk_host=?", (fk_host, ))
def _remove_extraports(self, fk_host):
"""
Remove extraports associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM extraports WHERE fk_host=?",
(fk_host, ))
def _remove_portused(self, fk_host):
"""
Remove portused associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM portused WHERE fk_host=?",
(fk_host, ))
def _remove_hostport(self, fk_host):
"""
Remove ports associated with fk_host from database.
"""
self.cursor.execute("DELETE FROM _host_port WHERE fk_host=?",
(fk_host, ))
def _remove_host(self, pk):
"""
Remove host associated with pk from database.
"""
self.cursor.execute("DELETE FROM host WHERE pk=?", (pk, ))
def _remove_scaninfo(self, fk_scan):
"""
Remove scaninfo associated with fk_scan from database.
"""
self.cursor.execute("DELETE FROM scaninfo WHERE fk_scan=?", (fk_scan, ))
def _remove_inventoryscan(self, fk_scan):
"""
Remove inventory scans associated with fk_scan from database.
"""
self.cursor.execute("DELETE FROM _inventory_scan WHERE fk_scan=?",
(fk_scan, ))
def _remove_scan(self, pk):
"""
Remove scan associated with pk from database.
"""
self.cursor.execute("DELETE FROM scan WHERE pk=?", (pk, ))
def _remove_inventory_change(self, pk):
"""
Remove inventory_change associated with pk from database.
"""
self.cursor.execute("DELETE FROM _inventory_changes WHERE pk=?", (pk, ))
if __name__ == "__main__":
# sample
remover = ScanRemover("/home/polo/.umit/umitng.db")
#remover = ScanRemover("../share/umit/config/umitng.db")
remover.remove_old_inventory_scans(5)
#remover.remove_old_umit_scans(120)
|