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.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +675 -0
  3. data/README.md +9 -0
  4. data/config.rb +39 -0
  5. data/lib/aio/base/debug.rb +30 -0
  6. data/lib/aio/base/toolkit/array.rb +24 -0
  7. data/lib/aio/base/toolkit/date.rb +46 -0
  8. data/lib/aio/base/toolkit/deep_clone.rb +10 -0
  9. data/lib/aio/base/toolkit/diff.rb +104 -0
  10. data/lib/aio/base/toolkit/excel_office.rb +421 -0
  11. data/lib/aio/base/toolkit/excel_wps.rb +437 -0
  12. data/lib/aio/base/toolkit/excel_wps.rb.bak +299 -0
  13. data/lib/aio/base/toolkit/ipaddr.rb +28 -0
  14. data/lib/aio/base/toolkit/os.rb +26 -0
  15. data/lib/aio/base/toolkit/regexp.rb +32 -0
  16. data/lib/aio/base/toolkit/string.rb +28 -0
  17. data/lib/aio/base/toolkit/table.rb +441 -0
  18. data/lib/aio/base/toolkit/test_diff.rb +9 -0
  19. data/lib/aio/base/toolkit/test_excel.rb +118 -0
  20. data/lib/aio/base/toolkit/test_word.rb +58 -0
  21. data/lib/aio/base/toolkit/word_wps.rb +492 -0
  22. data/lib/aio/base/toolkit.rb +18 -0
  23. data/lib/aio/base.rb +10 -0
  24. data/lib/aio/core/device/cisco.rb +13 -0
  25. data/lib/aio/core/device/cmd_switch.rb +113 -0
  26. data/lib/aio/core/device/h3c.rb +12 -0
  27. data/lib/aio/core/device/huawei.rb +10 -0
  28. data/lib/aio/core/device/juniper.rb +10 -0
  29. data/lib/aio/core/device/maipu.rb +11 -0
  30. data/lib/aio/core/device/methods.rb +233 -0
  31. data/lib/aio/core/device/methods.rb.bak +199 -0
  32. data/lib/aio/core/device/parent_device.rb +275 -0
  33. data/lib/aio/core/device.rb +15 -0
  34. data/lib/aio/core/device_manager.rb +207 -0
  35. data/lib/aio/core/module/cmd.rb +160 -0
  36. data/lib/aio/core/module/description.rb +67 -0
  37. data/lib/aio/core/module/input_style.rb +98 -0
  38. data/lib/aio/core/module/output_style.rb +80 -0
  39. data/lib/aio/core/module/platform.rb +30 -0
  40. data/lib/aio/core/module/ranking.rb +24 -0
  41. data/lib/aio/core/module/special_style.rb +30 -0
  42. data/lib/aio/core/module/template.rb +13 -0
  43. data/lib/aio/core/module.rb +15 -0
  44. data/lib/aio/core/module_loader.rb +161 -0
  45. data/lib/aio/core/module_loader.rb.bak +148 -0
  46. data/lib/aio/core/module_manager.rb +112 -0
  47. data/lib/aio/core/module_manager.rb.bak +78 -0
  48. data/lib/aio/core/parse/file.rb +19 -0
  49. data/lib/aio/core/parse/parser.rb +91 -0
  50. data/lib/aio/core/parse/parser_machine/bak/has_cmd_state.rb +14 -0
  51. data/lib/aio/core/parse/parser_machine/bak/has_context_state.rb +11 -0
  52. data/lib/aio/core/parse/parser_machine/bak/no_cmd_state.rb +11 -0
  53. data/lib/aio/core/parse/parser_machine/bak/no_context_state.rb +11 -0
  54. data/lib/aio/core/parse/parser_machine/full_state.rb +12 -0
  55. data/lib/aio/core/parse/parser_machine/has_device_state.rb +44 -0
  56. data/lib/aio/core/parse/parser_machine/no_device_state.rb +12 -0
  57. data/lib/aio/core/parse/parser_machine/parent_state.rb +26 -0
  58. data/lib/aio/core/parse/parser_machine.rb +47 -0
  59. data/lib/aio/core/parse.rb +6 -0
  60. data/lib/aio/core/text/context.rb +211 -0
  61. data/lib/aio/core/text/line_string.rb +74 -0
  62. data/lib/aio/core/text/warning.rb +179 -0
  63. data/lib/aio/core/text.rb +7 -0
  64. data/lib/aio/core/warning/description.rb +47 -0
  65. data/lib/aio/core/warning/warning_summarize.rb +232 -0
  66. data/lib/aio/core/warning.rb +6 -0
  67. data/lib/aio/core.rb +32 -0
  68. data/lib/aio/license.rb +687 -0
  69. data/lib/aio/resource/cover_picture.png +0 -0
  70. data/lib/aio/resource/line.png +0 -0
  71. data/lib/aio/resource/logo.png +0 -0
  72. data/lib/aio/ui/banner.rb +85 -0
  73. data/lib/aio/ui/readable_text.rb +75 -0
  74. data/lib/aio/ui/verbose.rb +29 -0
  75. data/lib/aio/ui/version.rb +9 -0
  76. data/lib/aio/ui.rb +138 -0
  77. data/lib/aio.rb +13 -0
  78. data/lib/modules/cmd/cisco/show_clock.rb +32 -0
  79. data/lib/modules/cmd/cisco/show_cpu.rb +32 -0
  80. data/lib/modules/cmd/cisco/show_env.rb +71 -0
  81. data/lib/modules/cmd/cisco/show_failover.rb +39 -0
  82. data/lib/modules/cmd/cisco/show_interface_ip_brief.rb +24 -0
  83. data/lib/modules/cmd/cisco/show_interfaces.rb +177 -0
  84. data/lib/modules/cmd/cisco/show_inv.rb +43 -0
  85. data/lib/modules/cmd/cisco/show_ip_interface_brief.rb +42 -0
  86. data/lib/modules/cmd/cisco/show_ip_ospf_nei.rb +38 -0
  87. data/lib/modules/cmd/cisco/show_ip_route_summary.rb +81 -0
  88. data/lib/modules/cmd/cisco/show_memory.rb +27 -0
  89. data/lib/modules/cmd/cisco/show_process_cpu.rb +35 -0
  90. data/lib/modules/cmd/cisco/show_process_memory.rb +63 -0
  91. data/lib/modules/cmd/cisco/show_version.rb +97 -0
  92. data/lib/modules/cmd/h3c/display_clock.rb +32 -0
  93. data/lib/modules/cmd/h3c/display_cpu.rb +51 -0
  94. data/lib/modules/cmd/h3c/display_device_manuinfo.rb +45 -0
  95. data/lib/modules/cmd/h3c/display_fan.rb +91 -0
  96. data/lib/modules/cmd/h3c/display_interface.rb +203 -0
  97. data/lib/modules/cmd/h3c/display_ip_interface_brief.rb +34 -0
  98. data/lib/modules/cmd/h3c/display_ip_routing.rb +68 -0
  99. data/lib/modules/cmd/h3c/display_ip_routing_stat.rb +90 -0
  100. data/lib/modules/cmd/h3c/display_memory.rb +35 -0
  101. data/lib/modules/cmd/h3c/display_ospf_peer.rb +38 -0
  102. data/lib/modules/cmd/h3c/display_power.rb +90 -0
  103. data/lib/modules/cmd/h3c/display_version.rb +54 -0
  104. data/lib/modules/cmd/h3c/display_vrrp_verbose.rb +86 -0
  105. data/lib/modules/cmd/maipu/show_env.rb +34 -0
  106. data/lib/modules/cmd/maipu/show_ip_route.rb +74 -0
  107. data/lib/modules/cmd/maipu/show_ip_route_statistic.rb +36 -0
  108. data/lib/modules/cmd/maipu/show_memory.rb +31 -0
  109. data/lib/modules/cmd/maipu/show_system_fan.rb +66 -0
  110. data/lib/modules/cmd/maipu/show_system_power.rb +66 -0
  111. data/lib/modules/cmd/maipu/show_version.rb +50 -0
  112. data/lib/modules/description/style/crc.rb +22 -0
  113. data/lib/modules/description/style/input_errors.rb +22 -0
  114. data/lib/modules/description/style/overrun.rb +22 -0
  115. data/lib/modules/description/style/proc_ratio.rb +22 -0
  116. data/lib/modules/description/style/protocol.rb +22 -0
  117. data/lib/modules/description/style/register.rb +22 -0
  118. data/lib/modules/description/style/runts.rb +22 -0
  119. data/lib/modules/description/style/template.rb +22 -0
  120. data/lib/modules/description/style/total_output_drops.rb +22 -0
  121. data/lib/modules/input/style/compare_xml.rb +89 -0
  122. data/lib/modules/input/style/console.rb +222 -0
  123. data/lib/modules/input/style/console.rb.bak +114 -0
  124. data/lib/modules/input/style/xinhua_nat.rb +70 -0
  125. data/lib/modules/output/style/boc_day.rb +223 -0
  126. data/lib/modules/output/style/cmds.rb +77 -0
  127. data/lib/modules/output/style/compare_json.rb +26 -0
  128. data/lib/modules/output/style/compare_report.rb +31 -0
  129. data/lib/modules/output/style/compare_xml.rb +86 -0
  130. data/lib/modules/output/style/excel_table_office.rb +407 -0
  131. data/lib/modules/output/style/excel_table_wps.rb +400 -0
  132. data/lib/modules/output/style/summary_report.rb +563 -0
  133. data/lib/modules/special/style/compare.rb +110 -0
  134. 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