irrc 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -4
- data/Gemfile +2 -5
- data/LICENSE +1 -1
- data/README.md +10 -32
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/irrc +89 -0
- data/irrc.gemspec +11 -6
- data/lib/irrc/client.rb +20 -8
- data/lib/irrc/connecting.rb +3 -10
- data/lib/irrc/irr.rb +30 -36
- data/lib/irrc/irrd/client.rb +45 -28
- data/lib/irrc/logging.rb +6 -0
- data/lib/irrc/parameter.rb +7 -7
- data/lib/irrc/prefix.rb +1 -1
- data/lib/irrc/query.rb +5 -1
- data/lib/irrc/query_status.rb +1 -1
- data/lib/irrc/runner.rb +35 -9
- data/lib/irrc/subquery.rb +48 -5
- data/lib/irrc/version.rb +1 -1
- data/lib/irrc/whoisd/client.rb +39 -41
- metadata +39 -27
- data/bin/irrc +0 -5
- data/lib/irrc/cli.rb +0 -1
- data/lib/irrc/cli/client.rb +0 -108
- data/lib/irrc/cli/yaml_printer.rb +0 -13
- data/spec/features/irr_as_set_resolution_spec.rb +0 -193
- data/spec/features/irr_invalid_object_resolution_spec.rb +0 -32
- data/spec/features/whois_as_set_resolution_spec.rb +0 -193
- data/spec/features/whois_invalid_object_resolution_spec.rb +0 -32
- data/spec/spec_helper.rb +0 -7
- data/spec/support/contexts.rb +0 -12
- data/spec/support/query.rb +0 -7
data/lib/irrc/logging.rb
CHANGED
@@ -9,5 +9,11 @@ module Irrc
|
|
9
9
|
def logger
|
10
10
|
@logger ||= Logger.new(STDERR).tap {|l| l.level = Logger::WARN }
|
11
11
|
end
|
12
|
+
|
13
|
+
class Logger < ::Logger
|
14
|
+
def add(severity, message = nil, progname = nil, &block)
|
15
|
+
super(severity, message, "(#{Thread.current[:id]}) #{progname}")
|
16
|
+
end
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
data/lib/irrc/parameter.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
module Irrc
|
2
2
|
module Parameter
|
3
|
-
|
4
3
|
# Public: Create a new IRRd / Whoisd client worker.
|
5
4
|
# You can customize the logger by specifying a block.
|
6
5
|
# The default logger is STDERR printer of more severe messages than INFO.
|
7
6
|
#
|
8
|
-
#
|
7
|
+
# fqdn - FQDN of IRR / Whois.
|
9
8
|
# queue - Queue object having query jobs.
|
10
9
|
# IRR / Whois name is also accespted.
|
11
10
|
# block - An optional block that can be used to customize the logger.
|
@@ -15,18 +14,19 @@ module Irrc
|
|
15
14
|
# Irrc::Irrd::Client.new('jpirr.nic.ad.jp', queue) {|c|
|
16
15
|
# c.logger = Logger.new('irrc.log')
|
17
16
|
# }
|
18
|
-
def initialize(
|
19
|
-
self.
|
17
|
+
def initialize(fqdn, queue, cache, &block)
|
18
|
+
self.fqdn = fqdn
|
20
19
|
self.queue = queue
|
20
|
+
@cache = cache
|
21
21
|
instance_eval(&block) if block_given?
|
22
22
|
end
|
23
23
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
def
|
28
|
-
raise ArgumentError, "Missing argument." unless
|
29
|
-
@
|
27
|
+
def fqdn=(fqdn)
|
28
|
+
raise ArgumentError, "Missing argument." unless fqdn
|
29
|
+
@fqdn = fqdn
|
30
30
|
end
|
31
31
|
|
32
32
|
def queue=(queue)
|
data/lib/irrc/prefix.rb
CHANGED
@@ -5,7 +5,7 @@ module Irrc
|
|
5
5
|
private
|
6
6
|
|
7
7
|
def classify_by_protocol(prefixes)
|
8
|
-
prefixes.each_with_object(Struct.new(:ipv4, :ipv6).new([], [])) {|prefix, result|
|
8
|
+
Array(prefixes).each_with_object(Struct.new(:ipv4, :ipv6).new([], [])) {|prefix, result|
|
9
9
|
addr = IPAddr.new(prefix)
|
10
10
|
if addr.ipv4?
|
11
11
|
result.ipv4 << prefix
|
data/lib/irrc/query.rb
CHANGED
@@ -40,6 +40,8 @@ module Irrc
|
|
40
40
|
#
|
41
41
|
# autnums - aut-num object(s) in String. Array form is also acceptable for multiple objects.
|
42
42
|
def add_aut_num_result(autnums)
|
43
|
+
result = root.result
|
44
|
+
|
43
45
|
@protocols.each do |protocol|
|
44
46
|
result[protocol] ||= {}
|
45
47
|
|
@@ -56,9 +58,11 @@ module Irrc
|
|
56
58
|
# protocol - Which protocol the route object(s) is for. :ipv4 or :ipv6.
|
57
59
|
# A String or Symbol of protcol name is acceptable.
|
58
60
|
def add_prefix_result(prefixes, autnum, protocol)
|
61
|
+
result = root.result
|
62
|
+
|
59
63
|
result[protocol] ||= {}
|
60
64
|
result[protocol][autnum] ||= []
|
61
|
-
result[protocol][autnum]
|
65
|
+
result[protocol][autnum].push *Array(prefixes)
|
62
66
|
end
|
63
67
|
|
64
68
|
|
data/lib/irrc/query_status.rb
CHANGED
data/lib/irrc/runner.rb
CHANGED
@@ -1,37 +1,63 @@
|
|
1
1
|
module Irrc
|
2
2
|
module Runner
|
3
|
-
def run
|
3
|
+
def run(threads)
|
4
4
|
done = []
|
5
5
|
|
6
6
|
loop do
|
7
|
-
|
8
|
-
|
7
|
+
# NOTE: trick to avoid dead lock
|
8
|
+
if last_thread_of?(threads) && @queue.empty?
|
9
|
+
terminate
|
10
|
+
logger.debug "Queue #{threads - 1} guard objects"
|
11
|
+
(threads - 1).times { @queue.push nil }
|
12
|
+
return done
|
13
|
+
end
|
14
|
+
|
15
|
+
query = @queue.pop
|
16
|
+
|
17
|
+
# NOTE: trick to avoid dead lock
|
18
|
+
if query.nil?
|
19
|
+
terminate
|
9
20
|
return done
|
10
21
|
end
|
11
22
|
|
12
|
-
query = queue.pop
|
13
23
|
connect unless established?
|
14
24
|
|
15
25
|
begin
|
16
|
-
|
26
|
+
logger.info "Processing #{query.object}"
|
27
|
+
query = process(query)
|
17
28
|
query.success
|
29
|
+
logger.debug "Queue new #{query.children.size} queries"
|
30
|
+
query.children.each {|q| @queue << q }
|
18
31
|
rescue
|
19
|
-
logger.error $!.message
|
32
|
+
logger.error "#{$!.message} when processing #{query.object} for #{query.root.object}"
|
20
33
|
query.fail
|
21
34
|
end
|
22
35
|
|
23
|
-
done << query
|
36
|
+
done << query if query.root?
|
24
37
|
end
|
25
38
|
end
|
26
39
|
|
27
40
|
|
28
41
|
private
|
29
42
|
|
43
|
+
def cache(object, sources, &block)
|
44
|
+
@cache["#{object}:#{sources}"] ||= yield
|
45
|
+
end
|
46
|
+
|
30
47
|
def execute(command)
|
31
48
|
return if command.nil? || command == ''
|
32
49
|
|
33
|
-
logger.debug
|
34
|
-
connection.cmd(command).tap {|result| logger.debug "
|
50
|
+
logger.debug %(Executing "#{command}")
|
51
|
+
connection.cmd(command).tap {|result| logger.debug %(Got "#{result}") }
|
52
|
+
end
|
53
|
+
|
54
|
+
def last_thread_of?(threads)
|
55
|
+
Thread.list.reject(&:stop?).size == 1 && Thread.list.size == threads+1
|
56
|
+
end
|
57
|
+
|
58
|
+
def terminate
|
59
|
+
logger.info "No more queries"
|
60
|
+
close
|
35
61
|
end
|
36
62
|
end
|
37
63
|
end
|
data/lib/irrc/subquery.rb
CHANGED
@@ -4,21 +4,64 @@ module Irrc
|
|
4
4
|
#
|
5
5
|
# object - IRR / Whois object to extract. (eg: as-set, route-set, aut-num object)
|
6
6
|
def fork(object)
|
7
|
-
Query.new(object, source: sources, protocol: protocols).tap {|q|
|
7
|
+
Query.new(object, source: @sources, protocol: @protocols).tap {|q|
|
8
8
|
q.parent = self
|
9
|
-
}
|
9
|
+
}.tap {|c| self.add_child c }
|
10
10
|
end
|
11
11
|
|
12
12
|
# Public: Returns the parent (associated) Query object, which is probably as-set.
|
13
13
|
def parent
|
14
|
-
@
|
14
|
+
@parent
|
15
15
|
end
|
16
16
|
|
17
17
|
# Public: Set a parent (associated) Query object, which is probably as-set.
|
18
18
|
#
|
19
19
|
# parent - Parent Query object.
|
20
|
-
def parent=(
|
21
|
-
@
|
20
|
+
def parent=(query)
|
21
|
+
@parent = query
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: Returns child Query objects
|
25
|
+
def children
|
26
|
+
@children ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Add a child Query object
|
30
|
+
def add_child(query)
|
31
|
+
children << query
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public: Delete a child Query object
|
35
|
+
def delete_child(query)
|
36
|
+
children.delete(query)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Public: Returns the IRR object to query including those from ancestor query objects.
|
40
|
+
#
|
41
|
+
# Returns: Array of String.
|
42
|
+
def ancestor_objects
|
43
|
+
@_ancestor_objects ||= Array(parent && parent.ancestor_objects) << object
|
44
|
+
end
|
45
|
+
|
46
|
+
# Public: Returns the root IRR object of the nested query
|
47
|
+
#
|
48
|
+
# Returns: String.
|
49
|
+
def root
|
50
|
+
@_root ||= if parent
|
51
|
+
parent.root
|
52
|
+
else
|
53
|
+
self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Public: Returns true if the query is root.
|
58
|
+
def root?
|
59
|
+
root == self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Public: Returns true if object is listed in ancestor IRR objects.
|
63
|
+
def ancestor_object?(object)
|
64
|
+
ancestor_objects.include?(object)
|
22
65
|
end
|
23
66
|
end
|
24
67
|
end
|
data/lib/irrc/version.rb
CHANGED
data/lib/irrc/whoisd/client.rb
CHANGED
@@ -20,68 +20,66 @@ module Irrc
|
|
20
20
|
include Irrc::Runner
|
21
21
|
include Irrc::Whoisd::Api
|
22
22
|
|
23
|
-
attr_reader :host, :queue
|
24
|
-
|
25
23
|
|
26
24
|
private
|
27
25
|
|
28
26
|
def process(query)
|
29
27
|
case query.object_type
|
30
28
|
when 'as-set'
|
31
|
-
|
32
|
-
resolve_prefixes_from_aut_nums query
|
29
|
+
expand_set query, 'as-set'
|
33
30
|
when 'route-set'
|
34
|
-
|
31
|
+
expand_set query, 'route-set'
|
35
32
|
when 'aut-num'
|
36
|
-
|
37
|
-
resolve_prefixes_from_aut_nums query
|
33
|
+
expand_aut_num query
|
38
34
|
end
|
39
|
-
end
|
40
35
|
|
41
|
-
|
42
|
-
command = expand_set_command(query.object, query.sources, type)
|
43
|
-
cache(query.object) {
|
44
|
-
result = execute(command)
|
45
|
-
parse_objects_from_set(result).map {|object|
|
46
|
-
expand_if_necessary(query.fork(object), type)
|
47
|
-
}.flatten.uniq.compact
|
48
|
-
}
|
49
|
-
rescue
|
50
|
-
raise "'#{command}' failed on '#{host}' (#{$!.message})."
|
36
|
+
query
|
51
37
|
end
|
52
38
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
39
|
+
# Public: Expand an as-set or route-set object into any object.
|
40
|
+
def expand_set(query, type)
|
41
|
+
result = cache(query.object, query.sources) {
|
42
|
+
begin
|
43
|
+
command = expand_set_command(query.object, query.sources, type)
|
44
|
+
execute(command)
|
45
|
+
rescue
|
46
|
+
raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
|
47
|
+
end
|
48
|
+
}
|
60
49
|
|
61
|
-
|
62
|
-
|
63
|
-
query.protocols.each do |protocol|
|
64
|
-
query.add_prefix_result prefixes[protocol], nil, protocol
|
65
|
-
end
|
66
|
-
end
|
50
|
+
parse_objects_from_set(result).each do |object|
|
51
|
+
next if query.ancestor_object?(object)
|
67
52
|
|
68
|
-
|
69
|
-
unless query.protocols.empty?
|
70
|
-
# ipv4 and ipv6 should have the same result so far
|
71
|
-
(query.result[:ipv4] || query.result[:ipv6]).keys.each do |autnum|
|
72
|
-
command = expand_aut_num_command(autnum, query.sources)
|
73
|
-
result = execute(command)
|
53
|
+
child = query.fork(object)
|
74
54
|
|
55
|
+
case child.object_type
|
56
|
+
when 'aut-num'
|
57
|
+
query.add_aut_num_result object
|
58
|
+
when nil # it looks prefix which is a member of route-set
|
59
|
+
prefix = classify_by_protocol(object)
|
75
60
|
query.protocols.each do |protocol|
|
76
|
-
query.add_prefix_result
|
61
|
+
query.add_prefix_result prefix[protocol], nil, protocol
|
77
62
|
end
|
78
63
|
end
|
79
64
|
end
|
80
65
|
end
|
81
66
|
|
82
|
-
|
83
|
-
|
84
|
-
|
67
|
+
# Public: Expand an aut-num object into routes
|
68
|
+
def expand_aut_num(query)
|
69
|
+
return if query.protocols.empty?
|
70
|
+
|
71
|
+
result = cache(query.object, query.sources) {
|
72
|
+
begin
|
73
|
+
command = expand_aut_num_command(query.object, query.sources)
|
74
|
+
execute(command)
|
75
|
+
rescue
|
76
|
+
raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
|
77
|
+
end
|
78
|
+
}
|
79
|
+
|
80
|
+
query.protocols.each do |protocol|
|
81
|
+
query.add_prefix_result parse_prefixes_from_aut_num(result, protocol), query.object, protocol
|
82
|
+
end
|
85
83
|
end
|
86
84
|
end
|
87
85
|
end
|
metadata
CHANGED
@@ -1,31 +1,59 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irrc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shintaro Kojima
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-telnet
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
33
|
+
version: '1.9'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
40
|
+
version: '1.9'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - ">="
|
@@ -56,12 +84,11 @@ files:
|
|
56
84
|
- LICENSE
|
57
85
|
- README.md
|
58
86
|
- Rakefile
|
59
|
-
- bin/
|
87
|
+
- bin/console
|
88
|
+
- bin/setup
|
89
|
+
- exe/irrc
|
60
90
|
- irrc.gemspec
|
61
91
|
- lib/irrc.rb
|
62
|
-
- lib/irrc/cli.rb
|
63
|
-
- lib/irrc/cli/client.rb
|
64
|
-
- lib/irrc/cli/yaml_printer.rb
|
65
92
|
- lib/irrc/client.rb
|
66
93
|
- lib/irrc/connecting.rb
|
67
94
|
- lib/irrc/irr.rb
|
@@ -80,13 +107,6 @@ files:
|
|
80
107
|
- lib/irrc/whoisd.rb
|
81
108
|
- lib/irrc/whoisd/api.rb
|
82
109
|
- lib/irrc/whoisd/client.rb
|
83
|
-
- spec/features/irr_as_set_resolution_spec.rb
|
84
|
-
- spec/features/irr_invalid_object_resolution_spec.rb
|
85
|
-
- spec/features/whois_as_set_resolution_spec.rb
|
86
|
-
- spec/features/whois_invalid_object_resolution_spec.rb
|
87
|
-
- spec/spec_helper.rb
|
88
|
-
- spec/support/contexts.rb
|
89
|
-
- spec/support/query.rb
|
90
110
|
homepage: https://github.com/codeout/irrc
|
91
111
|
licenses:
|
92
112
|
- MIT
|
@@ -99,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
119
|
requirements:
|
100
120
|
- - ">="
|
101
121
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
122
|
+
version: 2.0.0
|
103
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
124
|
requirements:
|
105
125
|
- - ">="
|
@@ -107,17 +127,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
127
|
version: '0'
|
108
128
|
requirements: []
|
109
129
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
130
|
+
rubygems_version: 2.6.8
|
111
131
|
signing_key:
|
112
132
|
specification_version: 4
|
113
133
|
summary: IRR / Whois client to expand as-set and route-set into a list of origin ASs
|
114
134
|
and prefixes
|
115
|
-
test_files:
|
116
|
-
- spec/features/irr_as_set_resolution_spec.rb
|
117
|
-
- spec/features/irr_invalid_object_resolution_spec.rb
|
118
|
-
- spec/features/whois_as_set_resolution_spec.rb
|
119
|
-
- spec/features/whois_invalid_object_resolution_spec.rb
|
120
|
-
- spec/spec_helper.rb
|
121
|
-
- spec/support/contexts.rb
|
122
|
-
- spec/support/query.rb
|
123
|
-
has_rdoc:
|
135
|
+
test_files: []
|