irrc 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: d0cea0cd7090c9cdc0050e02cc02368a03e48f12
4
- data.tar.gz: 022c5535b1e8acb15e3641fcff65959105ebd5c7
3
+ metadata.gz: 2153f20f9106d41a4879ffbc6ab3da228fb92c91
4
+ data.tar.gz: f79d595e7e9feba683de2e366dd08fdc93b9d119
5
5
  SHA512:
6
- metadata.gz: f3883807ba6822641f396177a1fb187f0d50c96595ac9b4b33c6d2693a789ac720cd7b324aa1b780ee76898760afd247cf93803a0a9d606c668e0bf826bb9f51
7
- data.tar.gz: 0e89f38a1c5b90241301ff54839949cc1778dc0194163659f8e60c23b457fe5e29cfbb25806ab41c707dffb9348eb07f29ef27a0230620445076e0d0460f728f
6
+ metadata.gz: 01730d20bad2b5b2509b1895fc237ebc299d372ba5a053f52cae32b74e31be9580aa3d84856424e946dd1debf0de1c45f7fb8636fff807258fe133f402ad9eb2
7
+ data.tar.gz: e45bce36c6a1449a6a4f866f6e258e76c264dd96fb6f1bc8eb4be9a1cd9e2badc9f409408fefadc39e8a185783eb6fb8b62415cc3c6f24104c0489923636912e
@@ -1,6 +1,14 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.0
5
- - 2.1.1
6
- - ruby-head
4
+ - 2.1.9
5
+ - 2.2.6
6
+ - 2.3.3
7
+ - ruby-head
8
+
9
+ before_install:
10
+ - gem update bundler
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
data/Gemfile CHANGED
@@ -1,7 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :test do
4
- gem 'rspec'
5
- end
6
-
7
- gemspec
3
+ # Specify your gem's dependencies in junoser.gemspec
4
+ gemspec
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Shintaro Kojima
3
+ Copyright (c) 2017 Shintaro Kojima
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -64,8 +64,8 @@ You can load irrc as a library and use it easily in your own code.
64
64
  require 'irrc'
65
65
 
66
66
  client = Irrc::Client.new
67
- client.query(:jpirr, 'AS-JPNIC', source: :jpirr) # queries JPIRR about AS-JPNIC with a SOURCE: filter
68
- client.query(:ripe, 'AS-RIPENCC', protocol: :ipv4) # queries RIPE Whoisd about AS-RIPENCC for IPv4 only
67
+ client.query :jpirr, 'AS-JPNIC', source: :jpirr # queries JPIRR about AS-JPNIC with a SOURCE: filter
68
+ client.query :ripe, 'AS-RIPENCC', protocol: :ipv4 # queries RIPE Whoisd about AS-RIPENCC for IPv4 only
69
69
  client.perform # returns the results in a Hash
70
70
  ```
71
71
 
@@ -99,7 +99,7 @@ AS-JPNIC: # queried object
99
99
 
100
100
  * Ruby >= 2.0.0
101
101
 
102
- Successfully tested with 2.0.0, 2.1.0, 2.1.1, 2.1.2.
102
+ Successfully tested with 2.1.9, 2.2.6, 2.3.3 and 2.4.0.
103
103
 
104
104
 
105
105
  ## Threading
@@ -146,34 +146,12 @@ client = Irrc::Client.new {|c| c.logger = Rails.logger }
146
146
 
147
147
  Here is a quick performance comparison with peval and irrpt.
148
148
 
149
- * Ordinary as-set
150
-
151
- | CLI command | user | system | cpu | total |
152
- | :------------------------------ | --------: | ---------: | ------: | ---------: |
153
- | peval -h jpirr.nic.ad.jp AS-OCN | 0.14s | 0.04s | 1% | 9.397 |
154
- | irrpt_eval AS-OCN | 0.35s | 0.06s | 5% | 8.021 |
155
- | **irrc -h jpirr AS-OCN** | **0.42s** | **0.09s** | **4%** | **10.639** |
156
-
157
- * Huge as-set
158
-
159
- Object caching may contribute to the query performance.
160
-
161
- | CLI command | user | system | cpu | total |
162
- | :---------------------------------------- | ----------: | ---------: | ------: | ----------: |
163
- | peval -h jpirr.nic.ad.jp AS-HURRICANE | 67.29s | 1.21s | 22% | 4:58.16 |
164
- | irrpt_eval AS-HURRICANE | 163.10s | 1.38s | 43% | 6:18.17 |
165
- | **irrc -h jpirr AS-HURRICANE** | **20.26s** | **1.84s** | **7%** | **4:54.37** |
166
-
167
- * Multiple as-set
168
-
169
- Multi-threading and object caching may contribute to the query performance.
170
-
171
- | CLI command | user | system | cpu | total |
172
- | :------------------------------------------------------------- | ----------: | ---------: | ------: | ----------: |
173
- | for i in AS-HURRICANE AS-GBLX; peval -h jpirr.nic.ad.jp $i | 76.47s | 1.08s | 20% | 6:15.80 |
174
- | irrpt_fetch | 174.21s | 1.29s | 44% | 6:38.50 |
175
- | irrc -h jpirr AS-HURRICANE AS-GBLX | 22.28s | 1.75s | 8% | 4:34.31 |
176
- | **irrc -h jpirr -t 2 AS-HURRICANE AS-GBLX** | **23.04s** | **1.81s** | **9%** | **4:09.27** |
149
+ | CLI command | user | system | cpu | total |
150
+ | :----------------------------------------------- | --------: | ---------: | ------: | ---------: |
151
+ | peval -h jpirr.nic.ad.jp 'afi ipv4, ipv6 AS-OCN' | 0.15s | 0.04s | 3% | 4.959 |
152
+ | irrpt_list_prefixes AS-OCN | 0.21s | 0.09s | 3% | 9.693 |
153
+ | **irrc -h jpirr AS-OCN** | **0.42s** | **0.12s** | **5%** | **9.622** |
154
+ | **irrc -h jpirr -t 4 AS-OCN** | **0.39s** | **0.13s** | **19%** | **2.754** |
177
155
 
178
156
 
179
157
  ## Contributing
@@ -192,4 +170,4 @@ For questions or feedbacks write to my twitter @codeout.
192
170
 
193
171
  ## Copyright and License
194
172
 
195
- Copyright (c) 2014 Shintaro Kojima. Code released under the [MIT license](LICENSE).
173
+ Copyright (c) 2017 Shintaro Kojima. Code released under the [MIT license](LICENSE).
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "foo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+
6
+ require 'irrc'
7
+
8
+
9
+ options = Struct.new(:host, :source, :protocol, :threads, :debug).new(nil, [], [], 1, nil)
10
+
11
+ opts = OptionParser.new do |opts|
12
+ opts.banner = <<-EOS
13
+
14
+ Usage: #{opts.program_name} [options] object [object ...]
15
+
16
+ If no [-4|-6|--ipv4|--ipv6] option given, it tries both of ipv4 and ipv6.
17
+ EOS
18
+ opts.separator ''
19
+ opts.separator 'Options:'
20
+
21
+ opts.on '-h HOST', 'Specify FQDN of IRR / Whois server to send queries.',
22
+ 'IRR / Whois name is also acceptable. This switch is mandatory.' do |host|
23
+ options.host = host
24
+ end
25
+
26
+ opts.on '-s SOURCE', '--source', 'Specify an authoritative IRR / Whois source name.',
27
+ 'Multiply this option for multiple SOURCE.',
28
+ "eg) #{opts.program_name} -s jpirr -s radb AS-JPNIC" do |source|
29
+ options.source |= [source]
30
+ end
31
+
32
+ opts.on '-4', '--ipv4', 'Resolve IPv4 prefixes.' do
33
+ options.protocol |= [:ipv4]
34
+ end
35
+
36
+ opts.on '-6', '--ipv6', 'Resolve IPv6 prefixes.' do
37
+ options.protocol |= [:ipv6]
38
+ end
39
+
40
+ opts.on '-t NUMBER', '--threads', 'Number of threads to resolve prefixes per IRR / Whois server.' do |threads|
41
+ options.threads = threads
42
+ end
43
+
44
+ opts.on '-d', '--debug', 'Print raw queries, answers and additional informations.' do
45
+ options.debug = true
46
+ end
47
+
48
+ opts.on_tail '--help', 'Show this message' do
49
+ puts "irrc: Better IRR client to resolve as-set, route-set or aut-num object into prefixes", opts
50
+ exit
51
+ end
52
+
53
+ opts.on_tail '-v', '--version', 'Show version' do
54
+ puts Irrc::VERSION
55
+ exit
56
+ end
57
+ end
58
+ opts.parse!
59
+
60
+
61
+ if ARGV.empty?
62
+ $stderr.puts 'Missing Argument: object is required.', opts
63
+ abort
64
+ end
65
+
66
+ unless options.host
67
+ $stderr.puts 'Missing Argument: -h option is required.', opts
68
+ abort
69
+ end
70
+
71
+
72
+ options.protocol = [:ipv4, :ipv6] if options.protocol.empty?
73
+
74
+
75
+ begin
76
+ client = if options.debug
77
+ Irrc::Client.new(options.threads) {|c| c.logger = Irrc::Logging::Logger.new(STDERR) }
78
+ else
79
+ Irrc::Client.new(options.threads)
80
+ end
81
+
82
+ client.query options.host, ARGV, source: options.source, protocol: options.protocol
83
+ puts client.perform.to_yaml
84
+ rescue
85
+ $stderr.print "#{$!.class}: " unless $!.instance_of?(RuntimeError)
86
+ $stderr.puts $!.message
87
+
88
+ abort
89
+ end
@@ -8,16 +8,21 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Irrc::VERSION
9
9
  spec.authors = ['Shintaro Kojima']
10
10
  spec.email = ['goodies@codeout.net']
11
+
11
12
  spec.summary = 'IRR / Whois client to expand as-set and route-set into a list of origin ASs and prefixes'
12
13
  spec.description = 'irrc is a lightweight and flexible client of IRR / Whois Database to expand arbitrary as-set and route-set objects into a list of origin ASs and prefixes belonging to the ASs. It allows concurrent queries to IRR / Whois Databases for performance.'
13
14
  spec.homepage = 'https://github.com/codeout/irrc'
14
15
  spec.license = 'MIT'
15
16
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ['lib']
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'net-telnet'
20
23
 
21
- spec.add_development_dependency 'bundler', '~> 1.6'
22
- spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'bundler', '~> 1.9'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.required_ruby_version = '>= 2.0.0'
23
28
  end
@@ -37,15 +37,14 @@ module Irrc
37
37
  #
38
38
  # Examples
39
39
  #
40
- # client.query(:jpirr, 'AS-JPNIC', source: :jpirr, protocol: :ipv4)
41
- # client.query(:jpirr, 'AS-JPNIC', source: [:jpirr, :radb])
40
+ # client.query :jpirr, 'AS-JPNIC', source: :jpirr, protocol: :ipv4
41
+ # client.query :jpirr, 'AS-JPNIC', source: [:jpirr, :radb]
42
42
  def query(host, objects, options={})
43
- raise ArgumentError, 'host required.' unless host
43
+ raise ArgumentError, 'host is required.' unless host
44
44
  fqdn = Irrc::Irr.host(host) || host
45
45
 
46
- queues[fqdn] ||= Queue.new
47
46
  Array(objects).map {|object|
48
- queues[fqdn] << Irrc::Query.new(object, options)
47
+ queue(fqdn) << Irrc::Query.new(object, options)
49
48
  }
50
49
  end
51
50
 
@@ -56,9 +55,10 @@ module Irrc
56
55
  done = []
57
56
 
58
57
  queues.each_with_object([]) {|(fqdn, queue), workers|
59
- @thread_limit.times.map {
58
+ @thread_limit.times.map.with_index {|i|
60
59
  workers << Thread.start {
61
- done.push *worker_class(fqdn).new(fqdn, queues[fqdn], &@block).run
60
+ Thread.current[:id] = i+1
61
+ done.push *worker_class(fqdn).new(fqdn, queue(fqdn), cache(fqdn), &@block).run(@thread_limit)
62
62
  }
63
63
  }
64
64
  }.each {|t| t.join }
@@ -90,7 +90,19 @@ module Irrc
90
90
  private
91
91
 
92
92
  def queues
93
- @_queues ||= {}
93
+ @queues ||= {}
94
+ end
95
+
96
+ def queue(fqdn)
97
+ queues[fqdn] ||= Queue.new
98
+ end
99
+
100
+ def caches
101
+ @caches ||= {}
102
+ end
103
+
104
+ def cache(fqdn)
105
+ caches[fqdn] ||= {}
94
106
  end
95
107
 
96
108
  def worker_class(fqdn)
@@ -11,8 +11,8 @@ module Irrc
11
11
  end
12
12
 
13
13
  def connect
14
- @connection ||= logger.info("Connecting to #{@host}") &&
15
- Net::Telnet.new('Host' => @host,
14
+ @connection ||= logger.info("Connecting to #{@fqdn}") &&
15
+ Net::Telnet.new('Host' => @fqdn,
16
16
  'Port' => 43,
17
17
  'Telnetmode' => false,
18
18
  'Prompt' => return_code)
@@ -20,7 +20,7 @@ module Irrc
20
20
 
21
21
  def close
22
22
  if established?
23
- logger.info "Closing a connection to #{@host}"
23
+ logger.info "Closing a connection to #{@fqdn}"
24
24
  @connection.close
25
25
  end
26
26
  end
@@ -28,12 +28,5 @@ module Irrc
28
28
  def established?
29
29
  @connection && !@connection.sock.closed?
30
30
  end
31
-
32
- def execute(command)
33
- return if command.nil? || command == ''
34
-
35
- logger.debug "Executing: #{command}"
36
- @connection.cmd(command).tap {|result| logger.debug "Returned: #{result}" }
37
- end
38
31
  end
39
32
  end
@@ -48,49 +48,43 @@ module Irrc
48
48
 
49
49
  # See http://www.irr.net/docs/list.html
50
50
  LIST = [
51
- ['ALTDB', 'whois.altdb.net', 'irrd'],
52
- ['AOLTW', 'whois.aoltw.net', 'irrd'],
53
- ['APNIC', 'whois.apnic.net', 'whoisd'],
54
- ['ARIN', 'rr.arin.net', 'whoisd'],
55
- # ['BCNET', 'whois.bc.net', nil],
56
- ['BELL', 'whois.in.bell.ca', 'irrd'],
57
- ['BBOI', 'irr.bboi.net', 'irrd'],
58
- ['CANARIE', 'whois.canarie.ca', 'whoisd'],
59
- ['D', 'whois.depository.net', 'whoisd'],
60
- # ['DERU', 'whois.deru.net', nil],
61
- # ['DIGITALREALM', 'rr.digitalrealm.net', nil],
62
- ['EASYNET', 'whois.noc.easynet.net', 'whoisd'],
63
- # ['EBIT', 'whois.ebit.ca', nil],
64
- ['EPOCH', 'whois.epoch.net', 'irrd'],
65
- ['GT', 'rr.gt.ca', 'irrd'],
66
- # ['GW', 'whois.gw.net', nil],
67
- ['HOST', 'rr.host.net', 'irrd'],
68
- ['JPIRR', 'jpirr.nic.ad.jp', 'irrd'],
69
- ['LEVEL3', 'rr.level3.net', 'whoisd'],
70
- # ['MTO', 'rr.mtotelecom.com', nil],
71
- ['NESTEGG', 'whois.nestegg.net', 'irrd'],
72
- ['NTTCOM', 'rr.ntt.net', 'irrd'],
73
- ['OPENFACE', 'whois.openface.ca', 'irrd'],
74
- ['OTTIX', 'whois.ottix.net', 'irrd'],
75
- ['PANIX', 'rrdb.access.net', 'irrd'],
76
- ['RADB', 'whois.radb.net', 'irrd'],
77
- ['REACH', 'rr.net.reach.com', 'irrd'],
78
- ['RGNET', 'whois.rg.net', 'irrd'],
79
- ['RIPE', 'whois.ripe.net', 'whoisd'],
80
- ['RISQ', 'rr.risq.net', 'irrd'],
81
- ['ROGERS', 'whois.rogerstelecom.net', 'irrd'],
82
- ['SAVVIS', 'rr.savvis.net', 'whoisd'],
83
- ['TC', 'bgp.net.br', 'irrd']
51
+ ['AFRINIC', 'whois.afrinic.net', 'whoisd'],
52
+ ['ALTDB', 'whois.altdb.net', 'irrd'],
53
+ ['AOLTW', 'whois.aoltw.net', 'irrd'],
54
+ ['APNIC', 'whois.apnic.net', 'whoisd'],
55
+ ['ARIN', 'rr.arin.net', 'whoisd'],
56
+ ['BELL', 'whois.in.bell.ca', 'irrd'],
57
+ ['BBOI', 'irr.bboi.net', 'irrd'],
58
+ ['CANARIE', 'whois.canarie.ca', 'whoisd'],
59
+ ['EASYNET', 'whois.noc.easynet.net', 'whoisd'],
60
+ ['EPOCH', 'whois.epoch.net', 'irrd'],
61
+ ['GT', 'rr.gt.ca', 'irrd'],
62
+ ['HOST', 'rr.host.net', 'irrd'],
63
+ ['JPIRR', 'jpirr.nic.ad.jp', 'irrd'],
64
+ ['LEVEL3', 'rr.level3.net', 'whoisd'],
65
+ ['NESTEGG', 'whois.nestegg.net', 'irrd'],
66
+ ['NTTCOM', 'rr.ntt.net', 'irrd'],
67
+ ['OPENFACE', 'whois.openface.ca', 'irrd'],
68
+ ['OTTIX', 'whois.ottix.net', 'irrd'],
69
+ ['PANIX', 'rrdb.access.net', 'irrd'],
70
+ ['RADB', 'whois.radb.net', 'irrd'],
71
+ ['REACH', 'rr.net.reach.com', 'irrd'],
72
+ ['RGNET', 'whois.rg.net', 'irrd'],
73
+ ['RIPE', 'whois.ripe.net', 'whoisd'],
74
+ ['RISQ', 'rr.risq.net', 'irrd'],
75
+ ['ROGERS', 'whois.rogerstelecom.net', 'irrd'],
76
+ ['SAVVIS', 'rr.savvis.net', 'whoisd'],
77
+ ['TC', 'whois.bgp.net.br', 'irrd']
84
78
  ]
85
79
  end
86
80
 
87
81
 
88
82
  def object
89
- @_object
83
+ @object
90
84
  end
91
85
 
92
86
  def object=(object)
93
- @_object = object
87
+ @object = object
94
88
  end
95
89
 
96
90
  # Public: Returns the object type to query.
@@ -98,7 +92,7 @@ module Irrc
98
92
  #
99
93
  # Returns: A String. ('as-set', 'route-set' or 'aut-num')
100
94
  def object_type
101
- case @_object
95
+ case @object
102
96
  when /^AS-[\w-]+$|:AS-[\w-]+$/i
103
97
  'as-set'
104
98
  when /^RS-[\w-]+$|:RS-[\w-]+$/i
@@ -20,8 +20,6 @@ module Irrc
20
20
  include Irrc::Runner
21
21
  include Irrc::Irrd::Api
22
22
 
23
- attr_reader :host, :queue
24
-
25
23
 
26
24
  private
27
25
 
@@ -35,54 +33,73 @@ module Irrc
35
33
 
36
34
  case query.object_type
37
35
  when 'as-set'
38
- resolve_aut_nums_from_as_set query
39
- resolve_prefixes_from_aut_nums query
36
+ expand_as_set query
40
37
  when 'route-set'
41
- resolve_prefixes_from_route_set query
38
+ expand_route_set query
42
39
  when 'aut-num'
43
- query.add_aut_num_result query.object
44
- resolve_prefixes_from_aut_nums query
40
+ expand_aut_num query
45
41
  end
42
+
43
+ query
46
44
  end
47
45
 
48
46
  def set_source(query)
49
47
  command = set_source_command(query.sources)
50
48
  if execute(command) =~ error_code
51
- raise "'#{command}' failed on '#{host}' (#{$1})."
49
+ raise "'#{command}' failed on '#{@fqdn}' (#{$1})."
52
50
  end
53
51
  end
54
52
 
55
- def resolve_aut_nums_from_as_set(query)
56
- command = expand_set_command(query.object)
57
- result = execute(command)
58
- query.add_aut_num_result parse_aut_nums_from_as_set(result)
59
- rescue
60
- raise "'#{command}' failed on '#{host}' (#{$!.message})."
53
+ # Public: Expand an as-set object into aut-nums
54
+ def expand_as_set(query)
55
+ result = cache(query.object, query.sources) {
56
+ begin
57
+ command = expand_set_command(query.object)
58
+ execute(command)
59
+ rescue
60
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
61
+ end
62
+ }
63
+
64
+ parse_aut_nums_from_as_set(result).each do |autnum|
65
+ child = query.fork(autnum)
66
+ query.add_aut_num_result autnum if child.aut_num?
67
+ end
61
68
  end
62
69
 
63
- def resolve_prefixes_from_route_set(query)
64
- command = expand_set_command(query.object)
65
- result = execute(command)
70
+ # Public: Expand a route-set into routes
71
+ def expand_route_set(query)
72
+ result = cache(query.object, query.sources) {
73
+ begin
74
+ command = expand_set_command(query.object)
75
+ execute(command)
76
+ rescue
77
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
78
+ end
79
+ }
80
+
66
81
  prefixes = classify_by_protocol(parse_prefixes_from_route_set(result))
67
82
 
68
83
  query.protocols.each do |protocol|
69
84
  query.add_prefix_result prefixes[protocol], nil, protocol
70
85
  end
71
- rescue
72
- raise "'#{command}' failed on '#{host}' (#{$!.message})."
73
86
  end
74
87
 
75
- def resolve_prefixes_from_aut_nums(query)
76
- unless query.protocols.empty?
77
- # ipv4 and ipv6 should have the same result so far
78
- (query.result[:ipv4] || query.result[:ipv6]).keys.each do |autnum|
79
- command = expand_aut_num_command(autnum)
80
- result = execute(command)
88
+ # Public: Expand an aut-num object into routes
89
+ def expand_aut_num(query)
90
+ return if query.protocols.empty?
81
91
 
82
- query.protocols.each do |protocol|
83
- query.add_prefix_result parse_prefixes_from_aut_num(result, protocol), autnum, protocol
84
- end
92
+ result = cache(query.object, query.sources) {
93
+ begin
94
+ command = expand_aut_num_command(query.object)
95
+ execute(command)
96
+ rescue
97
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
85
98
  end
99
+ }
100
+
101
+ query.protocols.each do |protocol|
102
+ query.add_prefix_result parse_prefixes_from_aut_num(result, protocol), query.object, protocol
86
103
  end
87
104
  end
88
105
  end