-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathaws-ips
executable file
·146 lines (110 loc) · 3.65 KB
/
aws-ips
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/ruby
require 'json'
require 'net/http'
require 'optparse'
require 'set'
require 'uri'
require 'yaml'
app_name = File.basename $PROGRAM_NAME
def get_address_ranges(url)
ip_source = URI(url)
res = Net::HTTP.get_response(ip_source)
if res.code.to_i != 200
echo "Failed to read IP addresses from #{ip_source}"
exit 1
end
json = JSON.load(res.body)
addresses = json['prefixes'] + json['ipv6_prefixes']
addresses.flatten!
addresses
end
def available(collection, key_name)
collected = Set.new
collection.collect { |e| collected.add(e[key_name]) }
collected.to_a.sort
end
options = {
ip_versions: ['4'],
debug: false,
url: 'https://ip-ranges.amazonaws.com/ip-ranges.json',
}
OptionParser.new do |opts|
opts.banner = 'Usage: #{app_name} [options]'
opts.on(
'-d', '--debug', 'Show the results as a YAML array of hashes'
) { options[:debug] = true }
opts.on(
'-iVERSION', '--ip=VERSION', '--ip_version=VERSION', 'Which IP versions to show. Defaults to IPv4'
) { |v| options[:ip_versions] = v.split(',') }
opts.on(
'-rregion', '--region=region', 'comma separated list of regions to show.'
) { |v| options[:region] = v.split(',') }
opts.on(
'--regions', 'Show the regions available in the fetched data.'
) { options[:regions] = true }
opts.on(
'-sSERVICE', '--service=SERVICE', 'Comma separated list of services to show'
) { |v| options[:service] = v.split(',') }
opts.on(
'--services', 'Show the services available in the fetched data.'
) { options[:services] = true }
opts.on(
'-uURL', '--url=URL', 'URL to fetch IP Ranges from'
) { |v| options[:url] = v.split(',') }
opts.separator <<-EOT
Examples:
Show all IPv4 addresses in the sa-east-1 and eu-west-1 regions
#{app_name} --region sa-east-1,eu-west-1
Show all services in the data file
#{app_name} --services
Show all IPv6 addresses in the ap-northeast-1 region
#{app_name} -r ap-northeast-1 -i 6
Show all IPv4 addresses used by the EC2 service in eu-west-1
#{app_name} --region eu-west-1 --service EC2
EOT
end.parse!
addresses = get_address_ranges(options[:url])
regions = available(addresses, 'region')
services = available(addresses, 'service')
# display the valid values and exit early if called with --regions or --services
if options[:regions]
puts regions.to_yaml
exit 0
end
if options[:services]
puts services.to_yaml
exit 0
end
## Sanity check that the regions and service names provided are present in the
## datafile
if options[:region]
options[:region].each do |region|
unless regions.include? region
puts "#{app_name}: #{region} is not a valid region. Use --regions to list valid options"
exit 0
end
end
end
if options[:service]
options[:service].each do |service|
unless services.include? service
puts "#{app_name}: #{service} is not a valid service. Use --services to list valid options"
exit 0
end
end
end
# select IP versions based on command line options. Default to showing IPv4
addresses.reject! { |e| e.key? 'ipv6_prefix' } unless options[:ip_versions].include? '6'
addresses.reject! { |e| e.key? 'ip_prefix' } unless options[:ip_versions].include? '4'
# filter out to the regions we care about
addresses.select! { |e| options[:region].include? e['region'] } if options[:region]
# only show the services we care about
addresses.select! { |e| options[:service].include? e['service'] } if options[:service]
# in debug mode show the data we get from the remote URL.
if options[:debug]
puts addresses.to_yaml
else
ips = addresses.collect { |e| e['ip_prefix'] || e['ipv6_prefix'] }
ips.uniq!
puts ips.sort.to_yaml
end