cisco_node_utils_mgx 2.1.0.1

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 (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,33 @@
1
+ # Copyright (c) 2015 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative 'client'
16
+
17
+ # Fail gracefully if submodule dependencies are not met
18
+ begin
19
+ Cisco::Client.silence_warnings do
20
+ require 'grpc'
21
+ end
22
+ rescue LoadError => e
23
+ raise unless e.message =~ /-- grpc/
24
+ # If grpc is not installed, raise an error that client understands.
25
+ raise LoadError, "Unable to load client/grpc -- #{e}"
26
+ end
27
+
28
+ # Namespace for Cisco EMS gRPC-specific code
29
+ class Cisco::Client::GRPC < Cisco::Client
30
+ end
31
+
32
+ # Auto-load all Ruby files in the subdirectory
33
+ Dir.glob(__dir__ + '/grpc/*.rb') { |file| require file }
@@ -0,0 +1,368 @@
1
+ # NXAPI client library.
2
+ #
3
+ # November 2014, Glenn F. Matthews
4
+ #
5
+ # Copyright (c) 2014-2019 Cisco and/or its affiliates.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative '../client'
20
+ require 'json'
21
+ require 'net/http'
22
+
23
+ include Cisco::Logger
24
+
25
+ # Class representing an HTTP client connecting to a NXAPI server.
26
+ class Cisco::Client::NXAPI < Cisco::Client
27
+ # Location of unix domain socket for NXAPI localhost
28
+ NXAPI_UDS = '/tmp/nginx_local/nginx_1_be_nxapi.sock'
29
+ # NXAPI listens for remote connections to "http://<switch IP>/ins"
30
+ # NXAPI listens for local connections to "http://<UDS>/ins_local"
31
+ NXAPI_REMOTE_URI_PATH = '/ins'
32
+ NXAPI_UDS_URI_PATH = '/ins_local'
33
+ # Latest supported version is 1.0
34
+ NXAPI_VERSION = '1.0'
35
+
36
+ register_client(self)
37
+
38
+ # Constructor for Client. By default this connects to the local
39
+ # unix domain socket. If you need to connect to a remote device,
40
+ # you must provide the host/username/password parameters.
41
+ def initialize(**kwargs)
42
+ # rubocop:disable Style/HashSyntax
43
+ super(data_formats: [:nxapi_structured, :cli],
44
+ platform: :nexus,
45
+ **kwargs)
46
+ # rubocop:enable Style/HashSyntax
47
+ # Default: connect to unix domain socket on localhost, if available
48
+ if @host.nil?
49
+ unless File.socket?(NXAPI_UDS)
50
+ fail Cisco::ConnectionRefused, \
51
+ "No host specified but no UDS found at #{NXAPI_UDS} either"
52
+ end
53
+ # net_http_unix provides NetX::HTTPUnix, a small subclass of Net::HTTP
54
+ # which supports connection to local unix domain sockets. We need this
55
+ # in order to run natively under NX-OS but it's not needed for off-box
56
+ # unit testing where the base Net::HTTP will meet our needs.
57
+ require 'net_http_unix'
58
+ @http = NetX::HTTPUnix.new('unix://' + NXAPI_UDS)
59
+ @cookie = kwargs[:cookie]
60
+ else
61
+ # Remote connection. This is primarily expected
62
+ # when running e.g. from a Unix server as part of Minitest.
63
+ @transport = kwargs[:transport] || 'http'
64
+ @verify_mode = kwargs[:verify_mode] || 'none'
65
+ @port.nil? ? @port = '' : @port = ":#{@port}"
66
+ uri = URI.parse("#{@transport}://#{@host}#{@port}")
67
+ @http = Net::HTTP.new(uri.host, uri.port)
68
+ end
69
+ # The default read time out is 60 seconds, which may be too short for
70
+ # scaled configuration to apply. Change it to 300 seconds, which is
71
+ # also used as the default config by firefox.
72
+ @http.read_timeout = 300
73
+ @address = @http.address
74
+ end
75
+
76
+ def self.validate_args(**kwargs)
77
+ super
78
+ if kwargs[:host].nil?
79
+ # Connection to UDS - no username or password either
80
+ fail ArgumentError unless kwargs[:username].nil? && kwargs[:password].nil?
81
+ validate_cookie(**kwargs)
82
+ else
83
+ # Connection to remote system - username and password are required
84
+ fail TypeError, 'username is required' if kwargs[:username].nil?
85
+ fail TypeError, 'password is required' if kwargs[:password].nil?
86
+ end
87
+ end
88
+
89
+ def self.validate_cookie(**kwargs)
90
+ return if kwargs[:cookie].nil?
91
+ format = 'Cookie format must match: <username>:local'
92
+ msg = "Invalid cookie: [#{kwargs[:cookie]}]. : #{format}"
93
+
94
+ fail TypeError, msg unless kwargs[:cookie].is_a?(String)
95
+ fail TypeError, msg unless /\S+:local/.match(kwargs[:cookie])
96
+ fail ArgumentError, 'empty cookie' if kwargs[:cookie].empty?
97
+ end
98
+
99
+ # Clear the cache of CLI output results.
100
+ #
101
+ # If cache_auto is true (default) then this will be performed automatically
102
+ # whenever a set() is called, but providers may also call this
103
+ # to explicitly force the cache to be cleared.
104
+ def cache_flush
105
+ @cache_hash = {
106
+ 'cli_conf' => {},
107
+ 'cli_show' => {},
108
+ 'cli_show_ascii' => {},
109
+ }
110
+ end
111
+
112
+ # Configure the given CLI command(s) on the device.
113
+ #
114
+ # @raise [RequestNotSupported] if this client doesn't support CLI config
115
+ #
116
+ # @param data_format one of Cisco::DATA_FORMATS. Default is :cli
117
+ # @param context [String, Array<String>] Zero or more configuration commands
118
+ # used to enter the desired CLI sub-mode
119
+ # @param values [String, Array<String>] One or more commands
120
+ # to enter within the CLI sub-mode.
121
+ # @param kwargs data-format-specific args
122
+ def set(data_format: :cli,
123
+ context: nil,
124
+ values: nil,
125
+ **_kwargs)
126
+ # we don't currently support nxapi_structured for configuration
127
+ fail Cisco::RequestNotSupported if data_format == :nxapi_structured
128
+ context = munge_to_array(context)
129
+ values = munge_to_array(values)
130
+ super
131
+ req('cli_conf', context + values)
132
+ end
133
+
134
+ # Get the given state from the device.
135
+ #
136
+ # Unlike set() this will not clear the CLI cache;
137
+ # multiple calls with the same parameters may return cached data
138
+ # rather than querying the device repeatedly.
139
+ #
140
+ # @raise [Cisco::RequestNotSupported] if
141
+ # structured output is requested but the given command can't provide it.
142
+ # @raise [Cisco::CliError] if the command is rejected by the device
143
+ #
144
+ # @param data_format one of Cisco::DATA_FORMATS. Default is :cli
145
+ # @param command [String] the show command to execute
146
+ # @param context [String, Array<String>] Context to refine the results
147
+ # @param value [String] Specific key to look up
148
+ # @param kwargs data-format-specific args
149
+ # @return [String, Hash]
150
+ def get(data_format: :cli,
151
+ command: nil,
152
+ context: nil,
153
+ value: nil,
154
+ **_kwargs)
155
+ context = munge_to_array(context)
156
+ super
157
+ if data_format == :cli
158
+ output = req('cli_show_ascii', command)
159
+ return self.class.filter_cli(cli_output: output,
160
+ context: context,
161
+ value: value)
162
+ elsif data_format == :nxapi_structured
163
+ output = req('cli_show', command)
164
+ return self.class.filter_data(data: output,
165
+ keys: context + munge_to_array(value))
166
+ else
167
+ fail TypeError
168
+ end
169
+ end
170
+
171
+ # Helper method to increase the default @http.read_timeout value from
172
+ # the default value of 300 to accomodate commands that are known to
173
+ # require more time to complete.
174
+ def read_timeout_check(request)
175
+ return unless request.body[/install all|install force-all/]
176
+ debug("Increasing http read_timeout to 1000 for 'install all' command")
177
+ @http.read_timeout = 1000
178
+ end
179
+
180
+ # Sends a request to the NX API and returns the body of the request or
181
+ # handles errors that happen.
182
+ # @raise Cisco::ConnectionRefused if NXAPI is disabled
183
+ # @raise Cisco::AuthenticationFailed if username/password are invalid
184
+ # @raise Cisco::ClientError (should never occur)
185
+ # @raise Cisco::RequestNotSupported
186
+ # @raise Cisco::RequestFailed if any command is rejected as invalid
187
+ #
188
+ # @param type ["cli_show", "cli_show_ascii"] Specifies the type of command
189
+ # to be executed.
190
+ # @param command_or_list [String, Array<String>] The command or array of
191
+ # commands which should be run.
192
+ # @return [Hash, Array<Hash>] output when type == "cli_show"
193
+ # @return [String, Array<String>] output when type == "cli_show_ascii"
194
+ def req(type, command_or_list)
195
+ if command_or_list.is_a?(Array)
196
+ # NXAPI wants config lines to be separated by ' ; '
197
+ command = command_or_list.join(' ; ')
198
+ else
199
+ command = command_or_list
200
+ command_or_list = [command]
201
+ end
202
+
203
+ debug("Input (#{type}): \'#{command}\'")
204
+ if cache_enable? && @cache_hash[type] && @cache_hash[type][command]
205
+ return @cache_hash[type][command]
206
+ end
207
+
208
+ # form the request
209
+ request = build_http_request(type, command)
210
+
211
+ # send the request and get the response
212
+ debug("Sending #{@transport} request to NX-API at #{@http.address}:\n" \
213
+ "#{request.to_hash}\n#{request.body}")
214
+ read_timeout_check(request)
215
+ tries = 2
216
+ begin
217
+ if @transport == 'https'
218
+ debug('Setting use_ssl to true')
219
+ @http.use_ssl = true
220
+ @http.verify_mode = handle_verify_mode(@verify_mode)
221
+ else
222
+ @http.use_ssl = false
223
+ end
224
+ response = @http.request(request)
225
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
226
+ emsg = 'Connection refused or reset. Is the NX-API feature enabled?'
227
+ raise Cisco::ConnectionRefused, emsg
228
+ rescue EOFError
229
+ tries -= 1
230
+ retry if tries > 0
231
+ raise
232
+ end
233
+ handle_http_response(response)
234
+ output = parse_response(response)
235
+
236
+ prev_cmds = []
237
+ if output.is_a?(Array)
238
+ output.zip(command_or_list) do |o, cmd|
239
+ handle_output(prev_cmds, cmd, o)
240
+ prev_cmds << cmd
241
+ end
242
+ output = output.each { |o| o['body'] }
243
+ else
244
+ handle_output(prev_cmds, command, output)
245
+ output = output['body']
246
+ end
247
+
248
+ output = '' if type == 'cli_show_ascii' && output.empty?
249
+
250
+ @cache_hash[type][command] = output if cache_enable?
251
+ output
252
+ end
253
+ private :req
254
+
255
+ def build_http_request(type, command_string)
256
+ if @username.nil? || @password.nil?
257
+ cookie = @cookie.nil? ? 'admin:local' : @cookie
258
+ request = Net::HTTP::Post.new(NXAPI_UDS_URI_PATH)
259
+ request['Cookie'] = "nxapi_auth=#{cookie}"
260
+ else
261
+ request = Net::HTTP::Post.new(NXAPI_REMOTE_URI_PATH)
262
+ request.basic_auth("#{@username}", "#{@password}")
263
+ end
264
+ request.content_type = 'application/json'
265
+ request.body = {
266
+ 'ins_api' => {
267
+ 'version' => NXAPI_VERSION,
268
+ 'type' => "#{type}",
269
+ 'chunk' => '0',
270
+ 'sid' => '1',
271
+ 'input' => "#{command_string}",
272
+ 'output_format' => 'json',
273
+ }
274
+ }.to_json
275
+ request
276
+ end
277
+ private :build_http_request
278
+
279
+ # Returns the OpenSSL verify mode based on the verify_mode arguments
280
+ #
281
+ # @raise if verify_mode param is not `peer`, `client-once`, `fail-no-peer`
282
+ # or `none`
283
+ #
284
+ # @param String verify mode to use
285
+ #
286
+ # @return OpenSSL::SSL verification mode
287
+ def handle_verify_mode(verify_mode)
288
+ case verify_mode
289
+ when 'peer'
290
+ OpenSSL::SSL::VERIFY_PEER
291
+ when 'client-once'
292
+ OpenSSL::SSL::VERIFY_CLIENT_ONCE
293
+ when 'fail-no-peer'
294
+ OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
295
+ when 'none'
296
+ OpenSSL::SSL::VERIFY_NONE
297
+ else
298
+ fail "#{verify_mode} is not a valid mode, " \
299
+ 'valid modes are: "none", "peer", ' \
300
+ '"client-once", "fail-no-peer"'
301
+ end
302
+ end
303
+ private :handle_verify_mode
304
+
305
+ def handle_http_response(response)
306
+ debug("HTTP Response: #{response.message}\n#{response.body}")
307
+ case response
308
+ when Net::HTTPUnauthorized
309
+ emsg = 'HTTP 401 Unauthorized. Are your NX-API credentials correct?'
310
+ fail Cisco::AuthenticationFailed, emsg
311
+ when Net::HTTPBadRequest
312
+ emsg = "HTTP 400 Bad Request\n#{response.body}"
313
+ fail Cisco::ClientError, emsg
314
+ end
315
+ end
316
+ private :handle_http_response
317
+
318
+ def parse_response(response)
319
+ body = JSON.parse(response.body)
320
+
321
+ # In case of an error the JSON may not be complete, so we need to
322
+ # proceed carefully, as blindly doing body["ins_api"]["outputs"]["output"]
323
+ # could throw an error otherwise.
324
+ output = body['ins_api']
325
+ fail Cisco::ClientError, "unexpected JSON output:\n#{body}" if output.nil?
326
+ output = output['outputs'] if output['outputs']
327
+ output = output['output'] if output['output']
328
+
329
+ output
330
+ rescue JSON::ParserError
331
+ raise Cisco::ClientError, "response is not JSON:\n#{response.body}"
332
+ end
333
+ private :parse_response
334
+
335
+ def handle_output(prev_cmds, command, output)
336
+ if output['code'] == '400'
337
+ # CLI error.
338
+ # Examples: "Invalid input", "Incomplete command", etc.
339
+ fail Cisco::CliError.new( # rubocop:disable Style/RaiseArgs
340
+ rejected_input: command,
341
+ clierror: output['clierror'],
342
+ msg: output['msg'],
343
+ code: output['code'],
344
+ successful_input: prev_cmds,
345
+ )
346
+ elsif output['code'] == '413'
347
+ # Request too large
348
+ fail Cisco::RequestNotSupported, "Error 413: #{output['msg']}"
349
+ elsif output['code'] == '501'
350
+ # if structured output is not supported for this command,
351
+ # raise an exception so that the calling function can
352
+ # handle accordingly
353
+ fail Cisco::RequestNotSupported, \
354
+ "Structured output not supported for #{command}"
355
+ # Error 432: Requested object does not exist
356
+ # Ignore 432 errors because it means that a property is not configured
357
+ elsif output['code'] =~ /[45]\d\d/ && output['code'] != '432'
358
+ fail Cisco::RequestFailed, \
359
+ "#{output['code']} Error: #{output['msg']}"
360
+ else
361
+ debug("Result for '#{command}': #{output['msg']}")
362
+ if output['body'] && !output['body'].empty?
363
+ debug("Output: #{output['body']}")
364
+ end
365
+ end
366
+ end
367
+ private :handle_output
368
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2015 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative 'client'
16
+
17
+ # Fail gracefully if submodule dependencies are not met
18
+ begin
19
+ require 'net_http_unix'
20
+ rescue LoadError => e
21
+ raise unless e.message =~ /-- net_http_unix/
22
+ # If net_http_unix is not installed, raise an error that client understands.
23
+ raise LoadError, "Unable to load client/nxapi -- #{e}"
24
+ end
25
+
26
+ # Namespace for Cisco NXAPI-specific code
27
+ class Cisco::Client::NXAPI < Cisco::Client
28
+ end
29
+
30
+ # Auto-load all Ruby files in the subdirectory
31
+ Dir.glob(__dir__ + '/nxapi/*.rb') { |file| require file }
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # January 2016, Glenn F. Matthews
4
+ #
5
+ # Copyright (c) 2015-2016 Cisco and/or its affiliates.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative '../constants'
20
+ require_relative '../logger'
21
+
22
+ # Utility methods for clients of various RPC formats
23
+ class Cisco::Client
24
+ # Make a best effort to convert a given input value to an Array.
25
+ # Strings are split by newlines, and nil becomes an empty Array.
26
+ def self.munge_to_array(val)
27
+ val = [] if val.nil?
28
+ val = val.split("\n") if val.is_a?(String)
29
+ val
30
+ end
31
+
32
+ def munge_to_array(val)
33
+ self.class.munge_to_array(val)
34
+ end
35
+
36
+ # Helper function that subclasses may use with get(data_format: :cli)
37
+ # Method for working with hierarchical show command output such as
38
+ # "show running-config". Searches the given multi-line string
39
+ # for all matches to the given value query. If context is provided,
40
+ # the matches will be filtered to only those that are located "under"
41
+ # the given context sequence (as determined by indentation).
42
+ #
43
+ # @param cli_output [String] The body of text to search
44
+ # @param context [*Regex] zero or more regular expressions defining
45
+ # the parent configs to filter by.
46
+ # @param value [Regex] The regular expression to match
47
+ # @return [[String], nil] array of matching (sub)strings, else nil.
48
+ #
49
+ # @example Find all OSPF router names in the running-config
50
+ # ospf_names = filter_cli(cli_output: running_cfg,
51
+ # value: /^router ospf (\d+)/)
52
+ #
53
+ # @example Find all address-family types under the given BGP router
54
+ # bgp_afs = filter_cli(cli_output: show_run_bgp,
55
+ # context: [/^router bgp #{ASN}/],
56
+ # value: /^address-family (.*)/)
57
+ def self.filter_cli(cli_output: nil,
58
+ context: nil,
59
+ value: nil)
60
+ return cli_output if cli_output.nil?
61
+ context ||= []
62
+ context.each { |filter| cli_output = find_subconfig(cli_output, filter) }
63
+ return nil if cli_output.nil? || cli_output.empty?
64
+ return cli_output if value.nil?
65
+ value = to_regexp(value)
66
+ match = cli_output.scan(value)
67
+ return nil if match.empty?
68
+ # find matches and return as array of String if it only does one match.
69
+ # Otherwise return array of array.
70
+ match.flatten! if match[0].is_a?(Array) && match[0].length == 1
71
+ match
72
+ end
73
+
74
+ # Returns the subsection associated with the given
75
+ # line of config
76
+ # @param [String] the body of text to search
77
+ # @param [Regex] the regex key of the config for which
78
+ # to retrieve the subsection
79
+ # @return [String, nil] the subsection of body, de-indented
80
+ # appropriately, or nil if no such subsection exists.
81
+ def self.find_subconfig(body, regexp_query)
82
+ return nil if body.nil? || regexp_query.nil?
83
+ regexp_query = to_regexp(regexp_query)
84
+
85
+ rows = body.split("\n")
86
+ match_row_index = rows.index { |row| regexp_query =~ row }
87
+ return nil if match_row_index.nil?
88
+
89
+ cur = match_row_index + 1
90
+ subconfig = []
91
+
92
+ until (/\A\s+.*/ =~ rows[cur]).nil? || cur == rows.length
93
+ subconfig << rows[cur]
94
+ cur += 1
95
+ end
96
+ return nil if subconfig.empty?
97
+ # Strip an appropriate minimal amount of leading whitespace from
98
+ # all lines in the subconfig
99
+ min_leading = subconfig.map { |line| line[/\A */].size }.min
100
+ subconfig = subconfig.map { |line| line[min_leading..-1] }
101
+ subconfig.join("\n")
102
+ end
103
+
104
+ # Helper method for CLI getters
105
+ #
106
+ # Convert a string or array of strings to a Regexp or array thereof
107
+ def self.to_regexp(input)
108
+ if input.is_a?(Regexp)
109
+ return input
110
+ elsif input.is_a?(Array)
111
+ return input.map { |item| to_regexp(item) }
112
+ else
113
+ # The string might be explicitly formatted as a regexp
114
+ # Dynamically handle modifiers
115
+ input.match(%r{(?<regex>^\/.*\/)(?<options>[imx]*)?}) do |m|
116
+ options = []
117
+ m['options'].each_char do |c|
118
+ case c
119
+ when 'i'
120
+ options << Regexp::IGNORECASE
121
+ when 'm'
122
+ options << Regexp::MULTILINE
123
+ when 'x'
124
+ options << Regexp::EXTENDED
125
+ end
126
+ end
127
+ return Regexp.new(m['regex'][1..-2], options.reduce(:|))
128
+ end
129
+ # otherwise this value is a regular string
130
+ # convert to case insensitive regex
131
+ # 'foo' => %r{^foo$}i
132
+ return Regexp.new("^#{input}$", Regexp::IGNORECASE)
133
+
134
+ end
135
+ end
136
+
137
+ # Helper method for get(data_format: :nxapi_structured).
138
+ #
139
+ # @param data [Array, Hash] structured output from node
140
+ # @param keys [Array] lookup sequence
141
+ def self.filter_data(data: nil,
142
+ keys: nil)
143
+ return nil if data.nil? || data.empty?
144
+ keys ||= []
145
+ keys.each do |filter|
146
+ # if filter is a Hash and data is an array, check each
147
+ # array index (which should return another hash) to see if
148
+ # it contains the matching key/value pairs specified in token,
149
+ # and return the first match (or nil)
150
+ if filter.kind_of?(Hash)
151
+ fail "Expected Array, got #{data.class}" unless data.is_a? Array
152
+ data = data.select { |x| filter.all? { |k, v| x[k] == v } }
153
+ fail "Multiple matches found for #{filter}" if data.length > 1
154
+ fail "No match found for #{filter}" if data.length == 0
155
+ data = data[0]
156
+ else # data is array or hash
157
+ if data.is_a? Array
158
+ final = []
159
+ data.each do |row|
160
+ final << row[filter]
161
+ end
162
+ return final
163
+ end
164
+ fail "No key \"#{filter}\" in #{data}" unless data.key?(filter)
165
+ data = data[filter]
166
+ end
167
+ end
168
+ data
169
+ end
170
+
171
+ # Helper method for calls into third-party code - suppresses Ruby warnings
172
+ # for the given block since we have no control over that code.
173
+ def self.silence_warnings(&block)
174
+ warn_level = $VERBOSE
175
+ $VERBOSE = nil
176
+ result = block.call
177
+ $VERBOSE = warn_level
178
+ result
179
+ end
180
+ end
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2015 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Namespace for Cisco-specific code
16
+ module Cisco
17
+ # Namespace for Cisco Client shim
18
+ class Client
19
+ end
20
+ end
21
+
22
+ require_relative 'client/client'
23
+
24
+ # Try to load known extensions
25
+ extensions = ['client/nxapi',
26
+ 'client/grpc',
27
+ ]
28
+ extensions.each do |ext|
29
+ begin
30
+ require_relative ext
31
+ rescue LoadError => e
32
+ # ignore missing client-(grpc|nxapi), they're not always required
33
+ raise unless e.message =~ /#{Regexp.escape(ext)}/
34
+ end
35
+ end