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,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
|