cisco_node_utils_mgx 2.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (357) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +96 -0
  5. data/.travis.yml +17 -0
  6. data/CHANGELOG.md +676 -0
  7. data/CONTRIBUTING.md +43 -0
  8. data/Gemfile +10 -0
  9. data/LICENSE +201 -0
  10. data/README.md +246 -0
  11. data/Rakefile +44 -0
  12. data/SUPPORT.md +3 -0
  13. data/bin/.rubocop.yml +18 -0
  14. data/bin/check_metric_limits.rb +109 -0
  15. data/bin/git/hooks/commit-msg/enforce_style +89 -0
  16. data/bin/git/hooks/hook_lib +115 -0
  17. data/bin/git/hooks/hooks-wrapper +38 -0
  18. data/bin/git/hooks/post-flow-hotfix-start/update-version +24 -0
  19. data/bin/git/hooks/post-flow-release-finish/update-version +29 -0
  20. data/bin/git/hooks/post-flow-release-start/update-version +19 -0
  21. data/bin/git/hooks/post-merge/update-hooks +6 -0
  22. data/bin/git/hooks/post-rewrite/update-hooks +6 -0
  23. data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
  24. data/bin/git/hooks/pre-commit/rubocop +25 -0
  25. data/bin/git/hooks/pre-commit/validate-diffs +45 -0
  26. data/bin/git/hooks/pre-commit/validate-yaml +18 -0
  27. data/bin/git/hooks/pre-push/check-changelog +24 -0
  28. data/bin/git/hooks/pre-push/rubocop +7 -0
  29. data/bin/git/update-hooks +123 -0
  30. data/bin/show_running_yang.rb +233 -0
  31. data/cisco_node_utils.gemspec +41 -0
  32. data/docs/README-develop-best-practices.md +521 -0
  33. data/docs/README-develop-node-utils-APIs.md +570 -0
  34. data/docs/README-maintainers.md +77 -0
  35. data/docs/README-test-execution.md +57 -0
  36. data/docs/README-utilities.md +14 -0
  37. data/docs/agent_files.png +0 -0
  38. data/docs/cisco_node_utils.yaml.example +36 -0
  39. data/docs/template-router.rb +123 -0
  40. data/docs/template-test_router.rb +104 -0
  41. data/ext/mkrf_conf.rb +63 -0
  42. data/lib/.rubocop.yml +18 -0
  43. data/lib/cisco_node_utils/aaa_authentication_login.rb +95 -0
  44. data/lib/cisco_node_utils/aaa_authentication_login_service.rb +138 -0
  45. data/lib/cisco_node_utils/aaa_authorization_service.rb +156 -0
  46. data/lib/cisco_node_utils/ace.rb +467 -0
  47. data/lib/cisco_node_utils/acl.rb +101 -0
  48. data/lib/cisco_node_utils/banner.rb +63 -0
  49. data/lib/cisco_node_utils/bfd_global.rb +305 -0
  50. data/lib/cisco_node_utils/bgp.rb +988 -0
  51. data/lib/cisco_node_utils/bgp_af.rb +545 -0
  52. data/lib/cisco_node_utils/bgp_af_aggr_addr.rb +207 -0
  53. data/lib/cisco_node_utils/bgp_neighbor.rb +527 -0
  54. data/lib/cisco_node_utils/bgp_neighbor_af.rb +780 -0
  55. data/lib/cisco_node_utils/bridge_domain.rb +178 -0
  56. data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
  57. data/lib/cisco_node_utils/cisco_cmn_utils.rb +444 -0
  58. data/lib/cisco_node_utils/client/client.rb +238 -0
  59. data/lib/cisco_node_utils/client/grpc/client.rb +395 -0
  60. data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
  61. data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
  62. data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
  63. data/lib/cisco_node_utils/client/grpc.rb +33 -0
  64. data/lib/cisco_node_utils/client/nxapi/client.rb +368 -0
  65. data/lib/cisco_node_utils/client/nxapi.rb +31 -0
  66. data/lib/cisco_node_utils/client/utils.rb +180 -0
  67. data/lib/cisco_node_utils/client.rb +35 -0
  68. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +590 -0
  69. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +25 -0
  70. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +38 -0
  71. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +40 -0
  72. data/lib/cisco_node_utils/cmd_ref/acl.yaml +48 -0
  73. data/lib/cisco_node_utils/cmd_ref/banner.yaml +11 -0
  74. data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
  75. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +383 -0
  76. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +223 -0
  77. data/lib/cisco_node_utils/cmd_ref/bgp_af_aa.yaml +38 -0
  78. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +174 -0
  79. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +236 -0
  80. data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +49 -0
  81. data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
  82. data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +128 -0
  83. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +55 -0
  84. data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
  85. data/lib/cisco_node_utils/cmd_ref/evpn_multicast.yaml +12 -0
  86. data/lib/cisco_node_utils/cmd_ref/evpn_multisite.yaml +18 -0
  87. data/lib/cisco_node_utils/cmd_ref/evpn_stormcontrol.yaml +18 -0
  88. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +48 -0
  89. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +183 -0
  90. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +40 -0
  91. data/lib/cisco_node_utils/cmd_ref/feature.yaml +126 -0
  92. data/lib/cisco_node_utils/cmd_ref/hostname.yaml +8 -0
  93. data/lib/cisco_node_utils/cmd_ref/hsrp_global.yaml +25 -0
  94. data/lib/cisco_node_utils/cmd_ref/images.yaml +8 -0
  95. data/lib/cisco_node_utils/cmd_ref/interface.yaml +781 -0
  96. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +45 -0
  97. data/lib/cisco_node_utils/cmd_ref/interface_evpn_multisite.yaml +17 -0
  98. data/lib/cisco_node_utils/cmd_ref/interface_hsrp_group.yaml +120 -0
  99. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +112 -0
  100. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +87 -0
  101. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +42 -0
  102. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
  103. data/lib/cisco_node_utils/cmd_ref/ip_multicast.yaml +22 -0
  104. data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
  105. data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
  106. data/lib/cisco_node_utils/cmd_ref/memory.yaml +24 -0
  107. data/lib/cisco_node_utils/cmd_ref/ntp_auth_key.yaml +10 -0
  108. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +27 -0
  109. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +34 -0
  110. data/lib/cisco_node_utils/cmd_ref/object_group.yaml +32 -0
  111. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +91 -0
  112. data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
  113. data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
  114. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +37 -0
  115. data/lib/cisco_node_utils/cmd_ref/pim.yaml +43 -0
  116. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +86 -0
  117. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +37 -0
  118. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +100 -0
  119. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +19 -0
  120. data/lib/cisco_node_utils/cmd_ref/route_map.yaml +601 -0
  121. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +9 -0
  122. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +84 -0
  123. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +81 -0
  124. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +9 -0
  125. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +74 -0
  126. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +91 -0
  127. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +57 -0
  128. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +23 -0
  129. data/lib/cisco_node_utils/cmd_ref/span_session.yaml +65 -0
  130. data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +235 -0
  131. data/lib/cisco_node_utils/cmd_ref/syslog_facility.yaml +10 -0
  132. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +34 -0
  133. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +45 -0
  134. data/lib/cisco_node_utils/cmd_ref/system.yaml +7 -0
  135. data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +37 -0
  136. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +63 -0
  137. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +45 -0
  138. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +64 -0
  139. data/lib/cisco_node_utils/cmd_ref/upgrade.yaml +38 -0
  140. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +52 -0
  141. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +8 -0
  142. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +106 -0
  143. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +233 -0
  144. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +86 -0
  145. data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +139 -0
  146. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +32 -0
  147. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +114 -0
  148. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +71 -0
  149. data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
  150. data/lib/cisco_node_utils/cmd_ref/yum.yaml +68 -0
  151. data/lib/cisco_node_utils/command_reference.rb +724 -0
  152. data/lib/cisco_node_utils/configparser_lib.rb +195 -0
  153. data/lib/cisco_node_utils/constants.rb +40 -0
  154. data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
  155. data/lib/cisco_node_utils/dns_domain.rb +93 -0
  156. data/lib/cisco_node_utils/domain_name.rb +82 -0
  157. data/lib/cisco_node_utils/encapsulation.rb +112 -0
  158. data/lib/cisco_node_utils/environment.rb +110 -0
  159. data/lib/cisco_node_utils/evpn_multicast.rb +66 -0
  160. data/lib/cisco_node_utils/evpn_multisite.rb +96 -0
  161. data/lib/cisco_node_utils/evpn_stormcontrol.rb +84 -0
  162. data/lib/cisco_node_utils/evpn_vni.rb +159 -0
  163. data/lib/cisco_node_utils/exceptions.rb +140 -0
  164. data/lib/cisco_node_utils/fabricpath_global.rb +405 -0
  165. data/lib/cisco_node_utils/fabricpath_topology.rb +137 -0
  166. data/lib/cisco_node_utils/feature.rb +377 -0
  167. data/lib/cisco_node_utils/hostname.rb +62 -0
  168. data/lib/cisco_node_utils/hsrp_global.rb +97 -0
  169. data/lib/cisco_node_utils/interface.rb +2128 -0
  170. data/lib/cisco_node_utils/interface_channel_group.rb +142 -0
  171. data/lib/cisco_node_utils/interface_evpn_multisite.rb +72 -0
  172. data/lib/cisco_node_utils/interface_hsrp_group.rb +557 -0
  173. data/lib/cisco_node_utils/interface_ospf.rb +378 -0
  174. data/lib/cisco_node_utils/interface_portchannel.rb +180 -0
  175. data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
  176. data/lib/cisco_node_utils/ip_multicast.rb +90 -0
  177. data/lib/cisco_node_utils/itd_device_group.rb +228 -0
  178. data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
  179. data/lib/cisco_node_utils/itd_service.rb +511 -0
  180. data/lib/cisco_node_utils/logger.rb +78 -0
  181. data/lib/cisco_node_utils/name_server.rb +64 -0
  182. data/lib/cisco_node_utils/node.rb +443 -0
  183. data/lib/cisco_node_utils/node_util.rb +111 -0
  184. data/lib/cisco_node_utils/ntp_auth_key.rb +67 -0
  185. data/lib/cisco_node_utils/ntp_config.rb +83 -0
  186. data/lib/cisco_node_utils/ntp_server.rb +86 -0
  187. data/lib/cisco_node_utils/object_group.rb +75 -0
  188. data/lib/cisco_node_utils/object_group_entry.rb +143 -0
  189. data/lib/cisco_node_utils/overlay_global.rb +142 -0
  190. data/lib/cisco_node_utils/pim.rb +131 -0
  191. data/lib/cisco_node_utils/pim_group_list.rb +109 -0
  192. data/lib/cisco_node_utils/pim_rp_address.rb +103 -0
  193. data/lib/cisco_node_utils/platform.rb +217 -0
  194. data/lib/cisco_node_utils/portchannel_global.rb +347 -0
  195. data/lib/cisco_node_utils/radius_global.rb +165 -0
  196. data/lib/cisco_node_utils/radius_server.rb +421 -0
  197. data/lib/cisco_node_utils/radius_server_group.rb +117 -0
  198. data/lib/cisco_node_utils/route_map.rb +2540 -0
  199. data/lib/cisco_node_utils/router_ospf.rb +77 -0
  200. data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
  201. data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
  202. data/lib/cisco_node_utils/router_ospf_vrf.rb +342 -0
  203. data/lib/cisco_node_utils/snmp_notification_receiver.rb +176 -0
  204. data/lib/cisco_node_utils/snmpcommunity.rb +109 -0
  205. data/lib/cisco_node_utils/snmpgroup.rb +54 -0
  206. data/lib/cisco_node_utils/snmpnotification.rb +57 -0
  207. data/lib/cisco_node_utils/snmpserver.rb +132 -0
  208. data/lib/cisco_node_utils/snmpuser.rb +403 -0
  209. data/lib/cisco_node_utils/span_session.rb +149 -0
  210. data/lib/cisco_node_utils/stp_global.rb +676 -0
  211. data/lib/cisco_node_utils/syslog_facility.rb +64 -0
  212. data/lib/cisco_node_utils/syslog_server.rb +146 -0
  213. data/lib/cisco_node_utils/syslog_settings.rb +174 -0
  214. data/lib/cisco_node_utils/tacacs_global.rb +137 -0
  215. data/lib/cisco_node_utils/tacacs_server.rb +173 -0
  216. data/lib/cisco_node_utils/tacacs_server_group.rb +149 -0
  217. data/lib/cisco_node_utils/tacacs_server_host.rb +216 -0
  218. data/lib/cisco_node_utils/upgrade.rb +122 -0
  219. data/lib/cisco_node_utils/vdc.rb +118 -0
  220. data/lib/cisco_node_utils/version.rb +21 -0
  221. data/lib/cisco_node_utils/vlan.rb +301 -0
  222. data/lib/cisco_node_utils/vpc.rb +466 -0
  223. data/lib/cisco_node_utils/vrf.rb +192 -0
  224. data/lib/cisco_node_utils/vrf_af.rb +327 -0
  225. data/lib/cisco_node_utils/vtp.rb +125 -0
  226. data/lib/cisco_node_utils/vxlan_vtep.rb +286 -0
  227. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +331 -0
  228. data/lib/cisco_node_utils/yang.rb +160 -0
  229. data/lib/cisco_node_utils/yum.rb +213 -0
  230. data/lib/cisco_node_utils.rb +21 -0
  231. data/lib/minitest/environment_plugin.rb +31 -0
  232. data/lib/minitest/log_level_plugin.rb +41 -0
  233. data/spec/client_spec.rb +7 -0
  234. data/spec/environment_spec.rb +384 -0
  235. data/spec/grpc_client_spec.rb +23 -0
  236. data/spec/isolate/all_clients_spec.rb +9 -0
  237. data/spec/isolate/grpc_only_spec.rb +16 -0
  238. data/spec/isolate/no_clients_spec.rb +26 -0
  239. data/spec/isolate/nxapi_only_spec.rb +16 -0
  240. data/spec/nxapi_client_spec.rb +42 -0
  241. data/spec/schema.yaml +82 -0
  242. data/spec/shared_examples_for_clients.rb +14 -0
  243. data/spec/spec_helper.rb +91 -0
  244. data/spec/whitespace_spec.rb +10 -0
  245. data/spec/yaml_spec.rb +42 -0
  246. data/tests/.rubocop.yml +18 -0
  247. data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
  248. data/tests/basetest.rb +243 -0
  249. data/tests/ciscotest.rb +577 -0
  250. data/tests/cmd_config.yaml +75 -0
  251. data/tests/cmd_config_invalid.yaml +16 -0
  252. data/tests/n9000_sample-1.0.0-7.0.3.x86_64.rpm +0 -0
  253. data/tests/noop.rb +7 -0
  254. data/tests/platform_info.rb +63 -0
  255. data/tests/tacacs_server.yaml.example +6 -0
  256. data/tests/test_aaa_authentication_login.rb +243 -0
  257. data/tests/test_aaa_authentication_login_service.rb +761 -0
  258. data/tests/test_aaa_authorization_service.rb +874 -0
  259. data/tests/test_ace.rb +304 -0
  260. data/tests/test_acl.rb +185 -0
  261. data/tests/test_banner.rb +85 -0
  262. data/tests/test_bfd_global.rb +272 -0
  263. data/tests/test_bgp_af.rb +875 -0
  264. data/tests/test_bgp_af_aa.rb +108 -0
  265. data/tests/test_bgp_neighbor.rb +596 -0
  266. data/tests/test_bgp_neighbor_af.rb +781 -0
  267. data/tests/test_bridge_domain.rb +198 -0
  268. data/tests/test_bridge_domain_vni.rb +109 -0
  269. data/tests/test_client_utils.rb +111 -0
  270. data/tests/test_cmn_utils.rb +76 -0
  271. data/tests/test_command_config.rb +206 -0
  272. data/tests/test_command_reference.rb +669 -0
  273. data/tests/test_dhcp_relay_global.rb +286 -0
  274. data/tests/test_dns_domain.rb +123 -0
  275. data/tests/test_domain_name.rb +96 -0
  276. data/tests/test_encapsulation.rb +75 -0
  277. data/tests/test_evpn_multicast.rb +65 -0
  278. data/tests/test_evpn_multisite.rb +70 -0
  279. data/tests/test_evpn_stormcontrol.rb +56 -0
  280. data/tests/test_evpn_vni.rb +131 -0
  281. data/tests/test_fabricpath_global.rb +246 -0
  282. data/tests/test_fabricpath_topology.rb +77 -0
  283. data/tests/test_feature.rb +272 -0
  284. data/tests/test_grpc.rb +166 -0
  285. data/tests/test_hostname.rb +64 -0
  286. data/tests/test_hsrp_global.rb +79 -0
  287. data/tests/test_interface.rb +1958 -0
  288. data/tests/test_interface_bdi.rb +80 -0
  289. data/tests/test_interface_channel_group.rb +131 -0
  290. data/tests/test_interface_evpn_multisite.rb +94 -0
  291. data/tests/test_interface_hsrp.rb +134 -0
  292. data/tests/test_interface_hsrp_group.rb +570 -0
  293. data/tests/test_interface_ospf.rb +820 -0
  294. data/tests/test_interface_portchannel.rb +135 -0
  295. data/tests/test_interface_private_vlan.rb +365 -0
  296. data/tests/test_interface_service_vni.rb +203 -0
  297. data/tests/test_interface_svi.rb +210 -0
  298. data/tests/test_interface_switchport.rb +468 -0
  299. data/tests/test_ip_multicast.rb +80 -0
  300. data/tests/test_itd_device_group.rb +145 -0
  301. data/tests/test_itd_device_group_node.rb +199 -0
  302. data/tests/test_itd_service.rb +314 -0
  303. data/tests/test_logger.rb +43 -0
  304. data/tests/test_name_server.rb +94 -0
  305. data/tests/test_node.rb +50 -0
  306. data/tests/test_node_ext.rb +406 -0
  307. data/tests/test_node_util.rb +119 -0
  308. data/tests/test_ntp_auth_key.rb +77 -0
  309. data/tests/test_ntp_config.rb +100 -0
  310. data/tests/test_ntp_server.rb +146 -0
  311. data/tests/test_nxapi.rb +236 -0
  312. data/tests/test_object_group.rb +122 -0
  313. data/tests/test_overlay_global.rb +108 -0
  314. data/tests/test_pim.rb +203 -0
  315. data/tests/test_pim_group_list.rb +147 -0
  316. data/tests/test_pim_rp_address.rb +155 -0
  317. data/tests/test_platform.rb +254 -0
  318. data/tests/test_portchannel_global.rb +322 -0
  319. data/tests/test_radius_global.rb +108 -0
  320. data/tests/test_radius_server.rb +377 -0
  321. data/tests/test_radius_server_group.rb +151 -0
  322. data/tests/test_route_map.rb +1479 -0
  323. data/tests/test_router_bgp.rb +1325 -0
  324. data/tests/test_router_ospf.rb +56 -0
  325. data/tests/test_router_ospf_area.rb +433 -0
  326. data/tests/test_router_ospf_area_vlink.rb +298 -0
  327. data/tests/test_router_ospf_vrf.rb +690 -0
  328. data/tests/test_snmp_notification_receiver.rb +169 -0
  329. data/tests/test_snmpcommunity.rb +422 -0
  330. data/tests/test_snmpgroup.rb +71 -0
  331. data/tests/test_snmpnotification.rb +91 -0
  332. data/tests/test_snmpserver.rb +251 -0
  333. data/tests/test_snmpuser.rb +666 -0
  334. data/tests/test_span_session.rb +155 -0
  335. data/tests/test_stp_global.rb +575 -0
  336. data/tests/test_syslog_facility.rb +80 -0
  337. data/tests/test_syslog_server.rb +119 -0
  338. data/tests/test_syslog_settings.rb +123 -0
  339. data/tests/test_tacacs_global.rb +109 -0
  340. data/tests/test_tacacs_server.rb +436 -0
  341. data/tests/test_tacacs_server_group.rb +434 -0
  342. data/tests/test_tacacs_server_host.rb +427 -0
  343. data/tests/test_upgrade.rb +105 -0
  344. data/tests/test_vdc.rb +64 -0
  345. data/tests/test_vlan.rb +386 -0
  346. data/tests/test_vlan_private.rb +656 -0
  347. data/tests/test_vpc.rb +548 -0
  348. data/tests/test_vrf.rb +248 -0
  349. data/tests/test_vrf_af.rb +288 -0
  350. data/tests/test_vtp.rb +278 -0
  351. data/tests/test_vxlan_vtep.rb +327 -0
  352. data/tests/test_vxlan_vtep_vni.rb +326 -0
  353. data/tests/test_yang.rb +369 -0
  354. data/tests/test_yum.rb +109 -0
  355. data/tests/upgrade_info.yaml.example +3 -0
  356. data/tests/yum_package.yaml +94 -0
  357. metadata +534 -0
@@ -0,0 +1,2128 @@
1
+ # November 2015, Chris Van Heuveln
2
+ #
3
+ # Copyright (c) 2015-2018 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'cisco_cmn_utils'
18
+ require_relative 'node_util'
19
+ require_relative 'vrf'
20
+ require_relative 'overlay_global'
21
+
22
+ # Cisco provider module
23
+ module Cisco
24
+ IF_SWITCHPORT_MODE = {
25
+ disabled: '',
26
+ access: 'access',
27
+ trunk: 'trunk',
28
+ fex_fabric: 'fex-fabric',
29
+ tunnel: 'dot1q-tunnel',
30
+ fabricpath: 'fabricpath',
31
+ }
32
+
33
+ # Interface - node utility class for general interface config management
34
+ class Interface < NodeUtil
35
+ # Regexp to match various Ethernet interface variants:
36
+ # Ethernet
37
+ # GigabitEthernet
38
+ # TenGigE
39
+ # HundredGigE
40
+ # MgmtEth
41
+ ETHERNET = Regexp.new('(Ethernet|GigE|MgmtEth)', Regexp::IGNORECASE)
42
+ # Regexp to match various link bundle interface variants
43
+ PORTCHANNEL = Regexp.new('(port-channel|Bundle-Ether)', Regexp::IGNORECASE)
44
+
45
+ attr_reader :name, :state_default, :show_name
46
+
47
+ def initialize(name, instantiate=true, default_state=false, show_name=nil)
48
+ fail TypeError unless name.is_a?(String)
49
+ fail ArgumentError unless name.length > 0
50
+
51
+ # @name is used for context: keys only
52
+ # @show_name is used for get_command: keys; allows callers to limit
53
+ # show command to a single interface
54
+ @name = name.downcase
55
+ @show_name = show_name.nil? ? '' : Utils.normalize_intf_pattern(show_name)
56
+ @get_args = { name: @name, show_name: @show_name }
57
+ @smr = config_get('interface', 'stp_mst_range')
58
+ @svr = config_get('interface', 'stp_vlan_range')
59
+ @match_found = false
60
+ # Keep track of default vs non-default state for
61
+ # interfaces that cannot be created/destroyed.
62
+ @state_default = nil
63
+ # Track ethernet but not sub-interfaces
64
+ if @name[/ethernet/] && !@name[/ethernet.*\.\d+/]
65
+ @state_default = default_state
66
+ end
67
+ create if instantiate
68
+ end
69
+
70
+ def to_s
71
+ "interface #{name}"
72
+ end
73
+
74
+ def self.interface_count
75
+ config_get('interface', 'all_count').to_i
76
+ end
77
+
78
+ def self.interfaces(opt=nil, show_name=nil)
79
+ hash = {}
80
+ show_name = Utils.normalize_intf_pattern(show_name)
81
+ begin
82
+ intf_list = config_get('interface', 'all_interfaces',
83
+ show_name: show_name)
84
+ rescue CliError => e
85
+ raise unless show_name
86
+ # ignore logical interfaces that do not exist
87
+ debug 'Interface.interfaces ignoring CliError => ' + e.to_s
88
+ end
89
+ return hash if intf_list.nil?
90
+
91
+ # Massage intf_list data into an array that is easy to work with.
92
+ # Use a MARKER to hide pesky 'interface' substrings
93
+ intf_list.collect! { |x| x.strip || x }
94
+ intf_list.delete('')
95
+ intf_list.collect! { |x| (x.sub('interface', '~!MARKER!~') unless x[/^interface /]) || x } # rubocop:disable Metrics/LineLength
96
+ intf_list = intf_list.join(' ').split('interface')
97
+ intf_list.delete('')
98
+ # Restore 'interface' substrings
99
+ intf_list.collect! { |x| x.sub('~!MARKER!~', 'interface') }
100
+
101
+ intf_list.each do |id|
102
+ int_data = id.strip.split(' ')
103
+ next if int_data[0].nil?
104
+ id = int_data[0].downcase
105
+ next if opt && filter(opt, id, show_name)
106
+ # If there are any additional options associated
107
+ # with this interface then it's in a non-default
108
+ # state.
109
+ default_state = int_data.size > 1 ? false : true
110
+ hash[id] = Interface.new(id, false, default_state, show_name)
111
+ end
112
+ hash
113
+ end
114
+
115
+ # General-purpose filter for Interface.interfaces().
116
+ # filter: This may be overloaded in the future to allow a hash of filters.
117
+ # id: The interface name
118
+ # show_name: needed for get_command: <show_name>
119
+ # Return: true if the interface should be filtered out, false to keep it.
120
+ def self.filter(filter, id, show_name)
121
+ case filter
122
+ when :pvlan_any
123
+ return false if config_get('interface', 'pvlan_any',
124
+ name: id, show_name: show_name)
125
+
126
+ else
127
+ # Just a basic pattern filter (:ethernet, :loopback, etc)
128
+ return false if id.match(filter.to_s)
129
+ end
130
+ true
131
+ end
132
+
133
+ # 'capabilities' is a getter-only helper for minitest and beaker.
134
+ # mode values:
135
+ # :hash = Transform the output into a hash
136
+ # :raw = The raw output from 'show int capabilities'. Some multi-line
137
+ # values do not translate easily so this option allows the
138
+ # caller to extract the data it needs.
139
+ #
140
+ # Sample cli output:
141
+ # Model: N7K-M132XP-12L
142
+ # Type (SFP capable): 10Gbase-SR
143
+ # Speed: 10,100,1000
144
+ #
145
+ # Sample hash output:
146
+ # {"Model"=>"N7K-M132XP-12L", "Type"=>"10Gbase-SR", "Speed"=>"10,100,1000"}
147
+ #
148
+ def self.capabilities(intf, mode=:hash)
149
+ array = []
150
+ begin
151
+ array = config_get('interface', 'capabilities', name: intf)
152
+ rescue CliError => e
153
+ raise unless e.clierror[/(Invalid command|Cmd exec error)/]
154
+ end
155
+ return array if mode == :raw
156
+ hash = {}
157
+ if array
158
+ array.delete('')
159
+ array.each do |line|
160
+ k, v = line.split(':')
161
+ next if k.nil? || v.nil?
162
+ k.gsub!(/ \(.*\)/, '') # Remove any parenthetical text from key
163
+ v.strip!
164
+ v.gsub!(%r{half/full}, 'half,full') if k == 'Duplex'
165
+ hash[k] = v
166
+ end
167
+ end
168
+ hash
169
+ end
170
+
171
+ def create
172
+ feature_vlan_set(true) if @name[/(vlan|bdi)/i]
173
+ config_set('interface', 'create', name: @name)
174
+ rescue Cisco::CliError
175
+ # Some XR platforms do not support channel-group configuration
176
+ # on some OS versions. Since this is an OS version difference and not
177
+ # a platform difference, we can't handle this in the YAML.
178
+ raise unless PORTCHANNEL =~ @name && platform == :ios_xr
179
+ raise Cisco::UnsupportedError.new('interface', @name, 'create')
180
+ end
181
+
182
+ def destroy
183
+ if @name[/ethernet/] && !@name[/ethernet.*\.\d+/]
184
+ config_set('interface', 'default', name: @name)
185
+ else
186
+ config_set('interface', 'destroy', name: @name)
187
+ end
188
+ end
189
+
190
+ def default?
191
+ state = config_get('interface', 'default', @get_args)
192
+ state.nil? ? true : false
193
+ end
194
+
195
+ def pvlan_enable
196
+ switchport_enable
197
+ Feature.private_vlan_enable
198
+ end
199
+
200
+ ########################################################
201
+ # PROPERTIES #
202
+ ########################################################
203
+
204
+ # For range based attributes, a new attribute purge will
205
+ # be added in future. When purge is set to true, all the
206
+ # ranges which are specified in the manifest will be set
207
+ # to the desired values and those which are not specified
208
+ # in the manifest will be set to default. When purge is
209
+ # false, only the ranges specified in the manifest will
210
+ # be set to the values given in the manifest and others
211
+ # are left untouched.
212
+
213
+ def lacp_rate_shut_needed?
214
+ config_get('interface', 'lacp_rate_shut_needed')
215
+ end
216
+
217
+ def lacp_rate
218
+ config_get('interface', 'lacp_rate', @get_args)
219
+ end
220
+
221
+ def lacp_rate=(val)
222
+ if val
223
+ state = ''
224
+ else
225
+ return unless lacp_rate
226
+ state = 'no'
227
+ val = lacp_rate
228
+ end
229
+ int = Interface.new(@name, false)
230
+ current_state = int.shutdown
231
+ int.shutdown = true if lacp_rate_shut_needed? && !current_state
232
+ config_set('interface', 'lacp_rate', name: @name,
233
+ state: state, type: val)
234
+ int.shutdown = current_state unless current_state == int.shutdown
235
+ end
236
+
237
+ def default_lacp_rate
238
+ config_get_default('interface', 'lacp_rate')
239
+ end
240
+
241
+ def access_vlan
242
+ return nil if switchport_mode == :disabled
243
+ config_get('interface', 'access_vlan', @get_args)
244
+ end
245
+
246
+ def access_vlan=(vlan)
247
+ config_set('interface', 'access_vlan', name: @name, vlan: vlan)
248
+ end
249
+
250
+ def default_access_vlan
251
+ config_get_default('interface', 'access_vlan')
252
+ end
253
+
254
+ def bfd_echo
255
+ return nil unless Feature.bfd_enabled?
256
+ return nil if @name[/loop/i]
257
+ config_get('interface', 'bfd_echo', @get_args)
258
+ end
259
+
260
+ def bfd_echo=(val)
261
+ fail ArgumentError, 'Interface cannot be loopback' if
262
+ @name[/loop/i]
263
+ return if val == bfd_echo
264
+ state = (val ? '' : 'no')
265
+ Feature.bfd_enable
266
+ config_set('interface', 'bfd_echo',
267
+ name: @name, state: state)
268
+ end
269
+
270
+ def default_bfd_echo
271
+ return nil unless Feature.bfd_enabled?
272
+ return nil if @name[/loop/i]
273
+ config_get_default('interface', 'bfd_echo')
274
+ end
275
+
276
+ def description
277
+ config_get('interface', 'description', @get_args)
278
+ end
279
+
280
+ def description=(desc)
281
+ fail TypeError unless desc.is_a?(String)
282
+ if desc.strip.empty?
283
+ config_set('interface', 'description',
284
+ name: @name, state: 'no', desc: '')
285
+ else
286
+ config_set('interface', 'description',
287
+ name: @name, state: '', desc: desc)
288
+ end
289
+ end
290
+
291
+ def default_description
292
+ config_get_default('interface', 'description')
293
+ end
294
+
295
+ def encapsulation_dot1q
296
+ config_get('interface', 'encapsulation_dot1q', @get_args)
297
+ end
298
+
299
+ def encapsulation_dot1q=(val)
300
+ if val.to_s.empty?
301
+ config_set('interface', 'encapsulation_dot1q',
302
+ name: @name, state: 'no', vlan: '')
303
+ else
304
+ config_set('interface', 'encapsulation_dot1q',
305
+ name: @name, state: '', vlan: val)
306
+ end
307
+ end
308
+
309
+ def default_encapsulation_dot1q
310
+ config_get_default('interface', 'encapsulation_dot1q')
311
+ end
312
+
313
+ def fabricpath_feature
314
+ FabricpathGlobal.fabricpath_feature
315
+ end
316
+
317
+ def fabricpath_feature_set(fabricpath_set)
318
+ FabricpathGlobal.fabricpath_feature_set(fabricpath_set)
319
+ end
320
+
321
+ def fabric_forwarding_anycast_gateway
322
+ config_get('interface', 'fabric_forwarding_anycast_gateway', @get_args)
323
+ end
324
+
325
+ def fabric_forwarding_anycast_gateway=(state)
326
+ return if fabric_forwarding_anycast_gateway == state
327
+ no_cmd = (state ? '' : 'no')
328
+ config_set('interface',
329
+ 'fabric_forwarding_anycast_gateway',
330
+ name: @name, state: no_cmd)
331
+ fail if fabric_forwarding_anycast_gateway.to_s != state.to_s
332
+ rescue Cisco::CliError => e
333
+ raise "#{e} 'fabric_forwarding_anycast_gateway' can only be " \
334
+ 'configured on a vlan interface' unless /vlan/.match(@name)
335
+ anycast_gateway_mac = OverlayGlobal.new.anycast_gateway_mac
336
+ if anycast_gateway_mac.nil? || anycast_gateway_mac.empty?
337
+ raise "#{e} Anycast gateway mac must be configured " \
338
+ 'before configuring forwarding mode under interface'
339
+ end
340
+ raise
341
+ end
342
+
343
+ def default_fabric_forwarding_anycast_gateway
344
+ config_get_default('interface', 'fabric_forwarding_anycast_gateway')
345
+ end
346
+
347
+ def hsrp_bfd
348
+ config_get('interface', 'hsrp_bfd', @get_args)
349
+ end
350
+
351
+ def hsrp_bfd=(val)
352
+ return if val == hsrp_bfd
353
+ state = val ? '' : 'no'
354
+ if val
355
+ Feature.hsrp_enable
356
+ Feature.bfd_enable
357
+ end
358
+ config_set('interface', 'hsrp_bfd', name: @name, state: state)
359
+ end
360
+
361
+ def default_hsrp_bfd
362
+ config_get_default('interface', 'hsrp_bfd')
363
+ end
364
+
365
+ # hsrp delay minimum and reload are in the same CLI
366
+ # hsrp delay minimum 0 reload 0
367
+ def hsrp_delay
368
+ match = config_get('interface', 'hsrp_delay', @get_args)
369
+ match.nil? ? default_hsrp_delay : match.collect(&:to_i)
370
+ end
371
+
372
+ def default_hsrp_delay
373
+ [default_hsrp_delay_minimum, default_hsrp_delay_reload]
374
+ end
375
+
376
+ def hsrp_delay_minimum
377
+ return nil if switchport_mode != :disabled || @name[/loop/i]
378
+ minimum, _reload = hsrp_delay
379
+ minimum.nil? ? default_hsrp_delay_minimum : minimum
380
+ end
381
+
382
+ # hsrp delay minimum and reload are in the same CLI
383
+ # but both can be set independent of each other
384
+ def hsrp_delay_minimum=(val)
385
+ Feature.hsrp_enable if val
386
+ config_set('interface', 'hsrp_delay', name: @name,
387
+ minimum: 'minimum', min: val, reload: '', rel: '')
388
+ end
389
+
390
+ def default_hsrp_delay_minimum
391
+ config_get_default('interface', 'hsrp_delay_minimum')
392
+ end
393
+
394
+ def hsrp_delay_reload
395
+ return nil if switchport_mode != :disabled || @name[/loop/i]
396
+ _minimum, reload = hsrp_delay
397
+ reload.nil? ? default_hsrp_delay_reload : reload
398
+ end
399
+
400
+ # hsrp delay minimum and reload are in the same CLI
401
+ # but both can be set independent of each other
402
+ def hsrp_delay_reload=(val)
403
+ Feature.hsrp_enable if val
404
+ config_set('interface', 'hsrp_delay', name: @name,
405
+ minimum: '', min: '', reload: 'reload', rel: val)
406
+ end
407
+
408
+ def default_hsrp_delay_reload
409
+ config_get_default('interface', 'hsrp_delay_reload')
410
+ end
411
+
412
+ def hsrp_mac_refresh
413
+ config_get('interface', 'hsrp_mac_refresh', @get_args)
414
+ end
415
+
416
+ def hsrp_mac_refresh=(val)
417
+ state = val ? '' : 'no'
418
+ time = val ? val : ''
419
+ Feature.hsrp_enable if val
420
+ config_set('interface', 'hsrp_mac_refresh', name: @name,
421
+ state: state, timeout: time)
422
+ end
423
+
424
+ def default_hsrp_mac_refresh
425
+ config_get_default('interface', 'hsrp_mac_refresh')
426
+ end
427
+
428
+ def hsrp_use_bia
429
+ match = config_get('interface', 'hsrp_use_bia', @get_args)
430
+ return default_hsrp_use_bia unless match
431
+ match.include?('scope') ? :use_bia_intf : :use_bia
432
+ end
433
+
434
+ def hsrp_use_bia=(val)
435
+ # Return early if device already set to the correct value
436
+ return if val == hsrp_use_bia
437
+ # need to reset before set
438
+ if val
439
+ Feature.hsrp_enable
440
+ if val == :use_bia
441
+ config_set('interface', 'hsrp_use_bia', name: name,
442
+ state: 'no', scope: ' scope interface')
443
+ config_set('interface', 'hsrp_use_bia', name: name,
444
+ state: '', scope: '')
445
+ else
446
+ config_set('interface', 'hsrp_use_bia', name: name,
447
+ state: 'no', scope: '')
448
+ config_set('interface', 'hsrp_use_bia', name: name,
449
+ state: '', scope: ' scope interface')
450
+ end
451
+ else
452
+ if hsrp_use_bia == :use_bia
453
+ config_set('interface', 'hsrp_use_bia', name: name,
454
+ state: 'no', scope: '')
455
+ else
456
+ config_set('interface', 'hsrp_use_bia', name: name,
457
+ state: 'no', scope: ' scope interface')
458
+ end
459
+ end
460
+ end
461
+
462
+ def default_hsrp_use_bia
463
+ config_get_default('interface', 'hsrp_use_bia')
464
+ end
465
+
466
+ def hsrp_version
467
+ return nil if switchport_mode != :disabled || @name[/loop/i]
468
+ config_get('interface', 'hsrp_version', @get_args)
469
+ end
470
+
471
+ def hsrp_version=(val)
472
+ Feature.hsrp_enable if val
473
+ config_set('interface', 'hsrp_version', name: name, ver: val)
474
+ end
475
+
476
+ def default_hsrp_version
477
+ config_get_default('interface', 'hsrp_version')
478
+ end
479
+
480
+ def ipv4_acl_in
481
+ config_get('interface', 'ipv4_acl_in', @get_args)
482
+ end
483
+
484
+ def ipv4_acl_in=(val)
485
+ if val != ''
486
+ state = ''
487
+ else
488
+ state = 'no'
489
+ val = ipv4_acl_in
490
+ end
491
+
492
+ return unless val && val != ''
493
+ config_set('interface', 'ipv4_acl_in',
494
+ name: @name, state: state, acl: val)
495
+ end
496
+
497
+ def default_ipv4_acl_in
498
+ config_get_default('interface', 'ipv4_acl_in')
499
+ end
500
+
501
+ def ipv4_acl_out
502
+ config_get('interface', 'ipv4_acl_out', @get_args)
503
+ end
504
+
505
+ def ipv4_acl_out=(val)
506
+ if val != ''
507
+ state = ''
508
+ else
509
+ state = 'no'
510
+ val = ipv4_acl_out
511
+ end
512
+
513
+ return unless val && val != ''
514
+ config_set('interface', 'ipv4_acl_out',
515
+ name: @name, state: state, acl: val)
516
+ end
517
+
518
+ def default_ipv4_acl_out
519
+ config_get_default('interface', 'ipv4_acl_out')
520
+ end
521
+
522
+ def ipv4_addr_mask_set(addr, mask, secondary=false)
523
+ check_switchport(:disabled)
524
+ sec = secondary ? 'secondary' : ''
525
+ if addr.nil? || addr == default_ipv4_address
526
+ state = 'no'
527
+ if secondary
528
+ return if ipv4_address_secondary == default_ipv4_address_secondary
529
+ # We need address and mask to remove.
530
+ am = "#{ipv4_address_secondary}/#{ipv4_netmask_length_secondary}"
531
+ else
532
+ return if ipv4_address == default_ipv4_address
533
+ am = "#{ipv4_address}/#{ipv4_netmask_length}"
534
+ end
535
+ else
536
+ state = ''
537
+ am = "#{addr}/#{mask}"
538
+ end
539
+ config_set('interface', 'ipv4_addr_mask',
540
+ name: @name, state: state, addr: am, secondary: sec)
541
+ end
542
+
543
+ def ipv4_addr_mask
544
+ val = config_get('interface', 'ipv4_addr_mask', @get_args)
545
+ if val && platform == :ios_xr
546
+ # IOS XR reports address as <address> <bitmask> [secondary] but we
547
+ # want <address>/<length> [secondary]
548
+ val.each_with_index do |entry, i|
549
+ mask = entry[1].split(' ')
550
+ mask[0] = Utils.bitmask_to_length(mask[0])
551
+ val[i][1] = mask.join(' ')
552
+ end
553
+ end
554
+ val
555
+ end
556
+
557
+ def select_ipv4_attribute(attribute)
558
+ d = ipv4_addr_mask.flatten unless ipv4_addr_mask.nil?
559
+ # (d)ata format after flatten: ['addr', 'mask', 'addr', 'mask secondary']
560
+ case attribute
561
+ when :v4_addr
562
+ v = d.nil? ? default_ipv4_address : d[0]
563
+ when :v4_mask
564
+ v = d.nil? ? default_ipv4_netmask_length : d[1].to_i
565
+ when :v4_addr_secondary
566
+ v = (d.nil? || d.size < 4) ? default_ipv4_address : d[2]
567
+ when :v4_mask_secondary
568
+ if d.nil? || d.size < 4
569
+ v = default_ipv4_netmask_length
570
+ else
571
+ v = d[3][0, 2].to_i
572
+ end
573
+ end
574
+ v
575
+ end
576
+
577
+ def ipv4_address
578
+ select_ipv4_attribute(:v4_addr)
579
+ end
580
+
581
+ def ipv4_address_secondary
582
+ select_ipv4_attribute(:v4_addr_secondary)
583
+ end
584
+
585
+ def ipv4_netmask_length
586
+ select_ipv4_attribute(:v4_mask)
587
+ end
588
+
589
+ def ipv4_netmask_length_secondary
590
+ select_ipv4_attribute(:v4_mask_secondary)
591
+ end
592
+
593
+ def default_ipv4_address
594
+ config_get_default('interface', 'ipv4_address')
595
+ end
596
+
597
+ def default_ipv4_address_secondary
598
+ default_ipv4_address
599
+ end
600
+
601
+ def default_ipv4_netmask_length
602
+ config_get_default('interface', 'ipv4_netmask_length')
603
+ end
604
+
605
+ def default_ipv4_netmask_length_secondary
606
+ default_ipv4_netmask_length
607
+ end
608
+
609
+ def ipv4_arp_timeout_lookup_string
610
+ case @name
611
+ when /vlan/i
612
+ return 'ipv4_arp_timeout'
613
+ else
614
+ return 'ipv4_arp_timeout_non_vlan_interfaces'
615
+ end
616
+ end
617
+
618
+ def ipv4_arp_timeout
619
+ config_get('interface', ipv4_arp_timeout_lookup_string, @get_args)
620
+ end
621
+
622
+ def ipv4_arp_timeout=(timeout)
623
+ fail "'ipv4 arp timeout' can ony be configured on a vlan interface" unless
624
+ /vlan/.match(@name)
625
+ state = (timeout == default_ipv4_arp_timeout) ? 'no' : ''
626
+ config_set('interface', 'ipv4_arp_timeout',
627
+ name: @name, state: state, timeout: timeout)
628
+ end
629
+
630
+ def default_ipv4_arp_timeout
631
+ config_get_default('interface', ipv4_arp_timeout_lookup_string)
632
+ end
633
+
634
+ def ipv4_dhcp_relay_addr
635
+ config_get('interface', 'ipv4_dhcp_relay_addr', @get_args)
636
+ end
637
+
638
+ def ipv4_dhcp_relay_addr=(list)
639
+ cur_list = ipv4_dhcp_relay_addr
640
+ # remove the current addresses first
641
+ unless cur_list.empty?
642
+ cur_list.each do |addr|
643
+ config_set('interface', 'ipv4_dhcp_relay_addr',
644
+ name: @name, state: 'no', addr: addr)
645
+ end
646
+ end
647
+ Feature.dhcp_enable unless list.empty?
648
+ list.each do |addr|
649
+ config_set('interface', 'ipv4_dhcp_relay_addr',
650
+ name: @name, state: '', addr: addr)
651
+ end
652
+ end
653
+
654
+ def default_ipv4_dhcp_relay_addr
655
+ config_get_default('interface', 'ipv4_dhcp_relay_addr')
656
+ end
657
+
658
+ def ipv4_dhcp_relay_info_trust
659
+ return nil if @name[/loop/i] || switchport_mode != :disabled
660
+ config_get('interface', 'ipv4_dhcp_relay_info_trust', @get_args)
661
+ end
662
+
663
+ def ipv4_dhcp_relay_info_trust=(state)
664
+ return false if !state && !Feature.dhcp_enabled?
665
+ Feature.dhcp_enable if state
666
+ config_set('interface', 'ipv4_dhcp_relay_info_trust',
667
+ name: @name, state: state ? '' : 'no')
668
+ end
669
+
670
+ def default_ipv4_dhcp_relay_info_trust
671
+ config_get_default('interface', 'ipv4_dhcp_relay_info_trust')
672
+ end
673
+
674
+ def ipv4_dhcp_relay_src_addr_hsrp
675
+ config_get('interface', 'ipv4_dhcp_relay_src_addr_hsrp', @get_args)
676
+ end
677
+
678
+ def ipv4_dhcp_relay_src_addr_hsrp=(state)
679
+ return false if !state && !Feature.dhcp_enabled?
680
+ Feature.dhcp_enable if state
681
+ config_set('interface', 'ipv4_dhcp_relay_src_addr_hsrp',
682
+ name: @name, state: state ? '' : 'no')
683
+ end
684
+
685
+ def default_ipv4_dhcp_relay_src_addr_hsrp
686
+ config_get_default('interface', 'ipv4_dhcp_relay_src_addr_hsrp')
687
+ end
688
+
689
+ def ipv4_dhcp_relay_src_intf
690
+ intf = config_get('interface', 'ipv4_dhcp_relay_src_intf', @get_args)
691
+ # Normalize by downcasing and removing white space
692
+ intf = intf.downcase.delete(' ') if intf
693
+ intf
694
+ end
695
+
696
+ def ipv4_dhcp_relay_src_intf=(val)
697
+ state = val == default_ipv4_dhcp_relay_src_intf ? 'no' : ''
698
+ return false if state == 'no' && !Feature.dhcp_enabled?
699
+ Feature.dhcp_enable if state.empty?
700
+ intf = val == default_ipv4_dhcp_relay_src_intf ? '' : val
701
+ config_set('interface', 'ipv4_dhcp_relay_src_intf',
702
+ name: @name, state: state, intf: intf)
703
+ end
704
+
705
+ def default_ipv4_dhcp_relay_src_intf
706
+ config_get_default('interface', 'ipv4_dhcp_relay_src_intf')
707
+ end
708
+
709
+ def ipv4_dhcp_relay_subnet_broadcast
710
+ return nil if @name[/loop/i] || switchport_mode != :disabled
711
+ config_get('interface', 'ipv4_dhcp_relay_subnet_broadcast', @get_args)
712
+ end
713
+
714
+ def ipv4_dhcp_relay_subnet_broadcast=(state)
715
+ return false if !state && !Feature.dhcp_enabled?
716
+ Feature.dhcp_enable if state
717
+ config_set('interface', 'ipv4_dhcp_relay_subnet_broadcast',
718
+ name: @name, state: state ? '' : 'no')
719
+ end
720
+
721
+ def default_ipv4_dhcp_relay_subnet_broadcast
722
+ config_get_default('interface', 'ipv4_dhcp_relay_subnet_broadcast')
723
+ end
724
+
725
+ def ipv4_dhcp_smart_relay
726
+ return nil if @name[/loop/i] || switchport_mode != :disabled
727
+ config_get('interface', 'ipv4_dhcp_smart_relay', @get_args)
728
+ end
729
+
730
+ def ipv4_dhcp_smart_relay=(state)
731
+ return false if !state && !Feature.dhcp_enabled?
732
+ Feature.dhcp_enable if state
733
+ config_set('interface', 'ipv4_dhcp_smart_relay',
734
+ name: @name, state: state ? '' : 'no')
735
+ end
736
+
737
+ def default_ipv4_dhcp_smart_relay
738
+ config_get_default('interface', 'ipv4_dhcp_smart_relay')
739
+ end
740
+
741
+ def ipv4_forwarding
742
+ config_get('interface', 'ipv4_forwarding', @get_args)
743
+ end
744
+
745
+ def ipv4_forwarding=(state)
746
+ return if state == ipv4_forwarding
747
+ config_set('interface', 'ipv4_forwarding',
748
+ name: @name, state: state ? '' : 'no')
749
+ end
750
+
751
+ def default_ipv4_forwarding
752
+ config_get_default('interface', 'ipv4_forwarding')
753
+ end
754
+
755
+ def ipv4_pim_sparse_mode
756
+ return nil unless switchport_mode == :disabled
757
+ config_get('interface', 'ipv4_pim_sparse_mode', @get_args)
758
+ end
759
+
760
+ def ipv4_pim_sparse_mode=(state)
761
+ check_switchport(:disabled)
762
+ Feature.pim_enable unless platform == :ios_xr
763
+ config_set('interface', 'ipv4_pim_sparse_mode',
764
+ name: @name, state: state ? '' : 'no')
765
+ end
766
+
767
+ def default_ipv4_pim_sparse_mode
768
+ config_get_default('interface', 'ipv4_pim_sparse_mode')
769
+ end
770
+
771
+ def ipv4_proxy_arp
772
+ return nil if @name[/loop/i] || switchport_mode != :disabled
773
+ config_get('interface', 'ipv4_proxy_arp', @get_args)
774
+ end
775
+
776
+ def ipv4_proxy_arp=(proxy_arp)
777
+ check_switchport(:disabled)
778
+ no_cmd = (proxy_arp ? '' : 'no')
779
+ config_set('interface', 'ipv4_proxy_arp', name: @name, state: no_cmd)
780
+ end
781
+
782
+ def default_ipv4_proxy_arp
783
+ config_get_default('interface', 'ipv4_proxy_arp')
784
+ end
785
+
786
+ def ipv4_redirects_lookup_string
787
+ case @name
788
+ when /loopback/i
789
+ return 'ipv4_redirects_loopback'
790
+ else
791
+ return 'ipv4_redirects_other_interfaces'
792
+ end
793
+ end
794
+
795
+ def ipv4_redirects
796
+ return nil unless switchport_mode == :disabled
797
+ config_get('interface', ipv4_redirects_lookup_string, @get_args)
798
+ end
799
+
800
+ def ipv4_redirects=(redirects)
801
+ check_switchport(:disabled)
802
+ no_cmd = (redirects ? '' : 'no')
803
+ config_set('interface', ipv4_redirects_lookup_string,
804
+ name: @name, state: no_cmd)
805
+ end
806
+
807
+ def default_ipv4_redirects
808
+ config_get_default('interface', ipv4_redirects_lookup_string)
809
+ end
810
+
811
+ def ipv6_acl_in
812
+ config_get('interface', 'ipv6_acl_in', @get_args)
813
+ end
814
+
815
+ def ipv6_acl_in=(val)
816
+ if val != ''
817
+ state = ''
818
+ else
819
+ state = 'no'
820
+ val = ipv6_acl_in
821
+ end
822
+ return unless val && val != ''
823
+ config_set('interface', 'ipv6_acl_in',
824
+ name: @name, state: state, acl: val)
825
+ end
826
+
827
+ def default_ipv6_acl_in
828
+ config_get_default('interface', 'ipv6_acl_in')
829
+ end
830
+
831
+ def ipv6_acl_out
832
+ config_get('interface', 'ipv6_acl_out', @get_args)
833
+ end
834
+
835
+ def ipv6_acl_out=(val)
836
+ if val != ''
837
+ state = ''
838
+ else
839
+ state = 'no'
840
+ val = ipv6_acl_out
841
+ end
842
+ return unless val && val != ''
843
+ config_set('interface', 'ipv6_acl_out',
844
+ name: @name, state: state, acl: val)
845
+ end
846
+
847
+ def default_ipv6_acl_out
848
+ config_get_default('interface', 'ipv6_acl_out')
849
+ end
850
+
851
+ def ipv6_dhcp_relay_addr
852
+ config_get('interface', 'ipv6_dhcp_relay_addr', @get_args)
853
+ end
854
+
855
+ def ipv6_dhcp_relay_addr=(list)
856
+ cur_list = ipv6_dhcp_relay_addr
857
+ # remove the current addresses first
858
+ unless cur_list.empty?
859
+ cur_list.each do |addr|
860
+ config_set('interface', 'ipv6_dhcp_relay_addr',
861
+ name: @name, state: 'no', addr: addr)
862
+ end
863
+ end
864
+ Feature.dhcp_enable unless list.empty?
865
+ list.each do |addr|
866
+ config_set('interface', 'ipv6_dhcp_relay_addr',
867
+ name: @name, state: '', addr: addr)
868
+ end
869
+ end
870
+
871
+ def default_ipv6_dhcp_relay_addr
872
+ config_get_default('interface', 'ipv6_dhcp_relay_addr')
873
+ end
874
+
875
+ def ipv6_dhcp_relay_src_intf
876
+ intf = config_get('interface', 'ipv6_dhcp_relay_src_intf', @get_args)
877
+ # Normalize by downcasing and removing white space
878
+ intf = intf.downcase.delete(' ') if intf
879
+ intf
880
+ end
881
+
882
+ def ipv6_dhcp_relay_src_intf=(val)
883
+ state = val == default_ipv6_dhcp_relay_src_intf ? 'no' : ''
884
+ return false if state == 'no' && !Feature.dhcp_enabled?
885
+ Feature.dhcp_enable if state.empty?
886
+ intf = val == default_ipv6_dhcp_relay_src_intf ? '' : val
887
+ config_set('interface', 'ipv6_dhcp_relay_src_intf',
888
+ name: @name, state: state, intf: intf)
889
+ end
890
+
891
+ def default_ipv6_dhcp_relay_src_intf
892
+ config_get_default('interface', 'ipv6_dhcp_relay_src_intf')
893
+ end
894
+
895
+ def ipv6_redirects
896
+ return nil if @name[/loop/i] || switchport_mode != :disabled
897
+ config_get('interface', 'ipv6_redirects', @get_args)
898
+ end
899
+
900
+ def ipv6_redirects=(redirects)
901
+ check_switchport(:disabled)
902
+ no_cmd = (redirects ? '' : 'no')
903
+ config_set('interface', 'ipv6_redirects',
904
+ name: @name, state: no_cmd)
905
+ end
906
+
907
+ def default_ipv6_redirects
908
+ config_get_default('interface', 'ipv6_redirects')
909
+ end
910
+
911
+ def feature_lacp?
912
+ config_get('interface', 'feature_lacp')
913
+ end
914
+
915
+ def feature_lacp_set(val)
916
+ return if feature_lacp? == val
917
+ config_set('interface', 'feature_lacp', state: val ? '' : 'no')
918
+ end
919
+
920
+ def load_interval_counter_1_delay
921
+ return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
922
+ config_get('interface', 'load_interval_counter_1_delay', @get_args)
923
+ end
924
+
925
+ def load_interval_counter_1_delay=(val)
926
+ fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
927
+ @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
928
+ config_set('interface', 'load_interval_counter_1_delay',
929
+ name: @name, delay: val)
930
+ end
931
+
932
+ def default_load_interval_counter_1_delay
933
+ # for vlan and bdi the default is 60
934
+ if @name[/(vlan|bdi)/i]
935
+ config_get_default('interface',
936
+ 'load_interval_counter_1_delay_vlan_bdi')
937
+ else
938
+ config_get_default('interface', 'load_interval_counter_1_delay')
939
+ end
940
+ end
941
+
942
+ def load_interval_counter_2_delay
943
+ return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
944
+ config_get('interface', 'load_interval_counter_2_delay', @get_args)
945
+ end
946
+
947
+ def load_interval_counter_2_delay=(val)
948
+ fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
949
+ @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
950
+ config_set('interface', 'load_interval_counter_2_delay',
951
+ name: @name, delay: val)
952
+ end
953
+
954
+ def default_load_interval_counter_2_delay
955
+ config_get_default('interface', 'load_interval_counter_2_delay')
956
+ end
957
+
958
+ def load_interval_counter_3_delay
959
+ return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
960
+ config_get('interface', 'load_interval_counter_3_delay', @get_args)
961
+ end
962
+
963
+ def load_interval_counter_3_delay=(val)
964
+ fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
965
+ @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
966
+ state = val ? '' : 'no'
967
+ delay = val ? val : ''
968
+ config_set('interface', 'load_interval_counter_3_delay',
969
+ name: @name, state: state, delay: delay)
970
+ end
971
+
972
+ def default_load_interval_counter_3_delay
973
+ config_get_default('interface', 'load_interval_counter_3_delay')
974
+ end
975
+
976
+ def mtu_lookup_string
977
+ case @name
978
+ when /loopback/i
979
+ return 'mtu_loopback'
980
+ else
981
+ return 'mtu_other_interfaces'
982
+ end
983
+ end
984
+
985
+ def mtu
986
+ config_get('interface', mtu_lookup_string, @get_args)
987
+ end
988
+
989
+ def mtu=(val)
990
+ return if mtu == val
991
+ check_switchport(:disabled)
992
+ config_set('interface', mtu_lookup_string,
993
+ name: @name, state: '', mtu: val)
994
+ end
995
+
996
+ def default_mtu
997
+ config_get_default('interface', mtu_lookup_string)
998
+ end
999
+
1000
+ def speed
1001
+ return nil if @name[/loop|vlan/i]
1002
+ config_get('interface', 'speed', @get_args)
1003
+ end
1004
+
1005
+ def speed=(val)
1006
+ config_set('interface', 'speed', name: @name, speed: val)
1007
+ end
1008
+
1009
+ def default_speed
1010
+ config_get_default('interface', 'speed')
1011
+ end
1012
+
1013
+ def duplex
1014
+ return nil if @name[/loop|vlan/i]
1015
+ config_get('interface', 'duplex', @get_args)
1016
+ end
1017
+
1018
+ def duplex=(val)
1019
+ config_set('interface', 'duplex', name: @name, duplex: val)
1020
+ end
1021
+
1022
+ def default_duplex
1023
+ config_get_default('interface', 'duplex')
1024
+ end
1025
+
1026
+ def negotiate_auto_lookup_string
1027
+ case @name
1028
+ when ETHERNET
1029
+ return 'negotiate_auto_ethernet'
1030
+ when PORTCHANNEL
1031
+ return 'negotiate_auto_portchannel'
1032
+ else
1033
+ return 'negotiate_auto_other_interfaces'
1034
+ end
1035
+ end
1036
+
1037
+ def negotiate_auto
1038
+ return nil if @name[/loop|vlan/]
1039
+ config_get('interface', negotiate_auto_lookup_string, @get_args)
1040
+ end
1041
+
1042
+ def negotiate_auto=(negotiate_auto)
1043
+ lookup = negotiate_auto_lookup_string
1044
+ no_cmd = (negotiate_auto ? '' : 'no')
1045
+ config_set('interface', lookup, name: @name, state: no_cmd)
1046
+ end
1047
+
1048
+ def default_negotiate_auto
1049
+ config_get_default('interface', negotiate_auto_lookup_string)
1050
+ end
1051
+
1052
+ def shutdown
1053
+ config_get('interface', 'shutdown', @get_args)
1054
+ end
1055
+
1056
+ def shutdown=(state)
1057
+ no_cmd = (state ? '' : 'no')
1058
+ config_set('interface', 'shutdown', name: @name, state: no_cmd)
1059
+ end
1060
+
1061
+ def default_shutdown
1062
+ case @name
1063
+ when ETHERNET
1064
+ def_sw = system_default_switchport
1065
+ def_shut = system_default_switchport_shutdown
1066
+
1067
+ if def_sw && def_shut
1068
+ lookup = 'shutdown_ethernet_switchport_shutdown'
1069
+ elsif def_sw && !def_shut
1070
+ lookup = 'shutdown_ethernet_switchport_noshutdown'
1071
+ elsif !def_sw && def_shut
1072
+ lookup = 'shutdown_ethernet_noswitchport_shutdown'
1073
+ elsif !def_sw && !def_shut
1074
+ lookup = 'shutdown_ethernet_noswitchport_noshutdown'
1075
+ else
1076
+ fail "Error: def_sw #{def_sw}, def_shut #{def_shut}"
1077
+ end
1078
+
1079
+ when /loopback/i
1080
+ lookup = 'shutdown_loopback'
1081
+
1082
+ when PORTCHANNEL
1083
+ lookup = 'shutdown_ether_channel'
1084
+
1085
+ when /Vlan/i
1086
+ lookup = 'shutdown_vlan'
1087
+
1088
+ else
1089
+ lookup = 'shutdown_unknown'
1090
+ end
1091
+ config_get_default('interface', lookup)
1092
+ end
1093
+
1094
+ def pim_bfd
1095
+ config_get('interface', 'pim_bfd', @get_args)
1096
+ end
1097
+
1098
+ def pim_bfd=(val)
1099
+ return if val == pim_bfd
1100
+ state = val ? '' : 'no'
1101
+ if val
1102
+ Feature.pim_enable
1103
+ Feature.bfd_enable
1104
+ end
1105
+ config_set('interface', 'pim_bfd', name: @name, state: state)
1106
+ end
1107
+
1108
+ def default_pim_bfd
1109
+ config_get_default('interface', 'pim_bfd')
1110
+ end
1111
+
1112
+ def storm_control_broadcast
1113
+ return nil if @name[/loop|vlan/i]
1114
+ config_get('interface', 'storm_control_broadcast', @get_args)
1115
+ end
1116
+
1117
+ def storm_control_broadcast=(val)
1118
+ return if val == storm_control_broadcast
1119
+ state = val == default_storm_control_broadcast ? 'no' : ''
1120
+ level = val == default_storm_control_broadcast ? '' : val
1121
+ config_set('interface', 'storm_control_broadcast',
1122
+ name: @name, state: state, level: level)
1123
+ end
1124
+
1125
+ def default_storm_control_broadcast
1126
+ config_get_default('interface', 'storm_control_broadcast')
1127
+ end
1128
+
1129
+ def storm_control_multicast
1130
+ return nil if @name[/loop|vlan/i]
1131
+ config_get('interface', 'storm_control_multicast', @get_args)
1132
+ end
1133
+
1134
+ def storm_control_multicast=(val)
1135
+ return if val == storm_control_multicast
1136
+ state = val == default_storm_control_multicast ? 'no' : ''
1137
+ level = val == default_storm_control_multicast ? '' : val
1138
+ config_set('interface', 'storm_control_multicast',
1139
+ name: @name, state: state, level: level)
1140
+ end
1141
+
1142
+ def default_storm_control_multicast
1143
+ config_get_default('interface', 'storm_control_multicast')
1144
+ end
1145
+
1146
+ def storm_control_unicast
1147
+ return nil if @name[/loop|vlan/i]
1148
+ config_get('interface', 'storm_control_unicast', @get_args)
1149
+ end
1150
+
1151
+ def storm_control_unicast=(val)
1152
+ return if val == storm_control_unicast
1153
+ state = val == default_storm_control_unicast ? 'no' : ''
1154
+ level = val == default_storm_control_unicast ? '' : val
1155
+ config_set('interface', 'storm_control_unicast',
1156
+ name: @name, state: state, level: level)
1157
+ end
1158
+
1159
+ def default_storm_control_unicast
1160
+ config_get_default('interface', 'storm_control_unicast')
1161
+ end
1162
+
1163
+ def stp_bpdufilter
1164
+ config_get('interface', 'stp_bpdufilter', @get_args)
1165
+ end
1166
+
1167
+ def stp_bpdufilter=(val)
1168
+ check_switchport([:access, :trunk])
1169
+ if val
1170
+ state = ''
1171
+ else
1172
+ state = 'no'
1173
+ val = ''
1174
+ end
1175
+ config_set('interface',
1176
+ 'stp_bpdufilter', name: @name, state: state, filter: val)
1177
+ end
1178
+
1179
+ def default_stp_bpdufilter
1180
+ config_get_default('interface', 'stp_bpdufilter')
1181
+ end
1182
+
1183
+ def stp_bpduguard
1184
+ config_get('interface', 'stp_bpduguard', @get_args)
1185
+ end
1186
+
1187
+ def stp_bpduguard=(val)
1188
+ if val
1189
+ state = ''
1190
+ else
1191
+ state = 'no'
1192
+ val = ''
1193
+ end
1194
+ config_set('interface',
1195
+ 'stp_bpduguard', name: @name, state: state, guard: val)
1196
+ end
1197
+
1198
+ def default_stp_bpduguard
1199
+ config_get_default('interface', 'stp_bpduguard')
1200
+ end
1201
+
1202
+ def stp_cost
1203
+ return nil if switchport_mode == :disabled
1204
+ cost = config_get('interface', 'stp_cost', @get_args)
1205
+ cost == 'auto' ? cost : cost.to_i
1206
+ end
1207
+
1208
+ def stp_cost=(val)
1209
+ check_switchport([:access, :trunk])
1210
+ config_set('interface', 'stp_cost', name: @name, cost: val)
1211
+ end
1212
+
1213
+ def default_stp_cost
1214
+ config_get_default('interface', 'stp_cost')
1215
+ end
1216
+
1217
+ def stp_guard
1218
+ config_get('interface', 'stp_guard', @get_args)
1219
+ end
1220
+
1221
+ def stp_guard=(val)
1222
+ check_switchport([:access, :trunk])
1223
+ if val
1224
+ state = ''
1225
+ else
1226
+ state = 'no'
1227
+ val = ''
1228
+ end
1229
+ config_set('interface', 'stp_guard', name: @name, state: state,
1230
+ guard: val)
1231
+ end
1232
+
1233
+ def default_stp_guard
1234
+ config_get_default('interface', 'stp_guard')
1235
+ end
1236
+
1237
+ def stp_link_type
1238
+ return nil if switchport_mode == :disabled
1239
+ config_get('interface', 'stp_link_type', @get_args)
1240
+ end
1241
+
1242
+ def stp_link_type=(val)
1243
+ check_switchport([:access, :trunk])
1244
+ config_set('interface', 'stp_link_type', name: @name, type: val)
1245
+ end
1246
+
1247
+ def default_stp_link_type
1248
+ config_get_default('interface', 'stp_link_type')
1249
+ end
1250
+
1251
+ def stp_port_priority
1252
+ return nil if switchport_mode == :disabled
1253
+ config_get('interface', 'stp_port_priority', @get_args)
1254
+ end
1255
+
1256
+ def stp_port_priority=(val)
1257
+ check_switchport([:access, :trunk])
1258
+ config_set('interface', 'stp_port_priority', name: @name, pp: val)
1259
+ end
1260
+
1261
+ def default_stp_port_priority
1262
+ config_get_default('interface', 'stp_port_priority')
1263
+ end
1264
+
1265
+ # Getter: Builds an array of mst cost commands currently
1266
+ # on the device.
1267
+ # cli: spanning-tree mst 0,2-4,6,8-12 cost 1000
1268
+ # spanning-tree mst 4000-4020 cost 2568
1269
+ # array: [['0,2-4,6,8-12', '1000'], ['4000-4020', '2568']]
1270
+ #
1271
+ def stp_mst_cost
1272
+ config_get('interface', 'stp_mst_cost', @get_args)
1273
+ end
1274
+
1275
+ def stp_mst_cost=(list)
1276
+ check_switchport([:access, :trunk])
1277
+ config_set('interface', 'stp_mst_cost',
1278
+ name: @name, state: 'no', range: @smr,
1279
+ val: '') if list.empty?
1280
+ set_range_based_params(list, 'stp_mst_cost')
1281
+ end
1282
+
1283
+ def default_stp_mst_cost
1284
+ config_get_default('interface', 'stp_mst_cost')
1285
+ end
1286
+
1287
+ # Getter: Builds an array of mst port-priority commands
1288
+ # currently on the device.
1289
+ # cli: spanning-tree mst 0,2-4,6,8-12 port-priority 64
1290
+ # spanning-tree mst 4000-4020 port-priority 160
1291
+ # array: [['0,2-4,6,8-12', '64'], ['4000-4020', '160']]
1292
+ #
1293
+ def stp_mst_port_priority
1294
+ config_get('interface', 'stp_mst_port_priority', @get_args)
1295
+ end
1296
+
1297
+ def stp_mst_port_priority=(list)
1298
+ check_switchport([:access, :trunk])
1299
+ config_set('interface', 'stp_mst_port_priority',
1300
+ name: @name, state: 'no', range: @smr,
1301
+ val: '') if list.empty?
1302
+ set_range_based_params(list, 'stp_mst_port_priority')
1303
+ end
1304
+
1305
+ def default_stp_mst_port_priority
1306
+ config_get_default('interface', 'stp_mst_port_priority')
1307
+ end
1308
+
1309
+ def stp_port_type
1310
+ config_get('interface', 'stp_port_type', @get_args)
1311
+ end
1312
+
1313
+ def stp_port_type=(val)
1314
+ if val
1315
+ state = ''
1316
+ else
1317
+ return unless stp_port_type
1318
+ state = 'no'
1319
+ val = stp_port_type
1320
+ end
1321
+ config_set('interface', 'stp_port_type', name: @name,
1322
+ state: state, type: val)
1323
+ end
1324
+
1325
+ def default_stp_port_type
1326
+ config_get_default('interface', 'stp_port_type')
1327
+ end
1328
+
1329
+ # Getter: Builds an array of vlan cost commands currently
1330
+ # on the device.
1331
+ # cli: spanning-tree vlan 1-4,6,8-12 cost 1000
1332
+ # spanning-tree vlan 3000-3960 cost 2568
1333
+ # array: [['1-4,6,8-12', '1000'], ['3000-3960', '2568']]
1334
+ #
1335
+ def stp_vlan_cost
1336
+ config_get('interface', 'stp_vlan_cost', @get_args)
1337
+ end
1338
+
1339
+ def stp_vlan_cost=(list)
1340
+ check_switchport([:access, :trunk])
1341
+ config_set('interface', 'stp_vlan_cost',
1342
+ name: @name, state: 'no',
1343
+ range: @svr, val: '') if list.empty?
1344
+ set_range_based_params(list, 'stp_vlan_cost')
1345
+ end
1346
+
1347
+ def default_stp_vlan_cost
1348
+ config_get_default('interface', 'stp_vlan_cost')
1349
+ end
1350
+
1351
+ # Getter: Builds an array of vlan port-priority commands
1352
+ # currently on the device.
1353
+ # cli: spanning-tree vlan 1-4,6,8-12 port-priority 64
1354
+ # spanning-tree vlan 3000-3960 port-priority 160
1355
+ # array: [['1-4,6,8-12', '64'], ['3000-3960', '160']]
1356
+ #
1357
+ def stp_vlan_port_priority
1358
+ config_get('interface', 'stp_vlan_port_priority', @get_args)
1359
+ end
1360
+
1361
+ def stp_vlan_port_priority=(list)
1362
+ check_switchport([:access, :trunk])
1363
+ config_set('interface', 'stp_vlan_port_priority',
1364
+ name: @name, state: 'no',
1365
+ range: @svr, val: '') if list.empty?
1366
+ set_range_based_params(list, 'stp_vlan_port_priority')
1367
+ end
1368
+
1369
+ def default_stp_vlan_port_priority
1370
+ config_get_default('interface', 'stp_vlan_port_priority')
1371
+ end
1372
+
1373
+ def switchport
1374
+ # This is "switchport", not "switchport mode"
1375
+ config_get('interface', 'switchport', @get_args)
1376
+ end
1377
+
1378
+ def switchport_enable(val=true)
1379
+ config_set('interface', 'switchport', name: @name, state: val ? '' : 'no')
1380
+ end
1381
+
1382
+ # switchport_autostate_exclude is exclusive to switchport interfaces
1383
+ def switchport_autostate_exclude
1384
+ return nil if switchport_mode == :disabled
1385
+ config_get('interface', 'switchport_autostate_exclude', @get_args)
1386
+ end
1387
+
1388
+ def switchport_autostate_exclude=(val)
1389
+ if platform == :nexus
1390
+ # cannot configure autostate unless feature vlan is enabled
1391
+ fail('switchport mode must be configured before ' \
1392
+ 'switchport autostate') unless switchport
1393
+ feature_vlan_set(true)
1394
+ end
1395
+ config_set('interface', 'switchport_autostate_exclude',
1396
+ name: @name, state: val ? '' : 'no')
1397
+ end
1398
+
1399
+ def default_switchport_autostate_exclude
1400
+ config_get_default('interface', 'switchport_autostate_exclude')
1401
+ end
1402
+
1403
+ def switchport_mode_lookup_string
1404
+ case @name
1405
+ when ETHERNET
1406
+ return 'switchport_mode_ethernet'
1407
+ when PORTCHANNEL
1408
+ return 'switchport_mode_port_channel'
1409
+ else
1410
+ return 'switchport_mode_other_interfaces'
1411
+ end
1412
+ end
1413
+
1414
+ def switchport_mode
1415
+ return nil if platform == :ios_xr
1416
+ mode = config_get('interface', switchport_mode_lookup_string, @get_args)
1417
+
1418
+ return mode.nil? ? :disabled : IF_SWITCHPORT_MODE.key(mode)
1419
+
1420
+ rescue IndexError
1421
+ # Assume this is an interface that doesn't support switchport.
1422
+ # Do not raise exception since the providers will prefetch this property
1423
+ # regardless of interface type.
1424
+ # TODO: this should probably be nil instead
1425
+ return :disabled
1426
+ end
1427
+
1428
+ def switchport_enable_and_mode(mode_set)
1429
+ switchport_enable
1430
+
1431
+ if :fabricpath == mode_set
1432
+ fabricpath_feature_set(:enabled) unless :enabled == fabricpath_feature
1433
+ elsif :fex_fabric == mode_set
1434
+ Feature.fex_enable
1435
+ end
1436
+ config_set('interface', switchport_mode_lookup_string,
1437
+ name: @name, state: '', mode: IF_SWITCHPORT_MODE[mode_set])
1438
+ end
1439
+
1440
+ def switchport_mode=(mode_set)
1441
+ # no system default switchport
1442
+ # int e1/1
1443
+ # switchport
1444
+ # switchport mode [access|trunk|fex|...]
1445
+ fail ArgumentError unless IF_SWITCHPORT_MODE.keys.include? mode_set
1446
+ case mode_set
1447
+ when :disabled
1448
+ if switchport
1449
+ # Note: turn off switchport command, not switchport mode
1450
+ config_set('interface', 'switchport', name: @name, state: 'no')
1451
+ end
1452
+
1453
+ when :default
1454
+ if :disabled == default_switchport_mode
1455
+ config_set('interface', switchport_mode_lookup_string,
1456
+ name: @name, state: 'no', mode: '')
1457
+ else
1458
+ switchport_enable_and_mode(mode_set)
1459
+ end
1460
+
1461
+ else
1462
+ switchport_enable_and_mode(mode_set)
1463
+ end # case
1464
+ end
1465
+
1466
+ def default_switchport_mode
1467
+ return nil if platform == :ios_xr
1468
+ return :disabled unless system_default_switchport
1469
+ IF_SWITCHPORT_MODE.key(
1470
+ config_get_default('interface', switchport_mode_lookup_string))
1471
+ end
1472
+
1473
+ def switchport_trunk_allowed_vlan
1474
+ return nil if switchport_mode == :disabled
1475
+ vlans = config_get('interface', 'switchport_trunk_allowed_vlan',
1476
+ @get_args)
1477
+ vlans = vlans.join(',') if vlans.is_a?(Array)
1478
+ vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
1479
+ vlans
1480
+ end
1481
+
1482
+ def switchport_trunk_allowed_vlan=(val)
1483
+ if val.nil?
1484
+ config_set('interface', 'switchport_trunk_allowed_vlan',
1485
+ name: @name, state: 'no', vlan: '')
1486
+ else
1487
+ config_set('interface', 'switchport_trunk_allowed_vlan',
1488
+ name: @name, state: '', vlan: val)
1489
+ end
1490
+ end
1491
+
1492
+ def default_switchport_trunk_allowed_vlan
1493
+ config_get_default('interface', 'switchport_trunk_allowed_vlan')
1494
+ end
1495
+
1496
+ def switchport_trunk_native_vlan
1497
+ return nil if switchport_mode == :disabled
1498
+ config_get('interface', 'switchport_trunk_native_vlan', @get_args)
1499
+ end
1500
+
1501
+ def switchport_trunk_native_vlan=(val)
1502
+ if val.nil?
1503
+ config_set('interface', 'switchport_trunk_native_vlan',
1504
+ name: @name, state: 'no', vlan: '')
1505
+ else
1506
+ config_set('interface', 'switchport_trunk_native_vlan',
1507
+ name: @name, state: '', vlan: val)
1508
+ end
1509
+ end
1510
+
1511
+ # --------------------------
1512
+ def cli_error_check(result)
1513
+ # Check for messages that can be safely ignored.
1514
+ # The NXOS interface private-vlan cli does not raise an exception
1515
+ # in some conditions and instead just displays a STDOUT error message
1516
+ # thus NXAPI does not detect the failure.
1517
+ # We must catch it by inspecting the "body" hash entry returned by NXAPI.
1518
+ # This vlan cli behavior is unlikely to change.
1519
+
1520
+ errors = /(ERROR:|VLAN:|Eth)/
1521
+ return unless
1522
+ result[1].is_a?(Hash) && errors.match(result[1]['body'].to_s)
1523
+ # Split errors into a list, but keep the delimiter as part of the message.
1524
+ error_list =
1525
+ (result[1]['body'].split(errors) - ['']).each_slice(2).map(&:join)
1526
+ error_list.each do |_msg|
1527
+ fail result[1]['body']
1528
+ end
1529
+ end
1530
+
1531
+ # --------------------------
1532
+ # <state> switchport mode private-vlan host
1533
+ def switchport_pvlan_host
1534
+ return nil if switchport_mode == :disabled
1535
+ config_get('interface', 'switchport_pvlan_host', @get_args)
1536
+ end
1537
+
1538
+ def switchport_pvlan_host=(state)
1539
+ pvlan_enable
1540
+ config_set('interface', 'switchport_pvlan_host',
1541
+ name: @name, state: state ? '' : 'no')
1542
+ end
1543
+
1544
+ def default_switchport_pvlan_host
1545
+ config_get_default('interface', 'switchport_pvlan_host')
1546
+ end
1547
+
1548
+ # --------------------------
1549
+ # <state> switchport mode private-vlan promiscuous
1550
+ def switchport_pvlan_promiscuous
1551
+ return nil if switchport_mode == :disabled
1552
+ config_get('interface', 'switchport_pvlan_promiscuous', @get_args)
1553
+ end
1554
+
1555
+ def switchport_pvlan_promiscuous=(state)
1556
+ pvlan_enable
1557
+ config_set('interface', 'switchport_pvlan_promiscuous',
1558
+ name: @name, state: state ? '' : 'no')
1559
+ end
1560
+
1561
+ def default_switchport_pvlan_promiscuous
1562
+ config_get_default('interface', 'switchport_pvlan_promiscuous')
1563
+ end
1564
+
1565
+ # --------------------------
1566
+ # <state> switchport private-vlan host-association <pri> <sec>
1567
+ # Note this is NOT a multiple, unlike trunk association.
1568
+ def switchport_pvlan_host_association
1569
+ config_get('interface', 'switchport_pvlan_host_association', @get_args)
1570
+ end
1571
+
1572
+ # Input: An array of primary and secondary vlans: ['44', '244']
1573
+ def switchport_pvlan_host_association=(pri_and_sec)
1574
+ pvlan_enable
1575
+
1576
+ state = pri_and_sec.empty? ? 'no' : ''
1577
+ pri, sec = pri_and_sec
1578
+ cli_error_check(
1579
+ config_set('interface', 'switchport_pvlan_host_association',
1580
+ name: @name, state: state, pri: pri, sec: sec))
1581
+ end
1582
+
1583
+ def default_switchport_pvlan_host_association
1584
+ config_get_default('interface', 'switchport_pvlan_host_association')
1585
+ end
1586
+
1587
+ # --------------------------
1588
+ # <state> switchport private-vlan mapping <primary> <vlan>
1589
+ def switchport_pvlan_mapping
1590
+ config_get('interface', 'switchport_pvlan_mapping', @get_args)
1591
+ end
1592
+
1593
+ # Input: An array of primary vlan and range of vlans: ['44', '3-4,6']
1594
+ def switchport_pvlan_mapping=(primary_and_range)
1595
+ switchport_pvlan_mapping_delta(primary_and_range)
1596
+ end
1597
+
1598
+ def default_switchport_pvlan_mapping
1599
+ config_get_default('interface', 'switchport_pvlan_mapping')
1600
+ end
1601
+
1602
+ # --------------------------
1603
+ # Find the is/should delta and add/remove commands as needed.
1604
+ #
1605
+ # Inputs:
1606
+ # primary_and_range: An array of primary vlan and range of vlans
1607
+ def switchport_pvlan_mapping_delta(primary_and_range)
1608
+ # Enable switchport mode and feature private-vlan
1609
+ pvlan_enable
1610
+ primary, should_range = primary_and_range
1611
+
1612
+ # primary changes require removing the entire command first
1613
+ is_range = switchport_pvlan_mapping_remove?(primary)
1614
+
1615
+ # convert ranges to individual elements
1616
+ is = Utils.dash_range_to_elements(is_range)
1617
+ should = Utils.dash_range_to_elements(should_range)
1618
+
1619
+ # create the delta hash and apply the changes
1620
+ delta_hash = Utils.delta_add_remove(should, is)
1621
+ Cisco::Logger.debug('switchport_pvlan_mapping_delta: '\
1622
+ "#{primary}: #{delta_hash}")
1623
+ [:add, :remove].each do |action|
1624
+ delta_hash[action].each do |vlan|
1625
+ state = (action == :add) ? '' : 'no'
1626
+ cli_error_check(
1627
+ config_set('interface', 'switchport_pvlan_mapping',
1628
+ name: @name, state: state, primary: primary, vlan: vlan))
1629
+ end
1630
+ end
1631
+ end
1632
+
1633
+ # --------------------------
1634
+ # switchport_pvlan_mapping_remove?
1635
+ # This is a helper to check if command needs to be removed entirely.
1636
+ #
1637
+ # should_primary: the new primary vlan value
1638
+ # Returns: the current vlan range
1639
+ def switchport_pvlan_mapping_remove?(should_primary)
1640
+ is_primary, is_range = switchport_pvlan_mapping
1641
+
1642
+ if (is_primary != should_primary) && !is_primary.nil?
1643
+ cli_error_check(
1644
+ config_set('interface', 'switchport_pvlan_mapping',
1645
+ name: @name, state: 'no', primary: '', vlan: ''))
1646
+ is_range = []
1647
+ end
1648
+ is_range
1649
+ end
1650
+
1651
+ # --------------------------
1652
+ # <state> switchport private-vlan mapping trunk <primary> <vlan>
1653
+ def switchport_pvlan_mapping_trunk
1654
+ config_get('interface', 'switchport_pvlan_mapping_trunk', @get_args)
1655
+ end
1656
+
1657
+ # Input: A nested array of primary vlan and range of vlans:
1658
+ # [['44', '3-4,6'], ['99', '199']]
1659
+ def switchport_pvlan_mapping_trunk=(should)
1660
+ switchport_pvlan_mapping_trunk_delta(should)
1661
+ end
1662
+
1663
+ def default_switchport_pvlan_mapping_trunk
1664
+ config_get_default('interface', 'switchport_pvlan_mapping_trunk')
1665
+ end
1666
+
1667
+ # --------------------------
1668
+ # switchport_pvlan_mapping_trunk_delta(should)
1669
+ #
1670
+ # Find the is/should delta and add/remove commands as needed.
1671
+ # The 'should' value is a nested array of primary vlan and secondary
1672
+ # ranges; e.g.:
1673
+ # [['44', '144-145'], ['99', '199-201']
1674
+ #
1675
+ def switchport_pvlan_mapping_trunk_delta(should)
1676
+ # Enable switchport mode and feature private-vlan
1677
+ pvlan_enable
1678
+
1679
+ # Handle single-level arrays if found: [pri, range] -> [[pri,range]]
1680
+ should = [should] if !should.empty? && (Utils.depth(should) == 1)
1681
+
1682
+ is = switchport_pvlan_mapping_trunk
1683
+ delta_hash = Utils.delta_add_remove(should, is, :updates_not_allowed)
1684
+ Cisco::Logger.debug("switchport_pvlan_mapping_trunk_delta: #{delta_hash}")
1685
+ [:remove, :add].each do |action|
1686
+ delta_hash[action].each do |pri_and_range|
1687
+ pri, range = pri_and_range
1688
+ if action == :add
1689
+ state = ''
1690
+ else
1691
+ state = 'no'
1692
+ range = ''
1693
+ end
1694
+ cli_error_check(
1695
+ config_set('interface', 'switchport_pvlan_mapping_trunk',
1696
+ name: @name, state: state, primary: pri, range: range))
1697
+ end
1698
+ end
1699
+ end
1700
+
1701
+ # --------------------------
1702
+ # <state> switchport private-vlan association trunk <pri> <sec>
1703
+ # Supports multiple.
1704
+ def switchport_pvlan_trunk_association
1705
+ config_get('interface', 'switchport_pvlan_trunk_association', @get_args)
1706
+ end
1707
+
1708
+ # Input: A nested array of primary and secondary vlans:
1709
+ # [['44', '244'], ['99', '299']]
1710
+ def switchport_pvlan_trunk_association=(should)
1711
+ pvlan_enable
1712
+
1713
+ # Handle single-level arrays if found: [pri, sec] -> [[pri,sec]]
1714
+ should = [should] if !should.empty? && (Utils.depth(should) == 1)
1715
+
1716
+ is = switchport_pvlan_trunk_association
1717
+ pvlan_trunk_association_delta(is, should)
1718
+ end
1719
+
1720
+ def pvlan_trunk_association_delta(is, should)
1721
+ delta_hash = Utils.delta_add_remove(should, is)
1722
+ Cisco::Logger.debug("pvlan_trunk_association_delta: #{delta_hash}")
1723
+ [:remove, :add].each do |action|
1724
+ delta_hash[action].each do |pri_and_sec|
1725
+ state = (action == :add) ? '' : 'no'
1726
+ pri, sec = pri_and_sec
1727
+
1728
+ # Cli does not like removals that specify the secondary
1729
+ sec = '' if action[/remove/]
1730
+ cli_error_check(
1731
+ config_set('interface', 'switchport_pvlan_trunk_association',
1732
+ name: @name, state: state, pri: pri, sec: sec))
1733
+ end
1734
+ end
1735
+ end
1736
+
1737
+ def default_switchport_pvlan_trunk_association
1738
+ config_get_default('interface', 'switchport_pvlan_trunk_association')
1739
+ end
1740
+
1741
+ # --------------------------
1742
+ # <state> switchport mode private-vlan trunk promiscuous
1743
+ def switchport_pvlan_trunk_promiscuous
1744
+ return nil if switchport_mode == :disabled
1745
+ config_get('interface', 'switchport_pvlan_trunk_promiscuous', @get_args)
1746
+ end
1747
+
1748
+ def switchport_pvlan_trunk_promiscuous=(state)
1749
+ pvlan_enable
1750
+ config_set('interface', 'switchport_pvlan_trunk_promiscuous',
1751
+ name: @name, state: state ? '' : 'no')
1752
+ end
1753
+
1754
+ def default_switchport_pvlan_trunk_promiscuous
1755
+ config_get_default('interface', 'switchport_pvlan_trunk_promiscuous')
1756
+ end
1757
+
1758
+ # --------------------------
1759
+ # <state> switchport mode private-vlan trunk secondary
1760
+ def switchport_pvlan_trunk_secondary
1761
+ return nil if switchport_mode == :disabled
1762
+ config_get('interface', 'switchport_pvlan_trunk_secondary', @get_args)
1763
+ end
1764
+
1765
+ def switchport_pvlan_trunk_secondary=(state)
1766
+ pvlan_enable
1767
+ config_set('interface', 'switchport_pvlan_trunk_secondary',
1768
+ name: @name, state: state ? '' : 'no')
1769
+ end
1770
+
1771
+ def default_switchport_pvlan_trunk_secondary
1772
+ config_get_default('interface', 'switchport_pvlan_trunk_secondary')
1773
+ end
1774
+
1775
+ # --------------------------
1776
+ # <state> switchport private-vlan trunk allowed vlan <range>
1777
+ # Note that range is handled as a string because the entire range is
1778
+ # replaced instead of individually adding or removing vlans from the range.
1779
+ def switchport_pvlan_trunk_allowed_vlan
1780
+ return nil if switchport_mode == :disabled
1781
+ vlans = config_get('interface', 'switchport_pvlan_trunk_allowed_vlan',
1782
+ @get_args)
1783
+ vlans = vlans.join(',') if vlans.is_a?(Array)
1784
+ vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
1785
+ vlans
1786
+ end
1787
+
1788
+ def switchport_pvlan_trunk_allowed_vlan=(range)
1789
+ pvlan_enable
1790
+
1791
+ range = Utils.normalize_range_array(range, :string) unless
1792
+ range == default_switchport_pvlan_trunk_allowed_vlan
1793
+
1794
+ config_set('interface', 'switchport_pvlan_trunk_allowed_vlan',
1795
+ name: @name, range: range)
1796
+ end
1797
+
1798
+ def default_switchport_pvlan_trunk_allowed_vlan
1799
+ config_get_default('interface', 'switchport_pvlan_trunk_allowed_vlan')
1800
+ end
1801
+
1802
+ # --------------------------
1803
+ # <state> switchport trunk native vlan <vlan>
1804
+ def switchport_pvlan_trunk_native_vlan
1805
+ return nil if switchport_mode == :disabled
1806
+ config_get('interface', 'switchport_pvlan_trunk_native_vlan', @get_args)
1807
+ end
1808
+
1809
+ def switchport_pvlan_trunk_native_vlan=(vlan)
1810
+ pvlan_enable
1811
+ config_set('interface', 'switchport_pvlan_trunk_native_vlan',
1812
+ name: @name, vlan: vlan)
1813
+ end
1814
+
1815
+ def default_switchport_pvlan_trunk_native_vlan
1816
+ config_get_default('interface', 'switchport_pvlan_trunk_native_vlan')
1817
+ end
1818
+
1819
+ # --------------------------
1820
+ # This is an SVI property.
1821
+ # <state> private-vlan mapping <range> # ex. range = ['2-4,9']
1822
+ # Always returns an array.
1823
+ def pvlan_mapping
1824
+ range = config_get('interface', 'pvlan_mapping', @get_args)
1825
+ return default_pvlan_mapping if range.nil?
1826
+ range.empty? ? range : [range.delete(' ')]
1827
+ end
1828
+
1829
+ def pvlan_mapping=(range)
1830
+ feature_vlan_set
1831
+ Feature.private_vlan_enable
1832
+
1833
+ is = Utils.dash_range_to_elements(pvlan_mapping)
1834
+ should = Utils.dash_range_to_elements(range)
1835
+
1836
+ pvlan_mapping_delta(is, should)
1837
+ end
1838
+
1839
+ def pvlan_mapping_delta(is, should)
1840
+ delta_hash = Utils.delta_add_remove(should, is)
1841
+ Cisco::Logger.debug("pvlan_mapping_delta: #{delta_hash}")
1842
+ [:remove, :add].each do |action|
1843
+ delta_hash[action].each do |vlan|
1844
+ state = (action == :add) ? '' : 'no'
1845
+ cli_error_check(
1846
+ config_set('interface', 'pvlan_mapping',
1847
+ name: @name, state: state, vlan: vlan))
1848
+ end
1849
+ end
1850
+ end
1851
+
1852
+ def default_pvlan_mapping
1853
+ config_get_default('interface', 'pvlan_mapping')
1854
+ end
1855
+
1856
+ # --------------------------
1857
+ # vlan_mapping & vlan_mapping_enable
1858
+ # Hardware & Cli Dependencies:
1859
+ # - F3 linecards only
1860
+ # - vdc
1861
+ # - limit-resource
1862
+ # - bridge-domain
1863
+ # - feature vni
1864
+ # - switchport mode
1865
+
1866
+ # Getter: Builds an array of vlan_mapping commands currently
1867
+ # on the device.
1868
+ # cli: switchport vlan mapping 2 200
1869
+ # switchport vlan mapping 4 400
1870
+ # array: [['2', '200'], ['4', '400']]
1871
+ #
1872
+ def default_vlan_mapping
1873
+ config_get_default('interface', 'vlan_mapping')
1874
+ end
1875
+
1876
+ def vlan_mapping
1877
+ match = config_get('interface', 'vlan_mapping', @get_args)
1878
+ match.each(&:compact!) unless match.nil?
1879
+ match
1880
+ end
1881
+
1882
+ def vlan_mapping=(should_list)
1883
+ Feature.vni_enable
1884
+
1885
+ # Process a hash of vlan_mapping cmds from delta_add_remove().
1886
+ # The vlan_mapping cli does not allow commands to be updated, they must
1887
+ # first be removed if there is a change.
1888
+ delta_hash = Utils.delta_add_remove(should_list, vlan_mapping,
1889
+ :updates_not_allowed)
1890
+ return if delta_hash.values.flatten.empty?
1891
+ # Process :remove first to ensure "update" commands will not fail.
1892
+ [:remove, :add].each do |action|
1893
+ Cisco::Logger.debug("vlan_mapping delta #{@get_args}\n"\
1894
+ "#{action}: #{delta_hash[action]}")
1895
+ delta_hash[action].each do |original, translated|
1896
+ state = (action == :add) ? '' : 'no'
1897
+ config_set('interface', 'vlan_mapping', name: @name,
1898
+ state: state, original: original, translated: translated)
1899
+ end
1900
+ end
1901
+ end
1902
+
1903
+ # cli: switchport vlan mapping enable
1904
+ def default_vlan_mapping_enable
1905
+ config_get_default('interface', 'vlan_mapping_enable')
1906
+ end
1907
+
1908
+ def vlan_mapping_enable
1909
+ config_get('interface', 'vlan_mapping_enable', @get_args)
1910
+ end
1911
+
1912
+ def vlan_mapping_enable=(state)
1913
+ config_set('interface', 'vlan_mapping_enable',
1914
+ name: @name, state: state ? '' : 'no')
1915
+ end
1916
+
1917
+ def default_switchport_trunk_native_vlan
1918
+ config_get_default('interface', 'switchport_trunk_native_vlan')
1919
+ end
1920
+
1921
+ def system_default_switchport
1922
+ # This command is a user-configurable system default.
1923
+ #
1924
+ # Note: This is a simple boolean state but there is a bug on some
1925
+ # platforms that causes the cli to nvgen twice; this causes config_get to
1926
+ # raise an error when it encounters the multiple. Therefore we define it
1927
+ # as a multiple to avoid the raise and handle the array if necessary.
1928
+ #
1929
+ val = config_get('interface', 'system_default_switchport')
1930
+ return (val[0][/^no /] ? false : true) if val.is_a?(Array)
1931
+ val
1932
+ end
1933
+
1934
+ def system_default_switchport_shutdown
1935
+ # This command is a user-configurable system default.
1936
+ config_get('interface', 'system_default_switchport_shutdown')
1937
+ end
1938
+
1939
+ def system_default_svi_autostate
1940
+ # This command is a user-configurable system default.
1941
+ #
1942
+ # This property behaves differently on an n7k vs ni(3|9)k and therefore
1943
+ # needs special handling.
1944
+ # N7K: When enabled, does not nvgen.
1945
+ # When disabled, does nvgen, but differently then n(3|9)k.
1946
+ # Return true for the disabled case, false otherwise.
1947
+ # N(3|9)K: When enabled, does nvgen.
1948
+ # When disabled, does nvgen.
1949
+ # Return true for the enabled case, false otherwise.
1950
+ result = config_get('interface', 'system_default_svi_autostate')
1951
+ /N7K/.match(node.product_id) ? !result : result
1952
+ end
1953
+
1954
+ def switchport_vtp_mode_capable?
1955
+ !switchport_mode.to_s.match(/(access|trunk)/).nil?
1956
+ end
1957
+
1958
+ def switchport_vtp
1959
+ return nil unless switchport_vtp_mode_capable?
1960
+ config_get('interface', 'vtp', @get_args)
1961
+ end
1962
+
1963
+ def switchport_vtp=(vtp_set)
1964
+ # TODO: throw UnsupportedError instead of returning false?
1965
+ return false unless switchport_vtp_mode_capable?
1966
+ return false if !vtp_set && !Feature.vtp_enabled?
1967
+ Feature.vtp_enable if vtp_set
1968
+ no_cmd = (vtp_set) ? '' : 'no'
1969
+ config_set('interface', 'vtp', name: @name, state: no_cmd)
1970
+ end
1971
+
1972
+ def svi_cmd_allowed?(cmd)
1973
+ fail "[#{@name}] Invalid interface type for command [#{cmd}]" unless
1974
+ @name[/vlan/i]
1975
+ end
1976
+
1977
+ # svi_autostate is exclusive to svi interfaces
1978
+ def svi_autostate
1979
+ return nil unless @name[/^vlan/i]
1980
+ config_get('interface', 'svi_autostate', @get_args)
1981
+ end
1982
+
1983
+ def svi_autostate=(val)
1984
+ check_switchport(:disabled)
1985
+ svi_cmd_allowed?('autostate')
1986
+ config_set('interface', 'svi_autostate',
1987
+ name: @name, state: val ? '' : 'no')
1988
+ end
1989
+
1990
+ def default_svi_autostate
1991
+ system_default_svi_autostate
1992
+ end
1993
+
1994
+ def feature_vlan?
1995
+ config_get('interface', 'feature_vlan')
1996
+ end
1997
+
1998
+ def feature_vlan_set(val=true)
1999
+ # 'feature interface-vlan'
2000
+ # TBD: Replace this with Feature.interface_vlan_enable
2001
+ return if feature_vlan? == val
2002
+ config_set('interface', 'feature_vlan', state: val ? '' : 'no')
2003
+ end
2004
+
2005
+ # svi_management is exclusive to svi interfaces
2006
+ def svi_management
2007
+ return nil unless @name[/^vlan/i]
2008
+ config_get('interface', 'svi_management', @get_args)
2009
+ end
2010
+
2011
+ def svi_management=(val)
2012
+ check_switchport(:disabled)
2013
+ svi_cmd_allowed?('management')
2014
+ config_set('interface', 'svi_management',
2015
+ name: @name, state: val ? '' : 'no')
2016
+ end
2017
+
2018
+ def default_svi_management
2019
+ config_get_default('interface', 'svi_management')
2020
+ end
2021
+
2022
+ def default_switchport_vtp
2023
+ return nil unless switchport_vtp_mode_capable?
2024
+ config_get_default('interface', 'vtp')
2025
+ end
2026
+
2027
+ def switchport_vtp_feature?
2028
+ config_get('vtp', 'feature')
2029
+ end
2030
+
2031
+ def switchport_status?(status)
2032
+ case status
2033
+ when :disabled
2034
+ return true if switchport_mode == status || switchport_mode.nil?
2035
+ when :access, :trunk
2036
+ return switchport_mode == status
2037
+ when Array
2038
+ return status.include?(switchport_mode)
2039
+ else
2040
+ return false
2041
+ end
2042
+ end
2043
+
2044
+ def check_switchport(status)
2045
+ return if switchport_status?(status)
2046
+ fail("#{caller[0][/`.*'/][1..-2]} cannot be set unless " \
2047
+ "switchport mode is #{status}")
2048
+ end
2049
+
2050
+ def vpc_id
2051
+ config_get('interface', 'vpc_id', @get_args)
2052
+ end
2053
+
2054
+ def vpc_id=(num)
2055
+ if num
2056
+ config_set('interface', 'vpc_id', name: @name, state: '', id: num)
2057
+ else
2058
+ # 'no vpc' doesn't work for phy ports, so do a get
2059
+ num = vpc_id
2060
+ config_set('interface', 'vpc_id', name: @name, state: 'no', id: num)
2061
+ end
2062
+ end
2063
+
2064
+ def default_vpc_id
2065
+ config_get_default('interface', 'vpc_id')
2066
+ end
2067
+
2068
+ def vpc_peer_link
2069
+ return nil unless @name[/port-channel/i] && switchport_mode != :disabled
2070
+ config_get('interface', 'vpc_peer_link', @get_args)
2071
+ end
2072
+
2073
+ def vpc_peer_link=(state)
2074
+ return if vpc_peer_link == state
2075
+ no_cmd = (state ? '' : 'no')
2076
+ config_set('interface', 'vpc_peer_link', name: @name, state: no_cmd)
2077
+ end
2078
+
2079
+ def default_vpc_peer_link
2080
+ config_get_default('interface', 'vpc_peer_link')
2081
+ end
2082
+
2083
+ def vrf
2084
+ config_get('interface', 'vrf', @get_args)
2085
+ end
2086
+
2087
+ def vrf=(v)
2088
+ fail TypeError unless v.is_a?(String)
2089
+ return if v == vrf
2090
+ # Changing the VRF can result in loss of IP address, so cache it
2091
+ addr_1 = ipv4_address
2092
+ mask_1 = ipv4_netmask_length
2093
+ addr_2 = ipv4_address_secondary
2094
+ mask_2 = ipv4_netmask_length_secondary
2095
+ # XR actually blocks you from changing the VRF if IP addr is present
2096
+ unless platform == :nexus
2097
+ ipv4_addr_mask_set(nil, nil, false) unless addr_1.nil?
2098
+ ipv4_addr_mask_set(nil, nil, true) unless addr_2.nil?
2099
+ end
2100
+ if v.empty?
2101
+ config_set('interface', 'vrf', name: @name, state: 'no', vrf: '')
2102
+ else
2103
+ config_set('interface', 'vrf', name: @name, state: '', vrf: v)
2104
+ end
2105
+ ipv4_addr_mask_set(addr_1, mask_1, false) unless addr_1.nil?
2106
+ ipv4_addr_mask_set(addr_2, mask_2, true) unless addr_2.nil?
2107
+ end
2108
+
2109
+ def default_vrf
2110
+ config_get_default('interface', 'vrf')
2111
+ end
2112
+
2113
+ def set_range_based_params(list, param_name)
2114
+ list.each do |range, property_value|
2115
+ # if a particular range is set to default, use 'no' cmd
2116
+ if property_value == 'default'
2117
+ config_set('interface', param_name,
2118
+ name: @name, state: 'no',
2119
+ range: range, val: '')
2120
+ else
2121
+ config_set('interface', param_name,
2122
+ name: @name, state: '',
2123
+ range: range, val: property_value)
2124
+ end
2125
+ end
2126
+ end
2127
+ end # Class
2128
+ end # Module