useful_utilities 5.4.6 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/useful_utilities/ip.rb +222 -0
- data/lib/useful_utilities/version.rb +1 -1
- data/lib/useful_utilities.rb +1 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 070776adf9c916abe22c6c83c0bc51af55ce327b
|
4
|
+
data.tar.gz: 14abcd387fe88bcc23027e7375070543dd966470
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 815b9225aba50b2c7062b75740daa87bc9e78054d622d8915a8511c6f0df7d3e9319d304ed06b0dcf8fc09937d2a88e8781e94ca6f1428c6f9a8e919a7de5477
|
7
|
+
data.tar.gz: b164e91be3ab638bded3a1bc0f9dfd1a7d3f8b80ad78e697012fc944113714a5c2f019cf07e3a6f1b00eaf8136590fa5f2e26d8c42e4622712446c6bd18859c2
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
# Provides a bunch of convinient methods to deal with ip addresses
|
5
|
+
# The module rely on stdlib ipaddr
|
6
|
+
module IP
|
7
|
+
IPV4 = 4
|
8
|
+
IPV6 = 6
|
9
|
+
IPVERSIONS = [IPV4, IPV6].freeze
|
10
|
+
MAX_NET_MASK_IPV4 = 32
|
11
|
+
MAX_NET_MASK_IPV6 = 128
|
12
|
+
MIN_NET_MASK = 0
|
13
|
+
ZERO_IP_INTEGER = 0
|
14
|
+
|
15
|
+
# integer representing ip '10.0.0.0', start of '10.0.0.0/8'
|
16
|
+
PRIVATE_RANGE_10_START = 167772160
|
17
|
+
# integer representing ip '10.255.255.255', end of '10.0.0.0/8'
|
18
|
+
PRIVATE_RANGE_10_END = 184549375
|
19
|
+
|
20
|
+
# integer representing ip '172.16.0.0', start of '172.16.0.0/12'
|
21
|
+
PRIVATE_RANGE_172_START = 2886729728
|
22
|
+
# integer representing ip '172.31.255.255', end of '172.16.0.0/12'
|
23
|
+
PRIVATE_RANGE_172_END = 2887778303
|
24
|
+
|
25
|
+
# integer representing ip '192.168.0.0', start of '192.168.0.0/16'
|
26
|
+
PRIVATE_RANGE_192_START = 3232235520
|
27
|
+
# integer representing ip '192.168.255.255', end of '192.168.0.0/16'
|
28
|
+
PRIVATE_RANGE_192_END = 3232301055
|
29
|
+
|
30
|
+
# integer representing ip 'fc00::', start of 'fc00::/7'
|
31
|
+
PRIVATE_RANGE_FC_START = 334965454937798799971759379190646833152
|
32
|
+
# integer representing ip 'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
|
33
|
+
# end of 'fc00::/7'
|
34
|
+
PRIVATE_RANGE_FC_END = 337623910929368631717566993311207522303
|
35
|
+
|
36
|
+
private_constant :IPV4,
|
37
|
+
:IPV6,
|
38
|
+
:IPVERSIONS,
|
39
|
+
:MAX_NET_MASK_IPV4,
|
40
|
+
:MAX_NET_MASK_IPV6,
|
41
|
+
:MIN_NET_MASK,
|
42
|
+
:ZERO_IP_INTEGER,
|
43
|
+
:PRIVATE_RANGE_10_START,
|
44
|
+
:PRIVATE_RANGE_10_END,
|
45
|
+
:PRIVATE_RANGE_172_START,
|
46
|
+
:PRIVATE_RANGE_172_END,
|
47
|
+
:PRIVATE_RANGE_192_START,
|
48
|
+
:PRIVATE_RANGE_192_END,
|
49
|
+
:PRIVATE_RANGE_FC_START,
|
50
|
+
:PRIVATE_RANGE_FC_END
|
51
|
+
|
52
|
+
extend self
|
53
|
+
|
54
|
+
# @param ip_string [String]
|
55
|
+
# @return [Boolean] true if supplied string is parsable ip address string
|
56
|
+
# and false otherwise
|
57
|
+
# @example
|
58
|
+
# UsefulUtilities::IP.valid_ip('10.10.0.1') #=> true
|
59
|
+
# UsefulUtilities::IP.valid_ip('non-parsable-ip') #=> false
|
60
|
+
def valid_ip?(ip_string)
|
61
|
+
IPAddr.new(ip_string)
|
62
|
+
true
|
63
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
# @param ip_string [String]
|
68
|
+
# @return [Boolean] true if ip_string represent private ip address.
|
69
|
+
# If ip_sting is non-parsable ip address ArgumentError raises.
|
70
|
+
# It is a wrapper on the private? method of IPAddr class instance.
|
71
|
+
# IPv4 addresses in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined
|
72
|
+
# in RFC 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in
|
73
|
+
# RFC 4193 are considered private.
|
74
|
+
# @example
|
75
|
+
# UsefulUtilities::IP.private_ip?('10.10.10.10') #=> true
|
76
|
+
# UsefulUtilities::IP.private_ip?('8.10.10.10') #=> false
|
77
|
+
def private_ip?(ip_string)
|
78
|
+
ip = IPAddr.new(ip_string)
|
79
|
+
|
80
|
+
# starting from ruby 2.5.0 an IPAddr instance has built-in private? method
|
81
|
+
# use the built-in method if exists
|
82
|
+
return ip.private? if ip.respond_to?(:private?)
|
83
|
+
|
84
|
+
check_private_ip(ip)
|
85
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
86
|
+
raise ArgumentError, 'Invalid ip address string supplied!'
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param address [Integer]
|
90
|
+
# @param version. If version is not equal 4 or 6 ArgumentError raises.
|
91
|
+
# If supplied address can not be converted into ip address string
|
92
|
+
# then ArgumentError raises.
|
93
|
+
# @return string as human readable ip address.
|
94
|
+
# @example
|
95
|
+
# UsefulUtilities::IP.integer_to_ip_string(1,version: 4) #=> '0.0.0.1'
|
96
|
+
# UsefulUtilities::IP.integer_to_ip_string(1,version: 6) #=> '::1'
|
97
|
+
def integer_to_ip_string(address, version:)
|
98
|
+
unless address.is_a? Integer
|
99
|
+
raise ArgumentError, 'Supplied address is not integer!'
|
100
|
+
end
|
101
|
+
|
102
|
+
IPAddr.new(address, ip_address_family(version)).to_s
|
103
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
104
|
+
raise ArgumentError, 'Invalid address!'
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param ip_string [String]
|
108
|
+
# @return integer representation of supplied ip string.
|
109
|
+
# ArgumentError raises if ip string can not be parsed as ip address.
|
110
|
+
# @example
|
111
|
+
# UsefulUtilities::IP.ip_string_to_integer('0.0.0.2') #=> 2
|
112
|
+
# UsefulUtilities::IP.ip_string_to_integer('::2') #=> 2
|
113
|
+
def ip_string_to_integer(ip_string)
|
114
|
+
IPAddr.new(ip_string).to_i
|
115
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
116
|
+
raise ArgumentError, 'Invalid ip address string supplied!'
|
117
|
+
end
|
118
|
+
|
119
|
+
# @param ip_string [String]
|
120
|
+
# @return array of 2 elements,
|
121
|
+
# the first: integer representation of supplied ip string,
|
122
|
+
# the second: version of ip protocol 4 or 6.
|
123
|
+
# ArgumentError raises if ip string can not be parsed as ip address.
|
124
|
+
# @example
|
125
|
+
# UsefulUtilities::IP.ip_string_to_integer_with_version('0.0.0.1') #=> [1, 4]
|
126
|
+
# UsefulUtilities::IP.ip_string_to_integer_with_version('::1') #=> [1, 6]
|
127
|
+
def ip_string_to_integer_with_version(ip_string)
|
128
|
+
ip = IPAddr.new(ip_string)
|
129
|
+
version = IPV4 if ip.ipv4?
|
130
|
+
version = IPV6 if ip.ipv6?
|
131
|
+
|
132
|
+
[ip.to_i, version]
|
133
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
134
|
+
raise ArgumentError, 'Invalid ip address string supplied!'
|
135
|
+
end
|
136
|
+
|
137
|
+
# @param ip_string [String]
|
138
|
+
# @param network_mask [Integer]
|
139
|
+
# @return [String] value representing network address derived from supplied
|
140
|
+
# ip address and it's network mask
|
141
|
+
# @example
|
142
|
+
# UsefulUtilities::IP.network_address('10.10.15.33', 24) #=> "10.10.15.0"
|
143
|
+
def network_address(ip_string, network_mask)
|
144
|
+
ip = IPAddr.new(ip_string)
|
145
|
+
|
146
|
+
version = if ip.ipv4?
|
147
|
+
IPV4
|
148
|
+
elsif ip.ipv6?
|
149
|
+
IPV6
|
150
|
+
else
|
151
|
+
raise ArgumentError, 'Unsupported ip address version!'
|
152
|
+
end
|
153
|
+
|
154
|
+
unless acceptable_network_mask?(network_mask, version: version)
|
155
|
+
raise ArgumentError,
|
156
|
+
"Invalid network mask: '#{network_mask}' for address: '#{ip_string}'"
|
157
|
+
end
|
158
|
+
|
159
|
+
ip_network_address =
|
160
|
+
IPAddr.new(ZERO_IP_INTEGER, ip_address_family(version))
|
161
|
+
.~
|
162
|
+
.<<(max_network_mask(version) - network_mask)
|
163
|
+
.&(ip)
|
164
|
+
|
165
|
+
ip_network_address.to_s
|
166
|
+
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
167
|
+
raise ArgumentError, 'Invalid ip address string supplied!'
|
168
|
+
end
|
169
|
+
|
170
|
+
# @param network_mask [Integer]
|
171
|
+
# @param version [Integer]
|
172
|
+
# @return [Boolean]
|
173
|
+
# ArgumentError raises if version is not equal 4 or 6.
|
174
|
+
# @example
|
175
|
+
# UsefulUtilities::IP.acceptable_network_mask?('not int', version: 4) #=> false
|
176
|
+
# UsefulUtilities::IP.acceptable_network_mask?(24, version: 4) #=> true
|
177
|
+
def acceptable_network_mask?(network_mask, version:)
|
178
|
+
return false unless network_mask.is_a? Integer
|
179
|
+
|
180
|
+
network_mask >= MIN_NET_MASK && network_mask <= max_network_mask(version)
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def ip_address_family(ip_version)
|
186
|
+
return Socket::AF_INET if ip_version == IPV4
|
187
|
+
return Socket::AF_INET6 if ip_version == IPV6
|
188
|
+
|
189
|
+
raise ArgumentError,
|
190
|
+
'Unsupported ip address version! '\
|
191
|
+
"Supported argument values: #{IPV4} or #{IPV6}."
|
192
|
+
end
|
193
|
+
|
194
|
+
def max_network_mask(ip_version)
|
195
|
+
return MAX_NET_MASK_IPV4 if ip_version == IPV4
|
196
|
+
return MAX_NET_MASK_IPV6 if ip_version == IPV6
|
197
|
+
|
198
|
+
raise ArgumentError,
|
199
|
+
'Unsupported version supplied! '\
|
200
|
+
"Supported version values: #{IPV4} or #{IPV6}."
|
201
|
+
end
|
202
|
+
|
203
|
+
def check_private_ip(ip)
|
204
|
+
return true if ip.ipv4? && in_private_ipv4?(ip.to_i)
|
205
|
+
return true if ip.ipv6? && in_private_ipv6?(ip.to_i)
|
206
|
+
|
207
|
+
false
|
208
|
+
end
|
209
|
+
|
210
|
+
def in_private_ipv4?(integer_ip)
|
211
|
+
[
|
212
|
+
(PRIVATE_RANGE_10_START..PRIVATE_RANGE_10_END),
|
213
|
+
(PRIVATE_RANGE_172_START..PRIVATE_RANGE_172_END),
|
214
|
+
(PRIVATE_RANGE_192_START..PRIVATE_RANGE_192_END)
|
215
|
+
].any? { |range| range.include?(integer_ip) }
|
216
|
+
end
|
217
|
+
|
218
|
+
def in_private_ipv6?(integer_ip)
|
219
|
+
(PRIVATE_RANGE_FC_START..PRIVATE_RANGE_FC_END).include?(integer_ip)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
data/lib/useful_utilities.rb
CHANGED
@@ -8,6 +8,7 @@ module UsefulUtilities
|
|
8
8
|
require_relative 'useful_utilities/size'
|
9
9
|
require_relative 'useful_utilities/api'
|
10
10
|
require_relative 'useful_utilities/i18n'
|
11
|
+
require_relative 'useful_utilities/ip'
|
11
12
|
require_relative 'useful_utilities/hash'
|
12
13
|
require_relative 'useful_utilities/yaml'
|
13
14
|
require_relative 'useful_utilities/redhat_release'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: useful_utilities
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OnApp Ltd.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -94,8 +94,7 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description:
|
98
|
-
A bunch of useful modules to work with time/size constants/hashes
|
97
|
+
description: " A bunch of useful modules to work with time/size constants/hashes\n"
|
99
98
|
email: onapp@onapp.com
|
100
99
|
executables: []
|
101
100
|
extensions: []
|
@@ -108,6 +107,7 @@ files:
|
|
108
107
|
- lib/useful_utilities/centos_version.rb
|
109
108
|
- lib/useful_utilities/hash.rb
|
110
109
|
- lib/useful_utilities/i18n.rb
|
110
|
+
- lib/useful_utilities/ip.rb
|
111
111
|
- lib/useful_utilities/numeric.rb
|
112
112
|
- lib/useful_utilities/redhat_release.rb
|
113
113
|
- lib/useful_utilities/size.rb
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.11
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Helpful methods for time, sizes, hashes etc.
|