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_pim.rb
CHANGED
data/tests/test_platform.rb
CHANGED
|
@@ -17,15 +17,40 @@ require_relative '../lib/cisco_node_utils/platform'
|
|
|
17
17
|
|
|
18
18
|
# TestPlatform - Minitest for Platform class
|
|
19
19
|
class TestPlatform < CiscoTestCase
|
|
20
|
+
def test_image_version
|
|
21
|
+
case platform
|
|
22
|
+
when :ios_xr
|
|
23
|
+
refute_empty(Platform.image_version)
|
|
24
|
+
|
|
25
|
+
when :nexus
|
|
26
|
+
# Supported Images:
|
|
27
|
+
# N3/9k: 7.0(3)I2(*), 7.0(3)I3(1)
|
|
28
|
+
# N7k: 7.3(1)D1(1)
|
|
29
|
+
# N5/6k: 7.3(0)N1(1)
|
|
30
|
+
|
|
31
|
+
in_pat = '(^ NXOS: version |^ system: version)'
|
|
32
|
+
s = @device.cmd("show version | i '#{in_pat}'")
|
|
33
|
+
|
|
34
|
+
out_pat = %r{/(\d\.\d\(\d\)[IDN])\d\(\d\)/}
|
|
35
|
+
show = s.match(out_pat).to_s
|
|
36
|
+
plat = Platform.image_version.match(out_pat).to_s
|
|
37
|
+
assert_equal(show, plat)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
20
41
|
def test_system_image
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
if platform == :ios_xr
|
|
43
|
+
assert_nil(Platform.system_image)
|
|
44
|
+
elsif platform == :nexus
|
|
45
|
+
s = @device.cmd('show version | i image').scan(/ (\S+)$/).flatten.first
|
|
46
|
+
assert_equal(s, Platform.system_image)
|
|
47
|
+
end
|
|
23
48
|
end
|
|
24
49
|
|
|
25
50
|
def test_packages
|
|
26
51
|
# [['pack1', 'state1'], ['pack2', 'state2'], ...]
|
|
27
52
|
# 'state' should always be a variant of Active or Inactive
|
|
28
|
-
pkgs = @device.cmd('sh inst patch
|
|
53
|
+
pkgs = @device.cmd('sh inst patch')
|
|
29
54
|
.scan(/\n(\S+)\s+(\S*[aA]ctive.*)\n/)
|
|
30
55
|
# convert to hash with key pkg_name and value pkg_state
|
|
31
56
|
pkg_hsh = {}
|
|
@@ -34,7 +59,13 @@ class TestPlatform < CiscoTestCase
|
|
|
34
59
|
end
|
|
35
60
|
|
|
36
61
|
def test_hardware_type
|
|
37
|
-
|
|
62
|
+
if platform == :ios_xr
|
|
63
|
+
s = @device.cmd('show inv | inc "Rack 0"').scan(/DESCR: "(.*)"/)
|
|
64
|
+
elsif platform == :nexus
|
|
65
|
+
s = @device.cmd('sh ver').scan(/Hardware\n\s+(.*)\n/)
|
|
66
|
+
end
|
|
67
|
+
s = s.flatten.first
|
|
68
|
+
refute_empty(Platform.hardware_type)
|
|
38
69
|
# hardware type returns a different value depending on whether you use the
|
|
39
70
|
# ascii or show output of nxapi, but show appears to be substring of ascii
|
|
40
71
|
assert(s.include?(Platform.hardware_type),
|
|
@@ -42,45 +73,60 @@ class TestPlatform < CiscoTestCase
|
|
|
42
73
|
end
|
|
43
74
|
|
|
44
75
|
def test_cpu
|
|
45
|
-
s = @device.cmd('sh ver
|
|
76
|
+
s = @device.cmd('sh ver').scan(
|
|
46
77
|
/Hardware\n\s+.*\n\s+(.*) with/).flatten.first
|
|
47
78
|
assert_equal(s, Platform.cpu)
|
|
48
79
|
end
|
|
49
80
|
|
|
50
81
|
def test_memory
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
82
|
+
if platform == :ios_xr
|
|
83
|
+
arr = @device.cmd('sh mem summ').scan(
|
|
84
|
+
/Physical Memory: (\S+) total.*\((\S+) available/).flatten
|
|
85
|
+
mem_hsh = { 'total' => arr[0],
|
|
86
|
+
'used' => nil,
|
|
87
|
+
'free' => arr[1] }
|
|
88
|
+
elsif platform == :nexus
|
|
89
|
+
arr = @device.cmd('sh sys reso').scan(
|
|
90
|
+
/(\S+) total.* (\S+) used.* (\S+) free/).flatten
|
|
91
|
+
mem_hsh = { 'total' => arr[0],
|
|
92
|
+
'used' => arr[1],
|
|
93
|
+
'free' => arr[2] }
|
|
94
|
+
end
|
|
57
95
|
assert_equal(mem_hsh['total'], Platform.memory['total'])
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
96
|
+
if platform == :nexus
|
|
97
|
+
# used and free mem change rapidly, compare total and sums of free + used
|
|
98
|
+
assert_equal(mem_hsh['used'].to_i + mem_hsh['free'].to_i,
|
|
99
|
+
Platform.memory['used'].to_i + Platform.memory['free'].to_i)
|
|
100
|
+
end
|
|
101
|
+
assert(Platform.memory.key?('used'),
|
|
102
|
+
"Platform memory has no key 'used'")
|
|
103
|
+
assert(Platform.memory.key?('free'),
|
|
104
|
+
"Platform memory has no key 'free'")
|
|
64
105
|
end
|
|
65
106
|
|
|
66
107
|
def test_board
|
|
67
|
-
s = @device.cmd('sh ver
|
|
108
|
+
s = @device.cmd('sh ver').scan(/Board ID (\S+)/).flatten.first
|
|
68
109
|
assert_equal(s, Platform.board)
|
|
69
110
|
end
|
|
70
111
|
|
|
71
112
|
def test_uptime
|
|
72
|
-
s = @device.cmd('sh ver
|
|
113
|
+
s = @device.cmd('sh ver').scan(/uptime is (.*)/).flatten.first
|
|
73
114
|
# compare without seconds
|
|
74
115
|
assert_equal(s.gsub(/\d+ sec/, ''), Platform.uptime.gsub(/\d+ sec/, ''))
|
|
75
116
|
end
|
|
76
117
|
|
|
77
118
|
def test_last_reset
|
|
78
|
-
s = @device.cmd('sh ver
|
|
79
|
-
|
|
119
|
+
s = @device.cmd('sh ver').scan(/usecs after\s+(.*)/).flatten.first
|
|
120
|
+
if Utils.nexus_i2_image
|
|
121
|
+
# Platform issue CSCuy72214, uncertain if this will ever be fixed in I2
|
|
122
|
+
assert_nil(Platform.last_reset)
|
|
123
|
+
else
|
|
124
|
+
assert_equal(s, Platform.last_reset)
|
|
125
|
+
end
|
|
80
126
|
end
|
|
81
127
|
|
|
82
128
|
def test_reset_reason
|
|
83
|
-
s = @device.cmd('sh ver
|
|
129
|
+
s = @device.cmd('sh ver').scan(/Reason: (.*)/).flatten.first
|
|
84
130
|
assert_equal(s, Platform.reset_reason)
|
|
85
131
|
end
|
|
86
132
|
|
|
@@ -103,25 +149,34 @@ class TestPlatform < CiscoTestCase
|
|
|
103
149
|
# Everything from DESCR onwards follows the same general format so we
|
|
104
150
|
# can define a single base regexp and extend it as needed for Chassis, Slot,
|
|
105
151
|
# Power Supply, and Fan inventory entries.
|
|
106
|
-
|
|
107
|
-
|
|
152
|
+
#
|
|
153
|
+
# On some platforms, some fields may be empty:
|
|
154
|
+
# NAME: "Chassis", DESCR: "NX-OSv Chassis"
|
|
155
|
+
# PID: N9K-NXOSV , VID: , SN:
|
|
156
|
+
def inv_cmn_re(name_expr)
|
|
157
|
+
/NAME:\s+"#{name_expr}",\s+
|
|
158
|
+
DESCR:\s+"(.*)"\s*
|
|
159
|
+
\n
|
|
160
|
+
PID:\s+(\S*)\s*,\s*
|
|
161
|
+
VID:\s+(\S*)\s*,\s*
|
|
162
|
+
SN:\s+(\S*)\s*
|
|
163
|
+
$/x
|
|
108
164
|
end
|
|
109
165
|
|
|
110
166
|
def test_chassis
|
|
111
|
-
arr = @device.cmd('sh inv
|
|
167
|
+
arr = @device.cmd('sh inv').scan(inv_cmn_re('Chassis'))
|
|
112
168
|
arr = arr.flatten
|
|
113
169
|
# convert to hash
|
|
114
170
|
chas_hsh = { 'descr' => arr[0],
|
|
115
171
|
'pid' => arr[1],
|
|
116
172
|
'vid' => arr[2],
|
|
117
173
|
'sn' => arr[3],
|
|
118
|
-
}
|
|
174
|
+
} unless arr.empty?
|
|
119
175
|
assert_equal(chas_hsh, Platform.chassis)
|
|
120
176
|
end
|
|
121
177
|
|
|
122
178
|
def test_slots
|
|
123
|
-
slots_arr_arr = @device.cmd('sh inv
|
|
124
|
-
.scan(/NAME:\s+"(Slot \d+)"#{inv_cmn_re}/)
|
|
179
|
+
slots_arr_arr = @device.cmd('sh inv').scan(inv_cmn_re('(Slot\s+\d+)'))
|
|
125
180
|
# convert to array of slot hashes
|
|
126
181
|
slots_hsh_hsh = {}
|
|
127
182
|
slots_arr_arr.each do |slot|
|
|
@@ -135,10 +190,8 @@ class TestPlatform < CiscoTestCase
|
|
|
135
190
|
end
|
|
136
191
|
|
|
137
192
|
def test_power_supplies
|
|
138
|
-
pwr_arr_arr = @device.cmd('sh inv
|
|
139
|
-
.scan(
|
|
140
|
-
refute_empty(pwr_arr_arr,
|
|
141
|
-
'Regex scan failed to match show inventory output')
|
|
193
|
+
pwr_arr_arr = @device.cmd('sh inv')
|
|
194
|
+
.scan(inv_cmn_re('(Power\s+Supply\s+\d+)'))
|
|
142
195
|
|
|
143
196
|
# convert to array of power supply hashes
|
|
144
197
|
pwr_hsh_hsh = {}
|
|
@@ -153,10 +206,7 @@ class TestPlatform < CiscoTestCase
|
|
|
153
206
|
end
|
|
154
207
|
|
|
155
208
|
def test_fans
|
|
156
|
-
fan_arr_arr = @device.cmd('sh inv
|
|
157
|
-
.scan(/NAME:\s+"(Fan \d+)"#{inv_cmn_re}/)
|
|
158
|
-
refute_empty(fan_arr_arr,
|
|
159
|
-
'Regex scan failed to match show inventory output')
|
|
209
|
+
fan_arr_arr = @device.cmd('sh inv').scan(inv_cmn_re('(Fan\s+\d+)'))
|
|
160
210
|
|
|
161
211
|
# convert to array of fan hashes
|
|
162
212
|
fan_hsh_hsh = {}
|
|
@@ -171,9 +221,6 @@ class TestPlatform < CiscoTestCase
|
|
|
171
221
|
end
|
|
172
222
|
|
|
173
223
|
def test_virtual_services
|
|
174
|
-
skip('Skip test: No virtual-services installed') unless
|
|
175
|
-
@device.cmd('show virtual-service list')[/Name\s+Status\s+Package Name/]
|
|
176
|
-
|
|
177
224
|
# this would be beyond ugly to parse from ascii, utilize config_get
|
|
178
225
|
vir_arr = node.config_get('virtual_service', 'services')
|
|
179
226
|
vir_arr = [vir_arr] if vir_arr.is_a? Hash
|
|
@@ -17,24 +17,26 @@ require_relative '../lib/cisco_node_utils/portchannel_global'
|
|
|
17
17
|
|
|
18
18
|
# TestX__CLASS_NAME__X - Minitest for X__CLASS_NAME__X node utility class
|
|
19
19
|
class TestPortchannelGlobal < CiscoTestCase
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
@skip_unless_supported = 'portchannel_global'
|
|
21
|
+
@@cleaned = false # rubocop:disable Style/ClassVars
|
|
22
22
|
DEFAULT_NAME = 'default'
|
|
23
23
|
|
|
24
24
|
def setup
|
|
25
25
|
super
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
n9k_platform? || n7k_platform?
|
|
26
|
+
cleanup unless @@cleaned
|
|
27
|
+
@@cleaned = true # rubocop:disable Style/ClassVars
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def teardown
|
|
32
|
-
|
|
33
|
-
config 'no port-channel load-balance ethernet' unless
|
|
34
|
-
n9k_platform? || n7k_platform?
|
|
31
|
+
cleanup
|
|
35
32
|
super
|
|
36
33
|
end
|
|
37
34
|
|
|
35
|
+
def cleanup
|
|
36
|
+
ethernet = node.product_id[/N(3|7|8|9)/] ? '' : 'ethernet'
|
|
37
|
+
config_no_warn "no port-channel load-balance #{ethernet}"
|
|
38
|
+
end
|
|
39
|
+
|
|
38
40
|
def n3k_in_n3k_mode?
|
|
39
41
|
return unless /N3/ =~ node.product_id
|
|
40
42
|
mode = config('show system switch-mode')
|
|
@@ -44,159 +46,233 @@ class TestPortchannelGlobal < CiscoTestCase
|
|
|
44
46
|
mode[Regexp.union(patterns)] ? true : false
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
def n7k_platform?
|
|
48
|
-
/N7/ =~ node.product_id
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def n9k_platform?
|
|
52
|
-
/N(3|9)/ =~ node.product_id
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def n6k_platform?
|
|
56
|
-
/N(5|6)/ =~ node.product_id
|
|
57
|
-
end
|
|
58
|
-
|
|
59
49
|
def create_portchannel_global(name=DEFAULT_NAME)
|
|
60
50
|
PortChannelGlobal.new(name)
|
|
61
51
|
end
|
|
62
52
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
def test_hash_distribution
|
|
54
|
+
global = create_portchannel_global
|
|
55
|
+
if validate_property_excluded?('portchannel_global', 'hash_distribution')
|
|
56
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
57
|
+
global.hash_distribution = 'fixed'
|
|
58
|
+
end
|
|
59
|
+
assert_nil(global.hash_distribution)
|
|
60
|
+
else
|
|
61
|
+
global.hash_distribution = 'fixed'
|
|
62
|
+
assert_equal('fixed', global.hash_distribution)
|
|
63
|
+
global.hash_distribution =
|
|
64
|
+
global.default_hash_distribution
|
|
65
|
+
assert_equal(global.default_hash_distribution,
|
|
66
|
+
global.hash_distribution)
|
|
67
|
+
end
|
|
73
68
|
end
|
|
74
69
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
def test_load_defer
|
|
71
|
+
global = create_portchannel_global
|
|
72
|
+
if validate_property_excluded?('portchannel_global', 'load_defer')
|
|
73
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
74
|
+
global.load_defer = 1000
|
|
75
|
+
end
|
|
76
|
+
assert_nil(global.load_defer)
|
|
77
|
+
else
|
|
78
|
+
global.load_defer = 1000
|
|
79
|
+
assert_equal(1000, global.load_defer)
|
|
80
|
+
global.load_defer =
|
|
81
|
+
global.default_load_defer
|
|
82
|
+
assert_equal(global.default_load_defer,
|
|
83
|
+
global.load_defer)
|
|
84
|
+
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
def
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
def test_resilient
|
|
88
|
+
global = create_portchannel_global
|
|
89
|
+
if validate_property_excluded?('portchannel_global', 'resilient')
|
|
90
|
+
assert_raises(Cisco::UnsupportedError) { global.resilient = true }
|
|
91
|
+
assert_nil(global.resilient)
|
|
92
|
+
return
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Verify that hardware supports feature. Unfortunately the current cli
|
|
96
|
+
# only displays a warning and does not raise an error so we have to
|
|
97
|
+
# test for it explicitly.
|
|
98
|
+
cmd = 'port-channel load-balance resilient'
|
|
99
|
+
skip('Skip test: Feature is not supported on this device') if
|
|
100
|
+
config(cmd)[/Resilient Hashing Mode unsupported/]
|
|
101
|
+
global = create_portchannel_global
|
|
102
|
+
# For n3k the default is different from n9k
|
|
103
|
+
if n3k_in_n3k_mode?
|
|
104
|
+
global.resilient = false
|
|
105
|
+
refute(global.resilient)
|
|
106
|
+
global.resilient = global.default_resilient
|
|
107
|
+
assert_equal(global.default_resilient, global.resilient)
|
|
108
|
+
else
|
|
109
|
+
config('no ' + cmd)
|
|
110
|
+
global = create_portchannel_global
|
|
111
|
+
global.resilient = true
|
|
112
|
+
assert(global.resilient)
|
|
113
|
+
global.resilient = global.default_resilient
|
|
114
|
+
assert_equal(global.default_resilient, global.resilient)
|
|
115
|
+
end
|
|
95
116
|
end
|
|
96
117
|
|
|
97
|
-
def
|
|
98
|
-
skip('
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
def test_load_balance_no_rotate
|
|
119
|
+
skip('Test not supported on this platform') unless n3k_in_n3k_mode?
|
|
120
|
+
|
|
121
|
+
global = create_portchannel_global
|
|
122
|
+
global.send(:port_channel_load_balance=,
|
|
123
|
+
'src-dst', 'ip-only', nil, nil, true, nil, nil)
|
|
103
124
|
assert_equal('src-dst',
|
|
104
|
-
|
|
105
|
-
assert_equal('ip-
|
|
106
|
-
|
|
107
|
-
assert_equal(true,
|
|
108
|
-
|
|
109
|
-
assert_equal(4, @global.rotate)
|
|
110
|
-
@global.send(
|
|
125
|
+
global.bundle_select)
|
|
126
|
+
assert_equal('ip-only',
|
|
127
|
+
global.bundle_hash)
|
|
128
|
+
assert_equal(true, global.symmetry)
|
|
129
|
+
global.send(
|
|
111
130
|
:port_channel_load_balance=,
|
|
112
|
-
|
|
113
|
-
|
|
131
|
+
global.default_bundle_select,
|
|
132
|
+
global.default_bundle_hash,
|
|
114
133
|
nil,
|
|
115
134
|
nil,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
assert_equal(
|
|
120
|
-
@global.default_bundle_select,
|
|
121
|
-
@global.bundle_select)
|
|
135
|
+
global.default_symmetry,
|
|
136
|
+
nil,
|
|
137
|
+
nil)
|
|
122
138
|
assert_equal(
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
global.default_bundle_select,
|
|
140
|
+
global.bundle_select)
|
|
125
141
|
assert_equal(
|
|
126
|
-
|
|
127
|
-
|
|
142
|
+
global.default_bundle_hash,
|
|
143
|
+
global.bundle_hash)
|
|
128
144
|
assert_equal(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
assert_equal(@global.default_rotate,
|
|
132
|
-
@global.rotate)
|
|
145
|
+
global.default_symmetry,
|
|
146
|
+
global.symmetry)
|
|
133
147
|
end
|
|
134
148
|
|
|
135
|
-
def
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
'src-dst', 'ip-only', 'CRC10c', nil, nil, nil, nil)
|
|
141
|
-
assert_equal('src-dst',
|
|
142
|
-
@global.bundle_select)
|
|
143
|
-
assert_equal('ip-only',
|
|
144
|
-
@global.bundle_hash)
|
|
145
|
-
assert_equal('CRC10c', @global.hash_poly)
|
|
146
|
-
@global.send(:port_channel_load_balance=,
|
|
147
|
-
'dst', 'mac', 'CRC10a', nil, nil, nil, nil)
|
|
148
|
-
assert_equal('dst',
|
|
149
|
-
@global.bundle_select)
|
|
150
|
-
assert_equal('mac',
|
|
151
|
-
@global.bundle_hash)
|
|
152
|
-
assert_equal('CRC10a', @global.hash_poly)
|
|
153
|
-
@global.send(
|
|
154
|
-
:port_channel_load_balance=,
|
|
155
|
-
@global.default_bundle_select,
|
|
156
|
-
@global.default_bundle_hash,
|
|
157
|
-
@global.default_hash_poly,
|
|
158
|
-
nil, nil, nil, nil)
|
|
159
|
-
assert_equal(
|
|
160
|
-
@global.default_bundle_select,
|
|
161
|
-
@global.bundle_select)
|
|
162
|
-
assert_equal(
|
|
163
|
-
@global.default_bundle_hash,
|
|
164
|
-
@global.bundle_hash)
|
|
165
|
-
assert_equal(@global.default_hash_poly,
|
|
166
|
-
@global.hash_poly)
|
|
167
|
-
end
|
|
149
|
+
def test_load_balance_sym_concat_rot
|
|
150
|
+
# rubocop:disable Style/MultilineOperationIndentation
|
|
151
|
+
skip('Test not supported on this platform') if n3k_in_n3k_mode? ||
|
|
152
|
+
validate_property_excluded?('portchannel_global', 'symmetry')
|
|
153
|
+
# rubocop:enable Style/MultilineOperationIndentation
|
|
168
154
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@global = create_portchannel_global
|
|
173
|
-
@global.send(:port_channel_load_balance=,
|
|
174
|
-
'src-dst', 'ip-vlan', nil, true, nil, nil, 4)
|
|
155
|
+
global = create_portchannel_global
|
|
156
|
+
global.send(:port_channel_load_balance=,
|
|
157
|
+
'src-dst', 'ip-l4port', nil, nil, true, true, 4)
|
|
175
158
|
assert_equal('src-dst',
|
|
176
|
-
|
|
177
|
-
assert_equal('ip-
|
|
178
|
-
|
|
179
|
-
assert_equal(true,
|
|
180
|
-
assert_equal(
|
|
181
|
-
|
|
159
|
+
global.bundle_select)
|
|
160
|
+
assert_equal('ip-l4port',
|
|
161
|
+
global.bundle_hash)
|
|
162
|
+
assert_equal(true, global.symmetry)
|
|
163
|
+
assert_equal(true, global.concatenation)
|
|
164
|
+
assert_equal(4, global.rotate)
|
|
165
|
+
global.send(
|
|
182
166
|
:port_channel_load_balance=,
|
|
183
|
-
|
|
184
|
-
|
|
167
|
+
global.default_bundle_select,
|
|
168
|
+
global.default_bundle_hash,
|
|
185
169
|
nil,
|
|
186
|
-
@global.default_asymmetric,
|
|
187
170
|
nil,
|
|
188
|
-
|
|
189
|
-
|
|
171
|
+
global.default_symmetry,
|
|
172
|
+
global.default_concatenation,
|
|
173
|
+
global.default_rotate)
|
|
174
|
+
assert_equal(
|
|
175
|
+
global.default_bundle_select,
|
|
176
|
+
global.bundle_select)
|
|
190
177
|
assert_equal(
|
|
191
|
-
|
|
192
|
-
|
|
178
|
+
global.default_bundle_hash,
|
|
179
|
+
global.bundle_hash)
|
|
193
180
|
assert_equal(
|
|
194
|
-
|
|
195
|
-
|
|
181
|
+
global.default_symmetry,
|
|
182
|
+
global.symmetry)
|
|
196
183
|
assert_equal(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
assert_equal(
|
|
200
|
-
|
|
184
|
+
global.default_concatenation,
|
|
185
|
+
global.concatenation)
|
|
186
|
+
assert_equal(global.default_rotate,
|
|
187
|
+
global.rotate)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# assert_hash_poly_crc
|
|
191
|
+
# Depending on the chipset, hash_poly may have have a different
|
|
192
|
+
# default value within the same platform family (this is done to
|
|
193
|
+
# avoid polarization) but there is currently no command available
|
|
194
|
+
# to dynamically determine the default state. As a result the
|
|
195
|
+
# getter simply hard-codes a default value which means it may
|
|
196
|
+
# encounter occasional idempotence issues.
|
|
197
|
+
# For testing purposes this becomes a best-effort test; i.e. we expect the
|
|
198
|
+
# hash_poly test to pass for all asserts except the one that matches the
|
|
199
|
+
# default value for that chipset.
|
|
200
|
+
def assert_hash_poly_crc(exp, actual)
|
|
201
|
+
assert_equal(exp, actual) if exp == actual
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def test_load_balance_hash_poly
|
|
205
|
+
global = create_portchannel_global
|
|
206
|
+
if validate_property_excluded?('portchannel_global', 'hash_poly')
|
|
207
|
+
skip('Test not supported on this platform')
|
|
208
|
+
return
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
global.send(:port_channel_load_balance=,
|
|
212
|
+
'src-dst', 'ip-only', 'CRC10c', nil, nil, nil, nil)
|
|
213
|
+
assert_equal('src-dst', global.bundle_select)
|
|
214
|
+
assert_equal('ip-only', global.bundle_hash)
|
|
215
|
+
assert_hash_poly_crc('CRC10c', global.hash_poly)
|
|
216
|
+
|
|
217
|
+
global.send(:port_channel_load_balance=,
|
|
218
|
+
'dst', 'mac', 'CRC10a', nil, nil, nil, nil)
|
|
219
|
+
assert_equal('dst', global.bundle_select)
|
|
220
|
+
assert_equal('mac', global.bundle_hash)
|
|
221
|
+
assert_hash_poly_crc('CRC10a', global.hash_poly)
|
|
222
|
+
|
|
223
|
+
global.send(:port_channel_load_balance=,
|
|
224
|
+
global.default_bundle_select,
|
|
225
|
+
global.default_bundle_hash,
|
|
226
|
+
'CRC10b', nil, nil, nil, nil)
|
|
227
|
+
assert_equal(global.default_bundle_select, global.bundle_select)
|
|
228
|
+
assert_equal(global.default_bundle_hash, global.bundle_hash)
|
|
229
|
+
assert_hash_poly_crc('CRC10b', global.hash_poly)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def test_load_balance_asym_rot
|
|
233
|
+
global = create_portchannel_global
|
|
234
|
+
if validate_property_excluded?('portchannel_global', 'asymmetric')
|
|
235
|
+
skip('Test not supported on this platform')
|
|
236
|
+
return
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
global.send(:port_channel_load_balance=,
|
|
240
|
+
'src-dst', 'ip-vlan', nil, true, nil, nil, 4)
|
|
241
|
+
assert_equal('src-dst', global.bundle_select)
|
|
242
|
+
assert_equal('ip-vlan', global.bundle_hash)
|
|
243
|
+
assert_equal(true, global.asymmetric)
|
|
244
|
+
assert_equal(4, global.rotate)
|
|
245
|
+
|
|
246
|
+
global.send(:port_channel_load_balance=,
|
|
247
|
+
global.default_bundle_select,
|
|
248
|
+
global.default_bundle_hash,
|
|
249
|
+
nil, global.default_asymmetric,
|
|
250
|
+
nil, nil, global.default_rotate)
|
|
251
|
+
assert_equal(global.default_bundle_select, global.bundle_select)
|
|
252
|
+
assert_equal(global.default_bundle_hash, global.bundle_hash)
|
|
253
|
+
assert_equal(global.default_asymmetric, global.asymmetric)
|
|
254
|
+
assert_equal(global.default_rotate, global.rotate)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_load_balance_no_hash_rot
|
|
258
|
+
global = create_portchannel_global
|
|
259
|
+
if validate_property_excluded?('portchannel_global', 'rotate')
|
|
260
|
+
skip('Test not supported on this platform')
|
|
261
|
+
return
|
|
262
|
+
end
|
|
263
|
+
global.send(:port_channel_load_balance=,
|
|
264
|
+
'src-dst', 'ip-vlan', nil, nil, nil, nil, 4)
|
|
265
|
+
assert_equal('src-dst', global.bundle_select)
|
|
266
|
+
assert_equal('ip-vlan', global.bundle_hash)
|
|
267
|
+
assert_equal(4, global.rotate)
|
|
268
|
+
|
|
269
|
+
global.send(:port_channel_load_balance=,
|
|
270
|
+
global.default_bundle_select,
|
|
271
|
+
global.default_bundle_hash,
|
|
272
|
+
nil, nil,
|
|
273
|
+
nil, nil, global.default_rotate)
|
|
274
|
+
assert_equal(global.default_bundle_select, global.bundle_select)
|
|
275
|
+
assert_equal(global.default_bundle_hash, global.bundle_hash)
|
|
276
|
+
assert_equal(global.default_rotate, global.rotate)
|
|
201
277
|
end
|
|
202
278
|
end
|