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,762 @@
1
+
2
+ # ZXCTN9000-8EA 接口
3
+
4
+ ```ruby
5
+ @sign << ["ZXCTN9000-8EA", "接口配置"]
6
+ @sign << ["ZXCTN9000-8EA", "接口物理信息"]
7
+ @sign << ["ZXCTN9000-8EA", "接口基本信息"]
8
+ @sign << ["ZXCTN9000-8EA", "接口vlan信息"]
9
+ @sign << ["ZXCTN9000-8EA", "接口acl信息"]
10
+ @sign << ["ZXCTN9000-8EA", "接口mpls信息"]
11
+ @sign << ["ZXCTN9000-8EA", "接口lacp信息"]
12
+ @sign << ["ZXCTN9000-8EA", "接口isis信息"]
13
+ @sign << ["ZXCTN9000-8EA", "接口multicast信息"]
14
+ @sign << ["ZXCTN9000-8EA", "接口firload信息"]
15
+ @sign << ["ZXCTN9000-8EA", "接口port_request_info信息"]
16
+ @sign << ["ZXCTN9000-8EA", "接口arp信息"]
17
+ @sign << ["ZXCTN9000-8EA", "接口nd信息"]
18
+ @sign << ["ZXCTN9000-8EA", "接口interface_performance信息"]
19
+ @sign << ["ZXCTN9000-8EA", "接口ospf信息"]
20
+ @sign << ["ZXCTN9000-8EA", "接口urpf信息"]
21
+ @sign << ["ZXCTN9000-8EA", "接口am信息"]
22
+ @sign << ["ZXCTN9000-8EA", "接口uim信息"]
23
+ @sign << ["ZXCTN9000-8EA", "接口QoS"]
24
+ @sign << ["ZXCTN9000-8EA", "接口流策略"]
25
+ @sign << ["ZXCTN9000-8EA", "接口统计"]
26
+ @sign << ["ZXCTN9000-8EA", "接口URPF"]
27
+ @sign << ["ZXCTN9000-8EA", "接口接入类型"]
28
+ @sign << ["ZXCTN9000-8EA", "特殊接口配置"]
29
+ @sign << ["ZXCTN9000-8EA", "物理接口配置"]
30
+ @sign << ["ZXCTN9000-8EA", "子接口配置"]
31
+ @sign << ["ZXCTN9000-8EA", "接口分捡"]
32
+ @sign << ["ZXCTN9000-8EA", "端口识别"]
33
+ @sign << ["ZXCTN9000-8EA", "端口MAC"]
34
+ @sign << ["ZXCTN9000-8EA", "端口管理状态"]
35
+ @sign << ["ZXCTN9000-8EA", "接口描述"]
36
+ @sign << ["ZXCTN9000-8EA", "接口地址"]
37
+ @sign << ["ZXCTN9000-8EA", "接口开关"]
38
+ @sign << ["ZXCTN9000-8EA", "接口vpn实例"]
39
+ @sign << ["ZXCTN9000-8EA", "聚合接口判定"]
40
+ @sign << ["ZXCTN9000-8EA", "聚合接口分捡"]
41
+ @sign << ["ZXCTN9000-8EA", "聚合逻辑接口"]
42
+ @sign << ["ZXCTN9000-8EA", "vlan分捡"]
43
+ @sign << ["ZXCTN9000-8EA", "vlan统计"]
44
+ @sign << ["ZXCTN9000-8EA", "端口去0"]
45
+ @sign << ["ZXCTN9000-8EA", "统计接口"]
46
+
47
+ module ZXCTN9000_8EA
48
+ module_function
49
+ #####################################################################################################
50
+ # 接口/端口配置的基本查询
51
+ # 接口集合 => 接口分检 => 物理接口集合,子接口集合,特殊接口集合
52
+
53
+ # 主动模块:
54
+ # firload
55
+ # port-request-info
56
+ # if-intf
57
+ # port-physical-config
58
+ # lacp
59
+ # vlan
60
+ # port-acl
61
+ # lldp # 未实现
62
+ # arp
63
+ # nd
64
+ # mpls
65
+ # interface-performance
66
+ # isis
67
+ # multicast
68
+ # ospfv2
69
+ # ospfv3
70
+ # qos # 未实现
71
+
72
+ # 被动模块:(暂不关联)
73
+ # samgr
74
+ # monitor
75
+ # alarm
76
+ # ftp
77
+ # ethernet-segment
78
+ # icbg
79
+ #####################################################################################################
80
+ def 接口配置 正文
81
+ 接口表 = {}
82
+ # these will be instancized!
83
+ [self.接口物理信息(正文), self.接口基本信息(正文), self.接口vlan信息(正文), self.接口acl信息(正文),
84
+ self.接口mpls信息(正文), self.接口isis信息(正文), self.接口multicast信息(正文), self.接口lacp信息(正文),
85
+ self.接口firload信息(正文), self.接口port_request_info信息(正文), self.接口ospf信息(正文),
86
+ self.接口arp信息(正文), self.接口nd信息(正文), self.接口interface_performance信息(正文),
87
+ # self.接口urpf信息(正文), self.接口am信息(正文), self.接口uim信息(正文),
88
+ ].each do|infolist|
89
+ infolist.each do|intf,text|
90
+ 接口表[intf]||=[]
91
+ 接口表[intf] << text
92
+ end
93
+ end
94
+ 接口表
95
+ end
96
+
97
+ def 接口物理信息 正文
98
+ tag = 正文["PORT-PHYSICAL-INFO"] ? "PORT-PHYSICAL-INFO" : "port-physical-config"
99
+ 接口物理表 = {}
100
+ if tag == "PORT-PHYSICAL-INFO"
101
+ (正文[tag]||"").split("\n!")\
102
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!=' '}\
103
+ .compact.each{|接口|接口物理表[/interface (.)*/.match(接口)[0].to_s.strip] = 接口}
104
+ elsif tag == "port-physical-config"
105
+ (正文[tag]||"").split("\n$")\
106
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!="\n!"}\
107
+ .compact.each{|接口|接口物理表[/interface (.)*/.match(接口)[0].to_s.strip] = 接口}
108
+ end
109
+ 接口物理表
110
+ end
111
+
112
+ def 接口基本信息 正文
113
+ tag = 正文["INTERFACE"] ? "INTERFACE" : "if-intf"
114
+ 接口基本表 = {}
115
+ if tag== "INTERFACE"
116
+ (正文[tag]||"").split("\n!")\
117
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" \
118
+ if l!=' ' && l.include?('interface')}\
119
+ .compact.each{|接口|接口基本表[/interface (.)*/.match(接口)[0].to_s.strip] = 接口}
120
+ elsif tag=="if-intf"
121
+ (正文[tag]||"").split("\n$")\
122
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" \
123
+ if l!=' ' && l.include?('interface')}\
124
+ .compact.each{|接口|接口基本表[/interface (.)*/.match(接口)[0].to_s.strip] = 接口}
125
+ end
126
+ 接口基本表
127
+ end
128
+
129
+ def 接口vlan信息 正文
130
+ tag = 正文["VLAN"] ? "VLAN" : "vlan"
131
+ 接口vlan表 = {}
132
+ if tag == "VLAN"
133
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
134
+ head,tail = "<#{tag}>\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
135
+ fragments.each{|frag| 接口vlan表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
136
+ elsif tag == "vlan"
137
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
138
+ head,tail = "<#{tag}>\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
139
+ fragments.each{|frag| 接口vlan表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
140
+ end
141
+ 接口vlan表
142
+ end
143
+
144
+ def 接口acl信息 正文
145
+ tag = 正文["PORT_ACL"] ? "PORT_ACL" : "port-acl"
146
+ 接口acl表 = {}
147
+ if tag =="PORT_ACL"
148
+ (正文[tag]||"").split("\n!")\
149
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!="\n!"}\
150
+ .compact.each{|接口|接口acl表[/interface (.)*/.match(接口)[0].to_s.strip]=接口}
151
+ elsif tag == "port-acl"
152
+ (正文[tag]||"").split("\n$")\
153
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!="\n!"}\
154
+ .compact.each{|接口|接口acl表[/interface (.)*/.match(接口)[0].to_s.strip]=接口}
155
+ end
156
+ 接口acl表
157
+ end
158
+
159
+ def 接口mpls信息 正文
160
+ tag = 正文["MPLS"] ? "MPLS" : "ldp"
161
+ 接口mpls表 = {}
162
+ if tag=="MPLS"
163
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
164
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(!\n)
165
+ fragments.each{|frag|接口mpls表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
166
+ elsif tag=="ldp"
167
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
168
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(!\n)
169
+ fragments.each{|frag|接口mpls表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
170
+ end
171
+ 接口mpls表
172
+ end
173
+
174
+ def 接口lacp信息 正文 # trunk
175
+ tag = 正文["LACP"] ? "LACP" : "lacp"
176
+ 接口lacp表 = {}
177
+ if tag=="LACP"
178
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
179
+ head,tail = "<#{tag}>\n#{context[0..3]}\n","$\n!</#{tag}>" # context tail(!\n)
180
+ fragments.each{|frag|接口lacp表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
181
+ elsif tag=="lacp"
182
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
183
+ head,tail = "<#{tag}>\n#{context[0..3]}\n","$\n!</#{tag}>" # context tail(!\n)
184
+ fragments.each{|frag|接口lacp表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
185
+ end
186
+ 接口lacp表
187
+ end
188
+
189
+ def 接口isis信息 正文
190
+ tag = 正文["ISIS"] ? "ISIS" : "isis"
191
+ 接口isis表 = {}
192
+ if tag == "ISIS"
193
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
194
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(\n!)
195
+ fragments.each{|frag|接口isis表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
196
+ elsif tag == "isis"
197
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
198
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(\n!)
199
+ fragments.each{|frag|接口isis表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
200
+ end
201
+ 接口isis表
202
+ end
203
+
204
+ def 接口multicast信息 正文
205
+ tag = 正文["MULTICAST"] ? "MULTICAST" : "multicast"
206
+ 接口multicast表 = {}
207
+ if tag == "MULTICAST"
208
+ za,pimsm = TextAbstract.draw_fragments (正文[tag]||""), /^ router pimsm/, /^ \$/
209
+ za,pimsm = TextAbstract.draw_fragments (正文[tag]||""), /^ router pim/, /^ \$/ unless pimsm[0]
210
+ za,igmp= TextAbstract.draw_fragments (正文[tag]||""), /^ router igmp/, /^ \$/
211
+ chead,ctail = "<#{tag}>\n#{za.split("\n")[0]}\n","!\n</#{tag}>" # common head
212
+ # pimsm
213
+ #begin
214
+ context,fragments = TextAbstract.draw_fragments pimsm[0],/^ interface (.)*/, /^ \$/
215
+ head,tail = context[0..-5],context[-4..-1] # open(... $\n)
216
+ fragments.each{|frag|接口multicast表[/interface (.)*/.match(frag)[0].to_s.strip] = chead+head+frag+tail+ctail}
217
+ #rescue;end
218
+ # igmp
219
+ context,fragments = TextAbstract.draw_fragments igmp.join, /^ interface (.)*/, /^ \$/
220
+ head,tail = context[0..-5],context[-4..-1] # open(... $\n)
221
+ fragments.each{|frag|接口multicast表[/interface (.)*/.match(frag)[0].to_s.strip] = chead+head+frag+tail+ctail}
222
+ elsif tag == "multicast"
223
+ za,pimsm = TextAbstract.draw_fragments (正文[tag]||""), /^ router pimsm/, /^ \$/
224
+ za,pimsm = TextAbstract.draw_fragments (正文[tag]||""), /^ router pim/, /^ \$/ unless pimsm[0]
225
+ za,igmp= TextAbstract.draw_fragments (正文[tag]||""), /^ router igmp/, /^ \$/
226
+ chead,ctail = "<#{tag}>\n#{za.split("\n")[0]}\n","!\n</#{tag}>" # common head
227
+ # pimsm
228
+ #begin
229
+ context,fragments = TextAbstract.draw_fragments pimsm[0].to_s, /^ interface (.)*/, /^ \$/
230
+ head,tail = context[0..-5],context[-4..-1] # open(... $\n)
231
+ fragments.each{|frag|接口multicast表[/interface (.)*/.match(frag)[0].to_s.strip] = chead+head+frag+tail+ctail}
232
+ #rescue;end
233
+ # igmp
234
+ context,fragments = TextAbstract.draw_fragments igmp.join, /^ interface (.)*/, /^ \$/
235
+ head,tail = context[0..-5],context[-4..-1] # open(... $\n)
236
+ fragments.each{|frag|接口multicast表[/interface (.)*/.match(frag)[0].to_s.strip] = chead+head+frag+tail+ctail}
237
+ end
238
+ 接口multicast表
239
+ end
240
+
241
+ def 接口firload信息 正文
242
+ tag = 正文["firload"] ? "firload" : "firload"
243
+ 接口firload表 = {}
244
+ if tag == "firload"
245
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
246
+ head,tail = "<#{tag}>\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
247
+ fragments.each{|frag| 接口firload表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
248
+ end
249
+ 接口firload表
250
+ end
251
+
252
+ def 接口port_request_info信息 正文
253
+ tag = 正文["port-request-info"] ? "port-request-info" : "port-request-info"
254
+ 接口pri表 = {}
255
+ if tag == "port-request-info"
256
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^interface (.)*/, /^\n/
257
+ head,tail = "<#{tag}>\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
258
+ fragments.each{|frag| 接口pri表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
259
+ end
260
+ 接口pri表
261
+ end
262
+
263
+ def 接口arp信息 正文
264
+ tag = 正文["arp"] ? "arp" : "arp"
265
+ 接口arp表 = {}
266
+ if tag == "arp"
267
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
268
+ head,tail = "<#{tag}>\narp\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
269
+ fragments.each{|frag| 接口arp表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
270
+ end
271
+ 接口arp表
272
+ end
273
+
274
+ def 接口nd信息 正文
275
+ tag = 正文["nd"] ? "nd" : "nd"
276
+ 接口nd表 = {}
277
+ if tag == "nd"
278
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^interface (.)*/, /^\$/
279
+ head,tail = "<#{tag}>\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
280
+ fragments.each{|frag| 接口nd表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
281
+ end
282
+ 接口nd表
283
+ end
284
+
285
+ def 接口interface_performance信息 正文
286
+ tag = 正文["interface-performance"] ? "interface-performance" : "interface-performance"
287
+ 接口iperf表 = {}
288
+ if tag == "interface-performance"
289
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^interface (.)*/, /^\$/
290
+ head,tail = "<#{tag}>\nintf-statistics\n#{context.split("\n")[0]}\n","!\n</#{tag}>"
291
+ fragments.each{|frag| 接口iperf表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
292
+ end
293
+ 接口iperf表
294
+ end
295
+
296
+ def 接口ospf信息 正文
297
+ tag = 正文["ospfv2"] ? "ospfv2" : "ospfv2"
298
+ 接口ospfv2表 = {}
299
+ if tag == "ospfv2"
300
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^router ospf (.)*/, /^\!/
301
+ paragraphs = TextAbstract.match_paragraph(context, /^router ospf (.)*/,/^\$/)
302
+ paragraphs.each do|para|
303
+ ospf = /^router ospf (.)*/.match(para)[0].to_s.strip
304
+ areas = TextAbstract.match_paragraph(para, /^ area (.)*/, /^ \$/)
305
+ areas.each do|area|
306
+ area_id = /^ area (.)*/.match(area)[0].to_s.rstrip
307
+ intfs = TextAbstract.match_paragraph(area, /^ interface (.)*/, /^ \$/)
308
+ intfs.each{|intf| 接口ospfv2表['ospfv2+'+/interface (.)*/.match(intf)[0].to_s.strip] = "<#{tag}>\n#{ospf}\n#{area_id}\n#{intf}\n $\n$\n!\n</#{tag}>"}
309
+ end
310
+ end
311
+ end
312
+
313
+ tag = 正文["ospfv3"] ? "ospfv3" : "ospfv3"
314
+ 接口ospfv3表 = {}
315
+ if tag == "ospfv3"
316
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ipv6 router ospf (.)*/, /^\!/
317
+ paragraphs = TextAbstract.match_paragraph(context, /^ipv6 router ospf (.)*/,/^\$/)
318
+ paragraphs.each do|para|
319
+ ospf = /^router ospf (.)*/.match(para)[0].to_s.strip
320
+ areas = TextAbstract.match_paragraph(para, /^ area (.)*/, /^ \$/)
321
+ areas.each do|area|
322
+ area_id = /^ area (.)*/.match(area)[0].to_s.rstrip
323
+ intfs = TextAbstract.match_paragraph(area, /^ interface (.)*/, /^ \$/)
324
+ intfs.each{|intf| 接口ospfv3表['ospfv3+'+/interface (.)*/.match(intf)[0].to_s.strip] = "<#{tag}>\n#{ospf}\n#{area_id}\n#{intf}\n $\n$\n!\n</#{tag}>"}
325
+ end
326
+ end
327
+ end
328
+
329
+ 接口ospfv2表.merge(接口ospfv3表)
330
+ end
331
+
332
+ def 接口urpf信息 正文
333
+ tag = 正文["URPF"] ? "URPF" : "urpf"
334
+ 接口urpf表 = {}
335
+ if tag == "URPF"
336
+ (正文[tag]||"").split("\n!")\
337
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!="\n!"}\
338
+ .compact.each{|接口|接口urpf表[/interface (.)*/.match(接口)[0].to_s.strip]=接口}
339
+ elsif tag == "urpf"
340
+ (正文[tag]||"").split("\n$")\
341
+ .collect{|l|"<#{tag}>\n"+l.strip+"\n!\n</#{tag}>" if l!="\n!"}\
342
+ .compact.each{|接口|接口urpf表[/interface (.)*/.match(接口)[0].to_s.strip]=接口}
343
+ end
344
+ 接口urpf表
345
+ end
346
+
347
+ def 接口am信息 正文
348
+ tag = 正文["AM"] ? "AM" : "am"
349
+ 接口am表 = {}
350
+ if tag == "AM"
351
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
352
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(!\n)
353
+ fragments.each{|frag|接口am表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
354
+ elsif tag == "am"
355
+ context,fragments = TextAbstract.draw_fragments (正文[tag]||""), /^ interface (.)*/, /^ \$/
356
+ head,tail = "<#{tag}>\n#{context[0..-3]}\n","!\n</#{tag}>" # context tail(!\n)
357
+ fragments.each{|frag|接口am表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
358
+ end
359
+ 接口am表
360
+ end
361
+
362
+ def 接口uim信息 正文
363
+ tag = 正文["UIM"] ? "UIM" : "uim"
364
+ 接口uim表 = {}
365
+ if tag =="UIM"
366
+ za,vcc = TextAbstract.draw_fragments (正文[tag]||""), /^vcc\-configuration/, /^\!/
367
+ za,vbui= TextAbstract.draw_fragments (正文[tag]||""), /^vbui\-configuration/, /^\!/
368
+ # vcc
369
+ context,fragments = TextAbstract.draw_fragments vcc.join, /^ interface (.)*/, /^ \$/
370
+ head,tail = "<#{tag}>\n#{context[0..-3]}","!\n</#{tag}>" # context tail(\n!\n)
371
+ fragments.each{|frag|接口uim表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
372
+ # vbui
373
+ context,fragments = TextAbstract.draw_fragments vbui.join, /^ interface (.)*/, /^ \$/
374
+ head,tail = "<#{tag}>\n#{context[0..-3]}","!\n</#{tag}>" # context tail(\n!\n)
375
+ fragments.each{|frag|接口uim表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
376
+ elsif tag =="uim"
377
+ za,vcc = TextAbstract.draw_fragments (正文[tag]||""), /^vcc\-configuration/, /^\$/
378
+ za,vbui= TextAbstract.draw_fragments (正文[tag]||""), /^vbui\-configuration/, /^\$/
379
+ # vcc
380
+ context,fragments = TextAbstract.draw_fragments vcc.join, /^ interface (.)*/, /^ \$/
381
+ head,tail = "<#{tag}>\n#{context[0..-3]}","!\n</#{tag}>" # context tail(\n!\n)
382
+ fragments.each{|frag|接口uim表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
383
+ # vbui
384
+ context,fragments = TextAbstract.draw_fragments vbui.join, /^ interface (.)*/, /^ \$/
385
+ head,tail = "<#{tag}>\n#{context[0..-3]}","!\n</#{tag}>" # context tail(\n!\n)
386
+ fragments.each{|frag|接口uim表[/interface (.)*/.match(frag)[0].to_s.strip] = head+frag+tail}
387
+ end
388
+ 接口uim表
389
+ end
390
+
391
+ # func: 端口应用QoS模板
392
+ def 接口QoS 正文
393
+ # QoS有一部分在流策略,这里只解析car限速
394
+ tag = 正文["CAR"] ? 'CAR' : 'car'
395
+ cars = {};current = nil; cars[current] = {}
396
+ lines = 正文[tag].to_s.split("\n")
397
+ lines.each_with_index do|line, index|
398
+ if line.include?('interface')
399
+ current = line.split('interface ').last
400
+ cars[current] ||= {}
401
+ end
402
+ if line.include?('rate-limit ')
403
+ if line.size==80 && lines[index+1][0..1]!=' '
404
+ words = (line+lines[index+1]).split(" ")
405
+ else
406
+ words = line.split(" ")
407
+ end
408
+ cars[current]['direction'] = words[words.index('rate-limit')+1]
409
+ cars[current]['cir'] = words.index('cir') ? words[(words.index('cir')+1)..(words.index('cir')+2)].join : ''
410
+ cars[current]['pir'] = words.index('pir') ? words[(words.index('pir')+1)..(words.index('pir')+2)].join : ''
411
+ cars[current]['cbs'] = words.index('cbs') ? words[words.index('cbs')+1]+'bytes' : ''
412
+ cars[current]['pbs'] = words.index('pbs') ? words[words.index('pbs')+1]+'bytes' : ''
413
+ cars[current]['action'] = [
414
+ words.index('conform-action') ? words[words.index('conform-action')+1] : '',
415
+ words.index('exceed-action') ? words[words.index('exceed-action')+1] : '',
416
+ words.index('violate-action') ? words[words.index('violate-action')+1] : ''
417
+ ]
418
+ end
419
+ end
420
+ cars.delete(nil)
421
+ cars
422
+ end
423
+
424
+ # func: 端口应用流量模板
425
+ def 接口流策略 正文
426
+ tag = 正文["hqos"] ? 'hqos' : 'hqos'
427
+ svc_policy = {}
428
+ lines = 正文[tag].to_s.split("\n")
429
+ lines.each_with_index do|line, index|
430
+ if line.include?('service-policy')
431
+ words = line.split(' ')
432
+ interface = words[words.index('service-policy')+1]
433
+ direction = words[words.index('service-policy')+2]
434
+ template = words[words.index('service-policy')+3]
435
+ svc_policy[interface] ||= {}
436
+ svc_policy[interface][direction] = template
437
+ end
438
+ end
439
+ svc_policy
440
+ end
441
+
442
+ # func: 端口统计功能
443
+ def 接口统计 正文
444
+ tag = 正文["interface-performance"] ? 'interface-performance' : 'interface-performance'
445
+ intf_perf = {}; current = nil; intf_perf[current] = {}
446
+ lines = 正文[tag].to_s.split("\n")
447
+ lines.each_with_index do|line, index|
448
+ if line.include?('interface-performance')
449
+ current = line.split('interface ').last
450
+ end
451
+ if line.include?('traffic-statistics enable')
452
+ intf_perf[current] = :statistic_enable
453
+ end
454
+ end
455
+ intf_perf.delete(nil)
456
+ intf_perf
457
+ end
458
+
459
+ # func: 端口URPF功能
460
+ def 接口URPF 正文
461
+ 接口urpf表 = self.接口urpf信息 正文
462
+ urpf = {}
463
+ 接口urpf表.each do|intf, conf|
464
+ words = conf.split(' ')
465
+ addr = words.join.include?('ipv4') ? 'ipv4' : 'ipv6'
466
+ mode = words[words.index('reachable-via')+1]=='any' ? 'loose' : 'strict'
467
+ acl = words.index('acl-name') ? words[words.index('acl-name')+1] : 'none'
468
+ ignr = words.include?('ignore-default-route') ? 'ignore-default-route' : 'none'
469
+ urpf[intf.split(' ').last] = {'addr'=>addr, 'mode'=>mode, 'acl'=>acl, 'ignore'=>ignr}
470
+ end
471
+ urpf
472
+ end
473
+
474
+ # func: 端口接入类型
475
+ def 接口接入类型 正文
476
+ 接口uim表 = self.接口uim信息 正文
477
+ access_type = {}
478
+ 接口uim表.each do|intf, conf|
479
+ type = conf.include?('ip-access-type') ? conf.split('ip-access-type ').last.split("\n").first : nil
480
+ access_type[intf.split(' ').last] = type if type
481
+ end
482
+ access_type
483
+ end
484
+
485
+ def 特殊接口配置 接口集合
486
+ 特殊接口集合 = []
487
+ 接口集合.each do|key,configs|
488
+ 特殊接口集合 << [key]+configs if key.include?('loopback') || key.include?('null') || \
489
+ key.include?('extimer') || key.include?('vbui') || key.include?('spi') || \
490
+ key.include?('gcvi') || key.include?('guvi') || key.include?('mgmt_eth') || \
491
+ key.include?('qx_eth') || key.include?('qx') || key.include?('gre_tunnel')
492
+ end
493
+ 特殊接口集合
494
+ end
495
+
496
+ def 物理接口配置 接口集合,特殊接口集合=nil
497
+ 物理接口集合 = []
498
+ 例外 = (特殊接口集合 ? 特殊接口集合 : (self.特殊接口配置 接口集合)).collect{|c|c[0]}
499
+ 接口集合.each do|key,configs|
500
+ 物理接口集合 << [key]+configs unless 例外.include?(key) || key.include?('.')
501
+ end
502
+ 物理接口集合
503
+ end
504
+
505
+ def 子接口配置 接口集合,特殊接口集合=nil
506
+ 子接口集合 = []
507
+ 例外 = (特殊接口集合 ? 特殊接口集合 : (self.特殊接口配置 接口集合)).collect{|c|c[0]}
508
+ 接口集合.each do|key,configs|
509
+ 子接口集合 << [key]+configs if !例外.include?(key) && key.include?('.')
510
+ end
511
+ 子接口集合
512
+ end
513
+
514
+ def 接口分捡 接口集合
515
+ 特殊接口集合 = self.特殊接口配置 接口集合
516
+ 物理接口集合 = self.物理接口配置 接口集合,特殊接口集合
517
+ 子接口集合 = self.子接口配置 接口集合,特殊接口集合
518
+ return 物理接口集合,子接口集合,特殊接口集合
519
+ end
520
+
521
+
522
+ #####################################################################################################
523
+ # 端口描述信息相关
524
+ #####################################################################################################
525
+
526
+ # func: 根据一个端口的描述信息,给出其格式化的类型、连接符、端口编号
527
+ def 端口识别 描述
528
+ 描述 = 描述[0] if 描述.instance_of?(Array) # M6000取接口配置中名称部分 [name,<tag>...</tag>,...]
529
+ type = /xgei|gei|smartgroup|loopback|extimer|vbui|null|guvi|gcvi|mgmt_eth|vei|spi|flexe_client|flexe_group|ptp|gps|qx_eth|qx|bvi|pw|subvlan/.match(描述)
530
+ 类型 = type ? type.to_s : '未知类型'
531
+ port = /(\d+|\/|\.)*(\d+)/.match(描述.split(类型).join)
532
+ 端口 = port ? port.to_s : '未知端口'
533
+ 端口 = '' if 类型=='mgmt_eth'
534
+ 连接符 = if ['smartgroup','loopback','vbui','null','mgmt_eth','vei','flexe_client','flexe_group','qx','bvi','pw','subvlan'].include?(类型)
535
+ ''
536
+ elsif ['xgei','gei','extimer','guvi','gcvi','spi','ptp','gps','qx_eth'].include?(类型)
537
+ '-'
538
+ end
539
+ return 类型,连接符,端口
540
+ end
541
+
542
+ # func: 根据一个端口的描述信息,给出其mac地址,若无mac则返回nil
543
+ def 端口MAC 描述
544
+ 描述.each_line do|line|
545
+ if pattern = /\, address is (.+)/.match(line)
546
+ matcher = /[\d|A-F|a-f]+\.[\d|A-F|a-f]+\.[\d|A-F|a-f]+/.match(pattern[1].strip)
547
+ return pattern[1].strip if matcher.to_s==pattern[1].strip
548
+ end
549
+ end
550
+ return nil
551
+ end
552
+
553
+ # func: 根据一个端口的描述信息,给出其管理状态是打开/关闭的判断
554
+ def 端口管理状态 描述
555
+ 描述 = 描述[1..-1].join("\n") if 描述.instance_of?(Array) # M6000取接口配置中名称部分 [name,<tag>...</tag>,...]
556
+ 管理状态 = true
557
+ 描述.split("\n").each do|line|
558
+ 管理状态 = false if line.include?("shutdown") && !line.include?("no shutdown")
559
+ end
560
+ 管理状态
561
+ end
562
+
563
+ # func: 根据一个端口的配置给出其描述
564
+ def 接口描述 接口配置
565
+ 描述 = ''
566
+ 接口配置.join("\n").each_line do|line| if line.strip[0..10]=='description'
567
+ 描述 = line.split('description')[1..-1].join().strip; break
568
+ end end
569
+ 描述.to_s
570
+ end
571
+
572
+ # func: 根据一个端口的配置给出其配置的接口地址
573
+ def 接口地址 接口配置
574
+ 地址集 = []
575
+ 接口配置.join("\n").each_line do|line|
576
+ if line.strip[0..9]=='ip address'
577
+ 地址集 << line.gsub('secondary','').split('ip address')[-1].strip.split(' ')
578
+ end
579
+ if line.strip[0..11]=='ipv6 address'
580
+ 地址集 << line.gsub('secondary','').split('ipv6 address')[-1].strip.split('/')
581
+ end
582
+ end
583
+ 地址集
584
+ end
585
+
586
+ # func: 根据一个端口的配置给出其开关状态(配置层面的"端口管理状态")
587
+ def 接口开关 接口配置
588
+ 描述 = '' # for phy_if is shutdown, for sub_if,smartgroup are open
589
+ 接口配置.join("\n").each_line do|line|
590
+ if line.include?("no shutdown") and !line.include?('description')
591
+ 描述 = 'no shutdown'; break
592
+ end
593
+ if line.include?("smartgroup")
594
+ 描述 = 'no shutdown'; break
595
+ end
596
+ if line.include?("shutdown") and !line.include?('no') and !line.include?('description')
597
+ 描述 = 'shutdown'; break
598
+ end
599
+ end
600
+ 描述
601
+ end
602
+
603
+ # func: 根据一个端口的配置给出其关联的vpn实例
604
+ def 接口vpn实例 接口配置
605
+ 实例 = ''
606
+ 接口配置.join("\n").each_line do|line|
607
+ 实例 = "vpn-inst:" + /vrf forwarding .+/.match(line).to_s.split(" ")[-1] if /vrf forwarding .+/.match(line)
608
+ end
609
+ 实例
610
+ end
611
+
612
+
613
+ #####################################################################################################
614
+ # 聚合接口判定相关
615
+ #####################################################################################################
616
+
617
+ # func: 根据一个接口的描述信息,给出其所属聚合接口的信息,若非聚合端口返回空
618
+ def 聚合接口判定 配置
619
+ 配置.join.split("\n").each do|描述|
620
+ if 描述.include?("smartgroup") && 描述.include?("mode") &&
621
+ !描述.include?("description") && !self.端口识别(配置).join.include?("smartgroup")
622
+ return {self.端口识别(配置).join=>"smartgroup"+描述.strip.split(" ")[1]}
623
+ end
624
+ end;{}
625
+ end
626
+
627
+ # func: 给出聚合接口和物理接口的集合,通过计算找出所有聚合接口的集合
628
+ def 聚合接口分捡 聚合接口,物理接口集合
629
+ 聚合接口 = self.端口识别(聚合接口)
630
+ 聚合接口集合 = [聚合接口.join]
631
+ 物理接口集合.each do|物理接口| 物理接口.join.each_line do|line|
632
+ if line.include?("smartgroup") && !line.include?("description")
633
+ aggrnum = line.strip.split(" ")[1]
634
+ 聚合接口集合 << self.端口识别(物理接口).join if ['smartgroup','',aggrnum].join==聚合接口.join
635
+ end
636
+ end end
637
+ 聚合接口集合
638
+ end
639
+
640
+ # func: 根据一个接口的描述信息,给出其所属聚合接口的逻辑接口,若无返回空
641
+ def 聚合逻辑接口 配置
642
+ 配置.join.split("\n").each do|描述|
643
+ if 描述.include?("nas logic-interface")
644
+ num = 描述.split(" ")
645
+ return [num[-5],num[-3],num[-1]].join('/')
646
+ end
647
+ end
648
+ return nil
649
+ end
650
+
651
+ #####################################################################################################
652
+ # 接口VLAN相关
653
+ # 对接口vlan配置的解析
654
+ # dot1q : [vlan, ...]
655
+ # qinq : [[pvlan, (cvlan..cvlan)], [pvlan, cvlan], ...]
656
+ # vlan : [(cvlan..cvlan), cvlan, ...]
657
+ #####################################################################################################
658
+ def vlan分捡 接口配置
659
+ vlan = {}
660
+ vlan_part = 接口配置.find{|配置|(配置.include?("<VLAN>")&&配置.include?("</VLAN>")) || (配置.include?("<vlan>")&&配置.include?("</vlan>"))} || ""
661
+ vlan_part.each_line do|line| next if line.include?('no')
662
+ if pattern = /encapsulation-dot1q range (.+)/.match(line)
663
+ dot1q = eval(pattern[1].to_s.gsub('-','..')) # Range or Integer
664
+ vlan['dot1q'] ||= [];vlan['dot1q'] << dot1q;next
665
+ end
666
+ if pattern = /encapsulation-dot1q (\d+)/.match(line)
667
+ dot1q = eval(pattern[1].to_s)
668
+ vlan['dot1q'] ||= [];vlan['dot1q'] << dot1q;next
669
+ end
670
+ if pattern = /qinq range internal-vlan-range (.+) external-vlan-range (.+)/.match(line)
671
+ vlan['qinq'] ||= []
672
+ exvlan = eval(pattern[2].to_s.gsub('-','..')) # Range or Integer
673
+ invlan = eval(pattern[1].to_s.gsub('-','..'))
674
+ if exvlan.instance_of?(Range)
675
+ exvlan.each{|exv|vlan['qinq'] << [exv,invlan]}
676
+ elsif exvlan.instance_of?(Fixnum)
677
+ vlan['qinq'] << [exvlan,invlan]
678
+ end;next
679
+ end
680
+ if pattern = /qinq internal-vlanid (\d+) external-vlanid (\d+)/.match(line)
681
+ qinq = [pattern[2].to_i,pattern[1].to_i]
682
+ vlan['qinq'] ||= [];vlan['qinq'] << qinq;next
683
+ end
684
+ end
685
+ return vlan # {vlan:[ int|range ] qinq:[ [int,int|range] ] dot1q:[ int ]}
686
+ end
687
+
688
+ def vlan统计 name,物理接口集合,子接口集合
689
+ bas子接口数据库,聚合接口表 = {},[]
690
+ 聚合接口集合 = 物理接口集合.select{|物理接口|self.端口识别(物理接口)[0]=='smartgroup'}
691
+ 聚合接口表 += 聚合接口集合.collect{|聚合接口|self.聚合接口分捡(聚合接口,物理接口集合)}
692
+
693
+ 子接口集合.each do|接口配置|
694
+ 物理接口名称 = self.端口识别(接口配置).join.split(".")[0]
695
+ 物理接口 = 物理接口集合.find{|物理接口|物理接口[0].split(" ")[1]==(物理接口名称)}
696
+ next unless self.端口管理状态(物理接口) # 物理接口关闭的不统计
697
+ next unless self.端口管理状态(接口配置) # 子接口关闭的不统计
698
+
699
+ vlan配置 = {}
700
+ self.vlan分捡(接口配置).each do|type,data|
701
+ if type=='vlan' || type=='dot1q'
702
+ vlan配置[4096] ||= []; vlan配置[4096] += data # 用4096表示单层vlan
703
+ elsif type=='qinq'
704
+ data.each{|pvlan,cvlan|vlan配置[pvlan] ||= []; vlan配置[pvlan] << cvlan}
705
+ end
706
+ end
707
+
708
+ 子接口名称 = self.端口识别(接口配置)
709
+ if 子接口名称[0].include?("gei")
710
+ # 子接口索引 = ["eth--"+子接口名称[-1].split(".")[0].split('/')[-3..-1].join(',')] # AIBOS风格
711
+ 子接口索引 = [子接口名称.join.split(".")[0]] # 原生风格
712
+ end
713
+ if 子接口名称[0].include?("smartgroup") &&
714
+ 聚合接口组 = 聚合接口表.find{|聚合接口组|聚合接口组.include?(子接口名称.join.split('.')[0])}
715
+ 聚合接口的等效名称 = 聚合接口组.clone;
716
+ # 聚合接口的等效名称.delete(子接口名称.join.split('.')[0]) # 除了smartgroup自身,为所有等效接口创建 # 是否保留smartgroup是个争议
717
+ 子接口索引 = 聚合接口的等效名称.map do|等效名称|
718
+ # "eth--"+self.端口识别(等效名称)[-1].split(".")[0].split('/')[-3..-1].join(',') # AIBOS风格
719
+ self.端口识别(等效名称).join.split(".")[0] # 原生风格
720
+ end
721
+ # 子接口索引 << "trunk--"+[255,0,子接口名称[2].split('.')[0]].join(',') # AIBOS风格
722
+ 子接口索引 << 子接口名称.join.split(".")[0] # 原生风格
723
+ end
724
+
725
+ bas子接口数据库[name] ||= {}
726
+ 子接口索引.each do|索引|
727
+ bas子接口数据库[name][索引] ||= {}
728
+ vlan配置.each do|pv,cv|
729
+ bas子接口数据库[name][索引][pv] ||= []
730
+ bas子接口数据库[name][索引][pv] += cv
731
+ bas子接口数据库[name][索引][pv].uniq!
732
+ end
733
+ end
734
+ end
735
+ return bas子接口数据库
736
+ end
737
+
738
+
739
+ #####################################################################################################
740
+ # 接口相关统计信息的处理
741
+ #####################################################################################################
742
+
743
+ # gei-x/x/x.00000xxx => gei-x/x/x.xxx
744
+ # 一些统计场合子接口会补前置0,这里可以将其去掉
745
+ def 端口去0 描述
746
+ if 描述.include?("00") && 描述.include?('.')
747
+ 接口,子接口 = 描述.split(".")
748
+ [接口,子接口.to_i.to_s].join(".")
749
+ else
750
+ 描述
751
+ end
752
+ end
753
+
754
+ # 针对show intf-statistics utilization phy-interface-only
755
+ def 统计接口 文本
756
+ 文本.split("\n").inject([]) do|表格, 行|
757
+ 表格 << 行.split(" ") if 行.include?("gei-") or 行.include?("smartgroup") or 行.include?("spi-")
758
+ 表格 # [interface, in-bps, in-uti, out-bps, out-uti, in-errors, in-dbm, out-dbm]
759
+ end
760
+ end
761
+ end
762
+ ```