aio_elin 0.0.1
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 +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
|