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.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +4 -1
  6. data/CHANGELOG.md +81 -2
  7. data/CONTRIBUTING.md +2 -17
  8. data/Gemfile +5 -0
  9. data/README.md +92 -47
  10. data/Rakefile +23 -1
  11. data/bin/git/hooks/hook_lib +7 -0
  12. data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
  13. data/bin/git/hooks/pre-commit/rubocop +7 -2
  14. data/bin/git/hooks/pre-commit/validate-diffs +18 -4
  15. data/bin/git/hooks/pre-commit/validate-yaml +18 -0
  16. data/bin/git/update-hooks +64 -6
  17. data/cisco_node_utils.gemspec +9 -6
  18. data/docs/README-develop-best-practices.md +149 -50
  19. data/docs/README-develop-node-utils-APIs.md +92 -42
  20. data/docs/README-maintainers.md +7 -4
  21. data/docs/README-test-execution.md +57 -0
  22. data/docs/cisco_node_utils.yaml.example +30 -0
  23. data/docs/template-router.rb +4 -0
  24. data/ext/mkrf_conf.rb +63 -0
  25. data/lib/.rubocop.yml +2 -2
  26. data/lib/cisco_node_utils.rb +5 -0
  27. data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
  28. data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
  29. data/lib/cisco_node_utils/ace.rb +165 -12
  30. data/lib/cisco_node_utils/acl.rb +2 -1
  31. data/lib/cisco_node_utils/bgp.rb +184 -21
  32. data/lib/cisco_node_utils/bgp_af.rb +94 -249
  33. data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
  34. data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
  35. data/lib/cisco_node_utils/bridge_domain.rb +183 -0
  36. data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
  37. data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
  38. data/lib/cisco_node_utils/client.rb +35 -0
  39. data/lib/cisco_node_utils/client/client.rb +234 -0
  40. data/lib/cisco_node_utils/client/grpc.rb +33 -0
  41. data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
  42. data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
  43. data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
  44. data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
  45. data/lib/cisco_node_utils/client/nxapi.rb +31 -0
  46. data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
  47. data/lib/cisco_node_utils/client/utils.rb +164 -0
  48. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
  49. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
  50. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
  51. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
  52. data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
  53. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
  54. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
  55. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
  56. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
  57. data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
  58. data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
  59. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
  60. data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
  61. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
  62. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
  63. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
  64. data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
  65. data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
  66. data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
  67. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
  68. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
  69. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
  70. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
  71. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
  72. data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
  73. data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
  74. data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
  75. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
  76. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
  77. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
  78. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
  79. data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
  80. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
  81. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
  82. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
  83. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
  84. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
  85. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
  86. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
  87. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
  88. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
  89. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
  90. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
  91. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
  92. data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
  93. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
  94. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
  95. data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
  96. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
  97. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
  98. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
  99. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
  100. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
  101. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
  102. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
  103. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
  104. data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
  105. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
  106. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
  107. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
  108. data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
  109. data/lib/cisco_node_utils/command_reference.rb +261 -142
  110. data/lib/cisco_node_utils/constants.rb +33 -0
  111. data/lib/cisco_node_utils/encapsulation.rb +112 -0
  112. data/lib/cisco_node_utils/environment.rb +102 -0
  113. data/lib/cisco_node_utils/evpn_vni.rb +5 -3
  114. data/lib/cisco_node_utils/exceptions.rb +111 -0
  115. data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
  116. data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
  117. data/lib/cisco_node_utils/feature.rb +165 -3
  118. data/lib/cisco_node_utils/interface.rb +1051 -260
  119. data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
  120. data/lib/cisco_node_utils/interface_ospf.rb +1 -2
  121. data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
  122. data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
  123. data/lib/cisco_node_utils/itd_device_group.rb +248 -0
  124. data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
  125. data/lib/cisco_node_utils/itd_service.rb +523 -0
  126. data/lib/cisco_node_utils/logger.rb +75 -0
  127. data/lib/cisco_node_utils/node.rb +62 -192
  128. data/lib/cisco_node_utils/node_util.rb +56 -10
  129. data/lib/cisco_node_utils/overlay_global.rb +2 -2
  130. data/lib/cisco_node_utils/pim.rb +2 -13
  131. data/lib/cisco_node_utils/pim_group_list.rb +1 -1
  132. data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
  133. data/lib/cisco_node_utils/platform.rb +52 -21
  134. data/lib/cisco_node_utils/portchannel_global.rb +89 -19
  135. data/lib/cisco_node_utils/radius_server.rb +168 -37
  136. data/lib/cisco_node_utils/router_ospf.rb +20 -35
  137. data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
  138. data/lib/cisco_node_utils/snmpserver.rb +1 -6
  139. data/lib/cisco_node_utils/snmpuser.rb +6 -4
  140. data/lib/cisco_node_utils/stp_global.rb +676 -0
  141. data/lib/cisco_node_utils/syslog_server.rb +77 -18
  142. data/lib/cisco_node_utils/syslog_settings.rb +1 -1
  143. data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
  144. data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
  145. data/lib/cisco_node_utils/vdc.rb +12 -0
  146. data/lib/cisco_node_utils/version.rb +1 -1
  147. data/lib/cisco_node_utils/vlan.rb +147 -29
  148. data/lib/cisco_node_utils/vpc.rb +55 -3
  149. data/lib/cisco_node_utils/vrf.rb +72 -11
  150. data/lib/cisco_node_utils/vrf_af.rb +114 -29
  151. data/lib/cisco_node_utils/vtp.rb +34 -52
  152. data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
  153. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
  154. data/lib/minitest/environment_plugin.rb +31 -0
  155. data/lib/minitest/log_level_plugin.rb +41 -0
  156. data/spec/client_spec.rb +7 -0
  157. data/spec/environment_spec.rb +263 -0
  158. data/spec/grpc_client_spec.rb +23 -0
  159. data/spec/isolate/all_clients_spec.rb +9 -0
  160. data/spec/isolate/grpc_only_spec.rb +16 -0
  161. data/spec/isolate/no_clients_spec.rb +26 -0
  162. data/spec/isolate/nxapi_only_spec.rb +16 -0
  163. data/spec/nxapi_client_spec.rb +42 -0
  164. data/spec/schema.yaml +75 -0
  165. data/spec/shared_examples_for_clients.rb +14 -0
  166. data/spec/spec_helper.rb +91 -0
  167. data/spec/whitespace_spec.rb +10 -0
  168. data/spec/yaml_spec.rb +42 -0
  169. data/tests/.rubocop.yml +2 -2
  170. data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
  171. data/tests/basetest.rb +96 -36
  172. data/tests/ciscotest.rb +220 -12
  173. data/tests/cmd_config.yaml +71 -49
  174. data/tests/cmd_config_invalid.yaml +1 -1
  175. data/tests/test_aaa_authentication_login.rb +1 -0
  176. data/tests/test_aaa_authentication_login_service.rb +9 -0
  177. data/tests/test_aaa_authorization_service.rb +173 -367
  178. data/tests/test_ace.rb +171 -100
  179. data/tests/test_acl.rb +10 -1
  180. data/tests/test_bgp_af.rb +395 -728
  181. data/tests/test_bgp_neighbor.rb +274 -115
  182. data/tests/test_bgp_neighbor_af.rb +178 -77
  183. data/tests/test_bridge_domain.rb +191 -0
  184. data/tests/test_bridge_domain_vni.rb +116 -0
  185. data/tests/test_client_utils.rb +111 -0
  186. data/tests/test_command_config.rb +9 -5
  187. data/tests/test_command_reference.rb +380 -102
  188. data/tests/test_dns_domain.rb +13 -3
  189. data/tests/test_domain_name.rb +13 -3
  190. data/tests/test_encapsulation.rb +77 -0
  191. data/tests/test_evpn_vni.rb +25 -7
  192. data/tests/test_fabricpath_global.rb +167 -163
  193. data/tests/test_fabricpath_topology.rb +12 -33
  194. data/tests/test_feature.rb +215 -0
  195. data/tests/test_grpc.rb +166 -0
  196. data/tests/test_interface.rb +585 -344
  197. data/tests/test_interface_bdi.rb +80 -0
  198. data/tests/test_interface_channel_group.rb +6 -3
  199. data/tests/test_interface_ospf.rb +26 -24
  200. data/tests/test_interface_portchannel.rb +1 -0
  201. data/tests/test_interface_private_vlan.rb +724 -0
  202. data/tests/test_interface_service_vni.rb +37 -66
  203. data/tests/test_interface_svi.rb +98 -101
  204. data/tests/test_interface_switchport.rb +419 -549
  205. data/tests/test_itd_device_group.rb +145 -0
  206. data/tests/test_itd_device_group_node.rb +199 -0
  207. data/tests/test_itd_service.rb +298 -0
  208. data/tests/test_logger.rb +43 -0
  209. data/tests/test_name_server.rb +11 -2
  210. data/tests/test_node.rb +16 -75
  211. data/tests/test_node_ext.rb +174 -163
  212. data/tests/test_node_util.rb +119 -0
  213. data/tests/test_ntp_config.rb +5 -1
  214. data/tests/test_ntp_server.rb +2 -2
  215. data/tests/test_nxapi.rb +221 -0
  216. data/tests/test_overlay_global.rb +47 -38
  217. data/tests/test_pim.rb +2 -0
  218. data/tests/test_pim_group_list.rb +2 -0
  219. data/tests/test_pim_rp_address.rb +2 -0
  220. data/tests/test_platform.rb +86 -39
  221. data/tests/test_portchannel_global.rb +211 -135
  222. data/tests/test_radius_global.rb +13 -5
  223. data/tests/test_radius_server.rb +256 -104
  224. data/tests/test_radius_server_group.rb +2 -0
  225. data/tests/test_router_bgp.rb +781 -485
  226. data/tests/test_router_ospf.rb +26 -103
  227. data/tests/test_router_ospf_vrf.rb +52 -57
  228. data/tests/test_snmp_notification_receiver.rb +2 -0
  229. data/tests/test_snmpcommunity.rb +2 -0
  230. data/tests/test_snmpgroup.rb +2 -0
  231. data/tests/test_snmpnotification.rb +40 -21
  232. data/tests/test_snmpserver.rb +2 -0
  233. data/tests/test_snmpuser.rb +2 -0
  234. data/tests/test_stp_global.rb +563 -0
  235. data/tests/test_syslog_server.rb +32 -8
  236. data/tests/test_syslog_settings.rb +22 -9
  237. data/tests/test_tacacs_server.rb +32 -27
  238. data/tests/test_tacacs_server_group.rb +100 -45
  239. data/tests/test_tacacs_server_host.rb +135 -43
  240. data/tests/test_vdc.rb +2 -16
  241. data/tests/test_vlan.rb +106 -54
  242. data/tests/test_vlan_mt_full.rb +11 -21
  243. data/tests/test_vlan_private.rb +669 -0
  244. data/tests/test_vpc.rb +312 -159
  245. data/tests/test_vrf.rb +122 -113
  246. data/tests/test_vrf_af.rb +238 -0
  247. data/tests/test_vtp.rb +58 -102
  248. data/tests/test_vxlan_vtep.rb +38 -17
  249. data/tests/test_vxlan_vtep_vni.rb +61 -9
  250. data/tests/test_yum.rb +49 -25
  251. metadata +122 -36
  252. data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
  253. data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
  254. data/lib/cisco_node_utils/vni.rb +0 -227
  255. data/tests/test_vni.rb +0 -106
@@ -23,13 +23,27 @@ DEFAULT_TACACS_SERVER_HOST_ENCRYPTION_PASSWORD = ''
23
23
 
24
24
  # TestTacacsServerHost - Minitest for TacacsServerHost node utility
25
25
  class TestTacacsServerHost < CiscoTestCase
26
+ @skip_unless_supported = 'tacacs_server_host'
27
+
26
28
  def setup
27
29
  super
28
- @host_name = 'testhost'
29
- @default_show_command = 'show run all | inc "tacacs-server" | no-more'
30
+ if platform == :nexus
31
+ @host_name = 'testhost'
32
+ @default_show_command = 'show run all | inc "tacacs-server" | no-more'
33
+ else
34
+ @default_show_command = 'show running-config tacacs-server'
35
+ @host_name = '2.2.2.2'
36
+ end
30
37
  @default_output_pattern = /tacacs-server host\s(#{@host_name})(.*)/
31
38
  end
32
39
 
40
+ # Not for Nexus
41
+ def no_tacacsserver
42
+ # Turn the feature off for a clean test.
43
+ config('no aaa group server tacacs red',
44
+ 'no aaa group server tacacs blue')
45
+ end
46
+
33
47
  def test_tacacsserverhost_collection_empty
34
48
  hosts = TacacsServerHost.hosts
35
49
  hosts.each_value(&:destroy)
@@ -40,12 +54,16 @@ class TestTacacsServerHost < CiscoTestCase
40
54
 
41
55
  def test_tacacsserverhost_collection
42
56
  hosts_hash = {}
43
- hosts_hash['testhost1'] = 1138
44
- hosts_hash['testhost2'] = DEFAULT_TACACS_SERVER_HOST_PORT
57
+ hosts_hash['4.4.4.4'] = 1138
58
+ hosts_hash['5.5.5.5'] = DEFAULT_TACACS_SERVER_HOST_PORT
45
59
 
46
60
  hosts_hash.each do |name, port|
47
- host = TacacsServerHost.new(name)
48
- host.port = port
61
+ if platform != :ios_xr
62
+ host = TacacsServerHost.new(name)
63
+ host.port = port
64
+ else
65
+ TacacsServerHost.new(name, true, port)
66
+ end
49
67
  end
50
68
 
51
69
  hosts = TacacsServerHost.hosts
@@ -71,7 +89,7 @@ class TestTacacsServerHost < CiscoTestCase
71
89
  end
72
90
 
73
91
  def test_tacacsserverhost_create_valid
74
- host = TacacsServerHost.new('testhost')
92
+ host = TacacsServerHost.new(@host_name)
75
93
  assert_show_match(msg: 'Error: Tacacs Host not created')
76
94
  host.destroy
77
95
  end
@@ -113,21 +131,24 @@ class TestTacacsServerHost < CiscoTestCase
113
131
  host_name = 'testhost.example.com'
114
132
  host_ip = '192.168.1.1'
115
133
 
116
- config("tacacs-server host #{host_name}", "tacacs-server host #{host_ip}")
134
+ config("tacacs-server host #{host_name}") unless platform == :ios_xr
135
+ config("tacacs-server host #{host_ip}")
117
136
 
118
137
  line_name = assert_show_match(
119
138
  pattern: /tacacs-server host\s(testhost\.example\.com)(.*)/,
120
- msg: 'Error: Tacacs Host not found')
139
+ msg: 'Error: Tacacs Host not found') unless platform == :ios_xr
121
140
  line_ip = assert_show_match(
122
141
  pattern: /tacacs-server host\s(192\.168\.1\.1)(.*)/,
123
142
  msg: 'Error: Tacacs Host not found')
124
143
  hosts = TacacsServerHost.hosts
125
144
 
126
- assert_equal(host_name, line_name.captures[0],
127
- "Error: #{host_name} name mismatch")
128
- refute_nil(hosts[host_name], "Error: #{host_name} not retrieved.")
129
- assert_equal(host_name, hosts[host_name].name,
130
- "Error: #{host_name} name get value mismatch")
145
+ unless platform == :ios_xr
146
+ assert_equal(host_name, line_name.captures[0],
147
+ "Error: #{host_name} name mismatch")
148
+ refute_nil(hosts[host_name], "Error: #{host_name} not retrieved.")
149
+ assert_equal(host_name, hosts[host_name].name,
150
+ "Error: #{host_name} name get value mismatch")
151
+ end
131
152
 
132
153
  assert_equal(host_ip, line_ip.captures[0],
133
154
  "Error: #{host_ip} name mismatch")
@@ -145,16 +166,19 @@ class TestTacacsServerHost < CiscoTestCase
145
166
  port = DEFAULT_TACACS_SERVER_HOST_PORT
146
167
  assert_equal(port, host.port, 'Error: Tacacs Host port incorrect')
147
168
 
148
- # when configured
149
- port = 1138
150
- config("tacacs-server host #{@host_name} port #{port}")
151
- assert_equal(port, host.port, 'Error: Tacacs Host port incorrect')
169
+ # IOS XR support the same host using different ports
170
+ unless platform == :ios_xr
171
+ # when configured
172
+ port = 1138
173
+ host.port = port
174
+ assert_equal(port, host.port, 'Error: Tacacs Host port incorrect')
175
+ end
152
176
 
153
177
  host.destroy
154
178
  end
155
179
 
156
180
  def test_tacacsserverhost_get_default_port
157
- host = TacacsServerHost.new('testhost')
181
+ host = TacacsServerHost.new(@host_name)
158
182
 
159
183
  port = DEFAULT_TACACS_SERVER_HOST_PORT
160
184
  assert_equal(port, TacacsServerHost.default_port,
@@ -163,6 +187,8 @@ class TestTacacsServerHost < CiscoTestCase
163
187
  end
164
188
 
165
189
  def test_tacacsserverhost_set_port
190
+ return if platform == :ios_xr
191
+
166
192
  host = TacacsServerHost.new(@host_name)
167
193
 
168
194
  port = 1138
@@ -189,14 +215,14 @@ class TestTacacsServerHost < CiscoTestCase
189
215
 
190
216
  # when configured
191
217
  timeout = 30
192
- config("tacacs-server host #{@host_name} timeout #{timeout}")
218
+ host.timeout = timeout
193
219
  assert_equal(timeout, host.timeout, 'Error: Tacacs Host timeout incorrect')
194
220
 
195
221
  host.destroy
196
222
  end
197
223
 
198
224
  def test_tacacsserverhost_get_default_timeout
199
- host = TacacsServerHost.new('testhost')
225
+ host = TacacsServerHost.new(@host_name)
200
226
 
201
227
  timeout = DEFAULT_TACACS_SERVER_HOST_TIMEOUT
202
228
  assert_equal(timeout, TacacsServerHost.default_timeout,
@@ -210,10 +236,14 @@ class TestTacacsServerHost < CiscoTestCase
210
236
  timeout = 30
211
237
  host.timeout = timeout
212
238
  line = assert_show_match(msg: 'Error: Tacacs Host not found')
213
- assert_match(/timeout\s(\d*)/, line.captures[1])
214
- md = /timeout\s(\d*)/.match(line.captures[1])
215
- assert_equal(timeout, md.captures[0].to_i,
216
- 'Error: Tacacs Host timeout mismatch')
239
+
240
+ if platform != :ios_xr
241
+ assert_match(/timeout\s(\d*)/, line.captures[1])
242
+ md = /timeout\s(\d*)/.match(line.captures[1])
243
+ assert_equal(timeout, md.captures[0].to_i,
244
+ 'Error: Tacacs Host timeout mismatch')
245
+ end
246
+
217
247
  assert_equal(timeout, host.timeout, 'Error: Tacacs Host timeout incorrect')
218
248
 
219
249
  host.destroy
@@ -243,14 +273,14 @@ class TestTacacsServerHost < CiscoTestCase
243
273
  # when configured
244
274
  enctype = TACACS_SERVER_ENC_NONE
245
275
  sh_run_enctype = TACACS_SERVER_ENC_CISCO_TYPE_7
246
- config("tacacs-server host #{@host_name} key #{enctype} TEST")
276
+ host.encryption_key_set(enctype, 'TEST')
247
277
  assert_equal(sh_run_enctype, host.encryption_type,
248
278
  'Error: Tacacs Host encryption type incorrect')
249
279
  host.destroy
250
280
  end
251
281
 
252
282
  def test_tacacsserverhost_get_default_encryption_type
253
- host = TacacsServerHost.new('testhost')
283
+ host = TacacsServerHost.new(@host_name)
254
284
 
255
285
  assert_equal(TACACS_SERVER_ENC_NONE,
256
286
  TacacsServerHost.default_encryption_type,
@@ -269,14 +299,21 @@ class TestTacacsServerHost < CiscoTestCase
269
299
  # when configured
270
300
  pass = 'TEST'
271
301
  sh_run_pass = 'WAWY'
272
- config("tacacs-server host #{@host_name} key 0 #{pass}")
273
- assert_equal(sh_run_pass, host.encryption_password,
274
- 'Error: Tacacs Host encryption password incorrect')
302
+ host.encryption_key_set(0, pass)
303
+
304
+ if platform != :ios_xr
305
+ assert_equal(sh_run_pass, host.encryption_password,
306
+ 'Error: Tacacs Host encryption password incorrect')
307
+ else
308
+ # Only do not-nil checking for IOS XR
309
+ assert(!host.encryption_password.nil?)
310
+ end
311
+
275
312
  host.destroy
276
313
  end
277
314
 
278
315
  def test_tacacsserverhost_get_default_encryption_password
279
- host = TacacsServerHost.new('testhost')
316
+ host = TacacsServerHost.new(@host_name)
280
317
 
281
318
  assert_equal('', TacacsServerHost.default_encryption_password,
282
319
  'Error: Tacacs Host default encryption password incorrect')
@@ -293,18 +330,24 @@ class TestTacacsServerHost < CiscoTestCase
293
330
  host.encryption_key_set(enctype, pass)
294
331
 
295
332
  line = assert_show_match(msg: 'Error: Tacacs Host not found')
296
- assert_match(/key\s(\d*)\s(\S*)/, line.captures[1])
297
- md = /key\s(\d*)\s(\S*)/.match(line.captures[1])
298
- assert_equal(sh_run_enctype, md.captures[0].to_i,
299
- 'Error: Tacacs Host encryption type mismatch')
300
- assert_equal(sh_run_enctype, host.encryption_type,
301
- 'Error: Tacacs Host encryption type incorrect')
302
- # remove quotes surrounding the encrypted password
303
- pass_no_quotes = md.captures[1].gsub(/(?:^\")|(?:\"$)/, '')
304
- assert_equal(sh_run_pass, pass_no_quotes,
305
- 'Error: Tacacs Host encryption password mismatch')
306
- assert_equal(sh_run_pass, host.encryption_password,
307
- 'Error: Tacacs Host encryption password incorrect')
333
+
334
+ if platform != :ios_xr
335
+ assert_match(/key\s(\d*)\s(\S*)/, line.captures[1])
336
+ md = /key\s(\d*)\s(\S*)/.match(line.captures[1])
337
+ assert_equal(sh_run_enctype, md.captures[0].to_i,
338
+ 'Error: Tacacs Host encryption type mismatch')
339
+ assert_equal(sh_run_enctype, host.encryption_type,
340
+ 'Error: Tacacs Host encryption type incorrect')
341
+ # remove quotes surrounding the encrypted password
342
+ pass_no_quotes = md.captures[1].gsub(/(?:^\")|(?:\"$)/, '')
343
+ assert_equal(sh_run_pass, pass_no_quotes,
344
+ 'Error: Tacacs Host encryption password mismatch')
345
+ assert_equal(sh_run_pass, host.encryption_password,
346
+ 'Error: Tacacs Host encryption password incorrect')
347
+ else
348
+ # Only do not-nil checking for IOS XR
349
+ assert(!host.encryption_password.nil?)
350
+ end
308
351
 
309
352
  host.destroy
310
353
  end
@@ -335,4 +378,53 @@ class TestTacacsServerHost < CiscoTestCase
335
378
  'Error: Tacacs Host encryption password incorrect')
336
379
  host.destroy
337
380
  end
381
+
382
+ def setup_duplicates
383
+ return if platform != :ios_xr
384
+ config('tacacs-server host 8.8.8.8 port 11',
385
+ 'tacacs-server host 8.8.8.8 port 22',
386
+ 'tacacs-server host 8.8.8.8 port 33')
387
+ end
388
+
389
+ def no_duplicates
390
+ return if platform != :ios_xr
391
+ config('no tacacs-server host 8.8.8.8 port 11',
392
+ 'no tacacs-server host 8.8.8.8 port 22',
393
+ 'no tacacs-server host 8.8.8.8 port 33')
394
+ end
395
+
396
+ def test_create_destroy_single_with_duplicates
397
+ return if platform != :ios_xr
398
+ setup_duplicates
399
+
400
+ id = '8.8.8.8'
401
+
402
+ server = Cisco::TacacsServerHost.new(id, true, 55)
403
+
404
+ assert_includes(Cisco::TacacsServerHost.hosts, id)
405
+ assert_equal(server, Cisco::TacacsServerHost.hosts[id])
406
+
407
+ assert_equal(55, Cisco::TacacsServerHost.hosts[id].port)
408
+
409
+ if platform != :ios_xr
410
+ server.port = 66
411
+ assert_equal(66, Cisco::TacacsServerHost.hosts[id].port)
412
+
413
+ server.encryption_key_set(nil, nil)
414
+ assert_equal(nil,
415
+ Cisco::TacacsServerHost.hosts[id].encryption_password)
416
+
417
+ server.encryption_key_set('44444444', nil)
418
+ assert_equal('44444444',
419
+ Cisco::TacacsServerHost.hosts[id].encryption_password)
420
+ end
421
+
422
+ server.timeout = 33
423
+ assert_equal(33, Cisco::TacacsServerHost.hosts[id].timeout)
424
+
425
+ server.destroy
426
+ refute_includes(Cisco::TacacsServerHost.hosts, id)
427
+
428
+ no_duplicates
429
+ end
338
430
  end
data/tests/test_vdc.rb CHANGED
@@ -23,11 +23,10 @@ class TestVdc < CiscoTestCase
23
23
  # a) VDC support is limited to a narrow list of platforms.
24
24
  # b) License restrictions may limit platforms to a single vdc
25
25
  # c) Linecard restrictions may limit some tests to specific linecards
26
+ @skip_unless_supported = 'vdc'
26
27
 
27
28
  def setup
28
29
  super
29
- # Check for supported platform
30
- skip('Platform does not support VDCs') unless Vdc.vdc_support
31
30
  end
32
31
 
33
32
  def test_all_vdcs
@@ -45,21 +44,8 @@ class TestVdc < CiscoTestCase
45
44
  end
46
45
  end
47
46
 
48
- def compatible_interface?
49
- # MT-full tests require a specific linecard; either because they need a
50
- # compatible interface or simply to enable the features. Either way
51
- # we will provide an appropriate interface name if the linecard is present.
52
- # Example 'show mod' output to match against:
53
- # '9 12 10/40 Gbps Ethernet Module N7K-F312FQ-25 ok'
54
- sh_mod = @device.cmd("sh mod | i '^[0-9]+.*N7K-F3'")[/^(\d+)\s.*N7K-F3/]
55
- slot = sh_mod.nil? ? nil : Regexp.last_match[1]
56
- skip('Unable to find compatible interface in chassis') if slot.nil?
57
-
58
- "ethernet#{slot}/1"
59
- end
60
-
61
47
  def test_limit_resource_module_type
62
- compatible_interface?
48
+ mt_full_interface?
63
49
  v = Vdc.new('default')
64
50
  # Set limit-resource module-type to default (this is variable for each
65
51
  # device, so the default is for this device only)
data/tests/test_vlan.rb CHANGED
@@ -20,6 +20,8 @@ include Cisco
20
20
 
21
21
  # TestVlan - Minitest for Vlan node utility
22
22
  class TestVlan < CiscoTestCase
23
+ @skip_unless_supported = 'vlan'
24
+
23
25
  @@cleaned = false # rubocop:disable Style/ClassVars
24
26
  def cleanup
25
27
  Vlan.vlans.each do |vlan, obj|
@@ -29,6 +31,7 @@ class TestVlan < CiscoTestCase
29
31
  obj.destroy
30
32
  end
31
33
  interface_ethernet_default(interfaces[0])
34
+ config_no_warn('no feature vtp')
32
35
  end
33
36
 
34
37
  def setup
@@ -51,23 +54,23 @@ class TestVlan < CiscoTestCase
51
54
  flunk(e.message)
52
55
  end
53
56
 
54
- def test_vlan_collection_not_empty
57
+ def test_collection_not_empty
55
58
  vlans = Vlan.vlans
56
59
  assert_equal(false, vlans.empty?, 'VLAN collection is empty')
57
60
  assert(vlans.key?('1'), 'VLAN 1 does not exist')
58
61
  end
59
62
 
60
- def test_vlan_create_invalid
63
+ def test_create_invalid
61
64
  e = assert_raises(CliError) { Vlan.new(5000) }
62
65
  assert_match(/Invalid value.range/, e.message)
63
66
  end
64
67
 
65
- def test_vlan_create_invalid_non_numeric_vlan
68
+ def test_create_invalid_non_numeric_vlan
66
69
  e = assert_raises(ArgumentError) { Vlan.new('fred') }
67
70
  assert_match(/Invalid value.non-numeric/, e.message)
68
71
  end
69
72
 
70
- def test_vlan_create_and_destroy
73
+ def test_create_and_destroy
71
74
  v = Vlan.new(1000)
72
75
  vlans = Vlan.vlans
73
76
  assert(vlans.key?('1000'), 'Error: failed to create vlan 1000')
@@ -77,7 +80,7 @@ class TestVlan < CiscoTestCase
77
80
  refute(vlans.key?('1000'), 'Error: failed to destroy vlan 1000')
78
81
  end
79
82
 
80
- def test_vlan_name_default_1000
83
+ def test_name_default_1000
81
84
  v = Vlan.new(1000)
82
85
  assert_equal(v.default_vlan_name, v.vlan_name,
83
86
  'Error: Vlan name not initialized to default')
@@ -92,7 +95,7 @@ class TestVlan < CiscoTestCase
92
95
  v.destroy
93
96
  end
94
97
 
95
- def test_vlan_name_default_40
98
+ def test_name_default_40
96
99
  v = Vlan.new(40)
97
100
  assert_equal(v.default_vlan_name, v.vlan_name,
98
101
  'Error: Vlan name not initialized to default')
@@ -107,7 +110,7 @@ class TestVlan < CiscoTestCase
107
110
  v.destroy
108
111
  end
109
112
 
110
- def test_vlan_name_nil
113
+ def test_name_nil
111
114
  v = Vlan.new(1000)
112
115
  assert_raises(TypeError) do
113
116
  v.vlan_name = nil
@@ -115,7 +118,7 @@ class TestVlan < CiscoTestCase
115
118
  v.destroy
116
119
  end
117
120
 
118
- def test_vlan_name_invalid
121
+ def test_name_invalid
119
122
  v = Vlan.new(1000)
120
123
  assert_raises(TypeError) do
121
124
  v.vlan_name = Cisco::Node.instance
@@ -123,14 +126,14 @@ class TestVlan < CiscoTestCase
123
126
  v.destroy
124
127
  end
125
128
 
126
- def test_vlan_name_zero_length
129
+ def test_name_zero_length
127
130
  v = Vlan.new(1000)
128
131
  v.vlan_name = ''
129
132
  assert('', v.vlan_name)
130
133
  v.destroy
131
134
  end
132
135
 
133
- def test_vlan_name_length_valid
136
+ def test_name_length_valid
134
137
  v = Vlan.new(1000)
135
138
  alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'
136
139
  name = ''
@@ -146,7 +149,7 @@ class TestVlan < CiscoTestCase
146
149
  v.destroy
147
150
  end
148
151
 
149
- def test_vlan_name_too_long
152
+ def test_name_too_long
150
153
  v = Vlan.new(1000)
151
154
  name = 'a' * VLAN_NAME_SIZE
152
155
  assert_raises(RuntimeError, 'vlan misconfig did not raise RuntimeError') do
@@ -157,7 +160,7 @@ class TestVlan < CiscoTestCase
157
160
  v.destroy
158
161
  end
159
162
 
160
- def test_vlan_name_duplicate
163
+ def test_name_duplicate
161
164
  # Testbed cleanup
162
165
  v = Vlan.new(1000)
163
166
  v.destroy
@@ -174,15 +177,15 @@ class TestVlan < CiscoTestCase
174
177
  v2.destroy
175
178
  end
176
179
 
177
- def test_vlan_state_invalid
180
+ def test_state_invalid
178
181
  v = Vlan.new(1000)
179
- assert_raises(RuntimeError) do
182
+ assert_raises(CliError) do
180
183
  v.state = 'unknown'
181
184
  end
182
185
  v.destroy
183
186
  end
184
187
 
185
- def test_vlan_state_valid
188
+ def test_state_valid
186
189
  states = %w(unknown active suspend)
187
190
  v = Vlan.new(1000)
188
191
  states.each do |start|
@@ -197,7 +200,7 @@ class TestVlan < CiscoTestCase
197
200
  v.destroy
198
201
  end
199
202
 
200
- def test_vlan_shutdown_extended
203
+ def test_shutdown_extended
201
204
  v = Vlan.new(2000)
202
205
  assert_raises(RuntimeError, 'vlan misconfig did not raise RuntimeError') do
203
206
  v.shutdown = 'shutdown'
@@ -205,7 +208,7 @@ class TestVlan < CiscoTestCase
205
208
  v.destroy
206
209
  end
207
210
 
208
- def test_vlan_shutdown_valid
211
+ def test_shutdown_valid
209
212
  shutdown_states = [true, false]
210
213
  v = Vlan.new(1000)
211
214
  shutdown_states.each do |start|
@@ -219,63 +222,75 @@ class TestVlan < CiscoTestCase
219
222
  v.destroy
220
223
  end
221
224
 
222
- def test_vlan_add_remove_interface_valid
223
- v = Vlan.new(1000)
224
- interfaces = Interface.interfaces
225
- interfaces_added_to_vlan = []
226
- count = 3
227
- interfaces.each do |name, interface|
228
- next unless interface.name.match(%r{ethernet[0-9/]+$}) && count > 0
229
- interface_ethernet_default(%r{net(\d+/\d+)}.match(name)[1])
230
- interfaces_added_to_vlan << name
231
- interface.switchport_mode = :access
232
- v.add_interface(interface)
233
- count -= 1
234
- end
235
- assert_equal(0, count)
225
+ def test_add_remove_interface
226
+ vlan_id = 1000
227
+ v = Vlan.new(vlan_id)
236
228
 
237
- interfaces = v.interfaces
238
- interfaces.each do |name, interface|
239
- assert_includes(interfaces_added_to_vlan, name)
240
- assert_equal(v.vlan_id, interface.access_vlan, 'Interface.access_vlan')
241
- v.remove_interface(interface)
229
+ # Remove vlan_id from all interfaces currently using it
230
+ v.interfaces.each do |_name, i|
231
+ v.remove_interface(i)
242
232
  end
243
-
244
- interfaces = v.interfaces
245
- assert(interfaces.empty?)
233
+ assert_empty(v.interfaces, "access vlan #{vlan_id} should not be "\
234
+ 'present on any interfaces')
235
+
236
+ # Add test vlan to 3 ethernet interfaces
237
+ vlan_intf_max = 3
238
+ vlan_intf_list = []
239
+ Interface.interfaces.each do |name, i|
240
+ next unless i.name[/ethernet/]
241
+ interface_ethernet_default(name)
242
+ i.switchport_mode = :access
243
+ assert_equal(i.default_access_vlan, i.access_vlan,
244
+ "access vlan is not default on #{name}")
245
+
246
+ v.add_interface(i)
247
+ assert_equal(vlan_id, i.access_vlan,
248
+ "access vlan #{vlan_id} not present on #{name}")
249
+ vlan_intf_list << name
250
+ break if vlan_intf_list.count == vlan_intf_max
251
+ end
252
+ count = v.interfaces.count
253
+ assert_equal(vlan_intf_max, count,
254
+ "vlan #{vlan_id} found on #{count} interfaces, "\
255
+ "expected #{vlan_intf_max} total")
256
+
257
+ # Remove test vlan from interfaces
258
+ vlan_intf_list.each do |name|
259
+ i = Interface.new(name)
260
+ v.remove_interface(i)
261
+ assert_equal(i.default_access_vlan, i.access_vlan,
262
+ "access vlan #{vlan_id} should not be present on #{name}")
263
+ end
264
+ assert_empty(v.interfaces, "access vlan #{vlan_id} should not be "\
265
+ 'present on any interfaces')
246
266
  v.destroy
247
267
  end
248
268
 
249
- def test_vlan_add_interface_invalid
269
+ def test_add_interface_invalid
250
270
  v = Vlan.new(1000)
251
271
  interface = Interface.new(interfaces[0])
252
- begin
253
- interface.switchport_mode = :disabled
254
- assert_raises(RuntimeError) { v.add_interface(interface) }
255
- v.destroy
256
- end
272
+ interface.switchport_mode = :disabled
273
+ assert_raises(CliError) { v.add_interface(interface) }
274
+ v.destroy
257
275
  rescue RuntimeError => e
258
276
  linecard_cfg_change_not_allowed?(e)
259
277
  end
260
278
 
261
- def test_vlan_remove_interface_invalid
279
+ def test_remove_interface_invalid
262
280
  v = Vlan.new(1000)
263
281
  interface = Interface.new(interfaces[0])
264
282
  interface.switchport_mode = :access
265
283
  v.add_interface(interface)
266
- begin
267
- interface.switchport_mode = :disabled
268
- assert_raises(RuntimeError) { v.remove_interface(interface) }
269
- v.destroy
270
- end
284
+ interface.switchport_mode = :disabled
285
+ assert_raises(CliError) { v.remove_interface(interface) }
286
+
287
+ v.destroy
271
288
  rescue RuntimeError => e
272
289
  linecard_cfg_change_not_allowed?(e)
273
290
  end
274
291
 
275
- def test_vlan_mapped_vnis
292
+ def test_mapped_vnis
276
293
  # Map
277
- skip('Feature vn-segment-vlan-based is not supported on this platform.') if
278
- node.product_id =~ /N3K-C3048/
279
294
  v1 = Vlan.new(100)
280
295
  vni1 = 10_000
281
296
  v1.mapped_vni = vni1
@@ -299,5 +314,42 @@ class TestVlan < CiscoTestCase
299
314
 
300
315
  v3.mapped_vni = v3.default_mapped_vni
301
316
  assert_equal(v3.default_mapped_vni, v3.mapped_vni)
317
+ rescue RuntimeError => e
318
+ hardware_supports_feature?(e.message)
319
+ end
320
+
321
+ def test_another_vlan_as_fabric_control
322
+ if validate_property_excluded?('vlan', 'fabric_control')
323
+ assert_raises(Cisco::UnsupportedError) do
324
+ Vlan.new('100').fabric_control = true
325
+ end
326
+ return
327
+ end
328
+
329
+ vlan = Vlan.new('100')
330
+ assert_equal(vlan.default_fabric_control, vlan.fabric_control,
331
+ 'Error: Vlan fabric-control is not matching')
332
+ vlan.fabric_control = true
333
+ assert(vlan.fabric_control)
334
+ another_vlan = Vlan.new(101)
335
+
336
+ assert_raises(RuntimeError,
337
+ 'VLAN misconfig did not raise CliError') do
338
+ another_vlan.fabric_control = true
339
+ end
340
+ vlan.destroy
341
+ another_vlan.destroy
342
+ end
343
+
344
+ def test_mode_with_pvlan
345
+ v = Vlan.new(1000)
346
+ if validate_property_excluded?('vlan', 'private_vlan_type') ||
347
+ validate_property_excluded?('vlan', 'mode')
348
+ features = 'private_vlan_type and/or vlan mode'
349
+ skip("Skip test: Features #{features} are not supported on this device")
350
+ end
351
+ result = 'CE'
352
+ v.private_vlan_type = 'primary'
353
+ assert_equal(result, v.mode)
302
354
  end
303
355
  end