traceroute53 0.1.3 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c092c67488876b90c93716934989e5da3ca311d787d4f63f5f506035ed2c7a6b
4
- data.tar.gz: 4ad6dcf187f73112d4e8b90ed054eeb8b1879beadc6c7b0daef02b10fdf677b9
3
+ metadata.gz: 2366ea9ef30a2d88826cc6601ffae1c4f87cc14a275473375e19ded8c9771ea9
4
+ data.tar.gz: 8b95a5fd70d36a1a8fa26d846304f83a52ac61107a0a323b5aff5b82b1565845
5
5
  SHA512:
6
- metadata.gz: c8ce824f9311a9999f31ced357dd9e52afd9c2522945c2518a8007b4ec6a883f292ef98f6024b6c59083871329fa5002daa2ca21fed9a922e1083fb84f8b2446
7
- data.tar.gz: d195974076040536c4e49225bf296588070c685ef55d1054e600c745be923693cf17995ca7d9d4df97633198d0b188f807f6d823f1d15a6d1075524fde84465b
6
+ metadata.gz: b3661175cef71d2b88432e4e15f4667257a13f2f3586b822e505cc838a3f9ee1f095fb27fd895171289a4bb82498a41bda19ef3e0a20e7a433364dbd48cd3f9c
7
+ data.tar.gz: 96aa5bbe750855f4bd0c4222c0fa13a5573cfb2f00cb749afdb60badef01172c6f369a7ff943aae56a8890ac9a4e810d6cfc22433ed960e962bcfcecc95d56ad
data/exe/traceroute53 CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # Trace route53 and Load Balancers related to the given domain
3
3
  require 'aws-sdk-route53'
4
+ require 'aws-sdk-elasticloadbalancing'
4
5
  require 'aws-sdk-elasticloadbalancingv2'
5
6
  require 'aws-sdk-ec2'
6
7
  require 'optparse'
@@ -43,7 +44,22 @@ def list_resource_record_sets(client, hosted_zone)
43
44
  records
44
45
  end
45
46
 
46
- def describe_load_balancers(client)
47
+ def describe_load_balancers(client, name)
48
+ marker = nil
49
+ load_balancers = []
50
+ loop do
51
+ resp = client.describe_load_balancers({
52
+ load_balancer_names: [name],
53
+ marker: marker,
54
+ })
55
+ load_balancers.concat resp.load_balancer_descriptions
56
+ marker = resp.next_marker
57
+ break unless marker
58
+ end
59
+ load_balancers
60
+ end
61
+
62
+ def describe_load_balancersv2(client)
47
63
  marker = nil
48
64
  load_balancers = []
49
65
  loop do
@@ -72,6 +88,21 @@ def describe_listeners(client, load_balancer)
72
88
  listeners
73
89
  end
74
90
 
91
+ def describe_rules(client, listener)
92
+ marker = nil
93
+ rules = []
94
+ loop do
95
+ resp = client.describe_rules({
96
+ listener_arn: listener.listener_arn,
97
+ marker: marker,
98
+ })
99
+ rules.concat resp.rules
100
+ marker = resp.next_marker
101
+ break unless marker
102
+ end
103
+ rules
104
+ end
105
+
75
106
  def describe_target_groups(client, target_group_arns)
76
107
  marker = nil
77
108
  target_groups = []
@@ -129,7 +160,7 @@ end
129
160
  def main
130
161
  opt = OptionParser.new("usage: traceroute53 <domain>")
131
162
 
132
- profile = nil
163
+ profile = ENV['AWS_PROFILE']
133
164
  opt.on('--profile PROFILE', "use given profile") {|v| profile = v }
134
165
 
135
166
  opt.parse!(ARGV)
@@ -158,7 +189,7 @@ def main
158
189
 
159
190
  record_sets = list_resource_record_sets(client, hosted_zone)
160
191
  while true
161
- records = record_sets.select{|record| record.name == domain_dot}
192
+ records = record_sets.select{|r| r.name == domain_dot}
162
193
  if records.empty?
163
194
  STDERR.puts "resource record set not found in #{hosted_zone} for #{domain}"
164
195
  exit 1
@@ -168,73 +199,154 @@ def main
168
199
  STDERR.puts "more than one resource record set in #{hosted_zone} for #{domain}"
169
200
  exit 1
170
201
  end
171
- dns_name = records[0].alias_target.dns_name
172
- puts "dns name: #{dns_name}"
173
- if /([a-z0-9\-]+)\.elb\.amazonaws.com\.\z/ =~ dns_name
174
- break
202
+ record = records[0]
203
+ if record.alias_target
204
+ # The record is an AWS resource
205
+ dns_name = record.alias_target.dns_name
206
+ puts "dns name: #{dns_name}"
207
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Route53/Types/AliasTarget.html
208
+ if /\.elb\.(?:[a-z0-9\-]+\.)?amazonaws.com\.\z/ =~ dns_name
209
+ break
210
+ elsif /\.amazonaws.com\.\z/ =~ dns_name
211
+ STDERR.puts record.inspect
212
+ STDERR.puts "unsupported AWS resource '#{dns_name}'; pull request is welcome https://github.com/nurse/traceroute53"
213
+ exit 1
214
+ else
215
+ # assune Another Route 53 resource record set
216
+ domain_dot = dns_name
217
+ end
218
+ elsif record.type == 'CNAME'
219
+ puts "resource_records: #{record.resource_records.map(&:value)}"
220
+ domain_dot = record.resource_records[0].value
221
+ else
222
+ STDERR.puts record.inspect
223
+ STDERR.puts "unsupported record; pull request is welcome https://github.com/nurse/traceroute53"
224
+ exit 1
175
225
  end
176
- domain_dot = dns_name
177
226
  end
178
227
  dns_name.sub!(/\Adualstack\./, '')
179
228
  dns_name.chomp!('.')
180
229
 
181
- region = dns_name[/([a-z0-9\-]+)\.elb\.amazonaws.com\z/, 1]
182
- client = Aws::ElasticLoadBalancingV2::Client.new(
183
- region: region,
184
- profile: profile,
185
- )
186
- load_balancers = describe_load_balancers(client)
187
- if load_balancers.empty?
188
- STDERR.puts "load balancers not found in #{region} for #{dns_name}"
230
+ unless /([a-z0-9\-]+)?\.elb\.(?:([a-z0-9\-]+)\.)?amazonaws.com\z/ =~ dns_name
231
+ STDERR.puts "dns_name:#{dns_name} doesn't include AWS region name"
189
232
  exit 1
190
233
  end
191
- load_balancer = load_balancers.find{|lb| lb.dns_name == dns_name}
192
- unless load_balancer
193
- load_balancers.each_with_index do |lb, i|
194
- STDERR.puts "load balancer[#{i}]: #{lb.dns_name}"
234
+ region = $2 || $1
235
+
236
+ name = dns_name[/\A([a-z0-9\-]+)-\h+\./, 1]
237
+ puts "Load Balancer name is '#{name}'"
238
+
239
+ instance_ids = nil
240
+ begin
241
+ # Aws::ElasticLoadBalancingV2 (Application Load Balancer or Network Load Balancer)
242
+ client = Aws::ElasticLoadBalancingV2::Client.new(
243
+ region: region,
244
+ profile: profile,
245
+ )
246
+ load_balancers = describe_load_balancersv2(client)
247
+ # it raises LoadBalancerNotFound exception if not found
248
+ load_balancer = load_balancers.find{|lb| lb.dns_name == dns_name}
249
+ puts "load balancer: #{load_balancer.load_balancer_name} #{load_balancer.security_groups}"
250
+
251
+ listeners = describe_listeners(client, load_balancer)
252
+ if listeners.empty?
253
+ STDERR.puts "listeners not found in #{region} for #{load_balancer}"
254
+ exit 1
195
255
  end
196
- STDERR.puts "load balancers not found in #{region} for #{dns_name}"
197
- exit 1
198
- end
199
- puts "load balancer: #{load_balancer.load_balancer_name} #{load_balancer.security_groups}"
200
256
 
201
- listeners = describe_listeners(client, load_balancer)
202
- if listeners.empty?
203
- STDERR.puts "listeners not found in #{region} for #{load_balancer}"
204
- exit 1
257
+ instance_ids = []
258
+ target_group_arns = {}
259
+ listeners.each_with_index do |listener, i|
260
+ # p listener
261
+ puts "listener[#{i}]: port:#{listener.port} #{listener.listener_arn}"
262
+ rules = describe_rules(client, listener)
263
+ rules.each_with_index do |rule, j|
264
+ puts "listener[#{i}]rule[#{j}]: #{rule.rule_arn}#{rule.is_default ? ' (default)' : ''}"
265
+ rule.conditions.each_with_index do |condition, k|
266
+ puts "listener[#{i}]rule[#{j}]condition[#{k}]: #{condition.values}"
267
+ end
268
+ rule.actions.each_with_index do |action, k|
269
+ puts "listener[#{i}]rule[#{j}]action[#{k}]: #{action.type} #{action.target_group_arn}"
270
+ if target_group_arns[action.target_group_arn]
271
+ puts "listener[#{i}]rule[#{j}]action[#{k}]: the target group is already showed; skip"
272
+ else
273
+ target_group_arns[action.target_group_arn] = true
274
+ target_healths = describe_target_health(client, action.target_group_arn)
275
+ target_healths.each_with_index do |health, l|
276
+ puts "listener[#{i}]rule[#{j}]action[#{k}]target[#{l}]: #{health.target.id}:#{health.target.port} #{health.target_health.state}"
277
+ instance_ids << health.target.id
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ instance_ids
284
+
285
+ # p target_group_arns
286
+ # target_groups = describe_target_groups(client, target_group_arns)
287
+ # if target_groups.empty?
288
+ # STDERR.puts "target groups not found in #{region} for #{listeners}"
289
+ # exit 1
290
+ # end
291
+ # p target_groups
292
+
293
+ unless instance_ids
294
+ STDERR.puts "load balancers not found in #{region} for #{dns_name} with ELBv2"
295
+ # exit 1
296
+ end
297
+ rescue Aws::ElasticLoadBalancingV2::Errors::LoadBalancerNotFound
298
+ STDERR.puts "load balancers not found in #{region} for #{dns_name} with ELBv2"
205
299
  end
206
300
 
207
- instance_ids = []
208
- listeners.each_with_index do |listener, i|
209
- # p listener
210
- puts "listener[#{i}]: port:#{listener.port} #{listener.listener_arn}"
211
- listener.default_actions.each_with_index do |action, j|
212
- puts "listener[#{i}]action[#{j}]: #{action.type} #{action.target_group_arn}"
213
- target_healths = describe_target_health(client, action.target_group_arn)
214
- target_healths.each_with_index do |health, k|
215
- puts "listener[#{i}]action[#{j}]target[#{k}]: #{health.target.id}:#{health.target.port} #{health.target_health.state}"
216
- instance_ids << health.target.id
301
+ unless instance_ids
302
+ # Aws::ElasticLoadBalancing (Classic Load Balancer)
303
+ client = Aws::ElasticLoadBalancing::Client.new(
304
+ region: region,
305
+ profile: profile,
306
+ )
307
+ load_balancers = describe_load_balancers(client, name)
308
+ if load_balancers.empty?
309
+ STDERR.puts "load balancers not found in #{region} for #{dns_name}"
310
+ exit 1
311
+ end
312
+
313
+ load_balancer = load_balancers.find{|lb| lb.dns_name == dns_name}
314
+ instance_ids = []
315
+ unless load_balancer
316
+ load_balancers.each_with_index do |lb, i|
317
+ STDERR.puts "load balancer[#{i}]: #{lb.dns_name}"
217
318
  end
319
+ STDERR.puts "load balancers not found in #{region} for #{dns_name}"
320
+ exit 1
218
321
  end
219
- end
220
322
 
221
- # p target_group_arns
222
- # target_groups = describe_target_groups(client, target_group_arns)
223
- # if target_groups.empty?
224
- # STDERR.puts "target groups not found in #{region} for #{listeners}"
225
- # exit 1
226
- # end
227
- # p target_groups
323
+ load_balancer = load_balancers[0]
324
+ puts "load balancer: #{load_balancer.load_balancer_name} #{load_balancer.security_groups}"
325
+
326
+ load_balancer.instances.each_with_index do |instance, i|
327
+ puts "instances[#{i}]: #{instance[:instance_id]}"
328
+ instance_ids << instance[:instance_id]
329
+ end
330
+ end
228
331
 
332
+ # Inspect Security Group
229
333
  client = Aws::EC2::Client.new(
230
334
  region: region,
231
335
  profile: profile,
232
336
  )
233
337
  instances = describe_instances(client, instance_ids)
234
- group_ids_ary = instances.map{|instance| instance.security_groups.map(&:group_id)}.uniq
338
+ group_ids_hash = {}
339
+ instances.each do |instance|
340
+ group_ids = instance.security_groups.map(&:group_id)
341
+ group_ids_hash[group_ids] ||= []
342
+ group_ids_hash[group_ids] << instance.instance_id
343
+ end
235
344
 
236
- group_ids_ary.each_with_index do |group_ids, i|
345
+ # Assume that instances under an ELB have the same security groups.
346
+ # If they are varied, something weird is happening and it needs further investigation...
347
+ group_ids_hash.each_pair.with_index do |(group_ids, instance_ids), i|
237
348
  puts "group_ids[#{i}]: #{group_ids}"
349
+ puts "group_ids[#{i}]: #{instance_ids}"
238
350
  security_groups = describe_security_groups(client, group_ids)
239
351
  security_groups.each_with_index do |sg, j|
240
352
  puts "group_ids[#{i}]sg[#{j}]: #{sg.group_id}"
@@ -1,3 +1,3 @@
1
1
  module Traceroute53
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.6"
3
3
  end
data/traceroute53.gemspec CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = ["lib"]
38
38
 
39
39
  spec.add_dependency 'aws-sdk-route53', "~> 1"
40
+ spec.add_dependency 'aws-sdk-elasticloadbalancing', "~> 1"
40
41
  spec.add_dependency 'aws-sdk-elasticloadbalancingv2', "~> 1"
41
42
  spec.add_dependency 'aws-sdk-ec2', "~> 1"
42
43
  spec.add_development_dependency "bundler", "~> 1.17"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traceroute53
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - NARUSE, Yui
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-21 00:00:00.000000000 Z
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-route53
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-elasticloadbalancing
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: aws-sdk-elasticloadbalancingv2
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -121,7 +135,7 @@ licenses:
121
135
  metadata:
122
136
  homepage_uri: https://github.com/nurse/traceroute53
123
137
  source_code_uri: https://github.com/nurse/traceroute53
124
- post_install_message:
138
+ post_install_message:
125
139
  rdoc_options: []
126
140
  require_paths:
127
141
  - lib
@@ -136,8 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
150
  - !ruby/object:Gem::Version
137
151
  version: '0'
138
152
  requirements: []
139
- rubygems_version: 3.0.3
140
- signing_key:
153
+ rubygems_version: 3.3.7
154
+ signing_key:
141
155
  specification_version: 4
142
156
  summary: A tool to investigate Route53, ELB, EC2 and Security Groups
143
157
  test_files: []