network-utility 1.1.4

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 (179) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +2 -0
  3. data/document/acl-M6000-16E.md +27 -0
  4. data/document/acl-M6000-18S.md +27 -0
  5. data/document/acl-M6000-8.md +27 -0
  6. data/document/acl-M6000-8E.md +27 -0
  7. data/document/acl-MA5200G-8.md +204 -0
  8. data/document/acl-ME60-16.md +177 -0
  9. data/document/acl-ME60-X16.md +177 -0
  10. data/document/acl-NE40E-X16.md +204 -0
  11. data/document/acl-NE40E-X16A.md +204 -0
  12. data/document/acl-NE40E-X8.md +204 -0
  13. data/document/acl-NE40E.md +204 -0
  14. data/document/acl-NE5000E-20.md +25 -0
  15. data/document/acl-NE5000E-X16.md +25 -0
  16. data/document/acl-NE5000E-X16A.md +25 -0
  17. data/document/acl-NE80E.md +204 -0
  18. data/document/bgp-CR16010H-F.md +25 -0
  19. data/document/bgp-CR16018-F.md +25 -0
  20. data/document/bgp-CR19000-20.md +25 -0
  21. data/document/bgp-M6000-16E.md +25 -0
  22. data/document/bgp-M6000-18S.md +25 -0
  23. data/document/bgp-M6000-8.md +25 -0
  24. data/document/bgp-M6000-8E.md +25 -0
  25. data/document/bgp-MA5200G-8.md +25 -0
  26. data/document/bgp-ME60-16.md +25 -0
  27. data/document/bgp-ME60-X16.md +25 -0
  28. data/document/bgp-NE40E-X16.md +25 -0
  29. data/document/bgp-NE40E-X16A.md +25 -0
  30. data/document/bgp-NE40E-X8.md +25 -0
  31. data/document/bgp-NE40E.md +25 -0
  32. data/document/bgp-NE5000E-20.md +25 -0
  33. data/document/bgp-NE5000E-X16.md +25 -0
  34. data/document/bgp-NE5000E-X16A.md +25 -0
  35. data/document/bgp-NE80E.md +25 -0
  36. data/document/config.md +1153 -0
  37. data/document/document.rb +27 -0
  38. data/document/if-ALCATEL7750.md +48 -0
  39. data/document/if-C7609.md +47 -0
  40. data/document/if-CR16010H-F.md +300 -0
  41. data/document/if-CR16018-F.md +300 -0
  42. data/document/if-CR19000-20.md +300 -0
  43. data/document/if-CRS-16.md +47 -0
  44. data/document/if-CX600-X16A.md +349 -0
  45. data/document/if-CX600-X8A.md +349 -0
  46. data/document/if-M6000-16E.md +652 -0
  47. data/document/if-M6000-18S.md +846 -0
  48. data/document/if-M6000-8.md +653 -0
  49. data/document/if-M6000-8E.md +653 -0
  50. data/document/if-MA5200G-8.md +357 -0
  51. data/document/if-ME60-16.md +357 -0
  52. data/document/if-ME60-X16.md +357 -0
  53. data/document/if-NE40E-X16.md +357 -0
  54. data/document/if-NE40E-X16A.md +357 -0
  55. data/document/if-NE40E-X8.md +357 -0
  56. data/document/if-NE40E.md +357 -0
  57. data/document/if-NE5000E-20.md +357 -0
  58. data/document/if-NE5000E-X16.md +357 -0
  59. data/document/if-NE5000E-X16A.md +357 -0
  60. data/document/if-NE8000E-X8.md +357 -0
  61. data/document/if-NE80E.md +357 -0
  62. data/document/if-NE8100-X8.md +357 -0
  63. data/document/if-Nokia7750.md +48 -0
  64. data/document/if-T8000-18.md +653 -0
  65. data/document/if-V6000.md +663 -0
  66. data/document/if-VNE9000.md +357 -0
  67. data/document/if-ZXCTN9000-18EA.md +762 -0
  68. data/document/if-ZXCTN9000-8EA.md +762 -0
  69. data/document/lic-M6000-16E.md +28 -0
  70. data/document/lic-M6000-18S.md +28 -0
  71. data/document/lic-M6000-8.md +28 -0
  72. data/document/lic-M6000-8E.md +28 -0
  73. data/document/lic-MA5200G-8.md +27 -0
  74. data/document/lic-ME60-16.md +27 -0
  75. data/document/lic-ME60-X16.md +27 -0
  76. data/document/lic-NE40E-X16.md +27 -0
  77. data/document/lic-NE40E-X16A.md +27 -0
  78. data/document/lic-NE40E-X8.md +27 -0
  79. data/document/log-M6000-16E.md +36 -0
  80. data/document/log-M6000-18S.md +36 -0
  81. data/document/log-M6000-8.md +36 -0
  82. data/document/log-M6000-8E.md +36 -0
  83. data/document/log-MA5200G-8.md +61 -0
  84. data/document/log-ME60-16.md +61 -0
  85. data/document/log-ME60-X16.md +61 -0
  86. data/document/log-NE40E-X16.md +61 -0
  87. data/document/log-NE40E-X16A.md +61 -0
  88. data/document/log-NE40E-X8.md +61 -0
  89. data/document/log-NE40E.md +61 -0
  90. data/document/log-NE5000E-20.md +61 -0
  91. data/document/log-NE5000E-X16.md +61 -0
  92. data/document/log-NE5000E-X16A.md +61 -0
  93. data/document/log-NE80E.md +61 -0
  94. data/document/nat-CR16010H-F.md +27 -0
  95. data/document/nat-CR16018-F.md +27 -0
  96. data/document/nat-M6000-16E.md +27 -0
  97. data/document/nat-M6000-18S.md +27 -0
  98. data/document/nat-M6000-8.md +27 -0
  99. data/document/nat-M6000-8E.md +27 -0
  100. data/document/nat-ME60-16.md +44 -0
  101. data/document/nat-ME60-X16.md +44 -0
  102. data/document/nat-NE40E-X16.md +44 -0
  103. data/document/nat-NE40E-X16A.md +44 -0
  104. data/document/policy-M6000-16E.md +13 -0
  105. data/document/policy-M6000-18S.md +13 -0
  106. data/document/policy-M6000-8.md +13 -0
  107. data/document/policy-M6000-8E.md +13 -0
  108. data/document/policy-MA5200G-8.md +87 -0
  109. data/document/policy-ME60-16.md +87 -0
  110. data/document/policy-ME60-X16.md +87 -0
  111. data/document/policy-NE40E-X16.md +87 -0
  112. data/document/policy-NE40E-X16A.md +87 -0
  113. data/document/policy-NE40E-X8.md +87 -0
  114. data/document/policy-NE40E.md +87 -0
  115. data/document/policy-NE5000E-20.md +87 -0
  116. data/document/policy-NE5000E-X16.md +87 -0
  117. data/document/policy-NE5000E-X16A.md +87 -0
  118. data/document/policy-NE80E.md +87 -0
  119. data/document/pool-M6000-16E.md +126 -0
  120. data/document/pool-M6000-18S.md +126 -0
  121. data/document/pool-M6000-8.md +126 -0
  122. data/document/pool-M6000-8E.md +126 -0
  123. data/document/pool-MA5200G-8.md +138 -0
  124. data/document/pool-ME60-16.md +138 -0
  125. data/document/pool-ME60-X16.md +138 -0
  126. data/document/pool-NE40E-X16.md +138 -0
  127. data/document/pool-NE40E-X16A.md +138 -0
  128. data/document/pool-NE40E-X8.md +138 -0
  129. data/document/pool-NE40E.md +138 -0
  130. data/document/pool-NE80E.md +138 -0
  131. data/document/static-CR16010H-F.md +60 -0
  132. data/document/static-CR16018-F.md +60 -0
  133. data/document/static-CR19000-20.md +60 -0
  134. data/document/static-CX600-X16A.md +26 -0
  135. data/document/static-CX600-X8A.md +26 -0
  136. data/document/static-M6000-16E.md +104 -0
  137. data/document/static-M6000-18S.md +104 -0
  138. data/document/static-M6000-8.md +104 -0
  139. data/document/static-M6000-8E.md +104 -0
  140. data/document/static-MA5200G-8.md +82 -0
  141. data/document/static-ME60-16.md +82 -0
  142. data/document/static-ME60-X16.md +82 -0
  143. data/document/static-NE40E-X16.md +82 -0
  144. data/document/static-NE40E-X16A.md +81 -0
  145. data/document/static-NE40E-X8.md +82 -0
  146. data/document/static-NE40E.md +67 -0
  147. data/document/static-NE5000E-20.md +67 -0
  148. data/document/static-NE5000E-X16.md +67 -0
  149. data/document/static-NE5000E-X16A.md +67 -0
  150. data/document/static-NE8000E-X8.md +26 -0
  151. data/document/static-NE80E.md +67 -0
  152. data/document/static-NE8100-X8.md +26 -0
  153. data/document/static-T8000-18.md +34 -0
  154. data/document/static-ZXCTN9000-18EA.md +34 -0
  155. data/document/static-ZXCTN9000-8EA.md +34 -0
  156. data/document/system-M6000-16E.md +75 -0
  157. data/document/system-M6000-18S.md +76 -0
  158. data/document/system-M6000-8.md +75 -0
  159. data/document/system-M6000-8E.md +75 -0
  160. data/document/system-MA5200G-8.md +51 -0
  161. data/document/system-ME60-16.md +51 -0
  162. data/document/system-ME60-X16.md +51 -0
  163. data/document/system-NE40E-X16.md +51 -0
  164. data/document/system-NE40E-X16A.md +51 -0
  165. data/document/system-NE40E-X8.md +51 -0
  166. data/document/system-NE40E.md +51 -0
  167. data/document/system-NE5000E-20.md +51 -0
  168. data/document/system-NE5000E-X16.md +51 -0
  169. data/document/system-NE5000E-X16A.md +51 -0
  170. data/document/system-NE80E.md +51 -0
  171. data/document/telnet.md +332 -0
  172. data/network.rb +24 -0
  173. data/utility/ipv4_address.rb +266 -0
  174. data/utility/ipv6_address.rb +201 -0
  175. data/utility/mac_address.rb +77 -0
  176. data/utility/netmerge.rb +46 -0
  177. data/utility/route.rb +79 -0
  178. data/utility/whitelist.rb +21 -0
  179. metadata +258 -0
@@ -0,0 +1,27 @@
1
+ #coding:utf-8
2
+ uses 'CasetDown/casetdown','uuid', 'pathname'
3
+
4
+ class String
5
+ def refine *flags,&cond
6
+ path = self[-3..-1]=='.md' ? self : self+'.md'
7
+ unless flags.include?(:active)
8
+ gem_path = Pathname.new(__FILE__).realpath.join('..', '..')
9
+ path = gem_path.join('.', path)
10
+ end
11
+ if File.exist?(path)
12
+ cds = CasetDown.load path
13
+ else
14
+ warn "File #{path} not exist.";exit
15
+ end
16
+ codes = CasetDown::Check.all(cds).select{|segment|segment[:name]=='code' && segment[:class]=='ruby' && (cond ? cond.call(segment[:code]) : true) }
17
+ return codes.map{|s|s[:code].gsub("&lt;",'<').gsub('&gt;','>').gsub('&amp;','&')}
18
+ end
19
+ end
20
+
21
+ class Array
22
+ def run &proc
23
+ self.each do|code|
24
+ proc.call code
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+
2
+ # Alcatel7750 IF
3
+
4
+ ```ruby
5
+ @sign << ['ALCATEL7750', '接口配置', 'PENDING']
6
+ @sign << ['ALCATEL7750', '接口分检', 'PENDING']
7
+ @sign << ['ALCATEL7750', '端口识别', 'PENDING']
8
+ @sign << ['ALCATEL7750', '接口地址', 'PENDING']
9
+ @sign << ['ALCATEL7750', '接口描述', 'PENDING']
10
+ @sign << ['ALCATEL7750', '接口vpn实例', 'PENDING']
11
+ @sign << ['ALCATEL7750', '接口开关', 'PENDING']
12
+ @sign << ['ALCATEL7750', '接口QoS', 'PENDING']
13
+ @sign << ['ALCATEL7750', '接口流策略', 'PENDING']
14
+
15
+ module ALCATEL7750
16
+ module_function
17
+
18
+ def 接口配置 正文
19
+ []
20
+ end
21
+
22
+ def 接口分检 接口集合
23
+ []
24
+ end
25
+
26
+ def 端口识别 描述
27
+ end
28
+
29
+ def 接口地址 接口配置
30
+ end
31
+
32
+ def 接口描述 接口配置
33
+ end
34
+
35
+ def 接口vpn实例 接口配置
36
+ end
37
+
38
+ def 接口开关 接口配置
39
+ end
40
+
41
+ def 接口QoS 接口配置
42
+
43
+ end
44
+
45
+ def 接口流策略 接口配置
46
+ end
47
+ end
48
+ ```
@@ -0,0 +1,47 @@
1
+
2
+ # C7609 IF
3
+
4
+ ```ruby
5
+ @sign << ['C7609', '接口配置']
6
+ @sign << ['C7609', '接口分检']
7
+ @sign << ['C7609', '端口识别']
8
+ @sign << ['C7609', '接口地址']
9
+ @sign << ['C7609', '接口描述']
10
+ @sign << ['C7609', '接口vpn实例']
11
+ @sign << ['C7609', '接口开关']
12
+ @sign << ['C7609', '接口QoS']
13
+ @sign << ['C7609', '接口流策略']
14
+
15
+ module C7609
16
+ module_function
17
+
18
+ def 接口配置 正文
19
+ []
20
+ end
21
+
22
+ def 接口分检 接口集合
23
+ []
24
+ end
25
+
26
+ def 端口识别 描述
27
+ end
28
+
29
+ def 接口地址 接口配置
30
+ end
31
+
32
+ def 接口描述 接口配置
33
+ end
34
+
35
+ def 接口vpn实例 接口配置
36
+ end
37
+
38
+ def 接口开关 接口配置
39
+ end
40
+
41
+ def 接口QoS 接口配置
42
+ end
43
+
44
+ def 接口流策略 接口配置
45
+ end
46
+ end
47
+ ```
@@ -0,0 +1,300 @@
1
+
2
+ # CR16010H-F 接口
3
+
4
+ ```ruby
5
+ @sign << ["CR16010H-F", "接口配置"]
6
+ @sign << ["CR16010H-F", "特殊接口配置"]
7
+ @sign << ["CR16010H-F", "物理接口配置"]
8
+ @sign << ["CR16010H-F", "子接口配置"]
9
+ @sign << ["CR16010H-F", "接口分捡"]
10
+ @sign << ["CR16010H-F", "端口识别"]
11
+ @sign << ["CR16010H-F", "端口管理状态"]
12
+ @sign << ["CR16010H-F", "接口地址"]
13
+ @sign << ["CR16010H-F", "接口描述"]
14
+ @sign << ["CR16010H-F", "接口vpn实例"]
15
+ @sign << ["CR16010H-F", "接口开关"]
16
+ @sign << ["CR16010H-F", "接口QoS"]
17
+ @sign << ["CR16010H-F", "接口流策略"]
18
+ @sign << ["CR16010H-F", "接口统计"]
19
+ @sign << ["CR16010H-F", "接口URPF"]
20
+ @sign << ["CR16010H-F", "接口接入类型"]
21
+ @sign << ["CR16010H-F", "聚合接口判定"]
22
+ @sign << ["CR16010H-F", "聚合接口分捡"]
23
+ @sign << ["CR16010H-F", "聚合逻辑接口"]
24
+ @sign << ["CR16010H-F", "vlan分捡"]
25
+ @sign << ["CR16010H-F", "vlan统计"]
26
+
27
+ module CR16010H_F
28
+ module_function
29
+ #####################################################################################################
30
+ # 接口/端口配置的基本查询
31
+ # 接口集合 => 接口分检 => 物理接口集合,子接口集合,特殊接口集合
32
+ #####################################################################################################
33
+ def 接口配置 正文
34
+ 正文['interface'] # Array
35
+ end
36
+
37
+ def 特殊接口配置 接口集合
38
+ 接口集合.collect{|接口|
39
+ 接口 if /Virtual|NULL|LoopBack|M\-GigabitEthernet/.match(接口.split("\n")[0])
40
+ }.compact.sort_by{|接口|接口.split("\n")[0]}
41
+ end
42
+
43
+ def 物理接口配置 接口集合,特殊接口集合=nil
44
+ 其余接口 = 特殊接口集合 ? (接口集合-特殊接口集合) : (接口集合-self.特殊接口配置(接口集合))
45
+ 其余接口.collect{|接口|接口 unless 接口.split("\n")[0].include?('.')}.compact
46
+ end
47
+
48
+ def 子接口配置 接口集合,特殊接口集合=nil
49
+ 其余接口 = 特殊接口集合 ? (接口集合-特殊接口集合) : (接口集合-self.特殊接口配置(接口集合))
50
+ 其余接口.collect{|接口|接口 if 接口.split("\n")[0].include?('.')}.compact
51
+ end
52
+
53
+ def 接口分捡 接口集合
54
+ 特殊接口集合 = self.特殊接口配置(接口集合)
55
+ 物理接口集合 = self.物理接口配置(接口集合,特殊接口集合)
56
+ 子接口集合 = self.子接口配置(接口集合,特殊接口集合)
57
+ return 物理接口集合,子接口集合,特殊接口集合
58
+ end
59
+
60
+
61
+ #####################################################################################################
62
+ # 端口描述信息相关
63
+ #####################################################################################################
64
+
65
+ # func: 根据一个端口的描述信息,给出其格式化的类型、连接符、端口编号
66
+ def 端口识别 描述
67
+ 连接符 = ''
68
+ type = /HundredGigE|GigabitEthernet|Ten\-GigabitEthernet|M\-GigabitEthernet|Bridge\-Aggregation|Route\-Aggregation|Virtual\-Template|NULL|LoopBack/.match(描述)
69
+ 类型 = type ? type.to_s : '未知类型'
70
+ port = /(\d+|\/|\.)*(\d+)/.match(描述.split(类型).join)
71
+ 端口 = port ? port.to_s : '未知端口'
72
+ return 类型,连接符,端口
73
+ end
74
+
75
+ # func: 根据一个端口的描述信息,给出其管理状态是打开/关闭的判断
76
+ def 端口管理状态 描述
77
+ 管理状态 = true
78
+ 描述.to_s.split("\n").each do|line|
79
+ 管理状态 = false if line.include?("shutdown") && !line.include?("undo shutdown")
80
+ end
81
+ 管理状态
82
+ end
83
+
84
+ # func: 根据一个端口的配置给出其配置的接口地址
85
+ def 接口地址 接口配置
86
+ 地址集 = []
87
+ 接口配置.each_line do|line|
88
+ if line.strip[0..9]=='ip address' and !line.include?('unnumbered')
89
+ 地址集 << line.gsub("sub","").split('ip address')[-1].strip.split(' ')
90
+ end
91
+ if line.strip[0..11]=='ipv6 address' and !line.include?("auto link-local") and !line.include?('unnumbered')
92
+ 地址集 << line.gsub("sub","").split('ipv6 address')[-1].strip.split('/')
93
+ end
94
+ end
95
+ 地址集
96
+ end
97
+
98
+ # func: 根据一个端口的配置给出其描述
99
+ def 接口描述 接口配置
100
+ 描述 = ''
101
+ 接口配置.each_line do|line| if line.strip[0..10]=='description'
102
+ 描述 = line.split('description')[-1].strip; break
103
+ end end
104
+ 描述.to_s
105
+ end
106
+
107
+ # func: 根据一个端口的配置给出其关联的vpn实例
108
+ def 接口vpn实例 接口配置
109
+ 实例 = ''
110
+ 接口配置.each_line do|line|
111
+ 实例 = "vpn-inst:" + /vpn\-instance .+/.match(line).to_s.split(" ")[-1] if /vpn\-instance .+/.match(line)
112
+ 实例 = "vsi:" + /vsi .+/.match(line).to_s.split(" ")[-1] if /vsi .+/.match(line)
113
+ end
114
+ 实例
115
+ end
116
+
117
+ # func: 根据一个端口的配置给出其开关状态(配置层面的"端口管理状态")
118
+ def 接口开关 接口配置
119
+ 描述 = ''
120
+ 接口配置.each_line do|line|
121
+ if line.include?('shutdown') and !line.include?('no') and !line.include?('undo') and !line.include?('description')
122
+ 描述 = 'shutdown'; break
123
+ end
124
+ end
125
+ 描述
126
+ end
127
+
128
+ # func: 端口应用QoS模板
129
+ def 接口QoS 接口配置
130
+ qos = {}
131
+ 接口配置.each_line do|line|
132
+ if line.include?('qos apply user-profile')
133
+ words = line.split(' ')
134
+ direction = line.include?('inbound') ? 'inbound' : 'outbound'
135
+ profile = words[words.index('user-profile')+1]
136
+ qos[direction] = profile
137
+ end
138
+ end
139
+ qos
140
+ end
141
+
142
+ # func: 端口应用流量模板
143
+ def 接口流策略 接口配置
144
+ traffic = {}
145
+ 接口配置.each_line do|line|
146
+ if line.include?('qos apply policy')
147
+ words = line.split(' ')
148
+ direction = line.include?('inbound') ? 'inbound' : 'outbound'
149
+ profile = words[words.index('policy')+1]
150
+ traffic[direction] = profile
151
+ end
152
+ end
153
+ traffic
154
+ end
155
+
156
+ # func: 端口统计功能
157
+ def 接口统计 接口配置
158
+ 接口配置.each_line do|line|
159
+ return :statistic if line.strip =='statistic' and !line.include?('description')
160
+ end
161
+ return false
162
+ end
163
+
164
+ # func: 端口URPF功能
165
+ def 接口URPF 接口配置
166
+ 接口配置.each_line do|line|
167
+ return (line.include?('strict') ? 'strict' : 'loose') if line.include?('urpf')
168
+ end
169
+ return nil
170
+ end
171
+
172
+ # func: 端口接入类型
173
+ def 接口接入类型 接口配置
174
+ return {}
175
+ end
176
+
177
+ #####################################################################################################
178
+ # 聚合接口判定相关
179
+ #####################################################################################################
180
+
181
+ # func: 根据一个接口的描述信息,给出其所属聚合接口的信息,若非聚合端口返回空
182
+ def 聚合接口判定 配置
183
+ 配置.split("\n").each do|描述|
184
+ if 描述.include?("port link-aggregation group") && !描述.include?("description")
185
+ return {self.端口识别(配置).join=>"Route-Aggregation"+描述.split("group")[1].strip}
186
+ end
187
+ end;{}
188
+ end
189
+
190
+ # func: 给出聚合接口和物理接口的集合,通过计算找出所有聚合接口的集合
191
+ def 聚合接口分捡 聚合接口,物理接口集合
192
+ 聚合接口 = self.端口识别(聚合接口)
193
+ 聚合接口集合 = [聚合接口.join]
194
+ 物理接口集合.each do|物理接口| 物理接口.each_line do|line|
195
+ 聚合接口集合 << self.端口识别(物理接口).join if line.include?("port link-aggregation group #{聚合接口[-1]}")
196
+ end end
197
+ 聚合接口集合
198
+ end
199
+
200
+ # func: 根据一个接口的描述信息,给出其所属聚合接口的逻辑接口,若无返回空
201
+ def 聚合逻辑接口 配置
202
+ 配置.split("\n").each do|描述|
203
+ return 描述.split(" ")[-1] if 描述.include?("nas logic-port")
204
+ end
205
+ return nil
206
+ end
207
+
208
+ #####################################################################################################
209
+ # 接口VLAN相关
210
+ # 对接口vlan配置的解析
211
+ # dot1q : [vlan, ...]
212
+ # qinq : [[pvlan, (cvlan..cvlan)], [pvlan, cvlan], ...]
213
+ # vlan : [(cvlan..cvlan), cvlan, ...]
214
+ #####################################################################################################
215
+ def vlan分捡 接口配置
216
+ vlan = {}
217
+ 接口配置.each_line do|line| next if line.include?('undo')
218
+ if pattern = /vlan\-type dot1q vid (\d+)/.match(line)
219
+ dot1q = pattern[1].to_i
220
+ vlan['dot1q'] ||= [];vlan['dot1q'] << dot1q;next
221
+ end
222
+ if pattern = /user\-vlan dot1q vid (\d+) to (\d+) second\-dot1q (\d+) to (\d+)/.match(line)
223
+ (pattern[1].to_i..pattern[2].to_i).each do|svlan|
224
+ qinq = [svlan, (pattern[3].to_i)..(pattern[4].to_i)]
225
+ vlan['qinq'] ||= [];vlan['qinq'] << qinq
226
+ end;next
227
+ end
228
+ if pattern = /user\-vlan dot1q vid (\d+) to (\d+) second\-dot1q (\d+)/.match(line)
229
+ (pattern[1].to_i..pattern[2].to_i).each do|svlan|
230
+ qinq = [svlan, pattern[3].to_i]
231
+ vlan['qinq'] ||= [];vlan['qinq'] << qinq
232
+ end;next
233
+ end
234
+ if pattern = /user\-vlan dot1q vid (\d+) second\-dot1q (\d+) to (\d+)/.match(line)
235
+ qinq = [pattern[1].to_i, (pattern[2].to_i)..(pattern[3].to_i)]
236
+ vlan['qinq'] ||= [];vlan['qinq'] << qinq;next
237
+ end
238
+ if pattern = /user\-vlan dot1q vid (\d+) second\-dot1q (\d+)/.match(line)
239
+ qinq = [pattern[1].to_i, pattern[2].to_i]
240
+ vlan['qinq'] ||= [];vlan['qinq'] << qinq;next
241
+ end
242
+ if pattern = /user\-vlan dot1q vid (\d+)/.match(line)
243
+ user_vlan = pattern[1].to_i
244
+ vlan['vlan'] ||= [];vlan['vlan'] << user_vlan;next
245
+ end
246
+ end
247
+ return vlan # {vlan:[ int|range ] qinq:[ [int,int|range] ] dot1q:[ int ]}
248
+ end
249
+
250
+ def vlan统计 name,物理接口集合,子接口集合
251
+ bas子接口数据库,聚合接口表 = {},[]
252
+ 聚合接口集合 = 物理接口集合.select{|物理接口|self.端口识别(物理接口)[0]=='Route-Aggregation'}
253
+ 聚合接口表 += 聚合接口集合.collect{|聚合接口|self.聚合接口分捡(聚合接口,物理接口集合)}
254
+
255
+ 子接口集合.each do|接口配置|
256
+ 物理接口名称 = self.端口识别(接口配置).join.split(".")[0]
257
+ 物理接口 = 物理接口集合.find{|物理接口|物理接口.split("\n")[0].split(" ")[1]==(物理接口名称)}
258
+ next unless self.端口管理状态(物理接口) # 物理接口关闭的不统计
259
+ next unless self.端口管理状态(接口配置) # 子接口关闭的不统计
260
+
261
+ vlan配置 = {}
262
+ self.vlan分捡(接口配置).each do|type,data|
263
+ if type=='vlan'
264
+ vlan配置[4096] ||= []; vlan配置[4096] += data # 用4096表示单层vlan
265
+ elsif type=='qinq'
266
+ data.each{|pvlan,cvlan|vlan配置[pvlan] ||= []; vlan配置[pvlan] << cvlan}
267
+ else
268
+ # discard dot1q
269
+ end
270
+ end
271
+
272
+ 子接口名称 = self.端口识别(接口配置)
273
+ bas子接口数据库[name] ||= {}
274
+ if 子接口名称[0].include?("GigabitEthernet")
275
+ # 子接口索引 = ["eth--"+子接口名称[-1].split(".")[0].split('/')[-3..-1].join(',')] # AIBOS风格
276
+ 子接口索引 = [子接口名称.join.split(".")[0]] # 原生风格
277
+ end
278
+ if 子接口名称[0].include?("Route-Aggregation") &&
279
+ 聚合接口组 = 聚合接口表.find{|聚合接口组|聚合接口组.include?(子接口名称.join.split('.')[0])}
280
+ 聚合接口的等效名称 = 聚合接口组.clone
281
+ #聚合接口的等效名称.delete(子接口名称.join.split('.')[0]) # 除了trunk自身,为所有等效接口创建 # 是否保留Trunk是个争议
282
+ 子接口索引 = 聚合接口的等效名称.collect do|等效名称|
283
+ # "trunk--"+self.端口识别(等效名称)[-1].split(".")[0].split('/')[-3..-1].join(',') # AIBOS风格
284
+ self.端口识别(等效名称).join.split(".")[0] # 原生风格
285
+ end
286
+ end
287
+
288
+ 子接口索引.each do|索引|
289
+ bas子接口数据库[name][索引] ||= {}
290
+ vlan配置.each do|pv,cv|
291
+ bas子接口数据库[name][索引][pv] ||= []
292
+ bas子接口数据库[name][索引][pv] += cv
293
+ bas子接口数据库[name][索引][pv].uniq!
294
+ end
295
+ end if 子接口索引
296
+ end
297
+ return bas子接口数据库
298
+ end
299
+ end
300
+ ```