better_ipaddr 0.1.2
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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +12 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +675 -0
- data/README.md +118 -0
- data/Rakefile +10 -0
- data/better_ipaddr.gemspec +25 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/better_ipaddr.rb +2 -0
- data/lib/better_ipaddr/classes.rb +72 -0
- data/lib/better_ipaddr/core_extension.rb +11 -0
- data/lib/better_ipaddr/methods.rb +332 -0
- data/lib/better_ipaddr/space.rb +142 -0
- data/lib/better_ipaddr/version.rb +3 -0
- metadata +103 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
require "ipaddr"
|
2
|
+
require "better_ipaddr/classes"
|
3
|
+
|
4
|
+
module BetterIpaddr
|
5
|
+
class Space
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
attr_reader :networks, :space, :family
|
9
|
+
|
10
|
+
def initialize(networks, space: nil, family: nil)
|
11
|
+
@family = family || infer_address_family(space, *networks)
|
12
|
+
@networks = networks.map { |network| import(network) }.sort
|
13
|
+
return unless space
|
14
|
+
@space = space
|
15
|
+
outlier = @networks.find { |net| !@space.cover?(net) }
|
16
|
+
return unless outlier
|
17
|
+
fail ArgumentError, "Address space #{@space.inspect} does not cover "\
|
18
|
+
"network #{outlier.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def +(other)
|
22
|
+
self.class.new(networks + other.networks, family: family)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
networks == other.networks
|
27
|
+
end
|
28
|
+
|
29
|
+
def each
|
30
|
+
if block_given?
|
31
|
+
networks.each do |network|
|
32
|
+
yield network
|
33
|
+
end
|
34
|
+
else
|
35
|
+
networks.each
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_by_minimum_size(size)
|
40
|
+
find_all { |net| net.size >= size }.min_by(&:prefix_length)
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_by_minimum_prefix_length(length)
|
44
|
+
find_all { |net| net.prefix_length >= length }.min_by(&:prefix_length)
|
45
|
+
end
|
46
|
+
|
47
|
+
def gaps
|
48
|
+
gap_networks = if space
|
49
|
+
gaps_before + gaps_between + gaps_after
|
50
|
+
else
|
51
|
+
gaps_between
|
52
|
+
end
|
53
|
+
self.class.new(gap_networks, family: family)
|
54
|
+
end
|
55
|
+
|
56
|
+
def summarize
|
57
|
+
out = []
|
58
|
+
networks.each do |network|
|
59
|
+
summary = network.summarize_with(out.last)
|
60
|
+
if summary
|
61
|
+
out[-1] = summary
|
62
|
+
summarize_backtrack(out)
|
63
|
+
else
|
64
|
+
out << network
|
65
|
+
end
|
66
|
+
end
|
67
|
+
export(out)
|
68
|
+
end
|
69
|
+
|
70
|
+
def summarize_backtrack(list)
|
71
|
+
loop do
|
72
|
+
break unless list.size >= 2
|
73
|
+
summary = list[-1].summarize_with(list[-2])
|
74
|
+
break unless summary
|
75
|
+
list.pop 2
|
76
|
+
list << summary
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def with_space(space)
|
81
|
+
export(networks, space: space)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def import(network)
|
87
|
+
case network
|
88
|
+
when String, Numeric
|
89
|
+
IPAddr[network, family]
|
90
|
+
else
|
91
|
+
network
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def infer_address_family(*networks)
|
96
|
+
example = networks.find { |net| net.respond_to?(:family) }
|
97
|
+
return example.family if example
|
98
|
+
fail "Unable to infer address family"
|
99
|
+
end
|
100
|
+
|
101
|
+
def export(new_networks, space: nil)
|
102
|
+
self.class.new(new_networks, space: space, family: family)
|
103
|
+
end
|
104
|
+
|
105
|
+
def gaps_after
|
106
|
+
export([space.last.last, space.last + 1]).gaps
|
107
|
+
end
|
108
|
+
|
109
|
+
def gaps_before
|
110
|
+
export([space.first - 1, networks.first]).gaps
|
111
|
+
end
|
112
|
+
|
113
|
+
def gaps_between
|
114
|
+
gap_networks = []
|
115
|
+
summarize.each_cons(2) do |a, b|
|
116
|
+
gap_networks.concat(subnets_between(a, b))
|
117
|
+
end
|
118
|
+
export(gap_networks)
|
119
|
+
end
|
120
|
+
|
121
|
+
def subnets_between(before, after)
|
122
|
+
subnets = []
|
123
|
+
candidate = before.last + 1
|
124
|
+
while candidate < after
|
125
|
+
candidate = max_supernet_between(before, after, candidate)
|
126
|
+
break unless candidate
|
127
|
+
subnets << candidate
|
128
|
+
candidate = candidate.last + 1
|
129
|
+
end
|
130
|
+
subnets
|
131
|
+
end
|
132
|
+
|
133
|
+
def max_supernet_between(before, after, start)
|
134
|
+
next_candidate = start
|
135
|
+
until next_candidate.overlap?(before) || next_candidate.overlap?(after)
|
136
|
+
candidate = next_candidate
|
137
|
+
next_candidate = next_candidate.grow(1)
|
138
|
+
end
|
139
|
+
candidate
|
140
|
+
end
|
141
|
+
end # class Space
|
142
|
+
end # module BetterIpaddr
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: better_ipaddr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Miller
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- bmiller@rackspace.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
64
|
+
- CODE_OF_CONDUCT.md
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- better_ipaddr.gemspec
|
70
|
+
- bin/console
|
71
|
+
- bin/setup
|
72
|
+
- lib/better_ipaddr.rb
|
73
|
+
- lib/better_ipaddr/classes.rb
|
74
|
+
- lib/better_ipaddr/core_extension.rb
|
75
|
+
- lib/better_ipaddr/methods.rb
|
76
|
+
- lib/better_ipaddr/space.rb
|
77
|
+
- lib/better_ipaddr/version.rb
|
78
|
+
homepage: https://github.com/bjmllr/better_ipaddr
|
79
|
+
licenses:
|
80
|
+
- GPL-3.0
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.5.1
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: IPAddr enhancements for network management.
|
102
|
+
test_files: []
|
103
|
+
has_rdoc:
|