Skip to content

Instantly share code, notes, and snippets.

@mrkurt
Created February 16, 2021 18:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mrkurt/6f2123434cea8a1e47ad21aa9664de12 to your computer and use it in GitHub Desktop.
Save mrkurt/6f2123434cea8a1e47ad21aa9664de12 to your computer and use it in GitHub Desktop.
Cloud provider IP valuations
require "ipaddr"
require "net/http"
require "uri"
require "json"
def fetch(uri_str, limit = 10)
# You should choose better exception.
raise ArgumentError, "HTTP redirect too deep" if limit == 0
url = URI.parse(uri_str)
req = Net::HTTP::Get.new(url.path, { "User-Agent" => "Mozilla/5.0 (etc...)" })
response = Net::HTTP.start(url.host, url.port, use_ssl: true) { |http| http.request(req) }
case response
when Net::HTTPSuccess then response
when Net::HTTPRedirection then fetch(response["location"], limit - 1)
else
response.error!
end
end
def blocks_from_do(url = "https://digitalocean.com/geo/google.csv")
resp = fetch(url)
raw = resp.body.split("\n")
raw.map do |r|
IPAddr.new(r.split(",").first)
end.reject(&:nil?).uniq
end
def blocks_from_aws(url = "https://ip-ranges.amazonaws.com/ip-ranges.json")
resp = fetch(url)
raw = JSON.parse(resp.body)
raw["prefixes"].map do |r|
IPAddr.new(r["ip_prefix"])
end.reject(&:nil?).uniq
end
def blocks_from_gcloud(url = "https://www.gstatic.com/ipranges/cloud.json")
resp = fetch(url)
raw = JSON.parse(resp.body)
raw["prefixes"].map do |r|
p = r["ipv4Prefix"] || r["ipv6Prefix"]
IPAddr.new(p)
end.reject(&:nil?).uniq
end
def add_commas(num_string)
num_string.to_s.reverse.scan(/\d{3}|.+/).join(",").reverse
end
def print_row(name, blocks)
count = blocks.select(&:ipv4?).map { |b| 2 ** (32 - b.prefix) }.reduce(&:+) || 0
["**#{name}**", add_commas(blocks.length), add_commas(count), "~$#{add_commas(count * 25)}"]
end
BLOCKS = {}
BLOCKS["AWS"] = blocks_from_aws
BLOCKS["Google Cloud"] = blocks_from_gcloud
BLOCKS["DigitalOcean"] = blocks_from_do
output = []
output.push("**Provider** | **Blocks** | **Total IPs** | **Estimated Value**".split(" | "))
BLOCKS.each { |k, v| output.push(print_row(k, v)) }
lengths = (0..3).map do |i|
output.map { |r| r[i].length }.max + 2
end
i = -1
puts "| " + output[0].map { |v| i += 1; v.ljust(lengths[i]) }.join(" | ") + "|"
puts "| " + lengths.map { |l| "-".ljust(l, "-") }.join(" | ") + "|"
#puts output.to_json
output[1..].each do |o|
i = -1
puts "| " + o.map { |v| i += 1; v.ljust(lengths[i]) }.join(" | ") + "|"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment