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,275 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module Aio::Device
|
4
|
+
class ParentDevice
|
5
|
+
|
6
|
+
include Aio::Ui::Verbose
|
7
|
+
|
8
|
+
attr_accessor :device_name
|
9
|
+
|
10
|
+
# cmds_context = { "cmd_full_name" => [ {
|
11
|
+
# device_type_1 => klass1,
|
12
|
+
# device_type_2 => klass2},
|
13
|
+
# context ] }
|
14
|
+
attr_accessor :cmds_context
|
15
|
+
|
16
|
+
# 管理IP
|
17
|
+
attr_accessor :manager_ip
|
18
|
+
|
19
|
+
# 设备的基本信息
|
20
|
+
attr_accessor :device_info
|
21
|
+
|
22
|
+
# 按cmd名称管理有用信息
|
23
|
+
# Hash = { cmd_name => { :case => useful } }
|
24
|
+
attr_accessor :cmds_useful
|
25
|
+
|
26
|
+
# Warning信息模块
|
27
|
+
attr_accessor :warning_klass
|
28
|
+
|
29
|
+
# 设备类型
|
30
|
+
#attr_reader :device_type
|
31
|
+
|
32
|
+
InvalidInput = /Invalid input detected/
|
33
|
+
|
34
|
+
Interface = {
|
35
|
+
:geth => "GigabitEthernet",
|
36
|
+
:feth => "FastEthernet",
|
37
|
+
:eth => "Ethernet",
|
38
|
+
:loopback => "Loopback",
|
39
|
+
}
|
40
|
+
|
41
|
+
def interface
|
42
|
+
Interface
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
self.cmds_context = {}
|
47
|
+
self.device_name = ""
|
48
|
+
self.cmds_useful = {}
|
49
|
+
|
50
|
+
@warning_klass = Aio::Text::Warning.new
|
51
|
+
@device_type = ""
|
52
|
+
@device_info = {}
|
53
|
+
end
|
54
|
+
|
55
|
+
def instance
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
"#<#{self.class}>"
|
61
|
+
end
|
62
|
+
|
63
|
+
def device_type
|
64
|
+
if @device_type.empty?
|
65
|
+
return "other"
|
66
|
+
end
|
67
|
+
|
68
|
+
@device_type
|
69
|
+
end
|
70
|
+
|
71
|
+
# 判断是否有cmd的信息
|
72
|
+
def has_cmd?(cmd)
|
73
|
+
@cmds_useful.has_key?(cmd)
|
74
|
+
end
|
75
|
+
|
76
|
+
# 增加cmd
|
77
|
+
# @Param klass_info 为Array
|
78
|
+
# klass_info = ["maybe_device_type", cmd_klass]
|
79
|
+
def add_cmd(klass_info)
|
80
|
+
maybe_device_type = klass_info[0]
|
81
|
+
cmd_klass = klass_info[1]
|
82
|
+
|
83
|
+
cmd_full_name = cmd_klass.cmd_full
|
84
|
+
|
85
|
+
# 有可能已经有了其他设备类型的模块
|
86
|
+
# 那么通过Hash的方式存储所有的模块
|
87
|
+
cmds_context[cmd_full_name] ||= []
|
88
|
+
cmds_context[cmd_full_name][0] ||= {}
|
89
|
+
cmds_context[cmd_full_name][0][maybe_device_type] = cmd_klass
|
90
|
+
return cmd_full_name
|
91
|
+
end
|
92
|
+
|
93
|
+
# 两种用法:
|
94
|
+
# 在有klass的时候可以添加为完整cmds_context
|
95
|
+
# 当没有klass的话,也可以加。那么klass项为nil
|
96
|
+
def add_cmd_context_by_cmd_name(cmd_full_name, context)
|
97
|
+
cmds_context[cmd_full_name] ||= []
|
98
|
+
cmds_context[cmd_full_name][1] = context
|
99
|
+
end
|
100
|
+
|
101
|
+
# 整合上面两个方法,成为一步
|
102
|
+
def add_cmd_context_by_klass(klass_info, context)
|
103
|
+
cmd_full_name = add_cmd(klass_info)
|
104
|
+
add_cmd_context_by_cmd_name(cmd_full_name, context)
|
105
|
+
return cmds_context[cmd_full_name]
|
106
|
+
end
|
107
|
+
|
108
|
+
# 最终解析的地方
|
109
|
+
# 一定要确定设备类型,否则的话只能单一设备
|
110
|
+
# cmds_context = { cmd_name => [ {
|
111
|
+
# device_type_1 => klass1,
|
112
|
+
# device_type_2 => klass2},
|
113
|
+
# context ] }
|
114
|
+
def parse
|
115
|
+
|
116
|
+
# 做两次循环,第一次确定设备类型
|
117
|
+
2.times do |t|
|
118
|
+
cmds_context.each_pair do |cmd_name, info|
|
119
|
+
context = info[1]
|
120
|
+
|
121
|
+
# 如果没有cmd模块, 那么就跳过
|
122
|
+
next if info[0].nil?
|
123
|
+
|
124
|
+
info[0].each_pair do |device_type, module_klass|
|
125
|
+
|
126
|
+
#module_klass.clear_useful
|
127
|
+
|
128
|
+
# 如果找到了设备类型
|
129
|
+
# 那么之后就只对该类型进行解析,其他的跳过
|
130
|
+
if ! @device_type.empty? and @device_type != device_type
|
131
|
+
next
|
132
|
+
end
|
133
|
+
|
134
|
+
module_klass.context = context
|
135
|
+
module_klass.warning_klass = @warning_klass
|
136
|
+
|
137
|
+
# 循环模块对内容进行解析
|
138
|
+
# 当是第一遍遍历的时候,只找可以决定是什么设备类型的命令
|
139
|
+
# 一般都是通过show version 这类命令找到, 那么同时也能找到设备型号和软件版本
|
140
|
+
if t == 0 and not module_klass.key_stand
|
141
|
+
next
|
142
|
+
|
143
|
+
elsif t == 0 and module_klass.key_stand
|
144
|
+
module_klass.parse
|
145
|
+
push_device_info(module_klass)
|
146
|
+
|
147
|
+
module_klass.clear_useful
|
148
|
+
# 当device_type 有内容时,确定为已知设备类型,那么进行下次循环遍历
|
149
|
+
if @device_type.empty?
|
150
|
+
next
|
151
|
+
else
|
152
|
+
@warning_klass.clear
|
153
|
+
break
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
begin
|
158
|
+
# 当是第二遍的时候,则全部解析
|
159
|
+
module_klass.clear_useful
|
160
|
+
module_klass.device_info = device_info
|
161
|
+
module_klass.ext_info = {:device_name => @device_name}
|
162
|
+
module_klass.parse
|
163
|
+
rescue Aio::Text::Context::OutLineError
|
164
|
+
rescue NoMethodError
|
165
|
+
print_error "未找到方法,请检查模块的方法名拼写"
|
166
|
+
rescue Exception => e
|
167
|
+
print_error "#{e.class} : #{module_klass.class}"
|
168
|
+
print_error e.message
|
169
|
+
ensure
|
170
|
+
push_useful(module_klass, cmd_name)
|
171
|
+
next
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# 当所有解析循环完成后,如果找到了设备类型
|
178
|
+
# 就将此类转为对应子类
|
179
|
+
# changeto
|
180
|
+
if ! @device_type.empty?
|
181
|
+
to = self.send("changeto_#{@device_type}")
|
182
|
+
end
|
183
|
+
|
184
|
+
return to ? to : self
|
185
|
+
end
|
186
|
+
|
187
|
+
# 存放设备基本信息
|
188
|
+
def push_device_info(module_klass)
|
189
|
+
@device_type = module_klass.useful[:device_type].to_s
|
190
|
+
@device_info[:device_model] = module_klass.useful[:device_model].to_s
|
191
|
+
@device_info[:device_version] = module_klass.useful[:device_version].to_s
|
192
|
+
@device_info[:device_template] = module_klass.useful[:device_template].to_s
|
193
|
+
end
|
194
|
+
|
195
|
+
# 当一个模块解析完毕后,将有用信息放入cmds_useful
|
196
|
+
# 当有用信息中device_type类为真时,
|
197
|
+
# 就可以将此父类转变为具体的类型了
|
198
|
+
# check
|
199
|
+
def push_useful(module_klass, cmd_name)
|
200
|
+
|
201
|
+
if Aio::Base::Debug.enable?
|
202
|
+
puts "parent_device#push_useful"
|
203
|
+
pp module_klass
|
204
|
+
end
|
205
|
+
|
206
|
+
# 将有用信息放入整体有用信息
|
207
|
+
cmds_useful[cmd_name] = module_klass.useful
|
208
|
+
end
|
209
|
+
|
210
|
+
=begin
|
211
|
+
def warning_info
|
212
|
+
warning_klass.warning_info
|
213
|
+
end
|
214
|
+
|
215
|
+
def warning_info_serious
|
216
|
+
warning_klass.warning_info_serious
|
217
|
+
end
|
218
|
+
|
219
|
+
def warning_info_ordinary
|
220
|
+
warning_klass.warning_info_ordinary
|
221
|
+
end
|
222
|
+
|
223
|
+
def warning_info_compare
|
224
|
+
warning_klass.warning_info_compare
|
225
|
+
end
|
226
|
+
=end
|
227
|
+
|
228
|
+
# 1.导向命令方法模块
|
229
|
+
# 2.导向Warning类
|
230
|
+
def method_missing(m, *args, &block)
|
231
|
+
if Aio::Device::Methods.respond_to?(m)
|
232
|
+
Aio::Device::Methods.klass = self
|
233
|
+
Aio::Device::Methods.send(m)
|
234
|
+
|
235
|
+
elsif Aio::Text::Warning.instance_methods(false).include?(m.to_sym)
|
236
|
+
warning_klass.send(m, *args)
|
237
|
+
else
|
238
|
+
super
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def changeto_cisco
|
245
|
+
to = Cisco.new
|
246
|
+
clone(to)
|
247
|
+
end
|
248
|
+
|
249
|
+
def changeto_huawei
|
250
|
+
to = Huawei.new
|
251
|
+
clone(to)
|
252
|
+
end
|
253
|
+
|
254
|
+
def changeto_maipu
|
255
|
+
to = Maipu.new
|
256
|
+
clone(to)
|
257
|
+
end
|
258
|
+
|
259
|
+
def changeto_h3c
|
260
|
+
to = H3C.new
|
261
|
+
clone(to)
|
262
|
+
end
|
263
|
+
|
264
|
+
def clone(to)
|
265
|
+
to.device_name = Aio::Base::Toolkit::DeepClone.clone(self.device_name)
|
266
|
+
to.cmds_context = Aio::Base::Toolkit::DeepClone.clone(self.cmds_context)
|
267
|
+
to.manager_ip = Aio::Base::Toolkit::DeepClone.clone(self.manager_ip)
|
268
|
+
to.device_info = Aio::Base::Toolkit::DeepClone.clone(self.device_info)
|
269
|
+
to.cmds_useful = Aio::Base::Toolkit::DeepClone.clone(self.cmds_useful)
|
270
|
+
to.warning_klass = Aio::Base::Toolkit::DeepClone.clone(self.warning_klass)
|
271
|
+
to
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Aio
|
2
|
+
module Device
|
3
|
+
|
4
|
+
require "aio/core/device/parent_device"
|
5
|
+
require "aio/core/device/cisco"
|
6
|
+
require "aio/core/device/huawei"
|
7
|
+
require "aio/core/device/maipu"
|
8
|
+
require "aio/core/device/h3c"
|
9
|
+
require "aio/core/device/juniper"
|
10
|
+
require "aio/core/device/cmd_switch"
|
11
|
+
require "aio/core/device/methods"
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,207 @@
|
|
1
|
+
class Aio::DeviceManager
|
2
|
+
|
3
|
+
# 保存所有设备类
|
4
|
+
# devices = {"device_name" => device_klass}
|
5
|
+
attr_accessor :devices
|
6
|
+
|
7
|
+
# 按设备型号保存cmd
|
8
|
+
# cmds = {"device_type" => [module_klass1, module_klass2]}
|
9
|
+
attr_accessor :cmds
|
10
|
+
|
11
|
+
# 命令的正则表达式匹配
|
12
|
+
# cmds_reg = {module_klass => ["device_type", "cmd_reg"]}
|
13
|
+
attr_accessor :cmds_reg
|
14
|
+
|
15
|
+
# 警告信息汇总类
|
16
|
+
attr_reader :warning_summarize
|
17
|
+
|
18
|
+
# 模块管理信息,只读
|
19
|
+
attr_accessor :module_manager
|
20
|
+
|
21
|
+
# 当初始化完成,所有cmd模块已经整理完毕
|
22
|
+
def initialize(module_manager)
|
23
|
+
self.cmds = {}
|
24
|
+
self.cmds_reg = {}
|
25
|
+
self.devices = {}
|
26
|
+
@module_manager = module_manager
|
27
|
+
@warning_summarize = Aio::Warning::WarningSummarize.new(self)
|
28
|
+
tidy_cmds
|
29
|
+
end
|
30
|
+
|
31
|
+
def []=(key, val)
|
32
|
+
@devices[key] = val
|
33
|
+
end
|
34
|
+
|
35
|
+
def [](key)
|
36
|
+
@devices[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
# 设备台数
|
40
|
+
def devices_number
|
41
|
+
self.devices.keys.size
|
42
|
+
end
|
43
|
+
|
44
|
+
# 整理cmds 和 cmds_reg
|
45
|
+
# 返回为Hash = {"cisco" => [klass, klass]}
|
46
|
+
def tidy_cmds
|
47
|
+
device_type = @module_manager.get_modules_device_type_to_s
|
48
|
+
|
49
|
+
device_type.each do |type|
|
50
|
+
# 整理cmds
|
51
|
+
type_modules = @module_manager.get_modules_by_device_type(type)
|
52
|
+
self.cmds[type] = type_modules
|
53
|
+
|
54
|
+
# 整理cmds_reg
|
55
|
+
type_modules.each do |cmd_klass|
|
56
|
+
|
57
|
+
# 将cmd_short转变为正则表达式
|
58
|
+
# 相同的cmd_short会导致重复
|
59
|
+
cmd_short_reg = Aio::Base::Toolkit::Regexp.to_reg(cmd_klass.cmd_short)
|
60
|
+
cmds_reg[cmd_klass] = [type, cmd_short_reg]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return cmds
|
64
|
+
end
|
65
|
+
|
66
|
+
# 仅仅返回各个命令的正则表达式的数组,在input/console中使用
|
67
|
+
def just_cmds_reg
|
68
|
+
res = []
|
69
|
+
cmds_reg.each_pair do |klass, info|
|
70
|
+
res << info[1]
|
71
|
+
end
|
72
|
+
return res
|
73
|
+
end
|
74
|
+
|
75
|
+
def each_devices
|
76
|
+
devices.each_pair do |device_name, device_klass|
|
77
|
+
yield device_name, device_klass
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def each_devices_with_index
|
82
|
+
i = 0
|
83
|
+
devices.each_pair do |device_name, device_klass|
|
84
|
+
yield device_name, device_klass, i
|
85
|
+
i += 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# 轮询设备名以及有用信息
|
90
|
+
def each_devices_with_useful
|
91
|
+
each_devices do |device_name, device_klass|
|
92
|
+
useful = device_klass.cmds_useful
|
93
|
+
yield device_name, useful
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# 判断设备名是否存在
|
98
|
+
def device_exist?(opts={})
|
99
|
+
each_devices do |devices, _|
|
100
|
+
if devices == opts[:device_name]
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
|
107
|
+
# 设备类型分类
|
108
|
+
# 返回 { "cisco" => [device_name1, ...] }
|
109
|
+
def device_type_classify
|
110
|
+
res = {}
|
111
|
+
each_devices do |device_name, device_klass|
|
112
|
+
type = device_klass.device_type
|
113
|
+
unless res.has_key?(type)
|
114
|
+
res[type] = []
|
115
|
+
end
|
116
|
+
res[type] << device_name
|
117
|
+
end
|
118
|
+
|
119
|
+
return res
|
120
|
+
end
|
121
|
+
# 查找是否有符合指定的cmd模块
|
122
|
+
# 有可能两种设备类型同时存在同样的命令,在不确定设备类型的情况下,全部输出
|
123
|
+
# 注意此处输出的样式为 res = [ [device_type, cmd_klass], ... ]
|
124
|
+
# info = { cmd_klass => [type, cmd_reg] }
|
125
|
+
def cmd_module_assign(opts)
|
126
|
+
cmd = opts[:cmd]
|
127
|
+
res = []
|
128
|
+
|
129
|
+
device_type = opts[:device_type]
|
130
|
+
cmds_reg.each do |cmd_klass, info|
|
131
|
+
reg = info[1]
|
132
|
+
type = info[0]
|
133
|
+
if reg.match(cmd)
|
134
|
+
|
135
|
+
# 判断如果没有指定device_type,那么全部输出
|
136
|
+
# 如果指定,则只输出指定类型
|
137
|
+
if device_type == type
|
138
|
+
res << [type, cmd_klass]
|
139
|
+
elsif device_type.nil?
|
140
|
+
res << [type, cmd_klass]
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
return res.empty? ? nil : res
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# 在状态机中使用了,添加设备,并添加cmd-context
|
151
|
+
def add_device(opts)
|
152
|
+
|
153
|
+
# 判断是否已经有了device,如果有,则沿用,如果没有则新建
|
154
|
+
if has_device?(opts)
|
155
|
+
device_klass = self.devices[opts[:device_name]]
|
156
|
+
else
|
157
|
+
device_klass = Aio::Device::ParentDevice.new
|
158
|
+
device_klass.device_name = opts[:device_name]
|
159
|
+
end
|
160
|
+
|
161
|
+
# cmd 和 context 必须同时存在的情况下才能加载的
|
162
|
+
if opts[:cmd] and opts[:context]
|
163
|
+
|
164
|
+
cmd_arr = cmd_module_assign(opts)
|
165
|
+
if cmd_arr.nil?
|
166
|
+
device_klass.add_cmd_context_by_cmd_name(
|
167
|
+
opts[:cmd],
|
168
|
+
opts[:context]
|
169
|
+
)
|
170
|
+
elsif cmd_arr.size == 1
|
171
|
+
device_klass.add_cmd_context_by_klass(
|
172
|
+
cmd_arr[0],
|
173
|
+
opts[:context]
|
174
|
+
)
|
175
|
+
else
|
176
|
+
# 有多个cmd模块的情况,全部依次加进去,但是最后分析的时候,出现明显问题的将被删除
|
177
|
+
cmd_arr.each do |cmd_klass|
|
178
|
+
device_klass.add_cmd_context_by_klass(
|
179
|
+
cmd_klass,
|
180
|
+
opts[:context]
|
181
|
+
)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
self.devices[opts[:device_name]] = device_klass
|
188
|
+
end
|
189
|
+
|
190
|
+
# 将compare中得到的warning信息合并到各个设备的warning_klass中
|
191
|
+
def merge_warning(info)
|
192
|
+
info.each do |name, warn|
|
193
|
+
self[name].warning_klass.warning_compare(warn)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# 整理汇总警告信息
|
198
|
+
def warning_summarize_tidy
|
199
|
+
@warning_summarize.tidy_warning
|
200
|
+
end
|
201
|
+
|
202
|
+
# 是否已经有device_name
|
203
|
+
def has_device?(opts)
|
204
|
+
self.devices.has_key?(opts[:device_name])
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
class Cmd
|
5
|
+
|
6
|
+
include Aio::Ui::Verbose
|
7
|
+
|
8
|
+
class MethodError < StandardError
|
9
|
+
def to_s; "请重载此方法"; end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MismatchError < StandardError; end
|
13
|
+
|
14
|
+
autoload :Ranking, 'aio/module/ranking'
|
15
|
+
autoload :Platform, 'aio/module/platform'
|
16
|
+
|
17
|
+
# 加载的欲解析的文本
|
18
|
+
attr_accessor :context
|
19
|
+
|
20
|
+
# 模块的信息
|
21
|
+
attr_accessor :cmd_info
|
22
|
+
|
23
|
+
# 解析后得到的有用信息
|
24
|
+
# 以Hash = { :case => info }
|
25
|
+
attr_accessor :useful
|
26
|
+
|
27
|
+
# 加载warning信息
|
28
|
+
attr_accessor :warning_klass
|
29
|
+
|
30
|
+
# 加载设备的基本信息
|
31
|
+
# :device_version
|
32
|
+
# :device_model
|
33
|
+
attr_accessor :device_info
|
34
|
+
|
35
|
+
# 获取一些额外的信息,有device提供
|
36
|
+
attr_accessor :ext_info
|
37
|
+
|
38
|
+
def initialize(info = {})
|
39
|
+
@cmd_info = info.dup
|
40
|
+
@useful = {}
|
41
|
+
set_defaults()
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_defaults
|
45
|
+
self.cmd_info = {
|
46
|
+
:cmd_full => 'No full name',
|
47
|
+
:cmd_short => 'No short name',
|
48
|
+
:author => nil,
|
49
|
+
:description => 'No command description',
|
50
|
+
:ranking => Ranking_1,
|
51
|
+
# 用于确定设备类型
|
52
|
+
:key_stand => false,
|
53
|
+
:benchmark => {},
|
54
|
+
# 平台,是 route, switch 还是 failware
|
55
|
+
:platform => nil,
|
56
|
+
:license => Aio::AIO_LICENSE,
|
57
|
+
}.update(@cmd_info)
|
58
|
+
end
|
59
|
+
|
60
|
+
def type
|
61
|
+
Aio::Module::Cmd
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear_useful
|
65
|
+
@useful = {}
|
66
|
+
end
|
67
|
+
|
68
|
+
# 所有Cmd模块都必须重载此方法,用于解析命令
|
69
|
+
def parse
|
70
|
+
raise MethodError.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def cmd_full; self.cmd_info[:cmd_full]; end
|
74
|
+
def cmd_short; self.cmd_info[:cmd_short]; end
|
75
|
+
def author; self.cmd_info[:author]; end
|
76
|
+
def description; self.cmd_info[:description]; end
|
77
|
+
def ranking; self.cmd_info[:ranking]; end
|
78
|
+
def benchmark; self.cmd_info[:benchmark]; end
|
79
|
+
def platform; self.cmd_info[:platform]; end
|
80
|
+
def license; self.cmd_info[:license]; end
|
81
|
+
def key_stand; self.cmd_info[:key_stand]; end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
# 直接调用平级CMD模块
|
86
|
+
def call_cmd(cmd_constant)
|
87
|
+
begin
|
88
|
+
cmd_klass = cmd_constant.new
|
89
|
+
cmd_klass.useful = @useful
|
90
|
+
cmd_klass.context = @context
|
91
|
+
cmd_klass.warning_klass = @warning_klass
|
92
|
+
rescue Exception => e
|
93
|
+
print_error "<call_cmd> 方法调用失败: #{cmd_constant}"
|
94
|
+
end
|
95
|
+
cmd_klass.parse
|
96
|
+
end
|
97
|
+
|
98
|
+
def key_stand_cisco
|
99
|
+
useful[:device_type] = "cisco"
|
100
|
+
end
|
101
|
+
|
102
|
+
def key_stand_huawei
|
103
|
+
useful[:device_type] = "huawei"
|
104
|
+
end
|
105
|
+
|
106
|
+
def key_stand_h3c
|
107
|
+
useful[:device_type] = "h3c"
|
108
|
+
end
|
109
|
+
|
110
|
+
def key_stand_maipu
|
111
|
+
useful[:device_type] = "maipu"
|
112
|
+
end
|
113
|
+
|
114
|
+
def key_stand_juniper
|
115
|
+
useful[:device_type] = "juniper"
|
116
|
+
end
|
117
|
+
|
118
|
+
# 确定软件版本
|
119
|
+
def key_stand_version(ver)
|
120
|
+
useful[:device_version] = ver
|
121
|
+
end
|
122
|
+
|
123
|
+
def device_version
|
124
|
+
device_info[:device_version]
|
125
|
+
end
|
126
|
+
|
127
|
+
# 确定设备型号
|
128
|
+
def key_stand_model(model)
|
129
|
+
useful[:device_model] = model
|
130
|
+
end
|
131
|
+
|
132
|
+
def device_model
|
133
|
+
device_info[:device_model]
|
134
|
+
end
|
135
|
+
|
136
|
+
def key_stand_template(template)
|
137
|
+
begin
|
138
|
+
template.instance
|
139
|
+
rescue
|
140
|
+
raise RuntimeError, "请使用Template类"
|
141
|
+
end
|
142
|
+
useful[:device_template] = template.to_s
|
143
|
+
end
|
144
|
+
|
145
|
+
def device_template
|
146
|
+
Object::const_get(device_info[:device_template]).instance
|
147
|
+
end
|
148
|
+
|
149
|
+
def reg_blank
|
150
|
+
Aio::Base::Toolkit::Regexp.blank
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class Aio::Module::Cmd::Cisco < Aio::Module::Cmd; end
|
157
|
+
class Aio::Module::Cmd::Huawei < Aio::Module::Cmd; end
|
158
|
+
class Aio::Module::Cmd::H3C < Aio::Module::Cmd; end
|
159
|
+
class Aio::Module::Cmd::Maipu < Aio::Module::Cmd; end
|
160
|
+
class Aio::Module::Cmd::Juniper < Aio::Module::Cmd; end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module Aio::Module
|
4
|
+
class Description
|
5
|
+
|
6
|
+
attr_accessor :description_info
|
7
|
+
|
8
|
+
def initialize(info={})
|
9
|
+
@description_info = info.dup
|
10
|
+
set_defaults()
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_defaults
|
14
|
+
self.description_info = {
|
15
|
+
:author => nil,
|
16
|
+
:case => nil,
|
17
|
+
:name => nil,
|
18
|
+
:title => nil,
|
19
|
+
:description => nil,
|
20
|
+
:license => ::Aio::AIO_LICENSE,
|
21
|
+
}.update(@description_info)
|
22
|
+
end
|
23
|
+
|
24
|
+
def type
|
25
|
+
Aio::Module::Description
|
26
|
+
end
|
27
|
+
|
28
|
+
# 重载方法
|
29
|
+
def to_s
|
30
|
+
"暂无描述信息。"
|
31
|
+
end
|
32
|
+
|
33
|
+
# 判断是否是 Description 父类
|
34
|
+
def parent?
|
35
|
+
self.class == type ? true : false
|
36
|
+
end
|
37
|
+
|
38
|
+
# 创建临时信息,用于在没有描述类的时候使用
|
39
|
+
def temp(cs)
|
40
|
+
clear
|
41
|
+
@description_info[:case] = cs
|
42
|
+
@description_info[:name] = cs.to_s.upcase
|
43
|
+
@description_info[:title] = cs.to_s.upcase + "检查"
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# 清楚基本信息
|
48
|
+
def clear
|
49
|
+
self.description_info = {
|
50
|
+
:author => nil,
|
51
|
+
:case => nil,
|
52
|
+
:name => nil,
|
53
|
+
:title => nil,
|
54
|
+
:description => nil,
|
55
|
+
:license => ::Aio::AIO_LICENSE,
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def author; description_info[:author]; end
|
60
|
+
def case; description_info[:case]; end
|
61
|
+
def name; description_info[:name]; end
|
62
|
+
def title; description_info[:title]; end
|
63
|
+
def description; description_info[:description]; end
|
64
|
+
def license; description_info[:license]; end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|