Last updated at Fri, 30 Aug 2024 19:54:56 GMT
The introduction of the scan export/import feature opens up the ability to merge sites, at least through the Ruby gem.
Imagine a scenario where you had split up your assets into several sites, but now you realize it would be easier to manage them if you just merge them into one. Maybe you have duplicate assets across sites and that wasn't your intent. The script below allows you to merge multiple sites into one. I replays the scans from each site into the new one (in just a fraction of the amount of time it originally took to run the scans).
I'll let the comments in the script mostly speak for themselves, but a quick run-through is this:
- Designate the sites to merge into a new site
- Copy the asset configuration from those sites into the new one
- Collect the scans (the script only pulls in scans from the last 90 days) to merge
- Import those scans into the new site in chronological order.
#!/usr/bin/evn ruby
require 'nexpose'
include Nexpose
nsc = Connection.new('your-console-address', 'nxadmin', 'openSesame')
nsc.login
at_exit { nsc.logout }
# You can merge any number of sites into one.
to_merge = [38, 47]
unified_site = Site.new('Unity!')
# Grab assets from each merge site and add them.
to_merge.each do |site_id|
# Merge based on configured assets.
site = Site.load(nsc, site_id)
unified_site.assets.concat(site.assets)
# To merge based on actually scanned assets:
# nsc.assets(site_id).each do |asset|
# unified_site.add_asset(asset.address)
# end
end
# Will still need to configure credentials, schedules, etc.
unified_site.save(nsc)
# Collect the scan history from each site, limited to the last 90 days.
since = (DateTime.now - 90).to_time
scans = []
to_merge.each do |site_id|
recent_scans = nsc.site_scan_history(site_id).select { |s| s.end_time > since }
scans.concat(recent_scans)
end
# Order them chronologically
ordered = scans.sort_by { |s| s.end_time }.map { |s| s.scan_id }
zip = 'scan.zip'
ordered.each do |scan_id|
nsc.export_scan(scan_id, zip)
nsc.import_scan(unified_site.id, zip)
# Poll until scan is complete before attempting to import the next scan.
history = nil
loop do
sleep 15
history = nsc.site_scan_history(unified_site.id)
break unless history.nil?
end
last_scan = history.max_by { |s| s.start_time }.scan_id
while (nsc.scan_status(last_scan) == 'running')
sleep 10
end
File.delete(zip)
puts "Done importing scan #{scan_id}."
end
Just a few caveats.... With scan import, you pull in all data from the scan as it originally ran. If you deleted assets, for example, they will return in the new site. Also, the looping mechanism of the script is a bit clunky. If you have a lot of data to import, you may want to export all the scans and change the way you wait on scans to be finished, in order to be more fault tolerant. And scan import is all or none, there is no way to split up assets that were in a scan.