aio_elin 0.0.1 → 1.0.0
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 +4 -4
- data/config.rb +32 -32
- data/lib/aio/base/toolkit/excel_wps.rb +1 -0
- data/lib/aio/base/toolkit/hash.rb +95 -0
- data/lib/aio/base/toolkit/myers.rb +161 -0
- data/lib/aio/base/toolkit.rb +2 -0
- data/lib/aio/core/device/cmd_switch.rb +1 -1
- data/lib/aio/core/device/h3c.rb +2 -0
- data/lib/aio/core/device/maipu.rb +8 -0
- data/lib/aio/core/device/methods.rb +230 -228
- data/lib/aio/core/device/parent_device.rb +270 -267
- data/lib/aio/core/device_manager.rb +255 -202
- data/lib/aio/core/module/cmd.rb +155 -150
- data/lib/aio/core/module/compare.rb +39 -0
- data/lib/aio/core/module/output_style.rb +2 -0
- data/lib/aio/core/module.rb +1 -0
- data/lib/aio/core/module_loader.rb +11 -0
- data/lib/aio/core/parse/file.rb +12 -14
- data/lib/aio/core/parse/parser.rb +99 -87
- data/lib/aio/core/parse/parser_machine/has_device_state.rb +42 -42
- data/lib/aio/core/parse/parser_machine.rb +44 -44
- data/lib/aio/core/text/block.rb +88 -0
- data/lib/aio/core/text/compare.rb +109 -0
- data/lib/aio/core/text/context.rb +206 -206
- data/lib/aio/core/text/line_string.rb +17 -62
- data/lib/aio/core/text/match_string_info.rb +73 -0
- data/lib/aio/core/text/warning.rb +175 -175
- data/lib/aio/core/text.rb +3 -0
- data/lib/aio/core/warning/warning_summarize.rb +246 -229
- data/lib/aio/core.rb +3 -0
- data/lib/aio/ui/logger.rb +38 -0
- data/lib/aio/ui/verbose.rb +6 -2
- data/lib/aio/ui.rb +135 -134
- data/lib/modules/cmd/cisco/show_version.rb +84 -84
- data/lib/modules/cmd/h3c/display_cpu.rb +41 -41
- data/lib/modules/cmd/h3c/display_version.rb +43 -43
- data/lib/modules/cmd/maipu/show_clock.rb +32 -0
- data/lib/modules/cmd/maipu/show_cpu.rb +36 -0
- data/lib/modules/cmd/maipu/show_ip_interface_brief.rb +44 -0
- data/lib/modules/cmd/maipu/show_memory.rb +22 -22
- data/lib/modules/cmd/maipu/show_version.rb +40 -40
- data/lib/modules/input/style/compare_xml.rb +73 -73
- data/lib/modules/output/style/cmds.rb +3 -3
- data/lib/modules/output/style/compare_diff.rb +23 -0
- data/lib/modules/output/style/excel_table_office.rb +1 -0
- data/lib/modules/output/style/excel_table_wps.rb +1 -0
- data/lib/modules/output/style/summary_report.rb +2 -1
- data/lib/modules/special/style/compare.rb +153 -103
- data/lib/modules/special/style/compare_old.rb +121 -0
- data/lib/modules/special/style/compare_with_device_manager.rb +227 -0
- metadata +16 -3
data/lib/aio/core/module/cmd.rb
CHANGED
@@ -1,156 +1,161 @@
|
|
1
1
|
#coding=utf-8
|
2
2
|
|
3
3
|
module Aio::Module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
+
# 将自己分裂出来一份,以免遭到覆盖
|
45
|
+
def division
|
46
|
+
self.class.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_defaults
|
50
|
+
self.cmd_info = {
|
51
|
+
:cmd_full => 'No full name',
|
52
|
+
:cmd_short => 'No short name',
|
53
|
+
:author => nil,
|
54
|
+
:description => 'No command description',
|
55
|
+
:ranking => Ranking_1,
|
56
|
+
# 用于确定设备类型
|
57
|
+
:key_stand => false,
|
58
|
+
:benchmark => {},
|
59
|
+
# 平台,是 route, switch 还是 failware
|
60
|
+
:platform => nil,
|
61
|
+
:license => Aio::AIO_LICENSE,
|
62
|
+
}.update(@cmd_info)
|
63
|
+
end
|
64
|
+
|
65
|
+
def type
|
66
|
+
Aio::Module::Cmd
|
67
|
+
end
|
68
|
+
|
69
|
+
def clear_useful
|
70
|
+
@useful = {}
|
71
|
+
end
|
72
|
+
|
73
|
+
# 所有Cmd模块都必须重载此方法,用于解析命令
|
74
|
+
def parse
|
75
|
+
raise MethodError.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def cmd_full; self.cmd_info[:cmd_full]; end
|
79
|
+
def cmd_short; self.cmd_info[:cmd_short]; end
|
80
|
+
def author; self.cmd_info[:author]; end
|
81
|
+
def description; self.cmd_info[:description]; end
|
82
|
+
def ranking; self.cmd_info[:ranking]; end
|
83
|
+
def benchmark; self.cmd_info[:benchmark]; end
|
84
|
+
def platform; self.cmd_info[:platform]; end
|
85
|
+
def license; self.cmd_info[:license]; end
|
86
|
+
def key_stand; self.cmd_info[:key_stand]; end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# 直接调用平级CMD模块
|
91
|
+
def call_cmd(cmd_constant)
|
92
|
+
begin
|
93
|
+
cmd_klass = cmd_constant.new
|
94
|
+
cmd_klass.useful = @useful
|
95
|
+
cmd_klass.context = @context
|
96
|
+
cmd_klass.warning_klass = @warning_klass
|
97
|
+
rescue Exception
|
98
|
+
print_error "<call_cmd> 方法调用失败: #{cmd_constant}"
|
99
|
+
end
|
100
|
+
cmd_klass.parse
|
101
|
+
end
|
102
|
+
|
103
|
+
def key_stand_cisco
|
104
|
+
useful[:device_type] = "cisco"
|
105
|
+
end
|
106
|
+
|
107
|
+
def key_stand_huawei
|
108
|
+
useful[:device_type] = "huawei"
|
109
|
+
end
|
110
|
+
|
111
|
+
def key_stand_h3c
|
112
|
+
useful[:device_type] = "h3c"
|
113
|
+
end
|
114
|
+
|
115
|
+
def key_stand_maipu
|
116
|
+
useful[:device_type] = "maipu"
|
117
|
+
end
|
118
|
+
|
119
|
+
def key_stand_juniper
|
120
|
+
useful[:device_type] = "juniper"
|
121
|
+
end
|
122
|
+
|
123
|
+
# 确定软件版本
|
124
|
+
def key_stand_version(ver)
|
125
|
+
useful[:device_version] = ver
|
126
|
+
end
|
127
|
+
|
128
|
+
def device_version
|
129
|
+
device_info[:device_version]
|
130
|
+
end
|
131
|
+
|
132
|
+
# 确定设备型号
|
133
|
+
def key_stand_model(model)
|
134
|
+
useful[:device_model] = model
|
135
|
+
end
|
136
|
+
|
137
|
+
def device_model
|
138
|
+
device_info[:device_model]
|
139
|
+
end
|
140
|
+
|
141
|
+
def key_stand_template(template)
|
142
|
+
begin
|
143
|
+
template.instance
|
144
|
+
rescue
|
145
|
+
raise RuntimeError, "请使用Template类"
|
146
|
+
end
|
147
|
+
useful[:device_template] = template.to_s
|
148
|
+
end
|
149
|
+
|
150
|
+
def device_template
|
151
|
+
Object::const_get(device_info[:device_template]).instance
|
152
|
+
end
|
153
|
+
|
154
|
+
def reg_blank
|
155
|
+
Aio::Base::Toolkit::Regexp.blank
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
154
159
|
end
|
155
160
|
|
156
161
|
class Aio::Module::Cmd::Cisco < Aio::Module::Cmd; end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Aio::Module
|
2
|
+
|
3
|
+
class Compare
|
4
|
+
|
5
|
+
# 比较文件
|
6
|
+
attr_accessor :compare
|
7
|
+
|
8
|
+
# 被比较的文件
|
9
|
+
attr_accessor :compared
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@compare = {}
|
13
|
+
@compared = {}
|
14
|
+
|
15
|
+
@config_compare = Aio::Config::Warning::Compare
|
16
|
+
end
|
17
|
+
|
18
|
+
def compare_add(key, val)
|
19
|
+
@compare[key] = val
|
20
|
+
end
|
21
|
+
|
22
|
+
def compared_add(key, val)
|
23
|
+
@compared[key] = val
|
24
|
+
end
|
25
|
+
|
26
|
+
# 融合比较文件的内容
|
27
|
+
def compare_merge(hash)
|
28
|
+
@compare.merge!(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
# 融合被比较文件的内容
|
32
|
+
def compared_merge(hash)
|
33
|
+
@compared.merge(hash)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -31,6 +31,7 @@ module Aio::Module
|
|
31
31
|
:author => nil,
|
32
32
|
:description => "No Output Description",
|
33
33
|
:file_suffix => nil,
|
34
|
+
:platform => ['unix', 'windows'],
|
34
35
|
:license => ::Aio::AIO_LICENSE,
|
35
36
|
}.update(@output_info)
|
36
37
|
end
|
@@ -39,6 +40,7 @@ module Aio::Module
|
|
39
40
|
def description; self.output_info[:description]; end
|
40
41
|
def file_suffix; self.output_info[:file_suffix]; end
|
41
42
|
def license; self.output_info[:license]; end
|
43
|
+
def platform; self.output_info[:platform]; end
|
42
44
|
|
43
45
|
def type
|
44
46
|
Aio::Module::OutputStyle
|
data/lib/aio/core/module.rb
CHANGED
@@ -156,6 +156,17 @@ module Aio::Module
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
+
# 获取modules的路径
|
160
|
+
def self.modules_path
|
161
|
+
local_path = Pathname.new(File.dirname(__FILE__)).realpath
|
162
|
+
return File.join(local_path, "..", "..", "modules")
|
163
|
+
end
|
164
|
+
|
165
|
+
# 获取modules的路径
|
166
|
+
def modules_path
|
167
|
+
self.class.modules_path
|
168
|
+
end
|
169
|
+
|
159
170
|
end #class
|
160
171
|
end #module
|
161
172
|
|
data/lib/aio/core/parse/file.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
module Aio::Parse
|
2
2
|
|
3
|
-
|
3
|
+
class File
|
4
|
+
|
5
|
+
attr_accessor :file_open
|
4
6
|
|
5
|
-
|
7
|
+
def initialize(file_path)
|
8
|
+
self.file_open = File.open(file_path, "r+")
|
9
|
+
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# 改进点,加入sefe_string方法
|
14
|
-
yield line
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
|
11
|
+
def each_line
|
12
|
+
file_open.each_line do |line|
|
13
|
+
# 改进点,加入sefe_string方法
|
14
|
+
yield line
|
15
|
+
end
|
16
|
+
end
|
19
17
|
end
|
@@ -1,91 +1,103 @@
|
|
1
1
|
#coding=utf-8
|
2
2
|
|
3
3
|
module Aio::Parse
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
4
|
+
class Parser
|
5
|
+
attr_accessor :device_manager
|
6
|
+
attr_accessor :parser_machine
|
7
|
+
|
8
|
+
# 重要!在分析前需要确定input_klass
|
9
|
+
# input_klass 的类为input模块的类
|
10
|
+
# Aio::Module::InputStyle
|
11
|
+
attr_accessor :input_klass
|
12
|
+
|
13
|
+
include Aio::Ui::Verbose
|
14
|
+
|
15
|
+
def initialize(device_manager, parser_machine)
|
16
|
+
self.device_manager = device_manager
|
17
|
+
self.parser_machine = parser_machine
|
18
|
+
|
19
|
+
@invalid_input = Aio::Base::Toolkit::Regexp.merge([
|
20
|
+
Aio::Device::Cisco::InvalidInput,
|
21
|
+
Aio::Device::H3C::InvalidInput,
|
22
|
+
Aio::Device::Huawei::InvalidInput,
|
23
|
+
Aio::Device::Maipu::InvalidInput,
|
24
|
+
Aio::Device::Juniper::InvalidInput,
|
25
|
+
])
|
26
|
+
end
|
27
|
+
|
28
|
+
# 通过巡检文件的方式获得关键信息,并按cmd模块逐个解析
|
29
|
+
def parse_by_module
|
30
|
+
|
31
|
+
# 注意这里manager_ip可有可无, 没有的话默认为nil
|
32
|
+
print_good "正在加载信息..."
|
33
|
+
@input_klass.parse do |device_name, cmd, context, manager_ip|
|
34
|
+
device_info = {
|
35
|
+
:device_name => device_name,
|
36
|
+
:cmd => cmd.strip,
|
37
|
+
:context => Aio::Text::Context.new(context),
|
38
|
+
:manager_ip => manager_ip
|
39
|
+
}
|
40
|
+
|
41
|
+
# 判断 context 是否有效
|
42
|
+
next if invalid?(context)
|
43
|
+
|
44
|
+
# 所有判断交到状态机处理
|
45
|
+
self.parser_machine.get_device(device_info)
|
46
|
+
self.parser_machine.get_full(device_info)
|
47
|
+
end
|
48
|
+
print_good "信息加载完成"
|
49
|
+
|
50
|
+
# 获取所有设备数量
|
51
|
+
total = device_manager.devices_number
|
52
|
+
#Aio::Ui::Logger.instance.info = {devices_number: total}
|
53
|
+
|
54
|
+
print_good "总共 #{total} 台设备"
|
55
|
+
print_good "正在对各个设备进行分析..."
|
56
|
+
device_manager.each_devices_with_index do |name, klass, i|
|
57
|
+
# 将解析命令后,并修改了自身类的实例覆盖掉原来父类
|
58
|
+
progress_bar(total, i+1, name)
|
59
|
+
|
60
|
+
# Debug处
|
61
|
+
if name == "B_HBWHA_CAM_DS01"
|
62
|
+
#puts "now"
|
63
|
+
end
|
64
|
+
new_klass = klass.parse
|
65
|
+
device_manager[name] = new_klass.instance
|
66
|
+
end
|
67
|
+
clear_line
|
68
|
+
print_good "设备信息分析完成"
|
69
|
+
end
|
70
|
+
|
71
|
+
# 判断 context 是否有效
|
72
|
+
def invalid?(context)
|
73
|
+
return true if context.empty?
|
74
|
+
return true if @invalid_input.match(context[1])
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
# 通过output/compare_xml生成的XML文件解析,直接将结果保存
|
79
|
+
# compare_klass 为比较模块
|
80
|
+
# 其中只比较useful的值,并不会去比较warning
|
81
|
+
# warning 有原本device中以及比较中共同得出
|
82
|
+
def parse_by_compare(compare_klass)
|
83
|
+
|
84
|
+
# device_hash 为提供比较文件的hash
|
85
|
+
print_good "正在将比较文件转换为内部Hash表"
|
86
|
+
device_hash = @input_klass.parse
|
87
|
+
compare_klass.device_manager = device_manager
|
88
|
+
compare_klass.input_benchmark = device_hash
|
89
|
+
compare_hash = compare_klass.parse
|
90
|
+
device_manager.merge_warning(compare_hash)
|
91
|
+
end
|
92
|
+
|
93
|
+
# 按照两个 device_manager 来进行比较
|
94
|
+
def parse_by_compare_with_device_manager(compare_klass, other_device_manager)
|
95
|
+
print_good '正在导入device_manager信息'
|
96
|
+
compare_klass.device_manager = device_manager
|
97
|
+
compare_klass.input_benchmark = other_device_manager
|
98
|
+
compare_hash = compare_klass.parse
|
99
|
+
device_manager.merge_warning(compare_hash)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
91
103
|
end
|