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 +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: []
|