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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +5 -0
  6. data/CONTRIBUTING.md +31 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +201 -0
  9. data/README.md +113 -0
  10. data/Rakefile +4 -0
  11. data/cisco_node_utils.gemspec +30 -0
  12. data/lib/cisco_node_utils.rb +33 -0
  13. data/lib/cisco_node_utils/README_YAML.md +333 -0
  14. data/lib/cisco_node_utils/cisco_cmn_utils.rb +92 -0
  15. data/lib/cisco_node_utils/command_reference.rb +415 -0
  16. data/lib/cisco_node_utils/command_reference_common.yaml +845 -0
  17. data/lib/cisco_node_utils/command_reference_n3064.yaml +13 -0
  18. data/lib/cisco_node_utils/command_reference_n7k.yaml +48 -0
  19. data/lib/cisco_node_utils/command_reference_n9k.yaml +35 -0
  20. data/lib/cisco_node_utils/configparser_lib.rb +196 -0
  21. data/lib/cisco_node_utils/interface.rb +501 -0
  22. data/lib/cisco_node_utils/interface_ospf.rb +241 -0
  23. data/lib/cisco_node_utils/node.rb +673 -0
  24. data/lib/cisco_node_utils/platform.rb +184 -0
  25. data/lib/cisco_node_utils/platform_info.rb +58 -0
  26. data/lib/cisco_node_utils/platform_info.yaml +10 -0
  27. data/lib/cisco_node_utils/router_ospf.rb +96 -0
  28. data/lib/cisco_node_utils/router_ospf_vrf.rb +258 -0
  29. data/lib/cisco_node_utils/snmpcommunity.rb +91 -0
  30. data/lib/cisco_node_utils/snmpgroup.rb +55 -0
  31. data/lib/cisco_node_utils/snmpserver.rb +150 -0
  32. data/lib/cisco_node_utils/snmpuser.rb +342 -0
  33. data/lib/cisco_node_utils/tacacs_server.rb +175 -0
  34. data/lib/cisco_node_utils/tacacs_server_host.rb +128 -0
  35. data/lib/cisco_node_utils/version.rb +17 -0
  36. data/lib/cisco_node_utils/vlan.rb +153 -0
  37. data/lib/cisco_node_utils/vtp.rb +127 -0
  38. data/lib/cisco_node_utils/yum.rb +84 -0
  39. data/tests/basetest.rb +93 -0
  40. data/tests/ciscotest.rb +136 -0
  41. data/tests/cmd_config.yaml +51 -0
  42. data/tests/cmd_config_invalid.yaml +16 -0
  43. data/tests/test_all_cisco.rb +46 -0
  44. data/tests/test_command_config.rb +192 -0
  45. data/tests/test_command_reference.rb +222 -0
  46. data/tests/test_interface.rb +1017 -0
  47. data/tests/test_interface_ospf.rb +763 -0
  48. data/tests/test_interface_svi.rb +267 -0
  49. data/tests/test_interface_switchport.rb +722 -0
  50. data/tests/test_node.rb +108 -0
  51. data/tests/test_node_ext.rb +450 -0
  52. data/tests/test_platform.rb +188 -0
  53. data/tests/test_router_ospf.rb +164 -0
  54. data/tests/test_router_ospf_vrf.rb +753 -0
  55. data/tests/test_snmpcommunity.rb +344 -0
  56. data/tests/test_snmpgroup.rb +71 -0
  57. data/tests/test_snmpserver.rb +443 -0
  58. data/tests/test_snmpuser.rb +803 -0
  59. data/tests/test_tacacs_server.rb +388 -0
  60. data/tests/test_tacacs_server_host.rb +391 -0
  61. data/tests/test_vlan.rb +264 -0
  62. data/tests/test_vtp.rb +319 -0
  63. data/tests/test_yum.rb +106 -0
  64. 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