useful_utilities 5.4.6 → 5.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79bd418ad8787d74738d6fd2b99030e6c698ee1c
4
- data.tar.gz: 1f227b9d219366903e323a70b043bf951eb12f6a
3
+ metadata.gz: 070776adf9c916abe22c6c83c0bc51af55ce327b
4
+ data.tar.gz: 14abcd387fe88bcc23027e7375070543dd966470
5
5
  SHA512:
6
- metadata.gz: f09b24ef2b0714e6d53638984f206f04a89335fbdc37df399ae65ee66307b2094684629c0ded231edbd46947a705fcd4a0d3931ee9071a5943e1931c29069905
7
- data.tar.gz: 490c74b2afb5ac686e72f145739a29e8af0a5fc6dce80fb38985a3e4880cb8b5b65bcffa3def2626e1be001ed190ab44550b09a7aff3a3ae72a7c2ef378b94d2
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
@@ -1,3 +1,3 @@
1
1
  module UsefulUtilities
2
- VERSION = '5.4.6'.freeze
2
+ VERSION = '5.5.0'.freeze
3
3
  end
@@ -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.6
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-03-27 00:00:00.000000000 Z
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: |2
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.4.3
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.