cisco_node_utils 1.2.0 → 1.3.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 +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +4 -1
- data/CHANGELOG.md +81 -2
- data/CONTRIBUTING.md +2 -17
- data/Gemfile +5 -0
- data/README.md +92 -47
- data/Rakefile +23 -1
- data/bin/git/hooks/hook_lib +7 -0
- data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
- data/bin/git/hooks/pre-commit/rubocop +7 -2
- data/bin/git/hooks/pre-commit/validate-diffs +18 -4
- data/bin/git/hooks/pre-commit/validate-yaml +18 -0
- data/bin/git/update-hooks +64 -6
- data/cisco_node_utils.gemspec +9 -6
- data/docs/README-develop-best-practices.md +149 -50
- data/docs/README-develop-node-utils-APIs.md +92 -42
- data/docs/README-maintainers.md +7 -4
- data/docs/README-test-execution.md +57 -0
- data/docs/cisco_node_utils.yaml.example +30 -0
- data/docs/template-router.rb +4 -0
- data/ext/mkrf_conf.rb +63 -0
- data/lib/.rubocop.yml +2 -2
- data/lib/cisco_node_utils.rb +5 -0
- data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
- data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
- data/lib/cisco_node_utils/ace.rb +165 -12
- data/lib/cisco_node_utils/acl.rb +2 -1
- data/lib/cisco_node_utils/bgp.rb +184 -21
- data/lib/cisco_node_utils/bgp_af.rb +94 -249
- data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
- data/lib/cisco_node_utils/bridge_domain.rb +183 -0
- data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
- data/lib/cisco_node_utils/client.rb +35 -0
- data/lib/cisco_node_utils/client/client.rb +234 -0
- data/lib/cisco_node_utils/client/grpc.rb +33 -0
- data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
- data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
- data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
- data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
- data/lib/cisco_node_utils/client/nxapi.rb +31 -0
- data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
- data/lib/cisco_node_utils/client/utils.rb +164 -0
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
- data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
- data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
- data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
- data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
- data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
- data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
- data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
- data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
- data/lib/cisco_node_utils/command_reference.rb +261 -142
- data/lib/cisco_node_utils/constants.rb +33 -0
- data/lib/cisco_node_utils/encapsulation.rb +112 -0
- data/lib/cisco_node_utils/environment.rb +102 -0
- data/lib/cisco_node_utils/evpn_vni.rb +5 -3
- data/lib/cisco_node_utils/exceptions.rb +111 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
- data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
- data/lib/cisco_node_utils/feature.rb +165 -3
- data/lib/cisco_node_utils/interface.rb +1051 -260
- data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
- data/lib/cisco_node_utils/interface_ospf.rb +1 -2
- data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
- data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
- data/lib/cisco_node_utils/itd_device_group.rb +248 -0
- data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
- data/lib/cisco_node_utils/itd_service.rb +523 -0
- data/lib/cisco_node_utils/logger.rb +75 -0
- data/lib/cisco_node_utils/node.rb +62 -192
- data/lib/cisco_node_utils/node_util.rb +56 -10
- data/lib/cisco_node_utils/overlay_global.rb +2 -2
- data/lib/cisco_node_utils/pim.rb +2 -13
- data/lib/cisco_node_utils/pim_group_list.rb +1 -1
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
- data/lib/cisco_node_utils/platform.rb +52 -21
- data/lib/cisco_node_utils/portchannel_global.rb +89 -19
- data/lib/cisco_node_utils/radius_server.rb +168 -37
- data/lib/cisco_node_utils/router_ospf.rb +20 -35
- data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
- data/lib/cisco_node_utils/snmpserver.rb +1 -6
- data/lib/cisco_node_utils/snmpuser.rb +6 -4
- data/lib/cisco_node_utils/stp_global.rb +676 -0
- data/lib/cisco_node_utils/syslog_server.rb +77 -18
- data/lib/cisco_node_utils/syslog_settings.rb +1 -1
- data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
- data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
- data/lib/cisco_node_utils/vdc.rb +12 -0
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +147 -29
- data/lib/cisco_node_utils/vpc.rb +55 -3
- data/lib/cisco_node_utils/vrf.rb +72 -11
- data/lib/cisco_node_utils/vrf_af.rb +114 -29
- data/lib/cisco_node_utils/vtp.rb +34 -52
- data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
- data/lib/minitest/environment_plugin.rb +31 -0
- data/lib/minitest/log_level_plugin.rb +41 -0
- data/spec/client_spec.rb +7 -0
- data/spec/environment_spec.rb +263 -0
- data/spec/grpc_client_spec.rb +23 -0
- data/spec/isolate/all_clients_spec.rb +9 -0
- data/spec/isolate/grpc_only_spec.rb +16 -0
- data/spec/isolate/no_clients_spec.rb +26 -0
- data/spec/isolate/nxapi_only_spec.rb +16 -0
- data/spec/nxapi_client_spec.rb +42 -0
- data/spec/schema.yaml +75 -0
- data/spec/shared_examples_for_clients.rb +14 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/whitespace_spec.rb +10 -0
- data/spec/yaml_spec.rb +42 -0
- data/tests/.rubocop.yml +2 -2
- data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
- data/tests/basetest.rb +96 -36
- data/tests/ciscotest.rb +220 -12
- data/tests/cmd_config.yaml +71 -49
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/test_aaa_authentication_login.rb +1 -0
- data/tests/test_aaa_authentication_login_service.rb +9 -0
- data/tests/test_aaa_authorization_service.rb +173 -367
- data/tests/test_ace.rb +171 -100
- data/tests/test_acl.rb +10 -1
- data/tests/test_bgp_af.rb +395 -728
- data/tests/test_bgp_neighbor.rb +274 -115
- data/tests/test_bgp_neighbor_af.rb +178 -77
- data/tests/test_bridge_domain.rb +191 -0
- data/tests/test_bridge_domain_vni.rb +116 -0
- data/tests/test_client_utils.rb +111 -0
- data/tests/test_command_config.rb +9 -5
- data/tests/test_command_reference.rb +380 -102
- data/tests/test_dns_domain.rb +13 -3
- data/tests/test_domain_name.rb +13 -3
- data/tests/test_encapsulation.rb +77 -0
- data/tests/test_evpn_vni.rb +25 -7
- data/tests/test_fabricpath_global.rb +167 -163
- data/tests/test_fabricpath_topology.rb +12 -33
- data/tests/test_feature.rb +215 -0
- data/tests/test_grpc.rb +166 -0
- data/tests/test_interface.rb +585 -344
- data/tests/test_interface_bdi.rb +80 -0
- data/tests/test_interface_channel_group.rb +6 -3
- data/tests/test_interface_ospf.rb +26 -24
- data/tests/test_interface_portchannel.rb +1 -0
- data/tests/test_interface_private_vlan.rb +724 -0
- data/tests/test_interface_service_vni.rb +37 -66
- data/tests/test_interface_svi.rb +98 -101
- data/tests/test_interface_switchport.rb +419 -549
- data/tests/test_itd_device_group.rb +145 -0
- data/tests/test_itd_device_group_node.rb +199 -0
- data/tests/test_itd_service.rb +298 -0
- data/tests/test_logger.rb +43 -0
- data/tests/test_name_server.rb +11 -2
- data/tests/test_node.rb +16 -75
- data/tests/test_node_ext.rb +174 -163
- data/tests/test_node_util.rb +119 -0
- data/tests/test_ntp_config.rb +5 -1
- data/tests/test_ntp_server.rb +2 -2
- data/tests/test_nxapi.rb +221 -0
- data/tests/test_overlay_global.rb +47 -38
- data/tests/test_pim.rb +2 -0
- data/tests/test_pim_group_list.rb +2 -0
- data/tests/test_pim_rp_address.rb +2 -0
- data/tests/test_platform.rb +86 -39
- data/tests/test_portchannel_global.rb +211 -135
- data/tests/test_radius_global.rb +13 -5
- data/tests/test_radius_server.rb +256 -104
- data/tests/test_radius_server_group.rb +2 -0
- data/tests/test_router_bgp.rb +781 -485
- data/tests/test_router_ospf.rb +26 -103
- data/tests/test_router_ospf_vrf.rb +52 -57
- data/tests/test_snmp_notification_receiver.rb +2 -0
- data/tests/test_snmpcommunity.rb +2 -0
- data/tests/test_snmpgroup.rb +2 -0
- data/tests/test_snmpnotification.rb +40 -21
- data/tests/test_snmpserver.rb +2 -0
- data/tests/test_snmpuser.rb +2 -0
- data/tests/test_stp_global.rb +563 -0
- data/tests/test_syslog_server.rb +32 -8
- data/tests/test_syslog_settings.rb +22 -9
- data/tests/test_tacacs_server.rb +32 -27
- data/tests/test_tacacs_server_group.rb +100 -45
- data/tests/test_tacacs_server_host.rb +135 -43
- data/tests/test_vdc.rb +2 -16
- data/tests/test_vlan.rb +106 -54
- data/tests/test_vlan_mt_full.rb +11 -21
- data/tests/test_vlan_private.rb +669 -0
- data/tests/test_vpc.rb +312 -159
- data/tests/test_vrf.rb +122 -113
- data/tests/test_vrf_af.rb +238 -0
- data/tests/test_vtp.rb +58 -102
- data/tests/test_vxlan_vtep.rb +38 -17
- data/tests/test_vxlan_vtep_vni.rb +61 -9
- data/tests/test_yum.rb +49 -25
- metadata +122 -36
- data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
- data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
- data/lib/cisco_node_utils/vni.rb +0 -227
- data/tests/test_vni.rb +0 -106
data/tests/test_interface.rb
CHANGED
|
@@ -15,25 +15,14 @@
|
|
|
15
15
|
require_relative 'ciscotest'
|
|
16
16
|
require_relative '../lib/cisco_node_utils/acl'
|
|
17
17
|
require_relative '../lib/cisco_node_utils/interface'
|
|
18
|
+
require_relative '../lib/cisco_node_utils/interface_channel_group'
|
|
19
|
+
require_relative '../lib/cisco_node_utils/cisco_cmn_utils'
|
|
18
20
|
require_relative '../lib/cisco_node_utils/overlay_global'
|
|
19
21
|
|
|
20
22
|
include Cisco
|
|
21
23
|
|
|
22
24
|
# TestInterface - Minitest for general functionality of the Interface class.
|
|
23
25
|
class TestInterface < CiscoTestCase
|
|
24
|
-
# rubocop:disable Style/AlignHash
|
|
25
|
-
SWITCHPORT_SHUTDOWN_HASH = {
|
|
26
|
-
'shutdown_ethernet_switchport_shutdown' =>
|
|
27
|
-
['system default switchport', 'system default switchport shutdown'],
|
|
28
|
-
'shutdown_ethernet_switchport_noshutdown' =>
|
|
29
|
-
['system default switchport', 'no system default switchport shutdown'],
|
|
30
|
-
'shutdown_ethernet_noswitchport_shutdown' =>
|
|
31
|
-
['no system default switchport', 'system default switchport shutdown'],
|
|
32
|
-
'shutdown_ethernet_noswitchport_noshutdown' =>
|
|
33
|
-
['no system default switchport', 'no system default switchport shutdown'],
|
|
34
|
-
}
|
|
35
|
-
# rubocop:enable Style/AlignHash
|
|
36
|
-
|
|
37
26
|
DEFAULT_IF_ACCESS_VLAN = 1
|
|
38
27
|
DEFAULT_IF_DESCRIPTION = ''
|
|
39
28
|
DEFAULT_IF_IP_ADDRESS = nil
|
|
@@ -43,32 +32,103 @@ class TestInterface < CiscoTestCase
|
|
|
43
32
|
DEFAULT_IF_VRF = ''
|
|
44
33
|
IF_VRF_MAX_LENGTH = 32
|
|
45
34
|
|
|
35
|
+
def setup
|
|
36
|
+
super
|
|
37
|
+
interface_ethernet_default(interfaces[0])
|
|
38
|
+
if platform == :nexus
|
|
39
|
+
@port_channel = 'port-channel'
|
|
40
|
+
# rubocop:disable Style/AlignHash
|
|
41
|
+
@switchport_shutdown_hash = {
|
|
42
|
+
'shutdown_ethernet_switchport_shutdown' =>
|
|
43
|
+
['system default switchport',
|
|
44
|
+
'system default switchport shutdown'],
|
|
45
|
+
'shutdown_ethernet_switchport_noshutdown' =>
|
|
46
|
+
['system default switchport',
|
|
47
|
+
'no system default switchport shutdown'],
|
|
48
|
+
'shutdown_ethernet_noswitchport_shutdown' =>
|
|
49
|
+
['no system default switchport',
|
|
50
|
+
'system default switchport shutdown'],
|
|
51
|
+
'shutdown_ethernet_noswitchport_noshutdown' =>
|
|
52
|
+
['no system default switchport',
|
|
53
|
+
'no system default switchport shutdown'],
|
|
54
|
+
}
|
|
55
|
+
# rubocop:enable Style/AlignHash
|
|
56
|
+
elsif platform == :ios_xr
|
|
57
|
+
@port_channel = 'Bundle-Ether'
|
|
58
|
+
@switchport_shutdown_hash = {
|
|
59
|
+
# Not really applicable to XR
|
|
60
|
+
'shutdown_ethernet_noswitchport_shutdown' => []
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def teardown
|
|
66
|
+
interface_ethernet_default(interfaces[0])
|
|
67
|
+
super
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def ipv4
|
|
71
|
+
if platform == :nexus
|
|
72
|
+
'ip'
|
|
73
|
+
elsif platform == :ios_xr
|
|
74
|
+
'ipv4'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def ipv4_address_pattern(address, length, secondary=false)
|
|
79
|
+
if platform == :nexus
|
|
80
|
+
if secondary
|
|
81
|
+
%r{^\s+ip address #{address}/#{length} secondary$}
|
|
82
|
+
else
|
|
83
|
+
%r{^\s+ip address #{address}/#{length}$}
|
|
84
|
+
end
|
|
85
|
+
elsif platform == :ios_xr
|
|
86
|
+
mask = Utils.length_to_bitmask(length)
|
|
87
|
+
if secondary
|
|
88
|
+
/^\s+ipv4 address #{address} #{mask} secondary$/
|
|
89
|
+
else
|
|
90
|
+
/^\s+ipv4 address #{address} #{mask}$/
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
46
95
|
def interface_ipv4_config(ifname, address, length,
|
|
47
96
|
do_config=true, secip=false)
|
|
48
97
|
if do_config
|
|
98
|
+
config_no_warn("interface #{ifname}",
|
|
99
|
+
'no switchport') if platform == :nexus
|
|
49
100
|
if !secip
|
|
50
101
|
config("interface #{ifname}",
|
|
51
|
-
|
|
52
|
-
"ip address #{address}/#{length}")
|
|
102
|
+
"#{ipv4} address #{address}/#{length}")
|
|
53
103
|
else
|
|
54
104
|
config("interface #{ifname}",
|
|
55
|
-
|
|
56
|
-
"ip address #{address}/#{length} secondary")
|
|
105
|
+
"#{ipv4} address #{address}/#{length} secondary")
|
|
57
106
|
end
|
|
58
107
|
else
|
|
59
108
|
config("interface #{ifname}",
|
|
60
|
-
|
|
61
|
-
|
|
109
|
+
"no #{ipv4} address", # This will remove both primary and secondary
|
|
110
|
+
)
|
|
111
|
+
config("interface #{ifname}",
|
|
112
|
+
'switchport') if platform == :nexus
|
|
62
113
|
end
|
|
63
114
|
end
|
|
64
115
|
|
|
65
116
|
def show_cmd(name)
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
if platform == :nexus
|
|
118
|
+
all = (name =~ /port-channel\d/ && node.product_id =~ /N7/) ? '' : 'all'
|
|
119
|
+
"show run interface #{name} #{all} | no-more"
|
|
120
|
+
else
|
|
121
|
+
"show run interface #{name}"
|
|
122
|
+
end
|
|
68
123
|
end
|
|
69
124
|
|
|
70
125
|
def interface_count
|
|
71
|
-
|
|
126
|
+
if platform == :nexus
|
|
127
|
+
cmd = 'show run interface all | inc interface | no-more'
|
|
128
|
+
elsif platform == :ios_xr
|
|
129
|
+
cmd = 'show run interface | inc interface'
|
|
130
|
+
end
|
|
131
|
+
output = @device.cmd(cmd)
|
|
72
132
|
# Next line needs to be done because sh run interface all also shows
|
|
73
133
|
# ospf interface related config
|
|
74
134
|
arr = output.split("\n").select { |str| str.start_with?('interface') }
|
|
@@ -77,15 +137,34 @@ class TestInterface < CiscoTestCase
|
|
|
77
137
|
arr.count
|
|
78
138
|
end
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
140
|
+
def test_capabilities
|
|
141
|
+
if validate_property_excluded?('interface', 'capabilities')
|
|
142
|
+
assert_empty(Interface.capabilities(interfaces[0]))
|
|
143
|
+
else
|
|
144
|
+
refute_empty(Interface.capabilities(interfaces[0], :hash),
|
|
145
|
+
'A valid interface should return a non-empty hash')
|
|
146
|
+
assert_empty(Interface.capabilities('foo', :hash),
|
|
147
|
+
'An Invalid interface should return an empty hash')
|
|
148
|
+
|
|
149
|
+
refute_empty(Interface.capabilities(interfaces[0], :raw),
|
|
150
|
+
'A valid interface should return a non-empty array')
|
|
151
|
+
assert_empty(Interface.capabilities('foo', :raw),
|
|
152
|
+
'An Invalid interface should return an empty array')
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Helper to get valid speeds for port
|
|
157
|
+
def capable_speed_values(interface)
|
|
158
|
+
speed_capa = Interface.capabilities(interface.name)['Speed']
|
|
159
|
+
return [] if speed_capa.nil?
|
|
160
|
+
speed_capa.split(',')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Helper to get valid duplex values for port
|
|
164
|
+
def capable_duplex_values(interface)
|
|
165
|
+
duplex_capa = Interface.capabilities(interface.name)['Duplex']
|
|
166
|
+
return [] if duplex_capa.nil?
|
|
167
|
+
duplex_capa.split(',')
|
|
89
168
|
end
|
|
90
169
|
|
|
91
170
|
def create_interface(ifname=interfaces[0])
|
|
@@ -93,8 +172,47 @@ class TestInterface < CiscoTestCase
|
|
|
93
172
|
Interface.new(ifname)
|
|
94
173
|
end
|
|
95
174
|
|
|
96
|
-
def interface_ethernet_default(
|
|
97
|
-
config("default interface
|
|
175
|
+
def interface_ethernet_default(ethernet_intf)
|
|
176
|
+
config("default interface #{ethernet_intf}")
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def interface_supports_property?(intf, message)
|
|
180
|
+
patterns = ['requested config change not allowed',
|
|
181
|
+
'% Invalid command']
|
|
182
|
+
skip("Interface '#{intf}' does not support property") if
|
|
183
|
+
message[Regexp.union(patterns)]
|
|
184
|
+
flunk(message)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Helper to find first valid speed that isn't "auto"
|
|
188
|
+
def valid_speed_set(interface)
|
|
189
|
+
valid_speed = nil
|
|
190
|
+
speeds = capable_speed_values(interface)
|
|
191
|
+
speeds.each do |value|
|
|
192
|
+
next if value == 'auto'
|
|
193
|
+
begin
|
|
194
|
+
interface.speed = value
|
|
195
|
+
assert_equal(value, interface.speed)
|
|
196
|
+
rescue Cisco::CliError => e
|
|
197
|
+
next if speed_change_disallowed?(e.message)
|
|
198
|
+
raise
|
|
199
|
+
end
|
|
200
|
+
# Exit loop once proper speed is found
|
|
201
|
+
valid_speed = value
|
|
202
|
+
break
|
|
203
|
+
end
|
|
204
|
+
valid_speed
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Helper to check for misc speed change disallowed error messages.
|
|
208
|
+
def speed_change_disallowed?(message)
|
|
209
|
+
patterns = ['port doesn t support this speed',
|
|
210
|
+
'Changing interface speed is not permitted',
|
|
211
|
+
'requested config change not allowed',
|
|
212
|
+
/does not match the (transceiver speed|port capability)/,
|
|
213
|
+
'but the transceiver doesn t support this speed',
|
|
214
|
+
'% Ambiguous parameter']
|
|
215
|
+
message[Regexp.union(patterns)]
|
|
98
216
|
end
|
|
99
217
|
|
|
100
218
|
def validate_interfaces_not_empty
|
|
@@ -109,6 +227,7 @@ class TestInterface < CiscoTestCase
|
|
|
109
227
|
|
|
110
228
|
def system_default_switchport_shutdown
|
|
111
229
|
state = []
|
|
230
|
+
return state if platform == :ios_xr
|
|
112
231
|
s = @device.cmd("sh run all | in \"system default switchport\"")
|
|
113
232
|
|
|
114
233
|
s.split("\n")[1..-2].each do |line|
|
|
@@ -124,7 +243,7 @@ class TestInterface < CiscoTestCase
|
|
|
124
243
|
inttype_h.each do |k, v|
|
|
125
244
|
interface = v[:interface]
|
|
126
245
|
|
|
127
|
-
|
|
246
|
+
@switchport_shutdown_hash.each do |lookup_string, config_array|
|
|
128
247
|
# puts "lookup_string: #{lookup_string}"
|
|
129
248
|
|
|
130
249
|
# Configure the system default shwitchport and shutdown settings
|
|
@@ -178,7 +297,7 @@ class TestInterface < CiscoTestCase
|
|
|
178
297
|
"Error: #{interface.name}, switchport mode, default, " \
|
|
179
298
|
'not correct')
|
|
180
299
|
end
|
|
181
|
-
rescue
|
|
300
|
+
rescue Cisco::CliError => e
|
|
182
301
|
skip('NX-OS defect: system default switchport nvgens twice') if
|
|
183
302
|
e.message[/Expected zero.one value/]
|
|
184
303
|
flunk(e.message)
|
|
@@ -228,7 +347,7 @@ class TestInterface < CiscoTestCase
|
|
|
228
347
|
address = v[:address_len].split('/').first
|
|
229
348
|
length = v[:address_len].split('/').last.to_i
|
|
230
349
|
|
|
231
|
-
pattern =
|
|
350
|
+
pattern = ipv4_address_pattern(address, length)
|
|
232
351
|
assert_show_match(command: show_cmd(interface.name),
|
|
233
352
|
pattern: pattern)
|
|
234
353
|
assert_equal(address, interface.ipv4_address,
|
|
@@ -248,7 +367,6 @@ class TestInterface < CiscoTestCase
|
|
|
248
367
|
# Unconfigure ipaddress
|
|
249
368
|
interface.ipv4_addr_mask_set(interface.default_ipv4_address,
|
|
250
369
|
interface.default_ipv4_netmask_length)
|
|
251
|
-
pattern = %r{^\s+ip address #{address}/#{length}}
|
|
252
370
|
refute_show_match(command: show_cmd(interface.name),
|
|
253
371
|
pattern: pattern,
|
|
254
372
|
msg: "ipv4 address still present in CLI for #{k}")
|
|
@@ -270,7 +388,11 @@ class TestInterface < CiscoTestCase
|
|
|
270
388
|
cmd = show_cmd(interface.name)
|
|
271
389
|
|
|
272
390
|
# puts "value - #{v[:proxy_arp]}"
|
|
273
|
-
|
|
391
|
+
if platform == :nexus
|
|
392
|
+
pattern = /^\s+ip proxy-arp/
|
|
393
|
+
elsif platform == :ios_xr
|
|
394
|
+
pattern = /^\s+proxy-arp/
|
|
395
|
+
end
|
|
274
396
|
if v[:proxy_arp]
|
|
275
397
|
assert_show_match(command: cmd, pattern: pattern)
|
|
276
398
|
else
|
|
@@ -322,15 +444,15 @@ class TestInterface < CiscoTestCase
|
|
|
322
444
|
assert_equal(ref.default_value, interface.default_ipv4_redirects,
|
|
323
445
|
"ipv4 redirects default incorrect for interface #{k}")
|
|
324
446
|
|
|
325
|
-
if ref.
|
|
447
|
+
if ref.setter?
|
|
326
448
|
cmd = show_cmd(interface.name)
|
|
327
449
|
interface.ipv4_redirects = true
|
|
328
450
|
assert(interface.ipv4_redirects, "Couldn't set redirects to true")
|
|
329
|
-
refute_show_match(command: cmd, pattern:
|
|
451
|
+
refute_show_match(command: cmd, pattern: /^\s+no #{ipv4} redirects/)
|
|
330
452
|
|
|
331
453
|
interface.ipv4_redirects = false
|
|
332
454
|
refute(interface.ipv4_redirects, "Couldn't set redirects to false")
|
|
333
|
-
refute_show_match(command: cmd, pattern:
|
|
455
|
+
refute_show_match(command: cmd, pattern: /^#{ipv4} redirects/)
|
|
334
456
|
else
|
|
335
457
|
# Getter should return same value as default if setter isn't supported
|
|
336
458
|
assert_equal(interface.ipv4_redirects, interface.default_ipv4_redirects,
|
|
@@ -405,38 +527,18 @@ class TestInterface < CiscoTestCase
|
|
|
405
527
|
description = 'This is a test description ! '
|
|
406
528
|
interface.description = description
|
|
407
529
|
assert_equal(description.rstrip, interface.description)
|
|
408
|
-
interface_ethernet_default(interfaces_id[0])
|
|
409
530
|
end
|
|
410
531
|
|
|
411
|
-
def
|
|
532
|
+
def test_encapsulation_dot1q
|
|
412
533
|
interface = Interface.new(interfaces[0])
|
|
413
|
-
interface.switchport_mode = :disabled
|
|
534
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
414
535
|
subif = Interface.new(interfaces[0] + '.1')
|
|
415
|
-
|
|
536
|
+
assert_raises(Cisco::CliError) { subif.encapsulation_dot1q = 'hello' }
|
|
416
537
|
subif.encapsulation_dot1q = 20
|
|
417
538
|
assert_equal(20, subif.encapsulation_dot1q)
|
|
418
539
|
subif.encapsulation_dot1q = 25
|
|
419
540
|
assert_equal(25, subif.encapsulation_dot1q)
|
|
420
|
-
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
def test_interface_encapsulation_dot1q_invalid
|
|
424
|
-
interface = Interface.new(interfaces[0])
|
|
425
|
-
interface.switchport_mode = :disabled
|
|
426
|
-
subif = Interface.new(interfaces[0] + '.1')
|
|
427
|
-
|
|
428
|
-
assert_raises(RuntimeError) { subif.encapsulation_dot1q = 'hello' }
|
|
429
|
-
interface_ethernet_default(interfaces_id[0])
|
|
430
|
-
end
|
|
431
|
-
|
|
432
|
-
def test_interface_encapsulation_dot1q_valid
|
|
433
|
-
interface = Interface.new(interfaces[0])
|
|
434
|
-
interface.switchport_mode = :disabled
|
|
435
|
-
subif = Interface.new(interfaces[0] + '.1')
|
|
436
|
-
|
|
437
|
-
subif.encapsulation_dot1q = 20
|
|
438
|
-
assert_equal(20, subif.encapsulation_dot1q)
|
|
439
|
-
interface_ethernet_default(interfaces_id[0])
|
|
541
|
+
subif.destroy
|
|
440
542
|
end
|
|
441
543
|
|
|
442
544
|
def test_interface_mtu_change
|
|
@@ -446,13 +548,14 @@ class TestInterface < CiscoTestCase
|
|
|
446
548
|
assert_equal(1520, interface.mtu)
|
|
447
549
|
interface.mtu = 1580
|
|
448
550
|
assert_equal(1580, interface.mtu)
|
|
449
|
-
|
|
551
|
+
interface.mtu = interface.default_mtu
|
|
552
|
+
assert_equal(interface.default_mtu, interface.mtu)
|
|
450
553
|
end
|
|
451
554
|
|
|
452
555
|
def test_interface_mtu_invalid
|
|
453
556
|
interface = Interface.new(interfaces[0])
|
|
454
557
|
interface.switchport_mode = :disabled
|
|
455
|
-
assert_raises(
|
|
558
|
+
assert_raises(Cisco::CliError) { interface.mtu = 'hello' }
|
|
456
559
|
end
|
|
457
560
|
|
|
458
561
|
def test_interface_mtu_valid
|
|
@@ -460,65 +563,83 @@ class TestInterface < CiscoTestCase
|
|
|
460
563
|
interface.switchport_mode = :disabled
|
|
461
564
|
interface.mtu = 1550
|
|
462
565
|
assert_equal(1550, interface.mtu)
|
|
463
|
-
|
|
566
|
+
interface.mtu = interface.default_mtu
|
|
567
|
+
assert_equal(interface.default_mtu, interface.mtu)
|
|
464
568
|
end
|
|
465
569
|
|
|
466
|
-
def
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
interface_ethernet_default(interfaces_id[0])
|
|
474
|
-
rescue RuntimeError => e
|
|
475
|
-
speed_change_disallowed(e.message)
|
|
476
|
-
end
|
|
570
|
+
def test_mtu_invalid_loopback
|
|
571
|
+
# Loopback interfaces don't permit MTU configuration
|
|
572
|
+
interface = Interface.new('loopback100')
|
|
573
|
+
assert_nil(interface.mtu)
|
|
574
|
+
assert_nil(interface.default_mtu)
|
|
575
|
+
assert_raises(Cisco::UnsupportedError) { interface.mtu = 1550 }
|
|
576
|
+
interface.destroy
|
|
477
577
|
end
|
|
478
578
|
|
|
479
|
-
def
|
|
579
|
+
def test_speed
|
|
480
580
|
interface = Interface.new(interfaces[0])
|
|
481
|
-
|
|
482
|
-
|
|
581
|
+
if validate_property_excluded?('interface', 'speed')
|
|
582
|
+
assert_nil(interface.speed)
|
|
583
|
+
assert_nil(interface.default_speed)
|
|
584
|
+
assert_raises(Cisco::UnsupportedError) { interface.speed = 1000 }
|
|
585
|
+
return
|
|
586
|
+
end
|
|
483
587
|
|
|
484
|
-
|
|
485
|
-
interface =
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
588
|
+
# Test invalid speed
|
|
589
|
+
assert_raises(RuntimeError, Cisco::CliError) { interface.speed = 'hello' }
|
|
590
|
+
|
|
591
|
+
# Test up to two non-default values
|
|
592
|
+
speed_values = capable_speed_values(interface)
|
|
593
|
+
warn("No valid speeds found on #{interface.name}") if speed_values.empty?
|
|
594
|
+
successful_runs = 0
|
|
595
|
+
speed_values.each do |value|
|
|
596
|
+
break if successful_runs >= 2
|
|
597
|
+
begin
|
|
598
|
+
interface.speed = value
|
|
599
|
+
assert_equal(value, interface.speed)
|
|
600
|
+
successful_runs += 1
|
|
601
|
+
rescue Cisco::CliError => e
|
|
602
|
+
# Many of the 'capable' speeds are actually not valid values
|
|
603
|
+
# Try next available speed value if CLI rejects current value
|
|
604
|
+
next if speed_change_disallowed?(e.message)
|
|
605
|
+
raise
|
|
606
|
+
end
|
|
607
|
+
end
|
|
492
608
|
|
|
493
|
-
|
|
494
|
-
interface =
|
|
495
|
-
interface.speed
|
|
496
|
-
interface.duplex = 'full'
|
|
497
|
-
assert_equal('full', interface.duplex)
|
|
498
|
-
interface.duplex = 'auto'
|
|
499
|
-
assert_equal('auto', interface.duplex)
|
|
500
|
-
interface_ethernet_default(interfaces_id[0])
|
|
501
|
-
rescue RuntimeError => e
|
|
502
|
-
speed_change_disallowed(e.message)
|
|
609
|
+
# Test default speed value
|
|
610
|
+
interface.speed = interface.default_speed
|
|
611
|
+
assert_equal(interface.speed, interface.default_speed)
|
|
503
612
|
end
|
|
504
613
|
|
|
505
|
-
def
|
|
614
|
+
def test_duplex
|
|
506
615
|
interface = Interface.new(interfaces[0])
|
|
507
|
-
interface
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
616
|
+
if validate_property_excluded?('interface', 'duplex')
|
|
617
|
+
assert_nil(interface.duplex)
|
|
618
|
+
assert_nil(interface.default_duplex)
|
|
619
|
+
assert_raises(Cisco::UnsupportedError) { interface.duplex = 'full' }
|
|
620
|
+
return
|
|
621
|
+
end
|
|
513
622
|
|
|
514
|
-
|
|
515
|
-
interface =
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
623
|
+
# Test invalid duplex
|
|
624
|
+
assert_raises(RuntimeError, Cisco::CliError) { interface.duplex = 'hello' }
|
|
625
|
+
|
|
626
|
+
# Ensure speed is non-auto value
|
|
627
|
+
if interface.default_speed == 'auto'
|
|
628
|
+
valid_speed = valid_speed_set(interface)
|
|
629
|
+
skip('Cannot configure non-auto speed') if valid_speed.nil?
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
# Test non-default values
|
|
633
|
+
duplex_values = capable_duplex_values(interface)
|
|
634
|
+
warn("No valid duplex found on #{interface.name}") if duplex_values.empty?
|
|
635
|
+
duplex_values.each do |value|
|
|
636
|
+
interface.duplex = value
|
|
637
|
+
assert_equal(value, interface.duplex)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
# Test default duplex value
|
|
641
|
+
interface.duplex = interface.default_duplex
|
|
642
|
+
assert_equal(interface.duplex, interface.default_duplex)
|
|
522
643
|
end
|
|
523
644
|
|
|
524
645
|
def test_interface_shutdown_valid
|
|
@@ -528,30 +649,14 @@ class TestInterface < CiscoTestCase
|
|
|
528
649
|
|
|
529
650
|
interface.shutdown = false
|
|
530
651
|
refute(interface.shutdown, 'Error: shutdown state is not false')
|
|
531
|
-
interface_ethernet_default(interfaces_id[0])
|
|
532
|
-
end
|
|
533
|
-
|
|
534
|
-
def test_interface_get_access_vlan
|
|
535
|
-
interface = Interface.new(interfaces[0])
|
|
536
|
-
interface.switchport_mode = :disabled
|
|
537
|
-
interface.switchport_mode = :access
|
|
538
|
-
assert_equal(DEFAULT_IF_ACCESS_VLAN, interface.access_vlan)
|
|
539
|
-
interface_ethernet_default(interfaces_id[0])
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
def test_interface_get_access_vlan_switchport_disabled
|
|
543
|
-
interface = Interface.new(interfaces[0])
|
|
544
|
-
interface.switchport_mode = :disabled
|
|
545
|
-
assert_equal(DEFAULT_IF_ACCESS_VLAN, interface.access_vlan)
|
|
546
|
-
interface_ethernet_default(interfaces_id[0])
|
|
547
652
|
end
|
|
548
653
|
|
|
549
|
-
def
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
654
|
+
def test_svi_prop_nil_when_ethernet
|
|
655
|
+
intf = Interface.new(interfaces[0])
|
|
656
|
+
assert_nil(intf.svi_autostate,
|
|
657
|
+
'Error: svi_autostate should be nil when interface is ethernet')
|
|
658
|
+
assert_nil(intf.svi_management,
|
|
659
|
+
'Error: svi_management should be nil when interface is ethernet')
|
|
555
660
|
end
|
|
556
661
|
|
|
557
662
|
# def test_interface_get_prefix_list_when_switchport
|
|
@@ -559,13 +664,12 @@ class TestInterface < CiscoTestCase
|
|
|
559
664
|
# interface.switchport_mode = :access
|
|
560
665
|
# addresses = interface.prefixes
|
|
561
666
|
# assert_empty(addresses)
|
|
562
|
-
# interface_ethernet_default(interfaces_id[0])
|
|
563
667
|
# end
|
|
564
668
|
#
|
|
565
669
|
# def test_interface_get_prefix_list_with_ipv4_address_assignment
|
|
566
670
|
# interface = Interface.new(interfaces[0])
|
|
567
671
|
# interface.switchport_mode = :access
|
|
568
|
-
# interface.switchport_mode = :disabled
|
|
672
|
+
# interface.switchport_mode = :disabled if platform == :nexus
|
|
569
673
|
# config("interface #{interfaces[0]}",
|
|
570
674
|
# 'ip address 192.168.1.100 255.255.255.0')
|
|
571
675
|
# prefixes = interface.prefixes
|
|
@@ -573,13 +677,12 @@ class TestInterface < CiscoTestCase
|
|
|
573
677
|
# assert(prefixes.has_key?("192.168.1.100"))
|
|
574
678
|
# interface.switchport_mode = :access
|
|
575
679
|
# prefixes = nil
|
|
576
|
-
# interface_ethernet_default(interfaces_id[0])
|
|
577
680
|
# end
|
|
578
681
|
#
|
|
579
682
|
# def test_interface_get_prefix_list_with_ipv6_address_assignment
|
|
580
683
|
# interface = Interface.new(interfaces[0] )
|
|
581
684
|
# interface.switchport_mode = :access
|
|
582
|
-
# interface.switchport_mode = :disabled
|
|
685
|
+
# interface.switchport_mode = :disabled if platform == :nexus
|
|
583
686
|
# config("interface #{interfaces[0]}",
|
|
584
687
|
# 'ipv6 address fd56:31f7:e4ad:5585::1/64")
|
|
585
688
|
# prefixes = interface.prefixes
|
|
@@ -587,13 +690,12 @@ class TestInterface < CiscoTestCase
|
|
|
587
690
|
# assert(prefixes.has_key?("fd56:31f7:e4ad:5585::1"))
|
|
588
691
|
# interface.switchport_mode = :access
|
|
589
692
|
# prefixes = nil
|
|
590
|
-
# interface_ethernet_default(interfaces_id[0])
|
|
591
693
|
# end
|
|
592
694
|
#
|
|
593
695
|
# def test_interface_prefix_list_with_both_ip4_and_ipv6_address_assignments
|
|
594
696
|
# interface = Interface.new(interfaces[0])
|
|
595
697
|
# interface.switchport_mode = :access
|
|
596
|
-
# interface.switchport_mode = :disabled
|
|
698
|
+
# interface.switchport_mode = :disabled if platform == :nexus
|
|
597
699
|
# config("interface #{interfaces[0]}",
|
|
598
700
|
# 'ip address 192.168.1.100 255.255.255.0',
|
|
599
701
|
# 'ipv6 address fd56:31f7:e4ad:5585::1/64')
|
|
@@ -603,127 +705,131 @@ class TestInterface < CiscoTestCase
|
|
|
603
705
|
# assert(prefixes.has_key?("fd56:31f7:e4ad:5585::1"))
|
|
604
706
|
# interface.switchport_mode = :access
|
|
605
707
|
# prefixes = nil
|
|
606
|
-
# interface_ethernet_default(interfaces_id[0])
|
|
607
708
|
# end
|
|
608
709
|
|
|
609
|
-
def negotiate_auto_helper(interface, default,
|
|
710
|
+
def negotiate_auto_helper(interface, default, speed)
|
|
711
|
+
if validate_property_excluded?('interface',
|
|
712
|
+
interface.negotiate_auto_lookup_string)
|
|
713
|
+
assert_raises(Cisco::UnsupportedError) { interface.negotiate_auto = true }
|
|
714
|
+
return
|
|
715
|
+
end
|
|
716
|
+
# Check current default state before any other changes
|
|
610
717
|
inf_name = interface.name
|
|
611
|
-
|
|
612
|
-
# Test default
|
|
613
718
|
assert_equal(default, interface.default_negotiate_auto,
|
|
614
719
|
"Error: #{inf_name} negotiate auto default value mismatch")
|
|
615
720
|
|
|
616
|
-
|
|
617
|
-
#
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
interface.negotiate_auto = true
|
|
628
|
-
end
|
|
629
|
-
return
|
|
721
|
+
# Test non-defaults: Note that 'speed' and 'negotiate' are tightly coupled
|
|
722
|
+
# on some platforms. Some platforms need the speed command to be toggled
|
|
723
|
+
# before negotiate will work without raising an error; while others just
|
|
724
|
+
# need a non-'auto' speed value or may not support 'auto' at all; therefore
|
|
725
|
+
# just set a static speed value before setting any negotiate settings.
|
|
726
|
+
if default == true
|
|
727
|
+
negotiate_false(interface, speed)
|
|
728
|
+
negotiate_true(interface, speed)
|
|
729
|
+
else
|
|
730
|
+
negotiate_true(interface, speed)
|
|
731
|
+
negotiate_false(interface, speed)
|
|
630
732
|
end
|
|
733
|
+
end
|
|
631
734
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
735
|
+
def negotiate_true(interface, speed)
|
|
736
|
+
# puts " true: 'speed #{speed}', 'negotiate auto'"
|
|
737
|
+
intf = interface.name
|
|
738
|
+
interface.speed = speed
|
|
739
|
+
interface.negotiate_auto = true
|
|
740
|
+
assert(interface.negotiate_auto,
|
|
741
|
+
"#{intf} negotiate auto value should be true")
|
|
742
|
+
assert_show_match(pattern: /^\s+negotiate auto/)
|
|
743
|
+
rescue Cisco::CliError => e
|
|
744
|
+
# 10G+ interfaces do not support negotiation
|
|
745
|
+
interface_supports_property?(intf, e.message)
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
# Yes, this method is nearly identical to negotiate_true.
|
|
749
|
+
# The negotiate property is evil to troubleshoot. Keep them separate.
|
|
750
|
+
def negotiate_false(interface, speed)
|
|
751
|
+
# puts "false: 'speed #{speed}', 'no negotiate auto'"
|
|
752
|
+
intf = interface.name
|
|
753
|
+
interface.speed = speed
|
|
754
|
+
interface.negotiate_auto = false
|
|
755
|
+
refute(interface.negotiate_auto,
|
|
756
|
+
"#{intf} negotiate auto value should be false")
|
|
757
|
+
assert_show_match(pattern: /^\s+no negotiate auto/)
|
|
758
|
+
rescue Cisco::CliError => e
|
|
759
|
+
# 10G+ interfaces do not support negotiation
|
|
760
|
+
interface_supports_property?(intf, e.message)
|
|
761
|
+
end
|
|
640
762
|
|
|
641
|
-
|
|
642
|
-
#
|
|
763
|
+
def test_negotiate_auto_portchannel
|
|
764
|
+
# Create interface member of this group (required for XR)
|
|
765
|
+
member = InterfaceChannelGroup.new(interfaces[0])
|
|
643
766
|
begin
|
|
644
|
-
|
|
645
|
-
rescue
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
767
|
+
member.channel_group = 10
|
|
768
|
+
rescue Cisco::UnsupportedError
|
|
769
|
+
# Some XR platform/version combinations don't support port-channel intfs
|
|
770
|
+
skip('bundle id config not supported on this node') if platform == :ios_xr
|
|
771
|
+
raise
|
|
649
772
|
end
|
|
650
773
|
|
|
651
|
-
#
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
assert_equal(non_default, interface.negotiate_auto,
|
|
656
|
-
"Error: #{inf_name} negotiate auto value not #{non_default}")
|
|
657
|
-
|
|
658
|
-
pattern = cmd_ref.test_config_get_regex[non_default ? 1 : 0]
|
|
659
|
-
assert_show_match(pattern: pattern)
|
|
660
|
-
|
|
661
|
-
# Clean up after ourselves
|
|
662
|
-
interface.negotiate_auto = default
|
|
663
|
-
assert_equal(default, interface.negotiate_auto,
|
|
664
|
-
"Error: #{inf_name} negotiate auto value not #{default}")
|
|
774
|
+
# Clean up any stale config first
|
|
775
|
+
inf_name = "#{@port_channel}10"
|
|
776
|
+
Interface.new(inf_name).destroy
|
|
665
777
|
|
|
666
|
-
pattern = cmd_ref.test_config_get_regex[default ? 1 : 0]
|
|
667
|
-
assert_show_match(pattern: pattern)
|
|
668
|
-
end
|
|
669
|
-
|
|
670
|
-
def test_negotiate_auto_portchannel
|
|
671
|
-
ref = cmd_ref.lookup('interface',
|
|
672
|
-
'negotiate_auto_portchannel')
|
|
673
|
-
assert(ref, 'Error, reference not found')
|
|
674
|
-
|
|
675
|
-
inf_name = 'port-channel10'
|
|
676
|
-
config('interface port-channel 10')
|
|
677
778
|
interface = Interface.new(inf_name)
|
|
678
|
-
|
|
679
|
-
|
|
779
|
+
if validate_property_excluded?('interface', 'negotiate_auto_portchannel')
|
|
780
|
+
assert_nil(interface.negotiate_auto)
|
|
781
|
+
assert_nil(interface.default_negotiate_auto)
|
|
782
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
783
|
+
interface.negotiate_auto = false
|
|
784
|
+
end
|
|
785
|
+
else
|
|
786
|
+
default = interface.default_negotiate_auto
|
|
787
|
+
@default_show_command = show_cmd(inf_name)
|
|
680
788
|
|
|
681
|
-
|
|
682
|
-
|
|
789
|
+
# Port-channels will raise an error on some platforms unless they
|
|
790
|
+
# have a static speed value set first.
|
|
791
|
+
speed = '100'
|
|
683
792
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
793
|
+
# Test with switchport
|
|
794
|
+
interface.switchport_mode = :access
|
|
795
|
+
negotiate_auto_helper(interface, default, speed)
|
|
796
|
+
|
|
797
|
+
# Test with no switchport
|
|
798
|
+
interface.switchport_mode = :disabled
|
|
799
|
+
negotiate_auto_helper(interface, default, speed)
|
|
800
|
+
end
|
|
687
801
|
|
|
688
802
|
# Cleanup
|
|
689
|
-
|
|
803
|
+
interface.destroy
|
|
690
804
|
end
|
|
691
805
|
|
|
692
806
|
def test_negotiate_auto_ethernet
|
|
693
|
-
ref = cmd_ref.lookup('interface',
|
|
694
|
-
'negotiate_auto_ethernet')
|
|
695
|
-
assert(ref, 'Error, reference not found')
|
|
696
|
-
|
|
697
|
-
# Cleanup
|
|
698
|
-
interface_ethernet_default(interfaces_id[0])
|
|
699
|
-
|
|
700
|
-
# Some platforms does not support negotiate auto
|
|
701
|
-
# if so then we abort the test.
|
|
702
|
-
|
|
703
807
|
inf_name = interfaces[0]
|
|
704
808
|
interface = Interface.new(inf_name)
|
|
705
809
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
interface.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
810
|
+
if validate_property_excluded?('interface', 'negotiate_auto_ethernet')
|
|
811
|
+
assert_nil(interface.negotiate_auto)
|
|
812
|
+
assert_nil(interface.default_negotiate_auto)
|
|
813
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
814
|
+
interface.negotiate_auto = false
|
|
815
|
+
end
|
|
816
|
+
return
|
|
713
817
|
end
|
|
714
818
|
|
|
715
|
-
|
|
819
|
+
# Find a static speed. Some platforms will raise an error unless
|
|
820
|
+
# speed is configured before setting negotiate auto.
|
|
821
|
+
speed = valid_speed_set(interface)
|
|
822
|
+
|
|
823
|
+
default = interface.default_negotiate_auto
|
|
716
824
|
@default_show_command = show_cmd(inf_name)
|
|
717
825
|
|
|
718
826
|
# Test with switchport
|
|
719
|
-
|
|
827
|
+
interface.switchport_mode = :access
|
|
828
|
+
negotiate_auto_helper(interface, default, speed)
|
|
720
829
|
|
|
721
830
|
# Test with no switchport
|
|
722
|
-
|
|
723
|
-
negotiate_auto_helper(interface, default,
|
|
724
|
-
|
|
725
|
-
# Cleanup
|
|
726
|
-
interface_ethernet_default(interfaces_id[0])
|
|
831
|
+
interface.switchport_mode = :disabled
|
|
832
|
+
negotiate_auto_helper(interface, default, speed)
|
|
727
833
|
end
|
|
728
834
|
|
|
729
835
|
def test_negotiate_auto_loopback
|
|
@@ -731,12 +837,12 @@ class TestInterface < CiscoTestCase
|
|
|
731
837
|
'negotiate_auto_other_interfaces')
|
|
732
838
|
assert(ref, 'Error, reference not found')
|
|
733
839
|
|
|
734
|
-
|
|
735
|
-
config(
|
|
736
|
-
interface = Interface.new(
|
|
840
|
+
int = 'loopback2'
|
|
841
|
+
config("interface #{int}")
|
|
842
|
+
interface = Interface.new(int)
|
|
737
843
|
|
|
738
844
|
assert_equal(interface.negotiate_auto, ref.default_value,
|
|
739
|
-
"Error: #{
|
|
845
|
+
"Error: #{int} negotiate auto value mismatch")
|
|
740
846
|
|
|
741
847
|
assert_raises(Cisco::UnsupportedError) do
|
|
742
848
|
interface.negotiate_auto = true
|
|
@@ -746,7 +852,7 @@ class TestInterface < CiscoTestCase
|
|
|
746
852
|
end
|
|
747
853
|
|
|
748
854
|
# Cleanup
|
|
749
|
-
config(
|
|
855
|
+
config("no interface #{int}")
|
|
750
856
|
end
|
|
751
857
|
|
|
752
858
|
def test_interfaces_not_empty
|
|
@@ -755,20 +861,18 @@ class TestInterface < CiscoTestCase
|
|
|
755
861
|
|
|
756
862
|
def test_interface_ipv4_addr_mask_set_address_invalid
|
|
757
863
|
interface = create_interface
|
|
758
|
-
interface.switchport_mode = :disabled
|
|
759
|
-
assert_raises(
|
|
864
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
865
|
+
assert_raises(Cisco::CliError) do
|
|
760
866
|
interface.ipv4_addr_mask_set('', 14)
|
|
761
867
|
end
|
|
762
|
-
interface_ethernet_default(interfaces_id[0])
|
|
763
868
|
end
|
|
764
869
|
|
|
765
870
|
def test_interface_ipv4_addr_mask_set_netmask_invalid
|
|
766
871
|
interface = create_interface
|
|
767
|
-
interface.switchport_mode = :disabled
|
|
768
|
-
assert_raises(
|
|
872
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
873
|
+
assert_raises(Cisco::CliError) do
|
|
769
874
|
interface.ipv4_addr_mask_set('8.1.1.2', DEFAULT_IF_IP_NETMASK_LEN)
|
|
770
875
|
end
|
|
771
|
-
interface_ethernet_default(interfaces_id[0])
|
|
772
876
|
end
|
|
773
877
|
|
|
774
878
|
def test_ipv4_acl
|
|
@@ -781,9 +885,13 @@ class TestInterface < CiscoTestCase
|
|
|
781
885
|
|
|
782
886
|
# create acls first
|
|
783
887
|
%w(v4acl1 v4acl2 v4acl3 v4acl4).each do |acl_name|
|
|
784
|
-
|
|
888
|
+
if platform == :nexus
|
|
889
|
+
Acl.new('ipv4', acl_name)
|
|
890
|
+
else
|
|
891
|
+
# TODO: Acl is not yet supported on XR
|
|
892
|
+
config("ipv4 access-list #{acl_name} 1 permit any")
|
|
893
|
+
end
|
|
785
894
|
end
|
|
786
|
-
interface_ethernet_default(interfaces[0])
|
|
787
895
|
intf = Interface.new(interfaces[0])
|
|
788
896
|
|
|
789
897
|
intf.ipv4_acl_in = 'v4acl1'
|
|
@@ -803,7 +911,7 @@ class TestInterface < CiscoTestCase
|
|
|
803
911
|
|
|
804
912
|
# delete acls
|
|
805
913
|
%w(v4acl1 v4acl2 v4acl3 v4acl4).each do |acl_name|
|
|
806
|
-
config(
|
|
914
|
+
config("no #{ipv4} access-list #{acl_name}")
|
|
807
915
|
end
|
|
808
916
|
end
|
|
809
917
|
|
|
@@ -814,12 +922,16 @@ class TestInterface < CiscoTestCase
|
|
|
814
922
|
# ipv6 traffic-filter v6acl1 in
|
|
815
923
|
# ipv6 traffic-filter v6acl2 out
|
|
816
924
|
#
|
|
817
|
-
interface_ethernet_default(interfaces[0])
|
|
818
925
|
intf = Interface.new(interfaces[0])
|
|
819
926
|
|
|
820
927
|
# create acls first
|
|
821
928
|
%w(v6acl1 v6acl2 v6acl3 v6acl4).each do |acl_name|
|
|
822
|
-
|
|
929
|
+
if platform == :nexus
|
|
930
|
+
Acl.new('ipv6', acl_name)
|
|
931
|
+
else
|
|
932
|
+
# TODO: Acl is not yet supported on XR
|
|
933
|
+
config("ipv6 access-list #{acl_name} 1 permit any any")
|
|
934
|
+
end
|
|
823
935
|
end
|
|
824
936
|
|
|
825
937
|
intf.ipv6_acl_in = 'v6acl1'
|
|
@@ -845,7 +957,7 @@ class TestInterface < CiscoTestCase
|
|
|
845
957
|
|
|
846
958
|
def test_interface_ipv4_address
|
|
847
959
|
interface = create_interface
|
|
848
|
-
interface.switchport_mode = :disabled
|
|
960
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
849
961
|
address = '8.7.1.1'
|
|
850
962
|
sec_addr = '10.5.5.1'
|
|
851
963
|
secondary = true
|
|
@@ -853,7 +965,7 @@ class TestInterface < CiscoTestCase
|
|
|
853
965
|
|
|
854
966
|
# Primary: setter, getter
|
|
855
967
|
interface.ipv4_addr_mask_set(address, length)
|
|
856
|
-
pattern =
|
|
968
|
+
pattern = ipv4_address_pattern(address, length)
|
|
857
969
|
assert_show_match(pattern: pattern,
|
|
858
970
|
msg: 'Error: ipv4 address missing in CLI')
|
|
859
971
|
assert_equal(address, interface.ipv4_address,
|
|
@@ -863,12 +975,12 @@ class TestInterface < CiscoTestCase
|
|
|
863
975
|
|
|
864
976
|
# Secondary: setter, getter
|
|
865
977
|
interface.ipv4_addr_mask_set(sec_addr, length, secondary)
|
|
866
|
-
pattern =
|
|
978
|
+
pattern = ipv4_address_pattern(sec_addr, length, secondary)
|
|
867
979
|
assert_show_match(pattern: pattern,
|
|
868
980
|
msg: 'Error: ipv4 address missing in CLI')
|
|
869
981
|
assert_equal(sec_addr, interface.ipv4_address_secondary,
|
|
870
982
|
'Error: ipv4 address get value mismatch')
|
|
871
|
-
assert_equal(length, interface.
|
|
983
|
+
assert_equal(length, interface.ipv4_netmask_length_secondary,
|
|
872
984
|
'Error: ipv4 netmask length get value mismatch')
|
|
873
985
|
|
|
874
986
|
# get default
|
|
@@ -888,7 +1000,7 @@ class TestInterface < CiscoTestCase
|
|
|
888
1000
|
interface.ipv4_addr_mask_set(interface.default_ipv4_address, length,
|
|
889
1001
|
secondary)
|
|
890
1002
|
interface.ipv4_addr_mask_set(interface.default_ipv4_address, length)
|
|
891
|
-
pattern = (/^\s+ip address (.*)/)
|
|
1003
|
+
pattern = (/^\s+ip(v4)? address (.*)/)
|
|
892
1004
|
refute_show_match(pattern: pattern,
|
|
893
1005
|
msg: 'Error: ipv4 address still present in CLI')
|
|
894
1006
|
assert_equal(DEFAULT_IF_IP_ADDRESS, interface.ipv4_address,
|
|
@@ -896,8 +1008,6 @@ class TestInterface < CiscoTestCase
|
|
|
896
1008
|
assert_equal(DEFAULT_IF_IP_NETMASK_LEN,
|
|
897
1009
|
interface.ipv4_netmask_length,
|
|
898
1010
|
'Error: ipv4 netmask length default get value mismatch')
|
|
899
|
-
|
|
900
|
-
interface_ethernet_default(interfaces_id[0])
|
|
901
1011
|
end
|
|
902
1012
|
|
|
903
1013
|
def test_interface_ipv4_address_getter_with_preconfig
|
|
@@ -915,7 +1025,6 @@ class TestInterface < CiscoTestCase
|
|
|
915
1025
|
'Error: ipv4 netmask length get value mismatch')
|
|
916
1026
|
# unconfigure ipaddress
|
|
917
1027
|
interface_ipv4_config(ifname, address, length, false)
|
|
918
|
-
interface_ethernet_default(interfaces_id[0])
|
|
919
1028
|
end
|
|
920
1029
|
|
|
921
1030
|
def test_interface_ipv4_address_getter_with_preconfig_secondary
|
|
@@ -937,31 +1046,81 @@ class TestInterface < CiscoTestCase
|
|
|
937
1046
|
'Error: ipv4 netmask length get value mismatch')
|
|
938
1047
|
# unconfigure ipaddress includign secondary
|
|
939
1048
|
interface_ipv4_config(ifname, address, length, false, false)
|
|
940
|
-
interface_ethernet_default(interfaces_id[0])
|
|
941
1049
|
end
|
|
942
1050
|
|
|
943
1051
|
def test_interface_ipv4_arp_timeout
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1052
|
+
unless platform == :ios_xr
|
|
1053
|
+
# Setup
|
|
1054
|
+
config_no_warn('no interface vlan11')
|
|
1055
|
+
int = Interface.new('vlan11')
|
|
1056
|
+
|
|
1057
|
+
# Test default
|
|
1058
|
+
assert_equal(int.default_ipv4_arp_timeout, int.ipv4_arp_timeout)
|
|
1059
|
+
# Test non-default
|
|
1060
|
+
int.ipv4_arp_timeout = 300
|
|
1061
|
+
assert_equal(300, int.ipv4_arp_timeout)
|
|
1062
|
+
# Set back to default
|
|
1063
|
+
int.ipv4_arp_timeout = int.default_ipv4_arp_timeout
|
|
1064
|
+
assert_equal(int.default_ipv4_arp_timeout, int.ipv4_arp_timeout)
|
|
1065
|
+
end
|
|
957
1066
|
# Attempt to configure on a non-vlan interface
|
|
958
1067
|
nonvlanint = create_interface
|
|
959
1068
|
assert_raises(RuntimeError) { nonvlanint.ipv4_arp_timeout = 300 }
|
|
960
1069
|
end
|
|
961
1070
|
|
|
1071
|
+
def test_interface_ipv4_forwarding
|
|
1072
|
+
intf = interfaces[0]
|
|
1073
|
+
i = Interface.new(intf)
|
|
1074
|
+
|
|
1075
|
+
if platform == :ios_xr
|
|
1076
|
+
assert_nil(i.default_ipv4_forwarding)
|
|
1077
|
+
assert_nil(i.ipv4_forwarding)
|
|
1078
|
+
assert_raises(Cisco::UnsupportedError) { i.ipv4_forwarding = false }
|
|
1079
|
+
return
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
assert_equal(i.default_ipv4_forwarding, i.ipv4_forwarding)
|
|
1083
|
+
begin
|
|
1084
|
+
i.switchport_mode = :disabled
|
|
1085
|
+
i.ipv4_forwarding = true
|
|
1086
|
+
rescue RuntimeError, CliError => e
|
|
1087
|
+
# RuntimeError when switchport_mode fails (some lc's, e.g. N7K-F248XP-25E)
|
|
1088
|
+
# CliError when ipv4_forwarding fails
|
|
1089
|
+
interface_supports_property?(intf, e.message)
|
|
1090
|
+
end
|
|
1091
|
+
assert(i.ipv4_forwarding)
|
|
1092
|
+
|
|
1093
|
+
i.ipv4_forwarding = false
|
|
1094
|
+
refute(i.ipv4_forwarding)
|
|
1095
|
+
|
|
1096
|
+
i.ipv4_forwarding = true
|
|
1097
|
+
assert(i.ipv4_forwarding)
|
|
1098
|
+
i.ipv4_forwarding = i.default_ipv4_forwarding
|
|
1099
|
+
assert_equal(i.default_ipv4_forwarding, i.ipv4_forwarding)
|
|
1100
|
+
end
|
|
1101
|
+
|
|
962
1102
|
def test_interface_fabric_forwarding_anycast_gateway
|
|
1103
|
+
# Ensure N7k has compatible interface
|
|
1104
|
+
mt_full_interface? if node.product_id[/N7/]
|
|
1105
|
+
|
|
1106
|
+
if validate_property_excluded?('overlay_global', 'anycast_gateway_mac')
|
|
1107
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
1108
|
+
OverlayGlobal.new.anycast_gateway_mac = '1223.3445.5668'
|
|
1109
|
+
end
|
|
1110
|
+
return
|
|
1111
|
+
end
|
|
1112
|
+
if validate_property_excluded?('interface',
|
|
1113
|
+
'fabric_forwarding_anycast_gateway')
|
|
1114
|
+
int = Interface.new('vlan11')
|
|
1115
|
+
OverlayGlobal.new.anycast_gateway_mac = '1223.3445.5668'
|
|
1116
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
1117
|
+
int.fabric_forwarding_anycast_gateway = true
|
|
1118
|
+
end
|
|
1119
|
+
return
|
|
1120
|
+
end
|
|
1121
|
+
|
|
963
1122
|
# Setup
|
|
964
|
-
|
|
1123
|
+
config_no_warn('no interface vlan11')
|
|
965
1124
|
int = Interface.new('vlan11')
|
|
966
1125
|
foo = OverlayGlobal.new
|
|
967
1126
|
foo.anycast_gateway_mac = '1223.3445.5668'
|
|
@@ -986,17 +1145,26 @@ class TestInterface < CiscoTestCase
|
|
|
986
1145
|
|
|
987
1146
|
# 5. Attempt to set 'fabric forwarding anycast gateway' while the
|
|
988
1147
|
# overlay gateway mac is not set.
|
|
989
|
-
|
|
990
|
-
|
|
1148
|
+
int.destroy
|
|
1149
|
+
int = Interface.new('vlan11')
|
|
1150
|
+
bar = OverlayGlobal.new
|
|
1151
|
+
bar.anycast_gateway_mac = bar.default_anycast_gateway_mac
|
|
1152
|
+
assert_raises(RuntimeError) do
|
|
1153
|
+
int.fabric_forwarding_anycast_gateway = true
|
|
1154
|
+
end
|
|
991
1155
|
end
|
|
992
1156
|
|
|
993
1157
|
def test_interface_ipv4_proxy_arp
|
|
994
1158
|
interface = create_interface
|
|
995
|
-
interface.switchport_mode = :disabled
|
|
1159
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
996
1160
|
|
|
997
1161
|
# set with value true
|
|
998
1162
|
interface.ipv4_proxy_arp = true
|
|
999
|
-
|
|
1163
|
+
if platform == :nexus
|
|
1164
|
+
pattern = /^\s+ip proxy-arp/
|
|
1165
|
+
elsif platform == :ios_xr
|
|
1166
|
+
pattern = /^\s+proxy-arp/
|
|
1167
|
+
end
|
|
1000
1168
|
assert_show_match(pattern: pattern,
|
|
1001
1169
|
msg: 'Error: ip proxy-arp enable missing in CLI')
|
|
1002
1170
|
assert(interface.ipv4_proxy_arp,
|
|
@@ -1021,59 +1189,68 @@ class TestInterface < CiscoTestCase
|
|
|
1021
1189
|
assert_equal(DEFAULT_IF_IP_PROXY_ARP,
|
|
1022
1190
|
interface.ipv4_proxy_arp,
|
|
1023
1191
|
'Error: ip proxy-arp default get value mismatch')
|
|
1024
|
-
|
|
1025
|
-
interface_ethernet_default(interfaces_id[0])
|
|
1026
1192
|
end
|
|
1027
1193
|
|
|
1028
1194
|
def test_interface_ipv4_redirects
|
|
1029
1195
|
interface = create_interface
|
|
1030
|
-
interface.switchport_mode = :disabled
|
|
1196
|
+
interface.switchport_mode = :disabled if platform == :nexus
|
|
1197
|
+
|
|
1198
|
+
ref = cmd_ref.lookup('interface', 'ipv4_redirects_other_interfaces')
|
|
1199
|
+
assert(ref, 'Error, reference not found')
|
|
1200
|
+
|
|
1201
|
+
# check default value
|
|
1202
|
+
assert_equal(interface.default_ipv4_redirects, interface.ipv4_redirects,
|
|
1203
|
+
'Error: ip redirects default get value mismatch')
|
|
1031
1204
|
|
|
1032
1205
|
# set with value false
|
|
1033
1206
|
interface.ipv4_redirects = false
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1207
|
+
if interface.default_ipv4_redirects == true
|
|
1208
|
+
assert_show_match(pattern: /^\s+no #{ipv4} redirects/,
|
|
1209
|
+
msg: 'Error: ip redirects disable missing in CLI')
|
|
1210
|
+
end
|
|
1211
|
+
refute_show_match(pattern: /^\s+#{ipv4} redirects/)
|
|
1037
1212
|
refute(interface.ipv4_redirects,
|
|
1038
1213
|
"Error: ip redirects get value 'false' mismatch")
|
|
1039
1214
|
|
|
1040
1215
|
# set with value true
|
|
1041
1216
|
interface.ipv4_redirects = true
|
|
1042
|
-
|
|
1217
|
+
if interface.default_ipv4_redirects == false
|
|
1218
|
+
assert_show_match(pattern: /^\s+#{ipv4} redirects/)
|
|
1219
|
+
end
|
|
1220
|
+
refute_show_match(pattern: /^\s+no #{ipv4} redirects/,
|
|
1043
1221
|
msg: 'Error: ip redirects enable missing in CLI')
|
|
1044
1222
|
assert(interface.ipv4_redirects,
|
|
1045
1223
|
"Error: ip redirects get value 'true' mismatch")
|
|
1046
1224
|
|
|
1047
|
-
# get default
|
|
1048
|
-
assert_equal(DEFAULT_IF_IP_REDIRECTS,
|
|
1049
|
-
interface.default_ipv4_redirects,
|
|
1050
|
-
'Error: ip redirects get default value mismatch')
|
|
1051
|
-
|
|
1052
1225
|
# get default and set
|
|
1053
1226
|
interface.ipv4_redirects = interface.default_ipv4_redirects
|
|
1054
|
-
|
|
1227
|
+
if interface.default_ipv4_redirects
|
|
1228
|
+
pat = /^\s+no #{ipv4} redirects/
|
|
1229
|
+
else
|
|
1230
|
+
pat = /^\s+#{ipv4} redirects/
|
|
1231
|
+
end
|
|
1232
|
+
refute_show_match(pattern: pat,
|
|
1055
1233
|
msg: 'Error: default ip redirects set failed')
|
|
1056
|
-
assert_equal(
|
|
1234
|
+
assert_equal(interface.default_ipv4_redirects, interface.ipv4_redirects,
|
|
1057
1235
|
'Error: ip redirects default get value mismatch')
|
|
1058
|
-
|
|
1059
|
-
interface_ethernet_default(interfaces_id[0])
|
|
1060
1236
|
end
|
|
1061
1237
|
|
|
1062
1238
|
def config_from_hash(inttype_h)
|
|
1063
1239
|
inttype_h.each do |k, v|
|
|
1064
|
-
# puts "TEST: pre-config hash key : #{k}"
|
|
1065
1240
|
config('feature interface-vlan') if (/^Vlan\d./).match(k.to_s)
|
|
1066
1241
|
|
|
1067
|
-
# puts "TEST: pre-config k: v '#{k} : #{v}'"
|
|
1068
1242
|
cfg = ["interface #{k}"]
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1243
|
+
|
|
1244
|
+
switchport_intfs = Regexp.union(/ethernet/i, @port_channel)
|
|
1245
|
+
cfg << 'no switchport' if platform == :nexus && k =~ switchport_intfs
|
|
1246
|
+
|
|
1247
|
+
cfg << "#{ipv4} address #{v[:address_len]}" unless v[:address_len].nil?
|
|
1248
|
+
if platform == :nexus
|
|
1249
|
+
cfg << 'ip proxy-arp' if v[:proxy_arp]
|
|
1250
|
+
elsif platform == :ios_xr
|
|
1251
|
+
cfg << 'proxy-arp' if v[:proxy_arp]
|
|
1072
1252
|
end
|
|
1073
|
-
|
|
1074
|
-
cfg << "ip address #{v[:address_len]}" unless v[:address_len].nil?
|
|
1075
|
-
cfg << 'ip proxy-arp' if v[:proxy_arp]
|
|
1076
|
-
cfg << 'ip redirects' if v[:redirects]
|
|
1253
|
+
cfg << '#{ipv4} redirects' if v[:redirects]
|
|
1077
1254
|
cfg << "description #{v[:description]}" unless v[:description].nil?
|
|
1078
1255
|
config(*cfg)
|
|
1079
1256
|
|
|
@@ -1083,9 +1260,7 @@ class TestInterface < CiscoTestCase
|
|
|
1083
1260
|
inttype_h
|
|
1084
1261
|
end
|
|
1085
1262
|
|
|
1086
|
-
|
|
1087
|
-
# to be created or existing ones to be modified.
|
|
1088
|
-
def test_interface_ipv4_all_interfaces
|
|
1263
|
+
def interface_test_data
|
|
1089
1264
|
inttype_h = {}
|
|
1090
1265
|
inttype_h[interfaces[0]] = {
|
|
1091
1266
|
address_len: '8.7.1.1/15',
|
|
@@ -1097,31 +1272,33 @@ class TestInterface < CiscoTestCase
|
|
|
1097
1272
|
shutdown: false,
|
|
1098
1273
|
change_shutdown: true,
|
|
1099
1274
|
default_shutdown: false,
|
|
1100
|
-
switchport: :disabled,
|
|
1101
|
-
default_switchport: :disabled,
|
|
1102
|
-
access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1103
|
-
default_access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1104
|
-
vrf_new: 'test2',
|
|
1105
|
-
default_vrf: DEFAULT_IF_VRF,
|
|
1106
|
-
}
|
|
1107
|
-
inttype_h['Vlan45'] = {
|
|
1108
|
-
address_len: '9.7.1.1/15',
|
|
1109
|
-
proxy_arp: true,
|
|
1110
|
-
redirects: false,
|
|
1111
|
-
description: 'Company A',
|
|
1112
|
-
description_new: 'Mini Me',
|
|
1113
|
-
default_description: DEFAULT_IF_DESCRIPTION,
|
|
1114
|
-
shutdown: true,
|
|
1115
|
-
change_shutdown: false,
|
|
1116
|
-
default_shutdown: true,
|
|
1117
|
-
switchport: :disabled,
|
|
1118
|
-
default_switchport: :disabled,
|
|
1275
|
+
switchport: platform == :ios_xr ? nil : :disabled,
|
|
1276
|
+
default_switchport: platform == :ios_xr ? nil : :disabled,
|
|
1119
1277
|
access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1120
1278
|
default_access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1121
1279
|
vrf_new: 'test2',
|
|
1122
1280
|
default_vrf: DEFAULT_IF_VRF,
|
|
1123
1281
|
}
|
|
1124
|
-
|
|
1282
|
+
unless platform == :ios_xr
|
|
1283
|
+
inttype_h['Vlan45'] = {
|
|
1284
|
+
address_len: '9.7.1.1/15',
|
|
1285
|
+
proxy_arp: true,
|
|
1286
|
+
redirects: false,
|
|
1287
|
+
description: 'Company A',
|
|
1288
|
+
description_new: 'Mini Me',
|
|
1289
|
+
default_description: DEFAULT_IF_DESCRIPTION,
|
|
1290
|
+
shutdown: true,
|
|
1291
|
+
change_shutdown: false,
|
|
1292
|
+
default_shutdown: true,
|
|
1293
|
+
switchport: :disabled,
|
|
1294
|
+
default_switchport: :disabled,
|
|
1295
|
+
access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1296
|
+
default_access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1297
|
+
vrf_new: 'test2',
|
|
1298
|
+
default_vrf: DEFAULT_IF_VRF,
|
|
1299
|
+
}
|
|
1300
|
+
end
|
|
1301
|
+
inttype_h["#{@port_channel}48"] = {
|
|
1125
1302
|
address_len: '10.7.1.1/15',
|
|
1126
1303
|
proxy_arp: false,
|
|
1127
1304
|
redirects: false,
|
|
@@ -1131,8 +1308,8 @@ class TestInterface < CiscoTestCase
|
|
|
1131
1308
|
shutdown: false,
|
|
1132
1309
|
change_shutdown: true,
|
|
1133
1310
|
default_shutdown: false,
|
|
1134
|
-
switchport: :disabled,
|
|
1135
|
-
default_switchport: :disabled,
|
|
1311
|
+
switchport: platform == :ios_xr ? nil : :disabled,
|
|
1312
|
+
default_switchport: platform == :ios_xr ? nil : :disabled,
|
|
1136
1313
|
access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1137
1314
|
default_access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1138
1315
|
vrf_new: 'test2',
|
|
@@ -1147,8 +1324,8 @@ class TestInterface < CiscoTestCase
|
|
|
1147
1324
|
shutdown: false,
|
|
1148
1325
|
change_shutdown: true,
|
|
1149
1326
|
default_shutdown: false,
|
|
1150
|
-
switchport: :disabled,
|
|
1151
|
-
default_switchport: :disabled,
|
|
1327
|
+
switchport: platform == :ios_xr ? nil : :disabled,
|
|
1328
|
+
default_switchport: platform == :ios_xr ? nil : :disabled,
|
|
1152
1329
|
access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1153
1330
|
default_access_vlan: DEFAULT_IF_ACCESS_VLAN,
|
|
1154
1331
|
vrf_new: 'test2',
|
|
@@ -1156,52 +1333,71 @@ class TestInterface < CiscoTestCase
|
|
|
1156
1333
|
}
|
|
1157
1334
|
# Skipping mgmt0 interface since that interface is our 'path' to
|
|
1158
1335
|
# master should revisit this later
|
|
1336
|
+
inttype_h
|
|
1337
|
+
end
|
|
1338
|
+
|
|
1339
|
+
# NOTE - Changes to this method may require new validation methods
|
|
1340
|
+
# to be created or existing ones to be modified.
|
|
1341
|
+
def test_interface_ipv4_all_interfaces
|
|
1342
|
+
inttype_h = interface_test_data
|
|
1159
1343
|
|
|
1160
1344
|
# Set system defaults to "factory" values prior to initial test.
|
|
1161
1345
|
config(*
|
|
1162
|
-
|
|
1346
|
+
@switchport_shutdown_hash['shutdown_ethernet_noswitchport_shutdown'])
|
|
1163
1347
|
|
|
1164
1348
|
# pre-configure
|
|
1349
|
+
begin
|
|
1350
|
+
interface_ethernet_default(interfaces[1])
|
|
1351
|
+
InterfaceChannelGroup.new(interfaces[1]).channel_group = 48
|
|
1352
|
+
rescue Cisco::UnsupportedError
|
|
1353
|
+
raise unless platform == :ios_xr
|
|
1354
|
+
# Some XR platform/version combos don't support port-channels
|
|
1355
|
+
inttype_h.delete("#{@port_channel}48")
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1165
1358
|
inttype_h = config_from_hash(inttype_h)
|
|
1166
1359
|
|
|
1167
1360
|
# Steps to cleanup the preload configuration
|
|
1168
1361
|
cfg = []
|
|
1169
1362
|
inttype_h.each_key do |k|
|
|
1170
|
-
|
|
1363
|
+
if /ethernet/.match(k)
|
|
1364
|
+
# leave interface there, but unconfigure it
|
|
1365
|
+
cfg.push(*get_interface_cleanup_config(k))
|
|
1366
|
+
else
|
|
1367
|
+
# remove interface
|
|
1368
|
+
cfg << "no interface #{k}"
|
|
1369
|
+
end
|
|
1171
1370
|
end
|
|
1172
|
-
cfg << 'no feature interface-vlan'
|
|
1371
|
+
cfg << 'no feature interface-vlan' unless platform == :ios_xr
|
|
1173
1372
|
|
|
1174
1373
|
begin
|
|
1175
1374
|
# Validate the collection
|
|
1176
1375
|
validate_interfaces_not_empty
|
|
1177
1376
|
validate_get_switchport(inttype_h)
|
|
1178
1377
|
validate_description(inttype_h)
|
|
1179
|
-
validate_get_access_vlan(inttype_h)
|
|
1378
|
+
validate_get_access_vlan(inttype_h) unless platform == :ios_xr
|
|
1180
1379
|
validate_ipv4_address(inttype_h)
|
|
1181
1380
|
validate_ipv4_proxy_arp(inttype_h)
|
|
1182
1381
|
validate_ipv4_redirects(inttype_h)
|
|
1183
1382
|
validate_interface_shutdown(inttype_h)
|
|
1184
1383
|
validate_vrf(inttype_h)
|
|
1185
1384
|
config(*cfg)
|
|
1385
|
+
interface_ethernet_default(interfaces[1])
|
|
1186
1386
|
rescue Minitest::Assertion
|
|
1187
1387
|
# clean up before failing
|
|
1188
1388
|
config(*cfg)
|
|
1389
|
+
interface_ethernet_default(interfaces[1])
|
|
1189
1390
|
raise
|
|
1190
1391
|
end
|
|
1191
1392
|
end
|
|
1192
1393
|
|
|
1193
1394
|
def test_interface_vrf_default
|
|
1194
|
-
config('interface loopback1', 'vrf member foo')
|
|
1195
1395
|
interface = Interface.new('loopback1')
|
|
1396
|
+
assert_empty(interface.vrf)
|
|
1397
|
+
interface.vrf = 'foo'
|
|
1398
|
+
assert_equal(interface.vrf, 'foo')
|
|
1196
1399
|
interface.vrf = interface.default_vrf
|
|
1197
|
-
assert_equal(
|
|
1198
|
-
end
|
|
1199
|
-
|
|
1200
|
-
def test_interface_vrf_empty
|
|
1201
|
-
config('interface loopback1', 'vrf member foo')
|
|
1202
|
-
interface = Interface.new('loopback1')
|
|
1203
|
-
interface.vrf = DEFAULT_IF_VRF
|
|
1204
|
-
assert_equal(DEFAULT_IF_VRF, interface.vrf)
|
|
1400
|
+
assert_equal(interface.vrf, interface.default_vrf)
|
|
1205
1401
|
end
|
|
1206
1402
|
|
|
1207
1403
|
def test_interface_vrf_invalid_type
|
|
@@ -1212,7 +1408,7 @@ class TestInterface < CiscoTestCase
|
|
|
1212
1408
|
def test_interface_vrf_exceeds_max_length
|
|
1213
1409
|
interface = Interface.new('loopback1')
|
|
1214
1410
|
long_string = 'a' * (IF_VRF_MAX_LENGTH + 1)
|
|
1215
|
-
assert_raises(
|
|
1411
|
+
assert_raises(Cisco::CliError) { interface.vrf = long_string }
|
|
1216
1412
|
end
|
|
1217
1413
|
|
|
1218
1414
|
def test_interface_vrf_override
|
|
@@ -1233,14 +1429,59 @@ class TestInterface < CiscoTestCase
|
|
|
1233
1429
|
interface.destroy
|
|
1234
1430
|
end
|
|
1235
1431
|
|
|
1432
|
+
def test_vrf_change_with_ip_addr
|
|
1433
|
+
interface = Interface.new('loopback1')
|
|
1434
|
+
address = '192.168.100.1'
|
|
1435
|
+
length = 24
|
|
1436
|
+
interface_ipv4_config('loopback1', address, length)
|
|
1437
|
+
assert_equal(address, interface.ipv4_address)
|
|
1438
|
+
assert_equal(length, interface.ipv4_netmask_length)
|
|
1439
|
+
|
|
1440
|
+
vrf1 = 'test1'
|
|
1441
|
+
interface.vrf = vrf1
|
|
1442
|
+
assert_equal(address, interface.ipv4_address,
|
|
1443
|
+
'IPv4 address wrong after changing from vrf default => test1')
|
|
1444
|
+
assert_equal(length, interface.ipv4_netmask_length,
|
|
1445
|
+
'IPv4 mask wrong after changing from vrf default => test1')
|
|
1446
|
+
assert_equal(vrf1, interface.vrf)
|
|
1447
|
+
|
|
1448
|
+
vrf2 = 'test2'
|
|
1449
|
+
interface.vrf = vrf2
|
|
1450
|
+
assert_equal(address, interface.ipv4_address,
|
|
1451
|
+
'IPv4 address wrong after changing from vrf test1 => test2')
|
|
1452
|
+
assert_equal(length, interface.ipv4_netmask_length,
|
|
1453
|
+
'IPv4 mask wrong after changing from vrf test1 => test2')
|
|
1454
|
+
assert_equal(vrf2, interface.vrf)
|
|
1455
|
+
|
|
1456
|
+
interface.vrf = DEFAULT_IF_VRF
|
|
1457
|
+
assert_equal(address, interface.ipv4_address,
|
|
1458
|
+
'IPv4 address wrong after changing from vrf test2 => default')
|
|
1459
|
+
assert_equal(length, interface.ipv4_netmask_length,
|
|
1460
|
+
'IPv4 mask wrong after changing from vrf test2 => default')
|
|
1461
|
+
assert_equal(DEFAULT_IF_VRF, interface.vrf)
|
|
1462
|
+
end
|
|
1463
|
+
|
|
1236
1464
|
def test_ipv4_pim_sparse_mode
|
|
1465
|
+
config('no feature pim') if platform == :nexus
|
|
1466
|
+
i = Interface.new(interfaces[0])
|
|
1467
|
+
if platform == :ios_xr
|
|
1468
|
+
assert_nil(i.ipv4_pim_sparse_mode)
|
|
1469
|
+
assert_nil(i.default_ipv4_pim_sparse_mode)
|
|
1470
|
+
assert_raises(Cisco::UnsupportedError) { i.ipv4_pim_sparse_mode = true }
|
|
1471
|
+
return
|
|
1472
|
+
end
|
|
1473
|
+
begin
|
|
1474
|
+
i.switchport_mode = :disabled
|
|
1475
|
+
rescue Cisco::CliError => e
|
|
1476
|
+
skip_message = 'Interface does not support switchport disable'
|
|
1477
|
+
skip(skip_message) if e.message['requested config change not allowed']
|
|
1478
|
+
raise
|
|
1479
|
+
end
|
|
1237
1480
|
# Sample cli:
|
|
1238
1481
|
#
|
|
1239
1482
|
# interface Ethernet1/1
|
|
1240
1483
|
# ip pim sparse-mode
|
|
1241
1484
|
#
|
|
1242
|
-
config('no feature pim')
|
|
1243
|
-
i = Interface.new(interfaces[0])
|
|
1244
1485
|
i.ipv4_pim_sparse_mode = false
|
|
1245
1486
|
refute(i.ipv4_pim_sparse_mode)
|
|
1246
1487
|
|