cisco_node_utils 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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