aio_elin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +675 -0
- data/README.md +9 -0
- data/config.rb +39 -0
- data/lib/aio/base/debug.rb +30 -0
- data/lib/aio/base/toolkit/array.rb +24 -0
- data/lib/aio/base/toolkit/date.rb +46 -0
- data/lib/aio/base/toolkit/deep_clone.rb +10 -0
- data/lib/aio/base/toolkit/diff.rb +104 -0
- data/lib/aio/base/toolkit/excel_office.rb +421 -0
- data/lib/aio/base/toolkit/excel_wps.rb +437 -0
- data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
- data/lib/aio/base/toolkit/ipaddr.rb +28 -0
- data/lib/aio/base/toolkit/os.rb +26 -0
- data/lib/aio/base/toolkit/regexp.rb +32 -0
- data/lib/aio/base/toolkit/string.rb +28 -0
- data/lib/aio/base/toolkit/table.rb +441 -0
- data/lib/aio/base/toolkit/test_diff.rb +9 -0
- data/lib/aio/base/toolkit/test_excel.rb +118 -0
- data/lib/aio/base/toolkit/test_word.rb +58 -0
- data/lib/aio/base/toolkit/word_wps.rb +492 -0
- data/lib/aio/base/toolkit.rb +18 -0
- data/lib/aio/base.rb +10 -0
- data/lib/aio/core/device/cisco.rb +13 -0
- data/lib/aio/core/device/cmd_switch.rb +113 -0
- data/lib/aio/core/device/h3c.rb +12 -0
- data/lib/aio/core/device/huawei.rb +10 -0
- data/lib/aio/core/device/juniper.rb +10 -0
- data/lib/aio/core/device/maipu.rb +11 -0
- data/lib/aio/core/device/methods.rb +233 -0
- data/lib/aio/core/device/methods.rb.bak +199 -0
- data/lib/aio/core/device/parent_device.rb +275 -0
- data/lib/aio/core/device.rb +15 -0
- data/lib/aio/core/device_manager.rb +207 -0
- data/lib/aio/core/module/cmd.rb +160 -0
- data/lib/aio/core/module/description.rb +67 -0
- data/lib/aio/core/module/input_style.rb +98 -0
- data/lib/aio/core/module/output_style.rb +80 -0
- data/lib/aio/core/module/platform.rb +30 -0
- data/lib/aio/core/module/ranking.rb +24 -0
- data/lib/aio/core/module/special_style.rb +30 -0
- data/lib/aio/core/module/template.rb +13 -0
- data/lib/aio/core/module.rb +15 -0
- data/lib/aio/core/module_loader.rb +161 -0
- data/lib/aio/core/module_loader.rb.bak +148 -0
- data/lib/aio/core/module_manager.rb +112 -0
- data/lib/aio/core/module_manager.rb.bak +78 -0
- data/lib/aio/core/parse/file.rb +19 -0
- data/lib/aio/core/parse/parser.rb +91 -0
- data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
- data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
- data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
- data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
- data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
- data/lib/aio/core/parse/parser_machine.rb +47 -0
- data/lib/aio/core/parse.rb +6 -0
- data/lib/aio/core/text/context.rb +211 -0
- data/lib/aio/core/text/line_string.rb +74 -0
- data/lib/aio/core/text/warning.rb +179 -0
- data/lib/aio/core/text.rb +7 -0
- data/lib/aio/core/warning/description.rb +47 -0
- data/lib/aio/core/warning/warning_summarize.rb +232 -0
- data/lib/aio/core/warning.rb +6 -0
- data/lib/aio/core.rb +32 -0
- data/lib/aio/license.rb +687 -0
- data/lib/aio/resource/cover_picture.png +0 -0
- data/lib/aio/resource/line.png +0 -0
- data/lib/aio/resource/logo.png +0 -0
- data/lib/aio/ui/banner.rb +85 -0
- data/lib/aio/ui/readable_text.rb +75 -0
- data/lib/aio/ui/verbose.rb +29 -0
- data/lib/aio/ui/version.rb +9 -0
- data/lib/aio/ui.rb +138 -0
- data/lib/aio.rb +13 -0
- data/lib/modules/cmd/cisco/show_clock.rb +32 -0
- data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
- data/lib/modules/cmd/cisco/show_env.rb +71 -0
- data/lib/modules/cmd/cisco/show_failover.rb +39 -0
- data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
- data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
- data/lib/modules/cmd/cisco/show_inv.rb +43 -0
- data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
- data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
- data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
- data/lib/modules/cmd/cisco/show_memory.rb +27 -0
- data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
- data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
- data/lib/modules/cmd/cisco/show_version.rb +97 -0
- data/lib/modules/cmd/h3c/display_clock.rb +32 -0
- data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
- data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
- data/lib/modules/cmd/h3c/display_fan.rb +91 -0
- data/lib/modules/cmd/h3c/display_interface.rb +203 -0
- data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
- data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
- data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
- data/lib/modules/cmd/h3c/display_memory.rb +35 -0
- data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
- data/lib/modules/cmd/h3c/display_power.rb +90 -0
- data/lib/modules/cmd/h3c/display_version.rb +54 -0
- data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
- data/lib/modules/cmd/maipu/show_env.rb +34 -0
- data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
- data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
- data/lib/modules/cmd/maipu/show_memory.rb +31 -0
- data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
- data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
- data/lib/modules/cmd/maipu/show_version.rb +50 -0
- data/lib/modules/description/style/crc.rb +22 -0
- data/lib/modules/description/style/input_errors.rb +22 -0
- data/lib/modules/description/style/overrun.rb +22 -0
- data/lib/modules/description/style/proc_ratio.rb +22 -0
- data/lib/modules/description/style/protocol.rb +22 -0
- data/lib/modules/description/style/register.rb +22 -0
- data/lib/modules/description/style/runts.rb +22 -0
- data/lib/modules/description/style/template.rb +22 -0
- data/lib/modules/description/style/total_output_drops.rb +22 -0
- data/lib/modules/input/style/compare_xml.rb +89 -0
- data/lib/modules/input/style/console.rb +222 -0
- data/lib/modules/input/style/console.rb.bak +114 -0
- data/lib/modules/input/style/xinhua_nat.rb +70 -0
- data/lib/modules/output/style/boc_day.rb +223 -0
- data/lib/modules/output/style/cmds.rb +77 -0
- data/lib/modules/output/style/compare_json.rb +26 -0
- data/lib/modules/output/style/compare_report.rb +31 -0
- data/lib/modules/output/style/compare_xml.rb +86 -0
- data/lib/modules/output/style/excel_table_office.rb +407 -0
- data/lib/modules/output/style/excel_table_wps.rb +400 -0
- data/lib/modules/output/style/summary_report.rb +563 -0
- data/lib/modules/special/style/compare.rb +110 -0
- metadata +176 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module Aio::Module
|
6
|
+
class InputStyle
|
7
|
+
|
8
|
+
class ErrorModuleInput < StandardError
|
9
|
+
def to_s; "请重载此方法"; end
|
10
|
+
end
|
11
|
+
|
12
|
+
# 重要!
|
13
|
+
# 输入文件
|
14
|
+
attr_accessor :input_file
|
15
|
+
|
16
|
+
# 信息
|
17
|
+
attr_accessor :input_info
|
18
|
+
|
19
|
+
# 外加信息,用于针对特殊情况
|
20
|
+
attr_accessor :ext_info
|
21
|
+
|
22
|
+
def initialize(info={})
|
23
|
+
@input_info = info.dup
|
24
|
+
set_defaults()
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_defaults
|
28
|
+
self.input_info = {
|
29
|
+
:author => nil,
|
30
|
+
:description => "No Input Description",
|
31
|
+
# 产生文件的平台
|
32
|
+
:platform => nil,
|
33
|
+
:file_suffix => nil,
|
34
|
+
:pass_file => nil,
|
35
|
+
:license => ::Aio::AIO_LICENSE,
|
36
|
+
}.update(@input_info)
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def type
|
41
|
+
Aio::Module::InputStyle
|
42
|
+
end
|
43
|
+
|
44
|
+
# 保证输出的file为Pathname类
|
45
|
+
def check_file(file)
|
46
|
+
if file.class != Pathname
|
47
|
+
case file.class
|
48
|
+
when String
|
49
|
+
file = Pathname.new(file)
|
50
|
+
when File
|
51
|
+
file = Pathname.new(file.path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
file
|
55
|
+
end
|
56
|
+
|
57
|
+
# 请重载此方法
|
58
|
+
def parse
|
59
|
+
raise ErrorModuleInput.new
|
60
|
+
end
|
61
|
+
|
62
|
+
# 检查是否符合文件后缀,符合返回真
|
63
|
+
def file_suffix?(file)
|
64
|
+
if self.file_suffix.match(file)
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
|
70
|
+
# 检查是否符合pass_file, 符合返回真
|
71
|
+
def pass_file?(file)
|
72
|
+
self.pass_file.each do |pass|
|
73
|
+
if pass.match(Aio::Base::Toolkit::String.safe(file))
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
def input_file
|
81
|
+
@input_info[:input_file]
|
82
|
+
end
|
83
|
+
|
84
|
+
def input_file=(file)
|
85
|
+
file = check_file(file)
|
86
|
+
@input_info[:input_file] = file
|
87
|
+
end
|
88
|
+
|
89
|
+
def author; self.input_info[:author]; end
|
90
|
+
def description; self.input_info[:description]; end
|
91
|
+
def platform; self.input_info[:platform]; end
|
92
|
+
def file_suffix; self.input_info[:file_suffix]; end
|
93
|
+
def license; self.input_info[:license]; end
|
94
|
+
def pass_file; self.input_info[:pass_file]; end
|
95
|
+
|
96
|
+
|
97
|
+
end # class
|
98
|
+
end # module
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
class OutputStyle
|
5
|
+
|
6
|
+
class OutputMethodError < StandardError
|
7
|
+
def to_s
|
8
|
+
"请重载此方法"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# 输出的文件名
|
13
|
+
attr_accessor :output_file
|
14
|
+
|
15
|
+
# 信息
|
16
|
+
attr_accessor :output_info
|
17
|
+
|
18
|
+
# device_manager 加载
|
19
|
+
attr_accessor :device_manager
|
20
|
+
|
21
|
+
# module_manager 加载
|
22
|
+
attr_accessor :module_manager
|
23
|
+
|
24
|
+
def initialize(info={})
|
25
|
+
@output_info = info.dup
|
26
|
+
set_defaults()
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_defaults
|
30
|
+
self.output_info = {
|
31
|
+
:author => nil,
|
32
|
+
:description => "No Output Description",
|
33
|
+
:file_suffix => nil,
|
34
|
+
:license => ::Aio::AIO_LICENSE,
|
35
|
+
}.update(@output_info)
|
36
|
+
end
|
37
|
+
|
38
|
+
def author; self.output_info[:author]; end
|
39
|
+
def description; self.output_info[:description]; end
|
40
|
+
def file_suffix; self.output_info[:file_suffix]; end
|
41
|
+
def license; self.output_info[:license]; end
|
42
|
+
|
43
|
+
def type
|
44
|
+
Aio::Module::OutputStyle
|
45
|
+
end
|
46
|
+
|
47
|
+
# 输入的文件名,判断是否有后缀
|
48
|
+
# 如果没有则添加后缀
|
49
|
+
def output_file=(file_name)
|
50
|
+
file_pathname = Pathname.new(file_name)
|
51
|
+
if file_pathname.extname.empty?
|
52
|
+
base, name = file_pathname.split
|
53
|
+
suffix = output_info[:file_suffix]
|
54
|
+
|
55
|
+
# 当不需要suffix, 将其设为空
|
56
|
+
unless /^\./ =~ suffix
|
57
|
+
if suffix == "" or /(?i)null/ =~ suffix
|
58
|
+
suffix = ""
|
59
|
+
else
|
60
|
+
suffix = "." + suffix
|
61
|
+
end
|
62
|
+
end
|
63
|
+
name = name.to_s + suffix
|
64
|
+
file_pathname = Pathname.new(base + name)
|
65
|
+
end
|
66
|
+
@output_file = file_pathname
|
67
|
+
end
|
68
|
+
|
69
|
+
def each_devices_with_useful
|
70
|
+
self.device_manager.each_devices_with_useful do |k, v|
|
71
|
+
yield k, v
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# 生成文件
|
76
|
+
def generate
|
77
|
+
raise OutputMethodError.new
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Aio::Module
|
2
|
+
|
3
|
+
class Platform
|
4
|
+
attr_reader :platform
|
5
|
+
end
|
6
|
+
|
7
|
+
class RT < Platform
|
8
|
+
def self.to_s; "route"; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class SW < Platform
|
12
|
+
def self.to_s; "switch"; end
|
13
|
+
end
|
14
|
+
|
15
|
+
class FW < Platform
|
16
|
+
def self.to_s; "failwall"; end
|
17
|
+
end
|
18
|
+
|
19
|
+
class RS < Platform
|
20
|
+
def self.to_s; "route & switch"; end
|
21
|
+
end
|
22
|
+
|
23
|
+
class RF < Platform
|
24
|
+
def self.to_s; "route & failwall"; end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ALL < Platform
|
28
|
+
def self.to_s; "route & switch & failwall"; end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Aio::Module
|
2
|
+
|
3
|
+
class Ranking
|
4
|
+
attr_reader :ranking
|
5
|
+
end
|
6
|
+
|
7
|
+
class Ranking_1 < Ranking
|
8
|
+
def self.to_s; "level-1"; end
|
9
|
+
end
|
10
|
+
class Ranking_2 < Ranking
|
11
|
+
def self.to_s; "level-2"; end
|
12
|
+
end
|
13
|
+
class Ranking_3 < Ranking
|
14
|
+
def self.to_s; "level-3"; end
|
15
|
+
end
|
16
|
+
class Ranking_4 < Ranking
|
17
|
+
def self.to_s; "level-4"; end
|
18
|
+
end
|
19
|
+
class Ranking_5 < Ranking
|
20
|
+
def self.to_s; "level-5"; end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
class SpecialStyle
|
5
|
+
class MethodError < StandardError; end
|
6
|
+
|
7
|
+
attr_accessor :special_info
|
8
|
+
|
9
|
+
def initialize(info={})
|
10
|
+
@special_info = info.dup
|
11
|
+
set_defaults()
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_defaults
|
15
|
+
self.special_info = {
|
16
|
+
:author => nil,
|
17
|
+
:description => nil,
|
18
|
+
:license => ::Aio::AIO_LICENSE,
|
19
|
+
}.update(@special_info)
|
20
|
+
end
|
21
|
+
|
22
|
+
def type
|
23
|
+
Aio::Module::SpecialStyle
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse
|
27
|
+
raise MethodError, "请重载此方法"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Aio::Module
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
class Template
|
5
|
+
include Singleton
|
6
|
+
end
|
7
|
+
class Template_1 < Template; end
|
8
|
+
class Template_2 < Template; end
|
9
|
+
class Template_3 < Template; end
|
10
|
+
class Template_4 < Template; end
|
11
|
+
class Template_5 < Template; end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Aio
|
2
|
+
module Module
|
3
|
+
|
4
|
+
require "aio/core/module/ranking"
|
5
|
+
require "aio/core/module/platform"
|
6
|
+
require "aio/core/module/template"
|
7
|
+
require "aio/core/module/cmd"
|
8
|
+
require "aio/core/module/input_style"
|
9
|
+
require "aio/core/module/output_style"
|
10
|
+
require "aio/core/module/special_style"
|
11
|
+
require "aio/core/module/description"
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
#这一部分用来加载Module下各模块
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
require "find"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
class Loader
|
8
|
+
|
9
|
+
Reg_klass_filter = /class (.*)[\s]+<[\s]+Aio::Module/
|
10
|
+
Reg_ruby_file = /.rb$/
|
11
|
+
|
12
|
+
attr_accessor :module_manager
|
13
|
+
|
14
|
+
def initialize(module_manager)
|
15
|
+
@module_manager = module_manager
|
16
|
+
end
|
17
|
+
|
18
|
+
# 分析各个文件夹目录
|
19
|
+
# 目录格式 ~/aio/lib/modules/cisco/show_version.rb
|
20
|
+
# 目录格式 ~/aio/lib/modules/cmd/cisco/show_version.rb
|
21
|
+
# 目录格式包括了 cmd, input, output
|
22
|
+
# cmd 放置各个命令模块
|
23
|
+
# input 放置各种输入方式的模块
|
24
|
+
# output 放置各种输出方式的模块
|
25
|
+
def each_module_reference_name(path, opts={})
|
26
|
+
::Dir.foreach(path) do |entry|
|
27
|
+
if entry.downcase == "." or entry.downcase == ".."
|
28
|
+
next
|
29
|
+
end
|
30
|
+
|
31
|
+
full_entry_path = ::File.join(path, entry)
|
32
|
+
module_type = entry
|
33
|
+
|
34
|
+
# 第一层目录结构,判断是否为cmd, input, output 的模块类型
|
35
|
+
unless ::File.directory?(full_entry_path) and
|
36
|
+
module_manager.module_type_enable?(module_type)
|
37
|
+
next
|
38
|
+
end
|
39
|
+
|
40
|
+
# module_type = "cmd"
|
41
|
+
# full_entry_path = "~/aio/lib/modules/cmd"
|
42
|
+
|
43
|
+
full_entry_pathname = Pathname.new(full_entry_path)
|
44
|
+
|
45
|
+
Find.find(full_entry_path) do |entry_descendant_path|
|
46
|
+
if File.directory?(entry_descendant_path)
|
47
|
+
next
|
48
|
+
end
|
49
|
+
|
50
|
+
# 判断是不是.rb 结尾,而不是 .rb.swp 结尾
|
51
|
+
unless vaild_ruby_file?(entry_descendant_path)
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
# entry_descendant_path 为ruby文件的完整绝对路径
|
56
|
+
entry_descendant_pathname = Pathname.new(entry_descendant_path)
|
57
|
+
|
58
|
+
# 获得 modules 的二级目录名称, cmd/cisco 中的cisco
|
59
|
+
# 或者 input/style 中的style
|
60
|
+
base, _i = entry_descendant_pathname.split
|
61
|
+
_i, module_layer_2 = base.split
|
62
|
+
module_layer_2 = module_layer_2.to_s
|
63
|
+
|
64
|
+
# 查询是否有效并且取得模块的类名
|
65
|
+
module_klass_name = get_module_klass_name(entry_descendant_pathname)
|
66
|
+
if module_klass_name.empty?
|
67
|
+
next
|
68
|
+
end
|
69
|
+
|
70
|
+
# 获得参考名
|
71
|
+
relative_entry_descendant_pathname = entry_descendant_pathname.relative_path_from(full_entry_pathname)
|
72
|
+
_i, relative_entry_descendant_pathname = relative_entry_descendant_pathname.split
|
73
|
+
relative_entry_descendant_path = relative_entry_descendant_pathname.to_s
|
74
|
+
module_reference_name = module_reference_name_from_path(relative_entry_descendant_path)
|
75
|
+
|
76
|
+
module_reference_name = [module_type, module_layer_2, module_reference_name].join("/")
|
77
|
+
yield entry_descendant_path, module_type, module_layer_2, module_reference_name, module_klass_name
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# 取模块的类名,以便以后调用
|
84
|
+
def get_module_klass_name(full_path)
|
85
|
+
fo = File.open(full_path)
|
86
|
+
fo.each_line do |l|
|
87
|
+
l = Aio::Base::Toolkit::String.safe(l)
|
88
|
+
klass_name = Reg_klass_filter.match(l)
|
89
|
+
if klass_name == nil
|
90
|
+
next
|
91
|
+
end
|
92
|
+
klass_name = klass_name[1].strip
|
93
|
+
return klass_name
|
94
|
+
end
|
95
|
+
return ""
|
96
|
+
end
|
97
|
+
|
98
|
+
def module_reference_name_from_path(path)
|
99
|
+
path.gsub(Reg_ruby_file, '')
|
100
|
+
end
|
101
|
+
|
102
|
+
# 是否是有效的Ruby文件
|
103
|
+
def vaild_ruby_file?(path)
|
104
|
+
if Reg_ruby_file.match(path)
|
105
|
+
return true
|
106
|
+
end
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
|
110
|
+
# 全局加载模块
|
111
|
+
def load_modules(path, opts={})
|
112
|
+
count_by_module_type = {}
|
113
|
+
|
114
|
+
each_module_reference_name(path, opts={}) do |full_module_path, module_type, module_layer_2, module_reference_name, module_klass_name|
|
115
|
+
load_module(full_module_path,
|
116
|
+
module_type,
|
117
|
+
module_layer_2,
|
118
|
+
module_reference_name,
|
119
|
+
module_klass_name,
|
120
|
+
{
|
121
|
+
# :recalcuate_by_device_type => recalculate_by_device_type,
|
122
|
+
:count_by_module_type => count_by_module_type,
|
123
|
+
}
|
124
|
+
)
|
125
|
+
|
126
|
+
end
|
127
|
+
module_manager.notify({
|
128
|
+
:count_by_module_type => count_by_module_type,
|
129
|
+
})
|
130
|
+
end
|
131
|
+
|
132
|
+
# 真正加载处
|
133
|
+
# 并将模块全部实例化
|
134
|
+
def load_module(full_module_path, module_type,module_layer_2, module_reference_name, module_klass_name, opts={})
|
135
|
+
|
136
|
+
begin
|
137
|
+
require "#{full_module_path}"
|
138
|
+
module_klass = ::Object::const_get(module_klass_name).new
|
139
|
+
rescue Exception
|
140
|
+
puts "[-] Can not load module: #{full_module_path}"
|
141
|
+
#puts caller
|
142
|
+
return
|
143
|
+
end
|
144
|
+
@module_manager.add_module(full_module_path, module_type, module_layer_2, module_reference_name, module_klass)
|
145
|
+
|
146
|
+
# 计数
|
147
|
+
# count_by_module_type = {"cmd" => { "cisco" => 2 }, "input" => { "style" => 1 } }
|
148
|
+
count_by_module_type = opts[:count_by_module_type]
|
149
|
+
if count_by_module_type
|
150
|
+
if !count_by_module_type[module_type]
|
151
|
+
count_by_module_type[module_type] = {}
|
152
|
+
end
|
153
|
+
|
154
|
+
count_by_module_type[module_type][module_layer_2] ||= 0
|
155
|
+
count_by_module_type[module_type][module_layer_2] += 1
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end #class
|
160
|
+
end #module
|
161
|
+
|
@@ -0,0 +1,148 @@
|
|
1
|
+
#这一部分用来加载Module下各模块
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
require "find"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
class Loader
|
8
|
+
|
9
|
+
Reg_klass_filter = /class (.*) < Aio::Module::Cmd/
|
10
|
+
Reg_ruby_file = /.rb$/
|
11
|
+
|
12
|
+
attr_accessor :module_manager
|
13
|
+
|
14
|
+
def initialize(module_manager)
|
15
|
+
@module_manager = module_manager
|
16
|
+
end
|
17
|
+
|
18
|
+
# 分析各个文件夹目录
|
19
|
+
# 目录格式 ~/aio/lib/modules/cisco/show_version.rb
|
20
|
+
def each_module_reference_name(path, opts={})
|
21
|
+
::Dir.foreach(path) do |entry|
|
22
|
+
if entry.downcase == "." or entry.downcase == ".."
|
23
|
+
next
|
24
|
+
end
|
25
|
+
|
26
|
+
full_entry_path = ::File.join(path, entry)
|
27
|
+
device_type = entry
|
28
|
+
|
29
|
+
unless ::File.directory?(full_entry_path) and
|
30
|
+
module_manager.device_type_enable?(device_type)
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
# device_type = "cisco"
|
35
|
+
# full_entry_path = "~/aio/lib/modules/cisco"
|
36
|
+
|
37
|
+
full_entry_pathname = Pathname.new(full_entry_path)
|
38
|
+
|
39
|
+
Find.find(full_entry_path) do |entry_descendant_path|
|
40
|
+
if File.directory?(entry_descendant_path)
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
44
|
+
# 判断是不是.rb 结尾,而不是 .rb.swp 结尾
|
45
|
+
unless vaild_ruby_file?(entry_descendant_path)
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
|
+
# entry_descendant_path 为ruby文件的完整绝对路径
|
50
|
+
entry_descendant_pathname = Pathname.new(entry_descendant_path)
|
51
|
+
|
52
|
+
# 查询是否有效并且取得模块的类名
|
53
|
+
module_klass_name = get_module_klass_name(entry_descendant_pathname)
|
54
|
+
if module_klass_name.empty?
|
55
|
+
next
|
56
|
+
end
|
57
|
+
|
58
|
+
relative_entry_descendant_pathname = entry_descendant_pathname.relative_path_from(full_entry_pathname)
|
59
|
+
relative_entry_descendant_path = relative_entry_descendant_pathname.to_s
|
60
|
+
module_reference_name = module_reference_name_from_path(relative_entry_descendant_path)
|
61
|
+
yield entry_descendant_path, device_type, module_reference_name, module_klass_name
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# 取模块的类名,以便以后调用
|
68
|
+
def get_module_klass_name(full_path)
|
69
|
+
fo = File.open(full_path)
|
70
|
+
fo.each_line do |l|
|
71
|
+
l = safe_string(l)
|
72
|
+
klass_name = Reg_klass_filter.match(l)
|
73
|
+
if klass_name == nil
|
74
|
+
next
|
75
|
+
end
|
76
|
+
klass_name = klass_name[1].strip
|
77
|
+
return klass_name
|
78
|
+
end
|
79
|
+
return ""
|
80
|
+
end
|
81
|
+
|
82
|
+
def module_reference_name_from_path(path)
|
83
|
+
path.gsub(Reg_ruby_file, '')
|
84
|
+
end
|
85
|
+
|
86
|
+
def vaild_ruby_file?(path)
|
87
|
+
if Reg_ruby_file.match(path)
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
return false
|
91
|
+
end
|
92
|
+
|
93
|
+
# 遇到了 invalid byte sequence in UTF-8 (ArgumentError) 问题
|
94
|
+
# 解决办法参考 https://stackoverflow.com/questions/29877310/invalid-byte-sequence-in-utf-8-argumenterror
|
95
|
+
def safe_string(str)
|
96
|
+
if ! str.valid_encoding?
|
97
|
+
str = str.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
|
98
|
+
end
|
99
|
+
return str
|
100
|
+
end
|
101
|
+
|
102
|
+
# 全局加载模块
|
103
|
+
def load_modules(path, opts={})
|
104
|
+
count_by_device_type = {}
|
105
|
+
|
106
|
+
each_module_reference_name(path, opts={}) do |full_module_path, device_type, module_reference_name, module_klass_name|
|
107
|
+
load_module(full_module_path,
|
108
|
+
device_type,
|
109
|
+
module_reference_name,
|
110
|
+
module_klass_name,
|
111
|
+
{
|
112
|
+
# :recalcuate_by_device_type => recalculate_by_device_type,
|
113
|
+
:count_by_device_type => count_by_device_type,
|
114
|
+
}
|
115
|
+
)
|
116
|
+
|
117
|
+
end
|
118
|
+
module_manager.notify({
|
119
|
+
:count_by_device_type => count_by_device_type,
|
120
|
+
})
|
121
|
+
end
|
122
|
+
|
123
|
+
# 真正加载处
|
124
|
+
# 并将模块全部实例化
|
125
|
+
def load_module(full_module_path, device_type, module_reference_name, module_klass_name, opts={})
|
126
|
+
|
127
|
+
|
128
|
+
require "#{full_module_path}"
|
129
|
+
begin
|
130
|
+
module_klass = Object::const_get(module_klass_name).new
|
131
|
+
rescue Exception
|
132
|
+
puts "[-] Can not load module: #{full_module_path}"
|
133
|
+
puts caller
|
134
|
+
return
|
135
|
+
end
|
136
|
+
@module_manager.add_module(full_module_path, device_type, module_reference_name, module_klass)
|
137
|
+
|
138
|
+
# 计数
|
139
|
+
count_by_device_type = opts[:count_by_device_type]
|
140
|
+
if count_by_device_type
|
141
|
+
count_by_device_type[device_type] ||= 0
|
142
|
+
count_by_device_type[device_type] += 1
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end #class
|
147
|
+
end #module
|
148
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# 管理,保存各个加载的模块
|
2
|
+
class Aio::ModuleManager
|
3
|
+
|
4
|
+
attr_accessor :modules, :modules_count
|
5
|
+
|
6
|
+
include Aio::Ui::Verbose
|
7
|
+
|
8
|
+
# NOTE modules[reference_name] = {
|
9
|
+
# :module_type // 是cmd, input, output
|
10
|
+
# :module_layer_2 // cisco,huawei , style
|
11
|
+
# :full_path
|
12
|
+
# :klass
|
13
|
+
def initialize
|
14
|
+
# self.module_info_by_path = {}
|
15
|
+
# self.module_load_error_by_path = {}
|
16
|
+
# self.module_paths = []
|
17
|
+
self.modules = {}
|
18
|
+
self.modules_count = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# 加载一个目录下的所有模块
|
22
|
+
# @param [String] path 目录的路径
|
23
|
+
# @param [Hash] options
|
24
|
+
def load_modules(path, options={})
|
25
|
+
end
|
26
|
+
|
27
|
+
# 将实例化后的模块类放到 modules 中
|
28
|
+
def add_module(path, module_type, module_layer_2, reference_name, module_klass)
|
29
|
+
|
30
|
+
modules[reference_name] = {:module_type => module_type,
|
31
|
+
:module_layer_2 => module_layer_2,
|
32
|
+
:full_path => path,
|
33
|
+
:klass => module_klass
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# 获得指定模块类型
|
38
|
+
# 返回类型: Hash
|
39
|
+
def get_modules_by_type(type)
|
40
|
+
return_hash = {}
|
41
|
+
|
42
|
+
type = type.to_s
|
43
|
+
modules.each_pair do |n, m|
|
44
|
+
if m[:module_type] != type
|
45
|
+
next
|
46
|
+
end
|
47
|
+
return_hash[n] = m
|
48
|
+
end
|
49
|
+
|
50
|
+
return return_hash
|
51
|
+
end
|
52
|
+
|
53
|
+
# 通过设备类型获得模块类
|
54
|
+
# 返回类型为: 数组
|
55
|
+
def get_modules_by_device_type(device_type)
|
56
|
+
return_array = []
|
57
|
+
|
58
|
+
device_type = device_type.to_s
|
59
|
+
modules.each_pair do |_, m|
|
60
|
+
if m[:module_type] != "cmd"
|
61
|
+
next
|
62
|
+
end
|
63
|
+
|
64
|
+
type = m[:module_layer_2]
|
65
|
+
if device_type == type
|
66
|
+
return_array << m[:klass]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
return return_array
|
71
|
+
end
|
72
|
+
|
73
|
+
# 获得所有加载模块的设备类型的字符串型
|
74
|
+
# 返回类型为: 数组
|
75
|
+
def get_modules_device_type_to_s
|
76
|
+
return_array = []
|
77
|
+
|
78
|
+
modules_count["cmd"].keys.each do |key|
|
79
|
+
return_array << key.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
return return_array
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# 判断此设备类型的模块是否加载
|
87
|
+
def device_type_enable?(device_type)
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def module_type_enable?(module_type)
|
92
|
+
["cmd", "input", "output", "special", "description"].include?(module_type)
|
93
|
+
end
|
94
|
+
|
95
|
+
def notify(opts={})
|
96
|
+
if opts[:count_by_module_type]
|
97
|
+
@modules_count = opts[:count_by_module_type]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# 通过参考名获得模块类
|
102
|
+
def get_module_klass_by_name(reference_name)
|
103
|
+
begin
|
104
|
+
self.modules[reference_name][:klass]
|
105
|
+
rescue Exception
|
106
|
+
print_error "未找到指定模块: #{reference_name}"
|
107
|
+
exit 0
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
end
|