better_ipaddr 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ module BetterIpaddr
2
+ VERSION = "0.1.2"
3
+ end
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: