tools 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +11 -0
- data/Gemfile +1 -1
- data/Rakefile +9 -15
- data/aux2 +1 -5
- data/bin/tools +29 -37
- data/lib/files/requireds.rb +0 -2
- data/lib/lib/array.rb +45 -65
- data/lib/lib/cache.rb +11 -18
- data/lib/lib/config.rb +47 -76
- data/lib/lib/console.rb +92 -108
- data/lib/lib/display.rb +10 -29
- data/lib/lib/files.rb +26 -44
- data/lib/lib/hash.rb +21 -22
- data/lib/lib/log.rb +28 -32
- data/lib/lib/net.rb +58 -80
- data/lib/lib/object.rb +8 -7
- data/lib/lib/prompt.rb +24 -26
- data/lib/lib/string.rb +15 -15
- data/lib/lib/utils.rb +90 -66
- data/lib/tools.rb +3 -8
- data/lib/tools/version.rb +2 -2
- data/test/mini_array.rb +7 -12
- data/test/mini_cache.rb +9 -12
- data/test/mini_config.rb +21 -12
- data/test/mini_console.rb +6 -8
- data/test/mini_display.rb +6 -9
- data/test/mini_file.rb +20 -24
- data/test/mini_hash.rb +27 -38
- data/test/mini_log.rb +2 -4
- data/test/mini_net.rb +167 -185
- data/test/mini_object.rb +16 -21
- data/test/mini_prompt.rb +28 -16
- data/test/mini_string.rb +11 -14
- data/test/mini_utils.rb +13 -16
- data/test/run +9 -9
- data/tools.gemspec +12 -14
- metadata +35 -20
data/lib/lib/files.rb
CHANGED
@@ -2,9 +2,7 @@ require 'singleton'
|
|
2
2
|
class ToolsFiles
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
def initialize(options = {})
|
6
|
-
end
|
7
|
-
|
5
|
+
def initialize(options = {}); end
|
8
6
|
|
9
7
|
# Purge files in directory
|
10
8
|
#
|
@@ -15,15 +13,16 @@ class ToolsFiles
|
|
15
13
|
# @param select (sample: *.log)
|
16
14
|
# @param elipsed_time in seconds (sample: 2 weeks = 14*24*60*60)
|
17
15
|
# @return
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
# Cmdapi.configuration.home+'/.cmdapi/backup', '*', 14*24*60*60
|
17
|
+
def self.purge_files(path, select, time)
|
18
|
+
to_clean = Dir.glob(File.join(path, select)).select do |a|
|
19
|
+
Time.now - File.ctime(a) > time
|
20
|
+
end
|
21
21
|
to_clean.each do |file_to_delete|
|
22
22
|
File.delete(file_to_delete)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
26
|
# Create a directory in work area
|
28
27
|
#
|
29
28
|
# Sample
|
@@ -33,14 +32,10 @@ class ToolsFiles
|
|
33
32
|
# @param directory
|
34
33
|
# @param directory_name
|
35
34
|
# @return
|
36
|
-
def self.create_dir
|
37
|
-
unless directory.end_with? '/'
|
38
|
-
|
39
|
-
|
40
|
-
complete_file = (directory + '/').gsub('//','/')
|
41
|
-
unless File.exists? complete_file
|
42
|
-
Dir.mkdir(complete_file)
|
43
|
-
end
|
35
|
+
def self.create_dir(directory, directory_name)
|
36
|
+
directory += '/' unless directory.end_with? '/'
|
37
|
+
complete_file = (directory + '/').gsub('//', '/')
|
38
|
+
Dir.mkdir(complete_file) unless File.exist? complete_file
|
44
39
|
ToolsUtil.set_variable directory_name, complete_file
|
45
40
|
end
|
46
41
|
|
@@ -55,11 +50,9 @@ class ToolsFiles
|
|
55
50
|
# @param file_name
|
56
51
|
# @param file_name_set
|
57
52
|
# @return
|
58
|
-
def self.create_file
|
59
|
-
complete_file = (directory + '/' + file_name).gsub('//','/')
|
60
|
-
unless File.
|
61
|
-
file = File.open( complete_file , 'w')
|
62
|
-
end
|
53
|
+
def self.create_file(directory, file_name, file_name_set)
|
54
|
+
complete_file = (directory + '/' + file_name).gsub('//', '/')
|
55
|
+
File.open(complete_file, 'w') unless File.exist? complete_file
|
63
56
|
ToolsUtil.set_variable file_name_set, complete_file
|
64
57
|
end
|
65
58
|
|
@@ -70,11 +63,10 @@ class ToolsFiles
|
|
70
63
|
# ToolsFiles.load_file file_to_load
|
71
64
|
# @param file_to_load Object
|
72
65
|
# @return
|
73
|
-
def self.load_file
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
66
|
+
def self.load_file(file_to_load)
|
67
|
+
return unless File.exist? file_to_load
|
68
|
+
|
69
|
+
File.open(file_to_load, 'r')
|
78
70
|
end
|
79
71
|
|
80
72
|
# Delete a file in work area
|
@@ -84,27 +76,17 @@ class ToolsFiles
|
|
84
76
|
# ToolsFiles.delete_file file_to_delete
|
85
77
|
# @param file_to_delete Object
|
86
78
|
# @return
|
87
|
-
def self.remove_file
|
88
|
-
|
89
|
-
file = FileUtils.remove_file( file_to_removee )
|
90
|
-
return file
|
91
|
-
end
|
92
|
-
end
|
79
|
+
def self.remove_file(file_to_remove)
|
80
|
+
return unless File.exist? file_to_remove
|
93
81
|
|
82
|
+
FileUtils.remove_file(file_to_remove)
|
83
|
+
end
|
94
84
|
|
95
|
-
def self.open_file
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
TTY::Editor.open( file, command: default_editor)
|
101
|
-
end
|
102
|
-
rescue Exception => e
|
103
|
-
return e
|
85
|
+
def self.open_file(file, default_editor = nil)
|
86
|
+
if default_editor.nil?
|
87
|
+
TTY::Editor.open(file, command: :vi)
|
88
|
+
else
|
89
|
+
TTY::Editor.open(file, command: default_editor)
|
104
90
|
end
|
105
91
|
end
|
106
|
-
|
107
92
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
data/lib/lib/hash.rb
CHANGED
@@ -4,24 +4,24 @@ module HashRecursiveBlank
|
|
4
4
|
each_pair do |key, val|
|
5
5
|
r[key] = val.rblank if val.is_a?(Hash)
|
6
6
|
end
|
7
|
-
|
7
|
+
r.keep_if { |_key, val| val.is_a?(Hash) }
|
8
8
|
end
|
9
9
|
|
10
10
|
def rblank!
|
11
11
|
each_pair do |key, val|
|
12
12
|
self[key] = val.rblank! if val.is_a?(Hash)
|
13
13
|
end
|
14
|
-
|
14
|
+
keep_if { |_key, val| val.is_a?(Hash) }
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
module HashRecursiveMerge
|
19
19
|
def rmerge(other_hash, concat_if_array = false)
|
20
20
|
r = {}
|
21
|
-
|
21
|
+
merge(other_hash) do |key, oldval, newval|
|
22
22
|
if oldval.is_a?(Hash)
|
23
23
|
r[key] = oldval.rmerge(newval, concat_if_array)
|
24
|
-
elsif oldval.is_a?(Array)
|
24
|
+
elsif oldval.is_a?(Array) && newval.is_a?(Array)
|
25
25
|
r[key] = concat_if_array ? oldval + newval : newval
|
26
26
|
else
|
27
27
|
newval
|
@@ -30,10 +30,10 @@ module HashRecursiveMerge
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def rmerge!(other_hash, concat_if_array = false)
|
33
|
-
|
33
|
+
merge!(other_hash) do |_key, oldval, newval|
|
34
34
|
if oldval.is_a?(Hash)
|
35
35
|
oldval.rmerge!(newval, concat_if_array)
|
36
|
-
elsif oldval.is_a?(Array)
|
36
|
+
elsif oldval.is_a?(Array) && newval.is_a?(Array)
|
37
37
|
concat_if_array ? oldval + newval : newval
|
38
38
|
else
|
39
39
|
newval
|
@@ -47,33 +47,32 @@ class Hash
|
|
47
47
|
include HashRecursiveBlank
|
48
48
|
|
49
49
|
def diff(other)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
memo
|
59
|
-
end
|
50
|
+
(keys + other.keys).uniq.each_with_object({}) do |key, memo|
|
51
|
+
next if self[key] == other[key]
|
52
|
+
|
53
|
+
memo[key] = if self[key].is_a?(Hash) && other[key].is_a?(Hash)
|
54
|
+
self[key].diff(other[key])
|
55
|
+
else
|
56
|
+
[self[key], other[key]]
|
57
|
+
end
|
60
58
|
end
|
59
|
+
end
|
61
60
|
end
|
62
61
|
|
63
|
-
|
64
62
|
class Hash
|
65
|
-
|
66
63
|
# ensures nested hash from keys, and sets final key to value
|
67
64
|
# keys: Array of Symbol|String
|
68
65
|
# value: any
|
69
66
|
def nested_set(keys, value)
|
70
|
-
raise
|
67
|
+
raise 'DEBUG: nested_set keys must be an Array' unless keys.is_a?(Array)
|
71
68
|
|
72
69
|
final_key = keys.pop
|
73
70
|
return unless valid_key?(final_key)
|
71
|
+
|
74
72
|
position = self
|
75
|
-
|
73
|
+
keys.each do |key|
|
76
74
|
return unless valid_key?(key)
|
75
|
+
|
77
76
|
position[key] = {} unless position[key].is_a?(Hash)
|
78
77
|
position = position[key]
|
79
78
|
end
|
@@ -85,7 +84,7 @@ class Hash
|
|
85
84
|
# returns true if key is valid
|
86
85
|
def valid_key?(key)
|
87
86
|
return true if key.is_a?(Symbol) || key.is_a?(String)
|
87
|
+
|
88
88
|
raise "DEBUG: nested_set invalid key: #{key} (#{key.class})"
|
89
89
|
end
|
90
|
-
|
91
|
-
end
|
90
|
+
end
|
data/lib/lib/log.rb
CHANGED
@@ -2,8 +2,7 @@ require 'singleton'
|
|
2
2
|
class ToolsLog
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
def initialize(options = {})
|
6
|
-
end
|
5
|
+
def initialize(options = {}); end
|
7
6
|
|
8
7
|
# Create a Log file in work area
|
9
8
|
#
|
@@ -21,22 +20,20 @@ class ToolsLog
|
|
21
20
|
# @param log_name LogName to create
|
22
21
|
# @param log_file LogFile path
|
23
22
|
# @return
|
24
|
-
def self.create_log_file
|
25
|
-
if File.
|
26
|
-
unless File.ctime(log_file).to_date == Time.now.to_date
|
27
|
-
File.delete(log_file)
|
28
|
-
end
|
23
|
+
def self.create_log_file(log_name, log_file)
|
24
|
+
if File.exist? log_file
|
25
|
+
File.delete(log_file) unless File.ctime(log_file).to_date == Time.now.to_date
|
29
26
|
end
|
30
27
|
ToolsUtil.set_variable "#{log_name}_log_file", log_file
|
31
28
|
ToolsUtil.set_variable "#{log_name}_logger", Logger.new(log_file, 'daily')
|
32
|
-
(ToolsUtil.get_variable "#{log_name}_logger").formatter = proc do |severity, datetime,
|
33
|
-
"#{severity.chars.first} #{datetime.strftime
|
29
|
+
(ToolsUtil.get_variable "#{log_name}_logger").formatter = proc do |severity, datetime, _progname, msg|
|
30
|
+
"#{severity.chars.first} #{datetime.strftime '%H:%M:%S'}: #{msg}\n"
|
34
31
|
end
|
35
|
-
#ToolsUtil.purge_files Tools.home+'/.tools/backup', '*', 14*24*60*60
|
32
|
+
# ToolsUtil.purge_files Tools.home+'/.tools/backup', '*', 14*24*60*60
|
36
33
|
end
|
37
34
|
|
38
|
-
def self.method_missing(method, *args
|
39
|
-
#expected call format => STRING_LOGGER_TYPE + '_' + LOGGER_TYPE
|
35
|
+
def self.method_missing(method, *args)
|
36
|
+
# expected call format => STRING_LOGGER_TYPE + '_' + LOGGER_TYPE
|
40
37
|
# Ex.: tools_info
|
41
38
|
logger_name = method.to_s.split('_').first
|
42
39
|
logger_method = method.to_s.split('_').last
|
@@ -44,27 +41,26 @@ class ToolsLog
|
|
44
41
|
color = args.extract_color
|
45
42
|
if color.eql? :default
|
46
43
|
case logger_method
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
44
|
+
when 'info'
|
45
|
+
color = :cyan
|
46
|
+
when 'warn'
|
47
|
+
color = :yellow
|
48
|
+
when 'debug'
|
49
|
+
color = :green
|
50
|
+
when 'error'
|
51
|
+
color = :light_red
|
52
|
+
when 'ucolor'
|
53
|
+
color = nil
|
54
|
+
logger_method = 'info'
|
55
|
+
else
|
56
|
+
return false
|
60
57
|
end
|
61
58
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
text_to_print = if color.nil?
|
60
|
+
args.first
|
61
|
+
else
|
62
|
+
args.first.colorize(color)
|
63
|
+
end
|
67
64
|
logger.method(logger_method).call text_to_print
|
68
65
|
end
|
69
|
-
|
70
|
-
end
|
66
|
+
end
|
data/lib/lib/net.rb
CHANGED
@@ -2,69 +2,57 @@ require 'singleton'
|
|
2
2
|
class ToolsNet
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
def initialize(options = {})
|
6
|
-
end
|
5
|
+
def initialize(options = {}); end
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
# Test a host.
|
8
|
+
#
|
9
|
+
# Net::Ping::External.new(host || '0.0.0.1000', timeout = 1).ping?
|
10
|
+
#
|
11
|
+
# @param host or ip variable to test
|
12
|
+
# @return [Boolean]
|
13
|
+
def self.ping?(host)
|
14
|
+
Net::Ping::External.new(host || '0.0.0.1000', 1).ping?
|
10
15
|
end
|
11
16
|
|
12
17
|
def self.get_current_ip
|
13
|
-
|
14
|
-
# ip = Socket::getaddrinfo(Socket.gethostname, "echo", Socket::AF_INET)[0][3]
|
15
|
-
# return ip if IPAddress.valid?(ip)
|
16
|
-
# rescue Exception => e
|
17
|
-
# end
|
18
|
-
ip = (`ifconfig | grep -E '10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '{print $2}'`).split("\n").first
|
18
|
+
ip = `ifconfig | grep -E '10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '{print $2}'`.split("\n").first
|
19
19
|
unless valid_ip? ip
|
20
|
-
ip =
|
20
|
+
ip = `ifconfig | grep -E '192\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '{print $2}'`.split("\n").first
|
21
21
|
end
|
22
22
|
ip = ip.split("\n").first if ip.include? "\n"
|
23
23
|
return ip if IPAddress.valid?(ip)
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
26
|
# Resolv a ip to a dns.
|
28
27
|
#
|
29
28
|
# @param ip variable ip to resolv
|
30
29
|
# @return [String] Dns name resolved
|
31
|
-
def self.resolv_ip_name
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return nil
|
40
|
-
else
|
41
|
-
return e.message
|
42
|
-
end
|
30
|
+
def self.resolv_ip_name(ip)
|
31
|
+
ret = Resolv.new.getname(ip)
|
32
|
+
ret.instance_variable_get('@labels').join('.')
|
33
|
+
rescue Exception => e
|
34
|
+
case e.message
|
35
|
+
when 'Dnsruby::NXDomain' then nil
|
36
|
+
else
|
37
|
+
e.message
|
43
38
|
end
|
44
|
-
return s.strip
|
45
39
|
end
|
46
40
|
|
47
|
-
|
48
41
|
# Resolv a dns to a ip.
|
49
42
|
#
|
50
43
|
# @param domain variable ip to resolv
|
51
44
|
# @return [String] Dns address resolved
|
52
|
-
def self.resolv_dns
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
else
|
61
|
-
return e.message
|
62
|
-
end
|
45
|
+
def self.resolv_dns(domain)
|
46
|
+
dns = Dnsruby::DNS.new
|
47
|
+
dns.getaddress(domain).to_s
|
48
|
+
rescue Exception => e
|
49
|
+
case e.message
|
50
|
+
when 'Dnsruby::NXDomain' then nil
|
51
|
+
else
|
52
|
+
e.message
|
63
53
|
end
|
64
|
-
return ret
|
65
54
|
end
|
66
55
|
|
67
|
-
|
68
56
|
# Do the request, validate and decode response and do the retries if needed
|
69
57
|
#
|
70
58
|
# - restclient_obj: initialized RestClient object
|
@@ -82,7 +70,7 @@ class ToolsNet
|
|
82
70
|
# @param validate_opts validate opts
|
83
71
|
# @param retry_opts retry opts
|
84
72
|
# @param show_progress default false
|
85
|
-
def self.doreq(
|
73
|
+
def self.doreq(restclient_obj, path, method, method_opts: {}, validate_opts: {}, retry_opts: {}, show_progress: false)
|
86
74
|
res = nil
|
87
75
|
code = nil
|
88
76
|
data = method_opts.fetch(:data, nil)
|
@@ -100,23 +88,22 @@ class ToolsNet
|
|
100
88
|
res = validate_decode_response(response, request, result, validate_opts)
|
101
89
|
code = result.code.to_i
|
102
90
|
end
|
103
|
-
rescue Exception =>
|
91
|
+
rescue Exception => e
|
104
92
|
flag_error = true
|
105
93
|
end
|
106
94
|
# Other conditionals to retry
|
107
95
|
unless retry_opts.empty?
|
108
|
-
if retry_opts.
|
96
|
+
if retry_opts.key?(:when_res)
|
109
97
|
flag_error = true if retry_opts[:when_res].include?(res)
|
110
98
|
end
|
111
|
-
if retry_opts.
|
99
|
+
if retry_opts.key?(:when_code)
|
112
100
|
flag_error = true if retry_opts[:when_code].include?(code)
|
113
101
|
end
|
114
102
|
end
|
115
103
|
return res unless flag_error # got response, break the loop
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
104
|
+
|
105
|
+
doReqMSG = format '%d/%d', try, retries
|
106
|
+
ap doReqMSG if show_progress
|
120
107
|
if try >= retries
|
121
108
|
ap doreq_code
|
122
109
|
return nil
|
@@ -133,8 +120,8 @@ class ToolsNet
|
|
133
120
|
# @param result
|
134
121
|
# @param validate_opts
|
135
122
|
# @return [Object type] Array or Proc or String or Error
|
136
|
-
def self.validate_decode_response
|
137
|
-
if validate_opts.
|
123
|
+
def self.validate_decode_response(response, request, result, validate_opts)
|
124
|
+
if validate_opts.key? :expected
|
138
125
|
expected = validate_opts[:expected]
|
139
126
|
case expected.class.name
|
140
127
|
when 'Array'
|
@@ -157,31 +144,25 @@ class ToolsNet
|
|
157
144
|
else
|
158
145
|
return response
|
159
146
|
end
|
160
|
-
|
147
|
+
true
|
161
148
|
end
|
162
149
|
|
163
|
-
|
164
150
|
# Validate.: port number between valid range?.
|
165
151
|
#
|
166
152
|
# @param port number to be validate.
|
167
153
|
# @return [Boolean]
|
168
|
-
def self.valid_port?
|
169
|
-
if port.to_s.strip.match(/^\d{1,5}(?!\d)$/).nil?
|
170
|
-
|
171
|
-
end
|
172
|
-
unless port.to_i.between?(1, 65535)
|
173
|
-
return false
|
174
|
-
end
|
175
|
-
return true
|
176
|
-
end
|
177
|
-
|
154
|
+
def self.valid_port?(port)
|
155
|
+
return false if port.to_s.strip.match(/^\d{1,5}(?!\d)$/).nil?
|
156
|
+
return false unless port.to_i.between?(1, 65_535)
|
178
157
|
|
158
|
+
true
|
159
|
+
end
|
179
160
|
|
180
161
|
# Validate.: ip number or mask are valids?.
|
181
162
|
#
|
182
163
|
# @param that number or mask to be validate.
|
183
164
|
# @return [Hash] result info ip or ask or error
|
184
|
-
def self.validate_ipaddress
|
165
|
+
def self.validate_ipaddress(that)
|
185
166
|
result = {}
|
186
167
|
result[:status] = false
|
187
168
|
result[:type] = ''
|
@@ -189,9 +170,9 @@ class ToolsNet
|
|
189
170
|
result[:address] = that
|
190
171
|
result[:resolv] = ''
|
191
172
|
|
192
|
-
if IPAddress
|
173
|
+
if IPAddress.valid_ipv4? that
|
193
174
|
begin
|
194
|
-
ip = IPAddress
|
175
|
+
ip = IPAddress.valid_ipv4? that
|
195
176
|
result[:status] = true
|
196
177
|
result[:type] = 'ip'
|
197
178
|
result[:oct1] = that.split('.')[0]
|
@@ -223,43 +204,40 @@ class ToolsNet
|
|
223
204
|
# end
|
224
205
|
end
|
225
206
|
end
|
226
|
-
|
207
|
+
result
|
227
208
|
end
|
228
209
|
|
229
|
-
|
230
210
|
# Validate.: ip number is a backend?.
|
231
211
|
#
|
232
212
|
# @param original_addr number to be validate.
|
233
213
|
# @return [Boolean]
|
234
|
-
def self.is_backend?
|
235
|
-
glbbackend
|
236
|
-
|
214
|
+
def self.is_backend?(original_addr)
|
215
|
+
glbbackend = NetAddr::CIDR.create('10.0.0.0/8')
|
216
|
+
glbbackend.contains? original_addr
|
237
217
|
end
|
238
218
|
|
239
|
-
def self.valid_ip?
|
219
|
+
def self.valid_ip?(original_addr)
|
240
220
|
status = false
|
241
221
|
begin
|
242
222
|
status = IPAddress.valid?(original_addr)
|
243
|
-
rescue
|
223
|
+
rescue Exception => e
|
224
|
+
e
|
244
225
|
end
|
245
|
-
|
226
|
+
status
|
246
227
|
end
|
247
228
|
|
248
229
|
# Validate.: ip number is avalid network.
|
249
230
|
#
|
250
231
|
# @param original_addr network number to be validate.
|
251
232
|
# @return [Boolean]
|
252
|
-
def self.valid_network?
|
233
|
+
def self.valid_network?(original_addr)
|
253
234
|
status = false
|
254
235
|
begin
|
255
236
|
ip = IPAddress original_addr
|
256
237
|
status = true if ip.network?
|
257
|
-
rescue
|
238
|
+
rescue Exception => e
|
239
|
+
e
|
258
240
|
end
|
259
|
-
|
241
|
+
status
|
260
242
|
end
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
end
|
243
|
+
end
|