Files
baffle-hub/app/jobs/fetch_ipapi_data_job.rb

59 lines
2.1 KiB
Ruby

class FetchIpapiDataJob < ApplicationJob
queue_as :default
# Fetches IPAPI enrichment data for a NetworkRange
# @param network_range_id [Integer] ID of the tracking NetworkRange (usually /24)
def perform(network_range_id:)
tracking_network = NetworkRange.find_by(id: network_range_id)
return unless tracking_network
# Use the network address (first IP in range) as the representative IP
sample_ip = tracking_network.network_address.split('/').first
Rails.logger.info "Fetching IPAPI data for #{tracking_network.cidr} using IP #{sample_ip}"
ipapi_data = Ipapi.lookup(sample_ip)
if ipapi_data.present? && !ipapi_data.key?('error')
# Process IPAPI data and create network ranges
result = Ipapi.process_ipapi_data(ipapi_data, tracking_network)
# Mark the tracking network as having been queried
# Use the broadest CIDR returned for deduplication
tracking_network.mark_ipapi_queried!(result[:broadest_cidr])
Rails.logger.info "Successfully fetched IPAPI data for #{tracking_network.cidr} (created #{result[:networks].length} networks)"
# Broadcast to the tracking network
broadcast_ipapi_update(tracking_network, ipapi_data)
else
Rails.logger.warn "IPAPI returned error for #{tracking_network.cidr}: #{ipapi_data}"
# Still mark as queried to avoid retrying immediately
tracking_network.mark_ipapi_queried!(tracking_network.cidr)
end
rescue => e
Rails.logger.error "Failed to fetch IPAPI data for network_range #{network_range_id}: #{e.message}"
Rails.logger.error e.backtrace.join("\n")
ensure
# Always clear the fetching status when done
tracking_network&.clear_fetching_status!(:ipapi)
end
private
def broadcast_ipapi_update(network_range, ipapi_data)
# Broadcast to a stream specific to this network range
Turbo::StreamsChannel.broadcast_replace_to(
"network_range_#{network_range.id}",
target: "ipapi_data_section",
partial: "network_ranges/ipapi_data",
locals: {
ipapi_data: ipapi_data,
network_range: network_range,
parent_with_ipapi: nil,
ipapi_loading: false
}
)
end
end