cisco_node_utils 1.3.0 → 1.4.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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +1 -0
- data/README.md +44 -43
- data/bin/.rubocop.yml +18 -0
- data/bin/show_running_yang.rb +233 -0
- data/cisco_node_utils.gemspec +1 -1
- data/docs/README-maintainers.md +1 -0
- data/docs/README-utilities.md +14 -0
- data/lib/.rubocop.yml +1 -1
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +8 -3
- data/lib/cisco_node_utils/aaa_authorization_service.rb +6 -0
- data/lib/cisco_node_utils/bfd_global.rb +300 -0
- data/lib/cisco_node_utils/bgp.rb +6 -4
- data/lib/cisco_node_utils/bgp_af.rb +2 -0
- data/lib/cisco_node_utils/bgp_neighbor.rb +14 -0
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +4 -1
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +126 -0
- data/lib/cisco_node_utils/client/client.rb +6 -2
- data/lib/cisco_node_utils/client/grpc/client.rb +120 -36
- data/lib/cisco_node_utils/client/nxapi/client.rb +6 -2
- data/lib/cisco_node_utils/cmd_ref/DEPRECATED.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +14 -0
- data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +7 -7
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +125 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +141 -49
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +44 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +0 -3
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +3 -3
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +39 -15
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +43 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +48 -19
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +0 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +30 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +4 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +1 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +23 -10
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +8 -2
- data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +10 -1
- data/lib/cisco_node_utils/constants.rb +8 -1
- data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
- data/lib/cisco_node_utils/exceptions.rb +29 -0
- data/lib/cisco_node_utils/feature.rb +28 -0
- data/lib/cisco_node_utils/interface.rb +493 -402
- data/lib/cisco_node_utils/interface_DEPRECATED.rb +513 -0
- data/lib/cisco_node_utils/interface_ospf.rb +126 -0
- data/lib/cisco_node_utils/interface_portchannel.rb +16 -0
- data/lib/cisco_node_utils/logger.rb +3 -0
- data/lib/cisco_node_utils/node.rb +29 -1
- data/lib/cisco_node_utils/overlay_global.rb +1 -12
- data/lib/cisco_node_utils/pim.rb +1 -0
- data/lib/cisco_node_utils/pim_group_list.rb +1 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -0
- data/lib/cisco_node_utils/platform.rb +9 -2
- data/lib/cisco_node_utils/router_ospf.rb +1 -1
- data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
- data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +17 -0
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +27 -9
- data/lib/cisco_node_utils/snmpcommunity.rb +34 -8
- data/lib/cisco_node_utils/snmpserver.rb +4 -4
- data/lib/cisco_node_utils/snmpuser.rb +0 -0
- data/lib/cisco_node_utils/tacacs_global.rb +102 -0
- data/lib/cisco_node_utils/tacacs_server.rb +8 -7
- data/lib/cisco_node_utils/vdc.rb +25 -7
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +30 -56
- data/lib/cisco_node_utils/vlan_DEPRECATED.rb +108 -0
- data/lib/cisco_node_utils/yang.rb +160 -0
- data/lib/cisco_node_utils/yum.rb +25 -32
- data/tests/.rubocop.yml +3 -0
- data/tests/ciscotest.rb +136 -19
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/noop.rb +7 -0
- data/tests/tacacs_server.yaml.example +6 -0
- data/tests/test_aaa_authentication_login.rb +24 -1
- data/tests/test_aaa_authentication_login_service.rb +9 -16
- data/tests/test_aaa_authorization_service.rb +111 -84
- data/tests/test_bfd_global.rb +278 -0
- data/tests/test_bgp_neighbor.rb +20 -0
- data/tests/test_bridge_domain_vni.rb +2 -9
- data/tests/test_cmn_utils.rb +76 -0
- data/tests/test_dhcp_relay_global.rb +284 -0
- data/tests/test_dns_domain.rb +4 -4
- data/tests/test_domain_name.rb +2 -2
- data/tests/test_encapsulation.rb +2 -4
- data/tests/test_evpn_vni.rb +14 -7
- data/tests/test_fabricpath_global.rb +12 -13
- data/tests/test_feature.rb +35 -17
- data/tests/test_interface.rb +352 -127
- data/tests/test_interface_bdi.rb +2 -2
- data/tests/test_interface_channel_group.rb +1 -1
- data/tests/test_interface_ospf.rb +153 -23
- data/tests/test_interface_portchannel.rb +15 -6
- data/tests/test_interface_private_vlan.rb +200 -576
- data/tests/test_interface_svi.rb +5 -52
- data/tests/test_interface_switchport.rb +80 -240
- data/tests/test_itd_device_group.rb +2 -2
- data/tests/test_itd_device_group_node.rb +2 -2
- data/tests/test_itd_service.rb +1 -1
- data/tests/test_name_server.rb +3 -3
- data/tests/test_node_ext.rb +15 -17
- data/tests/test_ntp_config.rb +1 -1
- data/tests/test_ntp_server.rb +3 -3
- data/tests/test_nxapi.rb +1 -0
- data/tests/test_overlay_global.rb +15 -19
- data/tests/test_pim.rb +5 -5
- data/tests/test_pim_group_list.rb +1 -37
- data/tests/test_pim_rp_address.rb +1 -1
- data/tests/test_platform.rb +9 -11
- data/tests/test_portchannel_global.rb +43 -3
- data/tests/test_radius_server.rb +1 -1
- data/tests/test_radius_server_group.rb +1 -1
- data/tests/test_router_bgp.rb +17 -30
- data/tests/test_router_ospf_area.rb +433 -0
- data/tests/test_router_ospf_area_vlink.rb +298 -0
- data/tests/test_router_ospf_vrf.rb +17 -0
- data/tests/test_snmp_notification_receiver.rb +11 -11
- data/tests/test_snmpcommunity.rb +177 -69
- data/tests/test_snmpgroup.rb +7 -7
- data/tests/test_snmpserver.rb +164 -253
- data/tests/test_snmpuser.rb +73 -69
- data/tests/test_stp_global.rb +15 -15
- data/tests/test_syslog_settings.rb +1 -1
- data/tests/test_tacacs_global.rb +80 -0
- data/tests/test_tacacs_server.rb +129 -51
- data/tests/test_tacacs_server_group.rb +3 -29
- data/tests/test_tacacs_server_host.rb +24 -27
- data/tests/test_vlan.rb +57 -59
- data/tests/test_vlan_private.rb +271 -284
- data/tests/test_vpc.rb +10 -4
- data/tests/test_vrf.rb +2 -0
- data/tests/test_vrf_af.rb +2 -5
- data/tests/test_vtp.rb +5 -2
- data/tests/test_vxlan_vtep.rb +20 -44
- data/tests/test_vxlan_vtep_vni.rb +23 -16
- data/tests/test_yang.rb +369 -0
- data/tests/test_yum.rb +34 -42
- data/tests/yum_package.yaml +35 -0
- metadata +31 -4
- data/tests/test_vlan_mt_full.rb +0 -85
data/tests/test_vpc.rb
CHANGED
|
@@ -368,10 +368,16 @@ class TestVpc < CiscoTestCase
|
|
|
368
368
|
interface_pc.switchport_mode = :trunk
|
|
369
369
|
refute(interface_pc.vpc_peer_link,
|
|
370
370
|
'vpc_peer_link should not be set by default')
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
371
|
+
begin
|
|
372
|
+
# vpc peer-link has linecard limitations
|
|
373
|
+
interface_pc.vpc_peer_link = true
|
|
374
|
+
assert(interface_pc.vpc_peer_link, 'vpc_peer_link should be set')
|
|
375
|
+
interface_pc.vpc_peer_link = false
|
|
376
|
+
refute(interface_pc.vpc_peer_link, 'vpc_peer_link should not be set')
|
|
377
|
+
rescue RuntimeError => e
|
|
378
|
+
raise unless e.message[/Interface needs to be 10G to act as a peer-link/]
|
|
379
|
+
end
|
|
380
|
+
|
|
375
381
|
# clean up
|
|
376
382
|
interface.channel_group = false
|
|
377
383
|
refute(interface.channel_group, 'channel group should be unset')
|
data/tests/test_vrf.rb
CHANGED
data/tests/test_vrf_af.rb
CHANGED
|
@@ -111,15 +111,12 @@ class TestVrfAf < CiscoTestCase
|
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def test_route_target
|
|
114
|
+
vdc_limit_f3_no_intf_needed(:set)
|
|
114
115
|
[%w(ipv4 unicast), %w(ipv6 unicast)].each { |af| route_target(af) }
|
|
116
|
+
vdc_limit_f3_no_intf_needed(:clear)
|
|
115
117
|
end
|
|
116
118
|
|
|
117
119
|
def route_target(af)
|
|
118
|
-
#
|
|
119
|
-
# TBD: The evpn parts of this test need to check for compatible linecards to
|
|
120
|
-
# skip the evpn portions. Don't use vxlan_linecard? as that will cause all
|
|
121
|
-
# tests to be skipped.
|
|
122
|
-
#
|
|
123
120
|
# Common tester for route-target properties. Tests evpn and non-evpn.
|
|
124
121
|
# route_target_both_auto
|
|
125
122
|
# route_target_both_auto_evpn
|
data/tests/test_vtp.rb
CHANGED
|
@@ -87,9 +87,7 @@ class TestVtp < CiscoTestCase
|
|
|
87
87
|
assert_raises(ArgumentError) { vtp_domain(nil) }
|
|
88
88
|
assert_raises(ArgumentError) { vtp_domain('') }
|
|
89
89
|
|
|
90
|
-
# Create the same domain twice
|
|
91
90
|
vtp = vtp_domain('accounting')
|
|
92
|
-
assert_raises(Cisco::CliError) { vtp_domain('accounting') }
|
|
93
91
|
|
|
94
92
|
# Set password to nil
|
|
95
93
|
assert_raises(TypeError) { vtp.password = nil }
|
|
@@ -176,7 +174,12 @@ class TestVtp < CiscoTestCase
|
|
|
176
174
|
end
|
|
177
175
|
end
|
|
178
176
|
|
|
177
|
+
# this fails on n7k running 7.3(0)D1.1 image but it
|
|
178
|
+
# is fixed in later releases. The bugID is CSCuy87970
|
|
179
|
+
# which is already verified.
|
|
179
180
|
def test_password_special_characters
|
|
181
|
+
skip_legacy_defect?('7.3.0.(N1|D1).1.bin',
|
|
182
|
+
'CSCuy87970: NXAPI incorrect backslash escape')
|
|
180
183
|
vtp = vtp_domain('password')
|
|
181
184
|
vtp.password = 'hello!//\\#%$x'
|
|
182
185
|
assert_equal('hello!//\\#%$x', vtp.password)
|
data/tests/test_vxlan_vtep.rb
CHANGED
|
@@ -22,42 +22,39 @@ include Cisco
|
|
|
22
22
|
# TestVxlanVtep - Minitest for VxlanVtep node utility
|
|
23
23
|
class TestVxlanVtep < CiscoTestCase
|
|
24
24
|
@skip_unless_supported = 'vxlan_vtep'
|
|
25
|
+
@@pre_clean_needed = true # rubocop:disable Style/ClassVars
|
|
25
26
|
|
|
26
27
|
def setup
|
|
27
28
|
super
|
|
28
29
|
skip('Platform does not support MT-full or MT-lite') unless
|
|
29
30
|
VxlanVtep.mt_full_support || VxlanVtep.mt_lite_support
|
|
31
|
+
Interface.interfaces(:nve).each { |_nve, obj| obj.destroy }
|
|
32
|
+
vdc_limit_f3_no_intf_needed(:set)
|
|
33
|
+
feature_cleanup if @@pre_clean_needed
|
|
34
|
+
Feature.nv_overlay_enable
|
|
35
|
+
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
|
30
36
|
end
|
|
31
37
|
|
|
32
38
|
def teardown
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def mt_full_env_setup
|
|
41
|
-
skip('Platform does not support MT-full') unless VxlanVtep.mt_full_support
|
|
42
|
-
vxlan_linecard?
|
|
43
|
-
v = Vdc.new('default')
|
|
44
|
-
v.limit_resource_module_type = 'f3' unless
|
|
45
|
-
v.limit_resource_module_type == 'f3'
|
|
46
|
-
Feature.nv_overlay_disable
|
|
39
|
+
if first_or_last_teardown
|
|
40
|
+
vdc_limit_f3_no_intf_needed(:clear)
|
|
41
|
+
feature_cleanup
|
|
42
|
+
end
|
|
43
|
+
super
|
|
47
44
|
end
|
|
48
45
|
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
def feature_cleanup
|
|
47
|
+
config_no_warn('no feature-set fabricpath')
|
|
48
|
+
config_no_warn('no feature vni')
|
|
49
|
+
config_no_warn('no feature vn-segment-vlan-based')
|
|
50
|
+
config_no_warn('no nv overlay evpn ; no feature nv overlay')
|
|
51
|
+
# Rapid nv feature toggle can cause failures on some platforms;
|
|
52
|
+
# symptom e.g. 'show runn | i ^feature' will hang
|
|
53
|
+
sleep 5
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def test_create_destroy_one
|
|
57
57
|
# VxlanVtep.new() will enable 'feature nv overlay'
|
|
58
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
59
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
60
|
-
|
|
61
58
|
id = 'nve1'
|
|
62
59
|
vtep = VxlanVtep.new(id)
|
|
63
60
|
@default_show_command = "show running | i 'interface #{id}'"
|
|
@@ -74,11 +71,7 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
74
71
|
end
|
|
75
72
|
|
|
76
73
|
def test_mt_full_create_destroy_multiple
|
|
77
|
-
|
|
78
|
-
mt_full_env_setup
|
|
79
|
-
else
|
|
80
|
-
skip('Platform does not support MT-full')
|
|
81
|
-
end
|
|
74
|
+
skip('Platform does not support MT-full') unless VxlanVtep.mt_full_support
|
|
82
75
|
|
|
83
76
|
id1 = 'nve1'
|
|
84
77
|
id2 = 'nve2'
|
|
@@ -110,14 +103,11 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
110
103
|
|
|
111
104
|
def test_create_negative
|
|
112
105
|
# MT-lite supports a single nve int, MT-full supports 4.
|
|
113
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
114
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
115
106
|
if VxlanVtep.mt_lite_support
|
|
116
107
|
VxlanVtep.new('nve1')
|
|
117
108
|
negative_id = 'nve2'
|
|
118
109
|
|
|
119
110
|
elsif VxlanVtep.mt_full_support
|
|
120
|
-
mt_full_env_setup
|
|
121
111
|
(1..4).each { |n| VxlanVtep.new("nve#{n}") }
|
|
122
112
|
negative_id = 'nve5'
|
|
123
113
|
end
|
|
@@ -128,9 +118,6 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
128
118
|
end
|
|
129
119
|
|
|
130
120
|
def test_description
|
|
131
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
132
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
133
|
-
|
|
134
121
|
vtep = VxlanVtep.new('nve1')
|
|
135
122
|
|
|
136
123
|
# Set description to non-default value and verify
|
|
@@ -147,8 +134,6 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
147
134
|
def test_host_reachability
|
|
148
135
|
skip("Test not supported on #{node.product_id}") if
|
|
149
136
|
cmd_ref.lookup('vxlan_vtep', 'host_reachability').default_value.nil?
|
|
150
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
151
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
152
137
|
|
|
153
138
|
vtep = VxlanVtep.new('nve1')
|
|
154
139
|
|
|
@@ -163,9 +148,6 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
163
148
|
end
|
|
164
149
|
|
|
165
150
|
def test_shutdown
|
|
166
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
167
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
168
|
-
|
|
169
151
|
vtep = VxlanVtep.new('nve1')
|
|
170
152
|
|
|
171
153
|
vtep.shutdown = true
|
|
@@ -179,9 +161,6 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
179
161
|
end
|
|
180
162
|
|
|
181
163
|
def test_source_interface
|
|
182
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
183
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
184
|
-
|
|
185
164
|
vtep = VxlanVtep.new('nve1')
|
|
186
165
|
|
|
187
166
|
# Set source_interface to non-default value
|
|
@@ -204,9 +183,6 @@ class TestVxlanVtep < CiscoTestCase
|
|
|
204
183
|
end
|
|
205
184
|
|
|
206
185
|
def test_source_interface_hold_down_time
|
|
207
|
-
mt_full_env_setup if VxlanVtep.mt_full_support
|
|
208
|
-
mt_lite_env_setup if VxlanVtep.mt_lite_support
|
|
209
|
-
|
|
210
186
|
vtep = VxlanVtep.new('nve1')
|
|
211
187
|
if validate_property_excluded?('vxlan_vtep', 'source_intf_hold_down_time')
|
|
212
188
|
assert_nil(vtep.source_interface_hold_down_time)
|
|
@@ -25,31 +25,32 @@ class TestVxlanVtepVni < CiscoTestCase
|
|
|
25
25
|
|
|
26
26
|
def setup
|
|
27
27
|
super
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Feature.nv_overlay_disable
|
|
32
|
-
# nv overlay is slow on some platforms
|
|
33
|
-
sleep 1
|
|
34
|
-
vxlan_linecard?
|
|
35
|
-
if VxlanVtep.mt_full_support
|
|
36
|
-
return unless Vdc.vdc_support
|
|
37
|
-
v = Vdc.new('default')
|
|
38
|
-
v.limit_resource_module_type = 'f3' unless
|
|
39
|
-
v.limit_resource_module_type == 'f3'
|
|
40
|
-
else
|
|
41
|
-
config_no_warn('no feature vn-segment-vlan-based')
|
|
42
|
-
end
|
|
28
|
+
vdc_limit_f3_no_intf_needed(:set) if VxlanVtep.mt_full_support
|
|
29
|
+
Interface.interfaces(:nve).each { |_nve, obj| obj.destroy }
|
|
30
|
+
feature_cleanup if @@pre_clean_needed
|
|
43
31
|
Feature.nv_overlay_enable
|
|
44
32
|
config_no_warn('feature vn-segment-vlan-based') if VxlanVtep.mt_lite_support
|
|
45
33
|
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
|
46
34
|
end
|
|
47
35
|
|
|
48
36
|
def teardown
|
|
49
|
-
|
|
37
|
+
if first_or_last_teardown
|
|
38
|
+
vdc_limit_f3_no_intf_needed(:clear)
|
|
39
|
+
feature_cleanup
|
|
40
|
+
end
|
|
50
41
|
super
|
|
51
42
|
end
|
|
52
43
|
|
|
44
|
+
def feature_cleanup
|
|
45
|
+
config_no_warn('no feature-set fabricpath')
|
|
46
|
+
config_no_warn('no feature vni')
|
|
47
|
+
config_no_warn('no feature vn-segment-vlan-based')
|
|
48
|
+
config_no_warn('no nv overlay evpn ; no feature nv overlay')
|
|
49
|
+
# Rapid nv feature toggle can cause failures on some platforms;
|
|
50
|
+
# symptom e.g. 'show runn | i ^feature' will hang
|
|
51
|
+
sleep 5
|
|
52
|
+
end
|
|
53
|
+
|
|
53
54
|
def test_create_with_existing
|
|
54
55
|
VxlanVtep.new('nve1').host_reachability = 'evpn'
|
|
55
56
|
associate_vrf = true
|
|
@@ -110,6 +111,9 @@ class TestVxlanVtepVni < CiscoTestCase
|
|
|
110
111
|
end
|
|
111
112
|
|
|
112
113
|
def test_ingress_replication
|
|
114
|
+
skip_legacy_defect?('7.0.3.I3.1',
|
|
115
|
+
'CSCuy27700: Validation failed for vni mcast group configured')
|
|
116
|
+
|
|
113
117
|
vni = VxlanVtepVni.new('nve1', '5000')
|
|
114
118
|
if validate_property_excluded?('vxlan_vtep_vni', 'ingress_replication')
|
|
115
119
|
assert_raises(Cisco::UnsupportedError) { vni.ingress_replication = 'bgp' }
|
|
@@ -138,6 +142,9 @@ class TestVxlanVtepVni < CiscoTestCase
|
|
|
138
142
|
end
|
|
139
143
|
|
|
140
144
|
def test_multicast_group
|
|
145
|
+
skip_legacy_defect?('7.0.3.I3.1',
|
|
146
|
+
'CSCuy27700: Validation failed for vni mcast group configured')
|
|
147
|
+
|
|
141
148
|
vni1 = VxlanVtepVni.new('nve1', '6000')
|
|
142
149
|
vni2 = VxlanVtepVni.new('nve1', '8001-8200')
|
|
143
150
|
|
data/tests/test_yang.rb
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Yang Unit Tests
|
|
3
|
+
#
|
|
4
|
+
# Charles Burkett, May, 2016
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
|
|
20
|
+
require_relative 'ciscotest'
|
|
21
|
+
require_relative '../lib/cisco_node_utils/yang'
|
|
22
|
+
|
|
23
|
+
# TestYang - Minitest for Yang class
|
|
24
|
+
class TestYang < CiscoTestCase
|
|
25
|
+
BLUE_VRF = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
26
|
+
"vrf":[
|
|
27
|
+
{
|
|
28
|
+
"vrf-name":"BLUE",
|
|
29
|
+
"description":"Generic external traffic",
|
|
30
|
+
"create":[
|
|
31
|
+
null
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}}'
|
|
36
|
+
|
|
37
|
+
RED_VRF = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
38
|
+
"vrf":[
|
|
39
|
+
{
|
|
40
|
+
"vrf-name":"RED",
|
|
41
|
+
"create":[
|
|
42
|
+
null
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}}'
|
|
47
|
+
|
|
48
|
+
GREEN_VRF = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
49
|
+
"vrf":[
|
|
50
|
+
{
|
|
51
|
+
"vrf-name":"GREEN",
|
|
52
|
+
"create": [null]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}}'
|
|
56
|
+
|
|
57
|
+
BLUE_GREEN_VRF = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
58
|
+
"vrf":[
|
|
59
|
+
{
|
|
60
|
+
"vrf-name":"BLUE",
|
|
61
|
+
"create":[null],
|
|
62
|
+
"description":"Generic external traffic"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"vrf-name":"GREEN",
|
|
66
|
+
"create":[null]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}}'
|
|
70
|
+
|
|
71
|
+
BLUE_VRF_NO_PROPERTIES = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
72
|
+
"vrf":[
|
|
73
|
+
{
|
|
74
|
+
"vrf-name":"BLUE",
|
|
75
|
+
"create":[
|
|
76
|
+
null
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}}'
|
|
81
|
+
|
|
82
|
+
BLUE_VRF_PROPERTIES1 = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
83
|
+
"vrf":[
|
|
84
|
+
{
|
|
85
|
+
"vrf-name":"BLUE",
|
|
86
|
+
"create":[
|
|
87
|
+
null
|
|
88
|
+
],
|
|
89
|
+
"vpn-id":{
|
|
90
|
+
"vpn-oui":0,
|
|
91
|
+
"vpn-index":0
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}}'
|
|
96
|
+
|
|
97
|
+
BLUE_VRF_PROPERTIES2 = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
98
|
+
"vrf":[
|
|
99
|
+
{
|
|
100
|
+
"vrf-name":"BLUE",
|
|
101
|
+
"description":"Generic external traffic",
|
|
102
|
+
"create":[
|
|
103
|
+
null
|
|
104
|
+
],
|
|
105
|
+
"vpn-id":{
|
|
106
|
+
"vpn-oui":0,
|
|
107
|
+
"vpn-index":0
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}}'
|
|
112
|
+
|
|
113
|
+
BLUE_VRF_PROPERTIES3 = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs":{
|
|
114
|
+
"vrf":[
|
|
115
|
+
{
|
|
116
|
+
"vrf-name":"BLUE",
|
|
117
|
+
"description":"Generic ext traffic",
|
|
118
|
+
"create":[
|
|
119
|
+
null
|
|
120
|
+
],
|
|
121
|
+
"vpn-id":{
|
|
122
|
+
"vpn-oui":8,
|
|
123
|
+
"vpn-index":9
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}}'
|
|
128
|
+
|
|
129
|
+
NO_VRFS = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs": [null]}'
|
|
130
|
+
PATH_VRFS = '{"Cisco-IOS-XR-infra-rsi-cfg:vrfs": [null]}'
|
|
131
|
+
|
|
132
|
+
def self.runnable_methods
|
|
133
|
+
return [:all_skipped] unless platform == :ios_xr
|
|
134
|
+
super
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def all_skipped
|
|
138
|
+
puts 'Node under test does not appear to use the gRPC client'
|
|
139
|
+
assert(validate_property_excluded?('yang', 'support'))
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def setup
|
|
143
|
+
super
|
|
144
|
+
clear_vrfs
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def teardown
|
|
148
|
+
super
|
|
149
|
+
clear_vrfs
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def clear_vrfs
|
|
153
|
+
return unless platform == :ios_xr
|
|
154
|
+
current_vrfs = node.get_yang(PATH_VRFS)
|
|
155
|
+
|
|
156
|
+
# remove all vrfs
|
|
157
|
+
node.delete_yang(PATH_VRFS) unless Yang.empty?(current_vrfs)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_delete_vrfs
|
|
161
|
+
node.merge_yang(BLUE_VRF) # ensure at least one VRF is there
|
|
162
|
+
assert(node.get_yang(PATH_VRFS).match('BLUE'), 'Did not find the BLUE vrf')
|
|
163
|
+
|
|
164
|
+
clear_vrfs
|
|
165
|
+
assert_equal('', node.get_yang(PATH_VRFS),
|
|
166
|
+
'There are still vrfs configured')
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_add_vrf
|
|
170
|
+
node.merge_yang(BLUE_VRF) # create a single VRF
|
|
171
|
+
assert(node.get_yang(PATH_VRFS).match('BLUE'), 'Did not find the BLUE vrf')
|
|
172
|
+
|
|
173
|
+
node.replace_yang(GREEN_VRF) # create a single VRF
|
|
174
|
+
assert(node.get_yang(PATH_VRFS).match('GREEN'),
|
|
175
|
+
'Did not find the GREEN vrf')
|
|
176
|
+
refute(node.get_yang(PATH_VRFS).match('BLUE'),
|
|
177
|
+
'Found the BLUE vrf')
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_errors
|
|
181
|
+
# Note: Originally, we were checking for YangErrors and ClientErrors,
|
|
182
|
+
# but the type of error raised seemed to change from one XR image to the
|
|
183
|
+
# next, so now we check for the more general CiscoError in these tests.
|
|
184
|
+
|
|
185
|
+
# === test get_yang ===========
|
|
186
|
+
|
|
187
|
+
# Request is not wellformed
|
|
188
|
+
assert_raises(Cisco::CiscoError) { node.get_yang('aabbcc') }
|
|
189
|
+
|
|
190
|
+
# parse error: object key and value must be separated by a colon
|
|
191
|
+
assert_raises(Cisco::CiscoError) { node.get_yang('{"aabbcc"}') }
|
|
192
|
+
|
|
193
|
+
# unknown-namespace
|
|
194
|
+
assert_raises(Cisco::CiscoError) { node.get_yang('{"aabbcc": "foo"}') }
|
|
195
|
+
|
|
196
|
+
# unknown-element
|
|
197
|
+
assert_raises(Cisco::CiscoError) do
|
|
198
|
+
node.get_yang('{"Cisco-IOS-XR-infra-rsi-cfg:aabbcc": "foo"}')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# parse error: premature EOF
|
|
202
|
+
assert_raises(Cisco::CiscoError) { node.get_yang('{') }
|
|
203
|
+
|
|
204
|
+
# parse error: invalid object key (must be a string)
|
|
205
|
+
assert_raises(Cisco::CiscoError) { node.get_yang('{: "foo"}') }
|
|
206
|
+
|
|
207
|
+
# === test merge_yang ===========
|
|
208
|
+
|
|
209
|
+
# Request is not wellformed
|
|
210
|
+
assert_raises(Cisco::CiscoError) { node.merge_yang('aabbcc') }
|
|
211
|
+
|
|
212
|
+
# unknown-element
|
|
213
|
+
assert_raises(Cisco::CiscoError) do
|
|
214
|
+
node.merge_yang('{"Cisco-IOS-XR-infra-rsi-cfg:aabbcc": "foo"}')
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# bad-element
|
|
218
|
+
assert_raises(Cisco::CiscoError) do
|
|
219
|
+
node.merge_yang('{"Cisco-IOS-XR-infra-rsi-cfg:vrfs": "foo"}')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# missing-element
|
|
223
|
+
assert_raises(Cisco::CiscoError) do
|
|
224
|
+
node.merge_yang('{"Cisco-IOS-XR-infra-rsi-cfg:vrfs": {"vrf":[{}]}}')
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# === test replace_yang ===========
|
|
228
|
+
|
|
229
|
+
# unknown-namespace
|
|
230
|
+
assert_raises(Cisco::CiscoError) do
|
|
231
|
+
node.replace_yang('{"Cisco-IOS-XR-infra-rsi-cfg:aabbcc": "foo"}')
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Request is not wellformed
|
|
235
|
+
assert_raises(Cisco::CiscoError) do
|
|
236
|
+
node.replace_yang('{"Cisco-IOS-XR-infra-rsi-cfg:vrfs": }')
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_merge_diff
|
|
241
|
+
# ensure we think that a merge is needed (in-sinc = false)
|
|
242
|
+
refute(Yang.insync_for_merge?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
243
|
+
'Expected not in-sync')
|
|
244
|
+
|
|
245
|
+
node.merge_yang(BLUE_VRF) # create the blue VRF
|
|
246
|
+
|
|
247
|
+
# ensure we think that a merge is NOT needed (in-sinc = true)
|
|
248
|
+
assert(Yang.insync_for_merge?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
249
|
+
'Expected in-sync')
|
|
250
|
+
|
|
251
|
+
# ensure we think that the merge is needed (in-sinc = false)
|
|
252
|
+
refute(Yang.insync_for_merge?(RED_VRF, node.get_yang(PATH_VRFS)),
|
|
253
|
+
'Expected not in-sync')
|
|
254
|
+
|
|
255
|
+
node.merge_yang(RED_VRF) # create the red VRF
|
|
256
|
+
|
|
257
|
+
# ensure we think that a merge is NOT needed (in-sinc = true)
|
|
258
|
+
assert(Yang.insync_for_merge?(RED_VRF, node.get_yang(PATH_VRFS)),
|
|
259
|
+
'Expected in-sync')
|
|
260
|
+
|
|
261
|
+
node.merge_yang(GREEN_VRF) # create green VRF
|
|
262
|
+
# ensure we think that a merge is NOT needed (in-sinc = true)
|
|
263
|
+
assert(Yang.insync_for_merge?(GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
264
|
+
'Expected in-sync')
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def test_replace_diff
|
|
268
|
+
# ensure we think that a merge is needed (in-sinc = false)
|
|
269
|
+
refute(Yang.insync_for_replace?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
270
|
+
'Expected not in-sync')
|
|
271
|
+
|
|
272
|
+
node.replace_yang(BLUE_VRF) # create the blue VRF
|
|
273
|
+
# ensure we think that a replace is NOT needed (in-sinc = true)
|
|
274
|
+
assert(Yang.insync_for_replace?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
275
|
+
'Expected in-sync')
|
|
276
|
+
|
|
277
|
+
node.replace_yang(RED_VRF) # create the red VRF
|
|
278
|
+
# ensure we think that a replace is NOT needed (in-sinc = true)
|
|
279
|
+
assert(Yang.insync_for_replace?(RED_VRF, node.get_yang(PATH_VRFS)),
|
|
280
|
+
'Expected in-sync')
|
|
281
|
+
|
|
282
|
+
node.replace_yang(GREEN_VRF) # create green VRF
|
|
283
|
+
# ensure we think that a replace is NOT needed (in-sinc = true)
|
|
284
|
+
assert(Yang.insync_for_replace?(GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
285
|
+
'Expected in-sync')
|
|
286
|
+
|
|
287
|
+
node.merge_yang(BLUE_VRF)
|
|
288
|
+
|
|
289
|
+
# ensure we think that a replace is NOT needed (in-sinc = true)
|
|
290
|
+
assert(Yang.insync_for_replace?(BLUE_GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
291
|
+
'Expected in sync')
|
|
292
|
+
# ensure we think that a replace is needed (in-sinc = true)
|
|
293
|
+
refute(Yang.insync_for_replace?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
294
|
+
'Expected not in sync')
|
|
295
|
+
refute(Yang.insync_for_replace?(GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
296
|
+
'Expected not in sync')
|
|
297
|
+
|
|
298
|
+
node.replace_yang(BLUE_VRF)
|
|
299
|
+
# ensure we think that a replace is NOT needed (in-sinc = true)
|
|
300
|
+
assert(Yang.insync_for_replace?(BLUE_VRF, node.get_yang(PATH_VRFS)),
|
|
301
|
+
'Expected in-sync')
|
|
302
|
+
# ensure we think that a replace is needed (in-sinc = true)
|
|
303
|
+
refute(Yang.insync_for_replace?(GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
304
|
+
'Expected not in-sync')
|
|
305
|
+
refute(Yang.insync_for_replace?(BLUE_GREEN_VRF, node.get_yang(PATH_VRFS)),
|
|
306
|
+
'Expected not in-sync')
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def test_merge_leaves
|
|
310
|
+
node.merge_yang(BLUE_VRF) # create blue vrf with description
|
|
311
|
+
|
|
312
|
+
# merge blue vrf with vpn id to blue vrf with description
|
|
313
|
+
node.merge_yang(BLUE_VRF_PROPERTIES1)
|
|
314
|
+
|
|
315
|
+
# ensure that new leaves are merged with old.
|
|
316
|
+
assert(Yang.insync_for_merge?(BLUE_VRF_PROPERTIES2,
|
|
317
|
+
node.get_yang(PATH_VRFS)), 'Expected in-sync')
|
|
318
|
+
|
|
319
|
+
# update description and vpn-id
|
|
320
|
+
node.merge_yang(BLUE_VRF_PROPERTIES3)
|
|
321
|
+
assert(Yang.insync_for_merge?(BLUE_VRF_PROPERTIES3,
|
|
322
|
+
node.get_yang(PATH_VRFS)), 'Expected in-sync')
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def test_replace_leaves
|
|
326
|
+
node.replace_yang(BLUE_VRF) # create blue vrf with description
|
|
327
|
+
|
|
328
|
+
# replace blue vrf (description) by blue vrf (vpn-id)
|
|
329
|
+
node.replace_yang(BLUE_VRF_PROPERTIES1)
|
|
330
|
+
|
|
331
|
+
# ensure that new properties are replaced by old.
|
|
332
|
+
assert(Yang.insync_for_replace?(BLUE_VRF_PROPERTIES1,
|
|
333
|
+
node.get_yang(PATH_VRFS)),
|
|
334
|
+
'Expected in-sync')
|
|
335
|
+
|
|
336
|
+
# replace description and vpn-id
|
|
337
|
+
node.replace_yang(BLUE_VRF_PROPERTIES3)
|
|
338
|
+
assert(Yang.insync_for_replace?(BLUE_VRF_PROPERTIES3,
|
|
339
|
+
node.get_yang(PATH_VRFS)),
|
|
340
|
+
'Expected in-sync')
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def test_merge
|
|
344
|
+
node.merge_yang(BLUE_VRF) # create blue vrf
|
|
345
|
+
node.merge_yang(GREEN_VRF) # create green vrf
|
|
346
|
+
|
|
347
|
+
yang = node.get_yang(PATH_VRFS)
|
|
348
|
+
|
|
349
|
+
assert_yang_equal(BLUE_GREEN_VRF, yang)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def test_replace
|
|
353
|
+
node.merge_yang(BLUE_VRF) # create blue vrf
|
|
354
|
+
node.replace_yang(GREEN_VRF) # create green vrf
|
|
355
|
+
|
|
356
|
+
yang = node.get_yang(PATH_VRFS)
|
|
357
|
+
|
|
358
|
+
assert_yang_equal(GREEN_VRF, yang)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def assert_yang_equal(expected, actual)
|
|
362
|
+
equal = Yang.insync_for_replace?(expected, actual) &&
|
|
363
|
+
Yang.insync_for_replace?(actual, expected)
|
|
364
|
+
assert(equal,
|
|
365
|
+
"Expected: '#{expected}',\n"\
|
|
366
|
+
"Actual: '#{actual}',\n",
|
|
367
|
+
)
|
|
368
|
+
end
|
|
369
|
+
end
|