cisco_node_utils 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +113 -0
- data/Rakefile +4 -0
- data/cisco_node_utils.gemspec +30 -0
- data/lib/cisco_node_utils.rb +33 -0
- data/lib/cisco_node_utils/README_YAML.md +333 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +92 -0
- data/lib/cisco_node_utils/command_reference.rb +415 -0
- data/lib/cisco_node_utils/command_reference_common.yaml +845 -0
- data/lib/cisco_node_utils/command_reference_n3064.yaml +13 -0
- data/lib/cisco_node_utils/command_reference_n7k.yaml +48 -0
- data/lib/cisco_node_utils/command_reference_n9k.yaml +35 -0
- data/lib/cisco_node_utils/configparser_lib.rb +196 -0
- data/lib/cisco_node_utils/interface.rb +501 -0
- data/lib/cisco_node_utils/interface_ospf.rb +241 -0
- data/lib/cisco_node_utils/node.rb +673 -0
- data/lib/cisco_node_utils/platform.rb +184 -0
- data/lib/cisco_node_utils/platform_info.rb +58 -0
- data/lib/cisco_node_utils/platform_info.yaml +10 -0
- data/lib/cisco_node_utils/router_ospf.rb +96 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +258 -0
- data/lib/cisco_node_utils/snmpcommunity.rb +91 -0
- data/lib/cisco_node_utils/snmpgroup.rb +55 -0
- data/lib/cisco_node_utils/snmpserver.rb +150 -0
- data/lib/cisco_node_utils/snmpuser.rb +342 -0
- data/lib/cisco_node_utils/tacacs_server.rb +175 -0
- data/lib/cisco_node_utils/tacacs_server_host.rb +128 -0
- data/lib/cisco_node_utils/version.rb +17 -0
- data/lib/cisco_node_utils/vlan.rb +153 -0
- data/lib/cisco_node_utils/vtp.rb +127 -0
- data/lib/cisco_node_utils/yum.rb +84 -0
- data/tests/basetest.rb +93 -0
- data/tests/ciscotest.rb +136 -0
- data/tests/cmd_config.yaml +51 -0
- data/tests/cmd_config_invalid.yaml +16 -0
- data/tests/test_all_cisco.rb +46 -0
- data/tests/test_command_config.rb +192 -0
- data/tests/test_command_reference.rb +222 -0
- data/tests/test_interface.rb +1017 -0
- data/tests/test_interface_ospf.rb +763 -0
- data/tests/test_interface_svi.rb +267 -0
- data/tests/test_interface_switchport.rb +722 -0
- data/tests/test_node.rb +108 -0
- data/tests/test_node_ext.rb +450 -0
- data/tests/test_platform.rb +188 -0
- data/tests/test_router_ospf.rb +164 -0
- data/tests/test_router_ospf_vrf.rb +753 -0
- data/tests/test_snmpcommunity.rb +344 -0
- data/tests/test_snmpgroup.rb +71 -0
- data/tests/test_snmpserver.rb +443 -0
- data/tests/test_snmpuser.rb +803 -0
- data/tests/test_tacacs_server.rb +388 -0
- data/tests/test_tacacs_server_host.rb +391 -0
- data/tests/test_vlan.rb +264 -0
- data/tests/test_vtp.rb +319 -0
- data/tests/test_yum.rb +106 -0
- metadata +188 -0
@@ -0,0 +1,763 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Cisco and/or its affiliates.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require File.expand_path("../ciscotest", __FILE__)
|
16
|
+
require File.expand_path("../../lib/cisco_node_utils/cisco_cmn_utils", __FILE__)
|
17
|
+
require File.expand_path("../../lib/cisco_node_utils/interface_ospf", __FILE__)
|
18
|
+
require File.expand_path("../../lib/cisco_node_utils/router_ospf", __FILE__)
|
19
|
+
|
20
|
+
include Cisco
|
21
|
+
|
22
|
+
class TestInterfaceOspf < CiscoTestCase
|
23
|
+
def routerospf_router_destroy(router)
|
24
|
+
router.destroy
|
25
|
+
end
|
26
|
+
|
27
|
+
def routerospf_routers_destroy(routers)
|
28
|
+
routers.each { |name, router|
|
29
|
+
routerospf_router_destroy(router)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def interface_switchport_enable(ifname, enable)
|
34
|
+
@device.cmd("configure terminal")
|
35
|
+
@device.cmd("interface #{ifname}")
|
36
|
+
if enable == true
|
37
|
+
@device.cmd("switchport")
|
38
|
+
else
|
39
|
+
@device.cmd("no switchport")
|
40
|
+
end
|
41
|
+
@device.cmd("end")
|
42
|
+
node.cache_flush
|
43
|
+
end
|
44
|
+
|
45
|
+
def interfaceospf_interface_destroy(interface)
|
46
|
+
interface.destroy
|
47
|
+
end
|
48
|
+
|
49
|
+
def interfaceospf_interfaces_destroy(interfaces)
|
50
|
+
interfaces.each { |name, interface|
|
51
|
+
interfaceospf_interface_destroy(interface)
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_interfaceospf_match_line(name, pattern)
|
56
|
+
s = @device.cmd("show run interface all | " +
|
57
|
+
"sec \"interface .#{name[1..-1]}$\" | no-more")
|
58
|
+
line = pattern.match(s)
|
59
|
+
line
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_routerospf(ospfname="ospfTest")
|
63
|
+
@device.cmd("configure terminal")
|
64
|
+
@device.cmd("feature ospf")
|
65
|
+
@device.cmd("end")
|
66
|
+
node.cache_flush
|
67
|
+
routerospf = RouterOspf.new(ospfname, false)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_interfaceospf(routerospf, ifname=interfaces[0], area="0.0.0.0")
|
71
|
+
interface_switchport_enable(ifname, false)
|
72
|
+
interfaceospf = InterfaceOspf.new(ifname, routerospf.name, area)
|
73
|
+
end
|
74
|
+
|
75
|
+
def interface_ethernet_default(ethernet_id=interfaces_id[0])
|
76
|
+
@device.cmd("configure terminal")
|
77
|
+
@device.cmd("default interface ethernet #{ethernet_id}")
|
78
|
+
@device.cmd("end")
|
79
|
+
node.cache_flush
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_interfaceospf_collection_empty
|
83
|
+
@device.cmd("configure terminal")
|
84
|
+
@device.cmd("no feature ospf")
|
85
|
+
@device.cmd("feature ospf")
|
86
|
+
@device.cmd("router ospf TestOSPF")
|
87
|
+
@device.cmd("end")
|
88
|
+
node.cache_flush
|
89
|
+
|
90
|
+
routers = RouterOspf.routers()
|
91
|
+
routers.each do |name, router|
|
92
|
+
interfaces = InterfaceOspf.interfaces(router.name)
|
93
|
+
assert_empty(interfaces,
|
94
|
+
"InterfaceOspf collection is not empty")
|
95
|
+
end
|
96
|
+
routerospf_routers_destroy(routers)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_interfaceospf_collection_not_empty
|
100
|
+
ifname1 = interfaces[1].downcase
|
101
|
+
ifname2 = interfaces[2].downcase
|
102
|
+
ospf1 = "TestOSPF"
|
103
|
+
ospf2 = "bxb300"
|
104
|
+
# pre-configure
|
105
|
+
interface_switchport_enable(ifname1, false)
|
106
|
+
interface_switchport_enable(ifname2, false)
|
107
|
+
@device.cmd("configure terminal")
|
108
|
+
@device.cmd("no feature ospf")
|
109
|
+
@device.cmd("feature ospf")
|
110
|
+
@device.cmd("router ospf #{ospf1}")
|
111
|
+
@device.cmd("interface #{ifname1}")
|
112
|
+
@device.cmd("ip router ospf #{ospf1} area 0.0.0.0")
|
113
|
+
@device.cmd("router ospf #{ospf2}")
|
114
|
+
@device.cmd("interface #{ifname2}")
|
115
|
+
@device.cmd("ip router ospf #{ospf2} area 10.6.6.1")
|
116
|
+
@device.cmd("end")
|
117
|
+
node.cache_flush
|
118
|
+
|
119
|
+
routers = RouterOspf.routers()
|
120
|
+
# validate the collection
|
121
|
+
routers.each do |name, router|
|
122
|
+
interfaces = InterfaceOspf.interfaces(router.name)
|
123
|
+
refute_empty(interfaces,
|
124
|
+
"InterfaceOspf collection is empty")
|
125
|
+
assert_equal(1, interfaces.size(),
|
126
|
+
"InterfaceOspf collection (#{interfaces}) size is not 1")
|
127
|
+
interfaces.each do | ifname, interface|
|
128
|
+
pattern = (/\s+ip router ospf #{router.name} area #{interface.area}/)
|
129
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
130
|
+
refute_nil(line, "Error: ip router ospf #{router.name} " +
|
131
|
+
"area #{interface.area} not found under #{ifname}")
|
132
|
+
# using default check, since not configured anything
|
133
|
+
assert_equal(node.config_get_default("interface_ospf", "cost"),
|
134
|
+
interface.cost,
|
135
|
+
"Error: get cost failed")
|
136
|
+
assert_equal(node.config_get_default("interface_ospf",
|
137
|
+
"hello_interval"),
|
138
|
+
interface.hello_interval,
|
139
|
+
"Error: get hello interval failed")
|
140
|
+
assert_equal(node.config_get_default("interface_ospf",
|
141
|
+
"dead_interval"),
|
142
|
+
interface.dead_interval,
|
143
|
+
"Error: get dead interval failed")
|
144
|
+
assert_equal(node.config_get_default("interface_ospf",
|
145
|
+
"passive_interface"),
|
146
|
+
interface.passive_interface,
|
147
|
+
"Error: passive interface get failed")
|
148
|
+
assert_equal(node.config_get_default("interface_ospf",
|
149
|
+
"message_digest"),
|
150
|
+
interface.message_digest,
|
151
|
+
"Error: message digest get failed")
|
152
|
+
assert_equal(node.config_get_default("interface_ospf",
|
153
|
+
"message_digest_key_id"),
|
154
|
+
interface.message_digest_key_id,
|
155
|
+
"Error: message digest key get failed")
|
156
|
+
end
|
157
|
+
interfaceospf_interfaces_destroy(interfaces)
|
158
|
+
end
|
159
|
+
routerospf_routers_destroy(routers)
|
160
|
+
interface_ethernet_default(interfaces_id[2])
|
161
|
+
interface_ethernet_default(interfaces_id[1])
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_interfaceospf_create_routerospf_nil
|
165
|
+
assert_raises(TypeError) do
|
166
|
+
ospf = InterfaceOspf.new(interfaces[0], nil, "0.0.0.0")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_interfaceospf_create_interface_name_zero_length
|
171
|
+
name = "ospfTest"
|
172
|
+
ospf = RouterOspf.new(name)
|
173
|
+
assert_raises(ArgumentError) do
|
174
|
+
interface = InterfaceOspf.new("", ospf.name, "0.0.0.0")
|
175
|
+
end
|
176
|
+
routerospf_router_destroy(ospf)
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_interfaceospf_create_interface_area_zero_length
|
180
|
+
name = "ospfTest"
|
181
|
+
ospf = RouterOspf.new(name)
|
182
|
+
assert_raises(ArgumentError) do
|
183
|
+
interface = InterfaceOspf.new(interfaces[0], ospf.name, "")
|
184
|
+
end
|
185
|
+
routerospf_router_destroy(ospf)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_routerospf_create_valid
|
189
|
+
ospf = create_routerospf
|
190
|
+
ifname = interfaces[1]
|
191
|
+
area = "0.0.0.0"
|
192
|
+
interface_switchport_enable(ifname, false)
|
193
|
+
interface = InterfaceOspf.new(ifname, ospf.name, area)
|
194
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{area}/)
|
195
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
196
|
+
refute_nil(line, "Error: 'ip router ospf #{ospf.name} area #{area}' " +
|
197
|
+
"not configured")
|
198
|
+
assert_equal(ifname.downcase, interface.interface.name,
|
199
|
+
"Error: interface name get value mismatch ")
|
200
|
+
assert_equal(area, interface.area,
|
201
|
+
"Error: area get value mismatch ")
|
202
|
+
interfaceospf_interface_destroy(interface)
|
203
|
+
routerospf_router_destroy(ospf)
|
204
|
+
interface_ethernet_default(interfaces_id[1])
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_interfaceospf_destroy
|
208
|
+
ifname = interfaces[1]
|
209
|
+
area = "0.0.0.0"
|
210
|
+
ospf = create_routerospf
|
211
|
+
interface = create_interfaceospf(ospf, ifname, area)
|
212
|
+
interface.destroy
|
213
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{area}/)
|
214
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
215
|
+
assert_nil(line, "Error: 'ip router ospf #{ospf.name} area #{area}' " +
|
216
|
+
"not destroyed")
|
217
|
+
# check all the attributes are set to default.
|
218
|
+
pattern = (/^\s+ip ospf cost \S+/)
|
219
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
220
|
+
assert_nil(line,
|
221
|
+
"Error: 'ip ospf #{ospf.name} cost' not removed")
|
222
|
+
|
223
|
+
pattern = (/^\s+ip ospf hello-interval \S+/)
|
224
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
225
|
+
assert_nil(line,
|
226
|
+
"Error: 'ip ospf #{ospf.name} hello-interval' not removed")
|
227
|
+
|
228
|
+
# with default CLI still shows the value
|
229
|
+
pattern = (/^\s+ip ospf dead-interval \S+/)
|
230
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
231
|
+
assert_nil(line,
|
232
|
+
"Error: 'ip ospf #{ospf.name} dead-interval' not removed")
|
233
|
+
|
234
|
+
pattern = (/^\s+ip ospf passive-interface/)
|
235
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
236
|
+
assert_nil(line,
|
237
|
+
"Error: 'ip ospf #{ospf.name} passive interface' not removed")
|
238
|
+
|
239
|
+
routerospf_router_destroy(ospf)
|
240
|
+
interface_ethernet_default(interfaces_id[1])
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_routerospf_get_parent
|
244
|
+
ospf = create_routerospf
|
245
|
+
interface = create_interfaceospf(ospf)
|
246
|
+
assert_equal(ospf.name, interface.ospf_name)
|
247
|
+
interfaceospf_interface_destroy(interface)
|
248
|
+
routerospf_router_destroy(ospf)
|
249
|
+
interface_ethernet_default()
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_interfaceospf_cost_invalid_range
|
253
|
+
ospf = create_routerospf
|
254
|
+
interface = create_interfaceospf(ospf)
|
255
|
+
# upper range
|
256
|
+
assert_raises(CliError) do
|
257
|
+
interface.cost = 65536
|
258
|
+
end
|
259
|
+
# lower range just removes the config.
|
260
|
+
# assert_raises(RuntimeError) do
|
261
|
+
# interface.cost = 0
|
262
|
+
# end
|
263
|
+
interfaceospf_interface_destroy(interface)
|
264
|
+
routerospf_router_destroy(ospf)
|
265
|
+
interface_ethernet_default()
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_interfaceospf_cost
|
269
|
+
ospf = create_routerospf
|
270
|
+
interface = create_interfaceospf(ospf)
|
271
|
+
cost = 1000
|
272
|
+
# set with value
|
273
|
+
interface.cost = cost
|
274
|
+
pattern = (/\s+ip ospf cost #{cost}/)
|
275
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
276
|
+
refute_nil(line,
|
277
|
+
"Error: cost missing in CLI")
|
278
|
+
assert_equal(cost, interface.cost,
|
279
|
+
"Error: cost get value mismatch")
|
280
|
+
# set default
|
281
|
+
interface.cost = interface.default_cost
|
282
|
+
pattern = (/\s+ip ospf cost(.*)/)
|
283
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
284
|
+
assert_nil(line,
|
285
|
+
"Error: default cost set failed")
|
286
|
+
interfaceospf_interface_destroy(interface)
|
287
|
+
routerospf_router_destroy(ospf)
|
288
|
+
interface_ethernet_default()
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_interfaceospf_hello_interval_invalid_range
|
292
|
+
ospf = create_routerospf
|
293
|
+
interface = create_interfaceospf(ospf)
|
294
|
+
# upper range
|
295
|
+
assert_raises(CliError) do
|
296
|
+
interface.hello_interval = 65536
|
297
|
+
end
|
298
|
+
# lower range
|
299
|
+
assert_raises(CliError) do
|
300
|
+
interface.hello_interval = 0
|
301
|
+
end
|
302
|
+
interfaceospf_interface_destroy(interface)
|
303
|
+
routerospf_router_destroy(ospf)
|
304
|
+
interface_ethernet_default()
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_interfaceospf_hello_interval
|
308
|
+
ospf = create_routerospf
|
309
|
+
interface = create_interfaceospf(ospf)
|
310
|
+
interval = 90
|
311
|
+
# set with value
|
312
|
+
interface.hello_interval = interval
|
313
|
+
pattern = (/\s+ip ospf hello-interval #{interval}/)
|
314
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
315
|
+
refute_nil(line,
|
316
|
+
"Error: hello-interval missing in CLI")
|
317
|
+
assert_equal(interval, interface.hello_interval,
|
318
|
+
"Error: hello-interval get value mismatch")
|
319
|
+
|
320
|
+
# set default, when we set default CLI does not show it
|
321
|
+
interface.hello_interval = interface.default_hello_interval
|
322
|
+
pattern = (/\s+ip ospf hello-interval(.*)/)
|
323
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
324
|
+
assert_nil(line,
|
325
|
+
"Error: default hello-interval set failed")
|
326
|
+
interfaceospf_interface_destroy(interface)
|
327
|
+
routerospf_router_destroy(ospf)
|
328
|
+
interface_ethernet_default()
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_interfaceospf_dead_interval_invalid_range
|
332
|
+
ospf = create_routerospf
|
333
|
+
interface = create_interfaceospf(ospf)
|
334
|
+
|
335
|
+
ref = cmd_ref.lookup("interface_ospf", "dead_interval")
|
336
|
+
assert(ref, "Error, reference not found for dead_interval")
|
337
|
+
|
338
|
+
# upper range
|
339
|
+
assert_raises(CliError) do
|
340
|
+
interface.dead_interval = 262141
|
341
|
+
end
|
342
|
+
# lower range
|
343
|
+
assert_raises(CliError) do
|
344
|
+
interface.dead_interval = 0
|
345
|
+
end
|
346
|
+
interfaceospf_interface_destroy(interface)
|
347
|
+
routerospf_router_destroy(ospf)
|
348
|
+
interface_ethernet_default()
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_interfaceospf_dead_interval
|
352
|
+
ospf = create_routerospf
|
353
|
+
interface = create_interfaceospf(ospf)
|
354
|
+
interval = 150
|
355
|
+
# set with value
|
356
|
+
interface.dead_interval = interval
|
357
|
+
pattern = (/\s+ip ospf dead-interval #{interval}/)
|
358
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
359
|
+
refute_nil(line,
|
360
|
+
"Error: dead-interval missing in CLI")
|
361
|
+
assert_equal(interval, interface.dead_interval,
|
362
|
+
"Error: dead-interval get value mismatch")
|
363
|
+
# set default, the CLI shows with default value
|
364
|
+
interface.dead_interval = interface.default_dead_interval
|
365
|
+
pattern = (/^\s+ip ospf dead-interval #{interface.default_dead_interval}/)
|
366
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
367
|
+
refute_nil(line,
|
368
|
+
"Error: default dead-interval set failed")
|
369
|
+
interfaceospf_interface_destroy(interface)
|
370
|
+
routerospf_router_destroy(ospf)
|
371
|
+
interface_ethernet_default()
|
372
|
+
end
|
373
|
+
|
374
|
+
def test_interfaceospf_passive_interface
|
375
|
+
ospf = create_routerospf
|
376
|
+
interface = create_interfaceospf(ospf)
|
377
|
+
|
378
|
+
# set with value
|
379
|
+
interface.passive_interface = true
|
380
|
+
pattern = (/\s+ip ospf passive-interface/)
|
381
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
382
|
+
refute_nil(line, "Error: passive interface enable missing in CLI")
|
383
|
+
assert(interface.passive_interface,
|
384
|
+
"Error: passive interface get value mismatch")
|
385
|
+
|
386
|
+
# get default and set
|
387
|
+
interface.passive_interface = interface.default_passive_interface
|
388
|
+
node.cache_flush()
|
389
|
+
pattern = (/\s+no ip ospf passive-interface/)
|
390
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
391
|
+
refute_nil(line,
|
392
|
+
"Error: default passive interface set failed")
|
393
|
+
interfaceospf_interface_destroy(interface)
|
394
|
+
routerospf_router_destroy(ospf)
|
395
|
+
interface_ethernet_default()
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_interfaceospf_create_valid_multiple
|
399
|
+
# ospf and interfaces[0]
|
400
|
+
ospf = create_routerospf
|
401
|
+
interface = create_interfaceospf(ospf)
|
402
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{interface.area}/)
|
403
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
404
|
+
refute_nil(line, "Error: 'ip router ospf #{ospf.name} default area' " +
|
405
|
+
"not configured")
|
406
|
+
|
407
|
+
# ospf and interfaces_id[2]
|
408
|
+
ifname = interfaces[2]
|
409
|
+
area = "1.1.1.1"
|
410
|
+
interface1 = create_interfaceospf(ospf, ifname, area)
|
411
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{area}/)
|
412
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
413
|
+
refute_nil(line,
|
414
|
+
"Error: 'ip router ospf #{ospf.name} area #{area}' not configured")
|
415
|
+
interfaceospf_interface_destroy(interface)
|
416
|
+
interfaceospf_interface_destroy(interface1)
|
417
|
+
routerospf_router_destroy(ospf)
|
418
|
+
interface_ethernet_default()
|
419
|
+
interface_ethernet_default(interfaces_id[2])
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_interfaceospf_create_multiple_delete_one
|
423
|
+
# ospf and interfaces[0]
|
424
|
+
ospf = create_routerospf
|
425
|
+
interface = create_interfaceospf(ospf)
|
426
|
+
|
427
|
+
# ospf and interfaces_id[2]
|
428
|
+
ifname = interfaces[2]
|
429
|
+
area = "1.1.1.1"
|
430
|
+
interface1 = create_interfaceospf(ospf, ifname, area)
|
431
|
+
assert_equal(ifname.downcase, interface1.interface.name,
|
432
|
+
"Error: 'ip router ospf #{ospf.name} area #{area}' " +
|
433
|
+
"not configured")
|
434
|
+
|
435
|
+
# delete ospf instance from interfaces_id[2]
|
436
|
+
interface1.destroy
|
437
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{area}/)
|
438
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
439
|
+
assert_nil(line,
|
440
|
+
"Error: 'ip router ospf #{ospf.name} area #{area}' not deleted")
|
441
|
+
|
442
|
+
# check other interface association still exist.
|
443
|
+
pattern = (/\s+ip router ospf #{ospf.name} area #{interface.area}/)
|
444
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
445
|
+
refute_nil(line,
|
446
|
+
"Error: 'ip router ospf #{ospf.name} default area' " +
|
447
|
+
"not configured")
|
448
|
+
|
449
|
+
interfaceospf_interface_destroy(interface)
|
450
|
+
routerospf_router_destroy(ospf)
|
451
|
+
interface_ethernet_default()
|
452
|
+
interface_ethernet_default(interfaces_id[2])
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_interfaceospf_collection_multiple_interface
|
456
|
+
s = @device.cmd("conf t ; int port-channel 42 ; descr foo ; end")
|
457
|
+
known_failure = s[/ERROR:.*port channel not present/]
|
458
|
+
refute(known_failure, "ERROR: port channel not present")
|
459
|
+
|
460
|
+
ospf_h = Hash.new { |h, k| h[k] = {} }
|
461
|
+
ospf_h["ospfTest"] = {
|
462
|
+
interfaces[0].downcase => {
|
463
|
+
:area => "0.0.0.0", :cost => 10, :hello => 30, :dead => 120,
|
464
|
+
:pass => true,
|
465
|
+
},
|
466
|
+
interfaces[1].downcase => {
|
467
|
+
:area => "1.1.1.38", :dead => 40, :pass => false,
|
468
|
+
},
|
469
|
+
"vlan101" => {
|
470
|
+
:area => "2.2.2.101", :cost => 5, :hello => 20, :dead => 80,
|
471
|
+
:pass => true,
|
472
|
+
},
|
473
|
+
}
|
474
|
+
ospf_h["TestOspfInt"] = {
|
475
|
+
interfaces[2].downcase => {
|
476
|
+
:area => "0.0.0.19",
|
477
|
+
},
|
478
|
+
"vlan290" => {
|
479
|
+
:area => "2.2.2.29", :cost => 200, :hello => 30, :dead => 120,
|
480
|
+
:pass => true,
|
481
|
+
},
|
482
|
+
"port-channel100" => {
|
483
|
+
:area => "3.2.2.29", :cost => 25, :hello => 50, :dead => 200,
|
484
|
+
:pass => false,
|
485
|
+
},
|
486
|
+
}
|
487
|
+
# enable feature ospf
|
488
|
+
@device.cmd("configure terminal")
|
489
|
+
@device.cmd("no feature ospf") # cleanup prev configs
|
490
|
+
@device.cmd("feature ospf")
|
491
|
+
@device.cmd("feature interface-vlan")
|
492
|
+
@device.cmd("default interface interfaces[0] ")
|
493
|
+
@device.cmd("default interface interfaces[1] ")
|
494
|
+
@device.cmd("default interface interfaces[2] ")
|
495
|
+
@device.cmd("end")
|
496
|
+
|
497
|
+
# pre-configure
|
498
|
+
ospf_h.each do | k, v|
|
499
|
+
# puts "TEST: pre-config hash key : #{k}"
|
500
|
+
@device.cmd("configure terminal")
|
501
|
+
@device.cmd("router ospf #{k}")
|
502
|
+
@device.cmd("end")
|
503
|
+
v.each do | k1, v1|
|
504
|
+
# puts "TEST: pre-config k1: v1 '#{k1} : #{v1}'"
|
505
|
+
@device.cmd("configure terminal")
|
506
|
+
@device.cmd("interface #{k1}")
|
507
|
+
if !(/^ethernet\d.\d/).match(k1.to_s).nil? ||
|
508
|
+
!(/^port-channel\d/).match(k1.to_s).nil?
|
509
|
+
@device.cmd("no switchport")
|
510
|
+
# puts "switchport disable: #{k1}"
|
511
|
+
end
|
512
|
+
# puts "k1: #{k1}, k: #{k}, area #{v1[:area]}"
|
513
|
+
@device.cmd("ip router ospf #{k} area #{v1[:area]}")
|
514
|
+
@device.cmd("ip ospf cost #{v1[:cost]}") unless v1[:cost].nil?
|
515
|
+
@device.cmd("ip ospf hello-interval #{v1[:hello]}") unless v1[:hello].nil?
|
516
|
+
@device.cmd("ip ospf dead-interval #{v1[:dead]}") unless v1[:dead].nil?
|
517
|
+
@device.cmd("ip ospf passive-interface") if !v1[:pass].nil? &&
|
518
|
+
v1[:pass] == true
|
519
|
+
@device.cmd("exit")
|
520
|
+
end
|
521
|
+
@device.cmd("end")
|
522
|
+
end
|
523
|
+
node.cache_flush
|
524
|
+
|
525
|
+
routers = RouterOspf.routers()
|
526
|
+
# validate the collection
|
527
|
+
routers.each do | name, router|
|
528
|
+
interfaces = InterfaceOspf.interfaces(router.name)
|
529
|
+
refute_empty(interfaces, "InterfaceOspf collection is empty")
|
530
|
+
assert_includes(ospf_h, name)
|
531
|
+
ospfh = ospf_h.fetch(name)
|
532
|
+
assert_equal(ospfh.size(), interfaces.size(),
|
533
|
+
"InterfaceOspf #{name} collection size mismatch")
|
534
|
+
interfaces.each do | ifname, interface |
|
535
|
+
assert_includes(ospfh, ifname)
|
536
|
+
hv = ospfh.fetch(ifname)
|
537
|
+
pattern = (/\s+ip router ospf #{name} area #{hv[:area]}/)
|
538
|
+
line = get_interfaceospf_match_line(ifname, pattern)
|
539
|
+
refute_nil(line, "Error: ip router ospf #{name} area #{hv[:area]} "+
|
540
|
+
"not found under #{ifname}")
|
541
|
+
|
542
|
+
# check the cost
|
543
|
+
if hv[:cost].nil?
|
544
|
+
# using default check, since not configured anything
|
545
|
+
assert_equal(node.config_get_default("interface_ospf", "cost"),
|
546
|
+
interface.cost,
|
547
|
+
"Error: get default cost failed")
|
548
|
+
else
|
549
|
+
assert_equal(hv[:cost], interface.cost,
|
550
|
+
"Error: get cost failed")
|
551
|
+
end
|
552
|
+
# check the hello
|
553
|
+
if hv[:hello].nil?
|
554
|
+
assert_equal(node.config_get_default("interface_ospf",
|
555
|
+
"hello_interval"),
|
556
|
+
interface.hello_interval,
|
557
|
+
"Error: get default hello interval failed")
|
558
|
+
else
|
559
|
+
assert_equal(hv[:hello], interface.hello_interval,
|
560
|
+
"Error: get hello interval failed")
|
561
|
+
end
|
562
|
+
# check the dead
|
563
|
+
if hv[:dead].nil?
|
564
|
+
assert_equal(node.config_get_default("interface_ospf",
|
565
|
+
"dead_interval"),
|
566
|
+
interface.dead_interval,
|
567
|
+
"Error: get dead interval failed")
|
568
|
+
else
|
569
|
+
assert_equal(hv[:dead], interface.dead_interval,
|
570
|
+
"Error: get dead interval failed")
|
571
|
+
end
|
572
|
+
# check passive interface
|
573
|
+
if hv[:pass].nil?
|
574
|
+
assert_equal(node.config_get_default("interface_ospf",
|
575
|
+
"passive_interface"),
|
576
|
+
interface.passive_interface,
|
577
|
+
"Error: passive interface get failed")
|
578
|
+
else
|
579
|
+
assert_equal(hv[:pass], interface.passive_interface,
|
580
|
+
"Error: passive interface get failed")
|
581
|
+
end
|
582
|
+
end
|
583
|
+
# cleanup interfaces
|
584
|
+
# node.debug=true
|
585
|
+
interfaceospf_interfaces_destroy(interfaces)
|
586
|
+
# node.debug=true
|
587
|
+
interfaces=nil
|
588
|
+
end # interfaces hash
|
589
|
+
# clean up
|
590
|
+
routerospf_routers_destroy(routers)
|
591
|
+
routers=nil
|
592
|
+
|
593
|
+
# disable feature interface-vlan
|
594
|
+
@device.cmd("configure terminal")
|
595
|
+
@device.cmd("no feature interface-vlan")
|
596
|
+
@device.cmd("end")
|
597
|
+
# clean up port channel
|
598
|
+
ospf_h.each do | k, v|
|
599
|
+
v.each do | k1, v1|
|
600
|
+
unless (/^port-channel\d/).match(k1.to_s).nil?
|
601
|
+
@device.cmd("configure terminal")
|
602
|
+
@device.cmd("no interface #{k1}")
|
603
|
+
@device.cmd("end")
|
604
|
+
end
|
605
|
+
end # v each
|
606
|
+
end # ospf_h each
|
607
|
+
node.cache_flush
|
608
|
+
|
609
|
+
interface_ethernet_default(interfaces_id[0])
|
610
|
+
interface_ethernet_default(interfaces_id[1])
|
611
|
+
interface_ethernet_default(interfaces_id[2])
|
612
|
+
end
|
613
|
+
|
614
|
+
def test_interfaceospf_message_digest
|
615
|
+
ospf = create_routerospf
|
616
|
+
interface = create_interfaceospf(ospf)
|
617
|
+
|
618
|
+
# set with value
|
619
|
+
interface.message_digest = true
|
620
|
+
pattern = (/^\s+ip ospf authentication message-digest$/)
|
621
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
622
|
+
refute_nil(line,
|
623
|
+
"Error: message digest enable missing in CLI")
|
624
|
+
assert(interface.message_digest,
|
625
|
+
"Error: message digest get value mismatch")
|
626
|
+
|
627
|
+
# get default and set
|
628
|
+
interface.message_digest = interface.default_message_digest
|
629
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
630
|
+
assert_nil(line,
|
631
|
+
"Error: default message digest set failed")
|
632
|
+
refute(interface.message_digest,
|
633
|
+
"Error: message digest get value mismatch")
|
634
|
+
interfaceospf_interface_destroy(interface)
|
635
|
+
routerospf_router_destroy(ospf)
|
636
|
+
interface_ethernet_default()
|
637
|
+
end
|
638
|
+
|
639
|
+
def test_interfaceospf_message_digest_key
|
640
|
+
ospf = create_routerospf
|
641
|
+
interface = create_interfaceospf(ospf)
|
642
|
+
# auth params
|
643
|
+
keyid = 1
|
644
|
+
algo = :md5
|
645
|
+
encr = :cleartext
|
646
|
+
|
647
|
+
# set with value
|
648
|
+
interface.message_digest_key_set(keyid, algo, encr, "test123")
|
649
|
+
# need to revist TODO
|
650
|
+
pattern = (/^\s+ip ospf message-digest-key #{keyid} md5 \S \S+$/)
|
651
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
652
|
+
refute_nil(line,
|
653
|
+
"Error: message digest authentication with cleartext " +
|
654
|
+
"missing in CLI")
|
655
|
+
# TODO: assert(interface.message_digest,
|
656
|
+
# "Error: message digest get value mismatch")
|
657
|
+
# check key id exist
|
658
|
+
assert_equal(keyid, interface.message_digest_key_id,
|
659
|
+
"Error: message digest key #{keyid} not present")
|
660
|
+
# save encrypted password
|
661
|
+
md = /3 (\S+)$/.match(line.to_s)
|
662
|
+
encrypted_password = md.to_s.split(" ").last
|
663
|
+
assert_equal(encrypted_password, interface.message_digest_password)
|
664
|
+
|
665
|
+
# Check other attributes:
|
666
|
+
assert_equal(algo, interface.message_digest_algorithm_type)
|
667
|
+
assert_equal(:"3des", interface.message_digest_encryption_type)
|
668
|
+
|
669
|
+
# unconfigure auth
|
670
|
+
keyid = interface.default_message_digest_key_id
|
671
|
+
encr = :cleartext
|
672
|
+
interface.message_digest_key_set(keyid, algo, encr, "test123")
|
673
|
+
pattern = (/^\s+ip ospf message-digest-key #{keyid} .+/)
|
674
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
675
|
+
assert_nil(line,
|
676
|
+
"Error: message digest authentication still present in CLI")
|
677
|
+
assert_equal(interface.message_digest_key_id,
|
678
|
+
interface.default_message_digest_key_id)
|
679
|
+
assert_equal(interface.message_digest_algorithm_type,
|
680
|
+
interface.default_message_digest_algorithm_type)
|
681
|
+
assert_equal(interface.message_digest_encryption_type,
|
682
|
+
interface.default_message_digest_encryption_type)
|
683
|
+
|
684
|
+
# update enc with 3DES
|
685
|
+
keyid = 1
|
686
|
+
encr = :"3des"
|
687
|
+
interface.message_digest_key_set(keyid, algo, encr, encrypted_password)
|
688
|
+
pattern = (/^\s+ip ospf message-digest-key #{keyid} md5 3 \S+$/)
|
689
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
690
|
+
refute_nil(line,
|
691
|
+
"Error: message digest authentication with 3DES missing " +
|
692
|
+
"in CLI")
|
693
|
+
assert_equal(keyid, interface.message_digest_key_id)
|
694
|
+
assert_equal(algo, interface.message_digest_algorithm_type)
|
695
|
+
assert_equal(encr, interface.message_digest_encryption_type)
|
696
|
+
assert_equal(encrypted_password, interface.message_digest_password)
|
697
|
+
|
698
|
+
# update enc with cisco type 7
|
699
|
+
keyid = 1
|
700
|
+
encr = :cisco_type_7
|
701
|
+
interface.message_digest_key_set(keyid, algo, encr, encrypted_password)
|
702
|
+
pattern = (/^\s+ip ospf message-digest-key #{keyid} md5 7 \S+$/)
|
703
|
+
line = get_interfaceospf_match_line(interface.interface.name, pattern)
|
704
|
+
refute_nil(line,
|
705
|
+
"Error: message digest authentication with cisco type 7 " +
|
706
|
+
"missing in CLI")
|
707
|
+
assert_equal(keyid, interface.message_digest_key_id)
|
708
|
+
assert_equal(algo, interface.message_digest_algorithm_type)
|
709
|
+
assert_equal(encr, interface.message_digest_encryption_type)
|
710
|
+
|
711
|
+
interfaceospf_interface_destroy(interface)
|
712
|
+
routerospf_router_destroy(ospf)
|
713
|
+
interface_ethernet_default()
|
714
|
+
end
|
715
|
+
|
716
|
+
def test_interfaceospf_message_digest_key_invalid_password
|
717
|
+
ospf = create_routerospf
|
718
|
+
interface = create_interfaceospf(ospf)
|
719
|
+
|
720
|
+
# blank password
|
721
|
+
keyid = 1
|
722
|
+
algo = :md5
|
723
|
+
encr = :cleartext
|
724
|
+
password = ""
|
725
|
+
assert_raises(ArgumentError) do
|
726
|
+
interface.message_digest_key_set(keyid, algo, encr, password)
|
727
|
+
end
|
728
|
+
|
729
|
+
# mismatch password and encryption
|
730
|
+
encr = :"3des"
|
731
|
+
password = "test123"
|
732
|
+
assert_raises(CliError) do
|
733
|
+
interface.message_digest_key_set(keyid, algo, encr, password)
|
734
|
+
end
|
735
|
+
|
736
|
+
interfaceospf_interface_destroy(interface)
|
737
|
+
routerospf_router_destroy(ospf)
|
738
|
+
interface_ethernet_default()
|
739
|
+
end
|
740
|
+
|
741
|
+
def test_interfaceospf_nonexistent
|
742
|
+
# If the interface does exist but the OSPF instance does not, this is OK
|
743
|
+
@device.cmd("configure terminal")
|
744
|
+
@device.cmd("interface loopback122")
|
745
|
+
@device.cmd("end")
|
746
|
+
node.cache_flush
|
747
|
+
interface = InterfaceOspf.new("loopback122", "nonexistentOspf", "0")
|
748
|
+
|
749
|
+
assert_equal(interface.area, "0")
|
750
|
+
assert_equal(interface.hello_interval, interface.default_hello_interval)
|
751
|
+
|
752
|
+
interface.destroy
|
753
|
+
|
754
|
+
# If the interface doesn't exist, InterfaceOspf should raise an error
|
755
|
+
@device.cmd("configure terminal")
|
756
|
+
@device.cmd("no interface loopback122")
|
757
|
+
@device.cmd("end")
|
758
|
+
node.cache_flush
|
759
|
+
assert_raises(RuntimeError) do
|
760
|
+
interface = InterfaceOspf.new("loopback122", "nonexistentOspf", "0")
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|