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