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
data/tests/test_ace.rb ADDED
@@ -0,0 +1,304 @@
1
+ # Copyright (c) 2015-2018 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 'ciscotest'
16
+ require_relative '../lib/cisco_node_utils/acl'
17
+ require_relative '../lib/cisco_node_utils/ace'
18
+
19
+ # TestAce - Minitest for Ace node utility class
20
+ class TestAce < CiscoTestCase
21
+ @skip_unless_supported = 'acl'
22
+ @@pre_clean_needed = true # rubocop:disable Style/ClassVars
23
+
24
+ def setup
25
+ super
26
+ remove_all_acls if @@pre_clean_needed
27
+ @@pre_clean_needed = false # rubocop:disable Style/ClassVars
28
+ end
29
+
30
+ def teardown
31
+ super
32
+ remove_all_acls
33
+ end
34
+
35
+ def remove_all_acls
36
+ Acl.acls.each do |_afis, acls|
37
+ acls.values.each(&:destroy)
38
+ end
39
+ end
40
+
41
+ # Helper to create an ACE and return the obj. The test_hash contains
42
+ # only the minimum properties which can be added to or overwritten as
43
+ # required for each test.
44
+ def ace_helper(afi, props=nil)
45
+ test_hash = {
46
+ action: 'permit',
47
+ proto: 'tcp',
48
+ src_addr: 'any',
49
+ dst_addr: 'any',
50
+ }
51
+ test_hash.merge!(props) unless props.nil?
52
+
53
+ a = Ace.new(afi, afi, 10)
54
+ begin
55
+ a.ace_set(test_hash)
56
+ a
57
+ end
58
+ rescue CliError => e
59
+ skip('This property is not supported on this platform') if
60
+ e.message[/(Invalid parameter detected|Invalid command|Invalid number)/]
61
+ flunk(e.message)
62
+ end
63
+
64
+ # TESTS
65
+ def test_remark
66
+ %w(ipv4 ipv6).each do |afi|
67
+ a = ace_helper(afi, remark: afi)
68
+ assert_equal(afi, a.remark)
69
+ assert_nil(a.log)
70
+ assert_nil(a.established)
71
+ end
72
+ end
73
+
74
+ def test_action
75
+ %w(ipv4 ipv6).each do |afi|
76
+ %w(permit deny).each do |val|
77
+ a = ace_helper(afi, action: val)
78
+ assert_equal(val, a.action)
79
+ end
80
+ end
81
+ end
82
+
83
+ def test_proto
84
+ %w(ipv4 ipv6).each do |afi|
85
+ # Sampling of proto's
86
+ %w(ip tcp udp icmp).each do |val|
87
+ val = 'ipv6' if val[/ip/] && afi[/ipv6/]
88
+ a = ace_helper(afi, proto: val)
89
+ assert_equal(val, a.proto)
90
+ end
91
+ end
92
+ end
93
+
94
+ def test_addrs
95
+ val = '10.1.1.1/32'
96
+ a = ace_helper('ipv4', src_addr: val, dst_addr: val)
97
+ assert_equal(val, a.src_addr)
98
+ assert_equal(val, a.dst_addr)
99
+
100
+ val = '10.1.1.1 0.0.0.0'
101
+ exp = '10.1.1.1/32'
102
+ # This syntax will transform to 10.1.1.1/32
103
+ a = ace_helper('ipv4', src_addr: val, dst_addr: val)
104
+ assert_equal(exp, a.src_addr)
105
+ assert_equal(exp, a.dst_addr)
106
+
107
+ val = '10.1.1.1 2.3.4.5'
108
+ a = ace_helper('ipv4', src_addr: val, dst_addr: val)
109
+ assert_equal(val, a.src_addr)
110
+ assert_equal(val, a.dst_addr)
111
+
112
+ val = '10:1:1::1/128'
113
+ a = ace_helper('ipv6', src_addr: val, dst_addr: val)
114
+ assert_equal(val, a.src_addr)
115
+ assert_equal(val, a.dst_addr)
116
+
117
+ config_no_warn('object-group ip address my_addrgroup_ipv4')
118
+ config_no_warn('object-group ipv6 address my_addrgroup_ipv6')
119
+ %w(ipv4 ipv6).each do |afi|
120
+ val = "addrgroup my_addrgroup_#{afi}"
121
+ a = ace_helper(afi, src_addr: val, dst_addr: val)
122
+ assert_equal(val, a.src_addr)
123
+ assert_equal(val, a.dst_addr)
124
+ end
125
+ config_no_warn('no object-group ip address my_addrgroup_ipv4')
126
+ config_no_warn('no object-group ipv6 address my_addrgroup_ipv6')
127
+ end
128
+
129
+ def test_ports
130
+ config_no_warn('object-group ip port my_pg')
131
+ %w(ipv4 ipv6).each do |afi|
132
+ ['eq 2', 'neq 2', 'gt 2', 'lt 2',
133
+ 'portgroup my_pg'].each do |val|
134
+ a = ace_helper(afi, src_port: val, dst_port: val)
135
+ assert_equal(val, a.src_port)
136
+ assert_equal(val, a.dst_port)
137
+ end
138
+ end
139
+ config_no_warn('no object-group ip port my_pg')
140
+ end
141
+
142
+ def test_dscp
143
+ %w(ipv4 ipv6).each do |afi|
144
+ %w(5 60 af11 af12 af13 af21 af22 af23 af31 af32 af33 af41 af42 af43
145
+ cs1 cs2 cs3 cs4 cs5 cs6 cs7 default ef).each do |val|
146
+ a = ace_helper(afi, dscp: val)
147
+ assert_equal(val, a.dscp)
148
+ end
149
+ end
150
+ end
151
+
152
+ def test_vlan
153
+ %w(ipv4 ipv6).each do |afi|
154
+ %w(10 100).each do |val|
155
+ a = ace_helper(afi, proto: 'icmp', vlan: val)
156
+ assert_equal(val, a.vlan)
157
+ end
158
+ end
159
+ end
160
+
161
+ def test_tcp_flags
162
+ %w(ipv4 ipv6).each do |afi|
163
+ %w(ack fin urg syn psh rst) + [
164
+ 'ack fin', 'ack psh rst'].each do |val|
165
+ a = ace_helper(afi, tcp_flags: val)
166
+ assert_equal(val, a.tcp_flags)
167
+ end
168
+ end
169
+ end
170
+
171
+ def test_established
172
+ %w(ipv4 ipv6).each do |afi|
173
+ refute(ace_helper(afi).established)
174
+ a = ace_helper(afi, established: true)
175
+ assert(a.established)
176
+ a = ace_helper(afi, established: false)
177
+ refute(a.established)
178
+ end
179
+ end
180
+
181
+ def test_http_method
182
+ afi = 'ipv4'
183
+ %w(connect delete get head post put trace).each do |val|
184
+ a = ace_helper(afi, http_method: val)
185
+ assert_equal(val, a.http_method)
186
+ end
187
+ end
188
+
189
+ def test_log
190
+ %w(ipv4 ipv6).each do |afi|
191
+ refute(ace_helper(afi).log)
192
+ a = ace_helper(afi, log: true)
193
+ assert(a.log)
194
+ a = ace_helper(afi, log: false)
195
+ refute(a.log)
196
+ end
197
+ end
198
+
199
+ def test_log_proto_option
200
+ %w(ipv4 ipv6).each do |afi|
201
+ refute(ace_helper(afi).log)
202
+ a = ace_helper(afi, proto: 'icmp', proto_option: 'redirect', log: true)
203
+ assert(a.log)
204
+ end
205
+ end
206
+
207
+ def test_proto_option
208
+ %w(ipv4 ipv6).each do |afi|
209
+ refute(ace_helper(afi).log)
210
+ a = ace_helper(afi, proto: 'icmp', proto_option: 'time-exceeded')
211
+ assert_equal(a.proto_option, 'time-exceeded')
212
+ a = ace_helper(afi, proto: 'icmp', dscp: 'af11', proto_option: 'echo-reply')
213
+ assert_equal(a.proto_option, 'echo-reply')
214
+ assert_equal(a.dscp, 'af11')
215
+ end
216
+ end
217
+
218
+ def test_redirect_proto_option
219
+ afi = 'ipv4'
220
+ val = 'port-channel1,port-channel2'
221
+ a = ace_helper(afi, proto: 'icmp', proto_option: 'redirect',
222
+ redirect: val, log: true, set_erspan_dscp: '3', set_erspan_gre_proto: '33')
223
+ assert_equal(val, a.redirect)
224
+ assert_equal('redirect', a.proto_option)
225
+ end
226
+
227
+ def test_precedence
228
+ afi = 'ipv4'
229
+ %w(critical flash flash-override immediate internet network
230
+ priority routine).each do |val|
231
+ a = ace_helper(afi, precedence: val)
232
+ assert_equal(val, a.precedence)
233
+ end
234
+ end
235
+
236
+ def test_redirect
237
+ afi = 'ipv4'
238
+ val = 'port-channel1,port-channel2'
239
+ a = ace_helper(afi, redirect: val)
240
+ assert_equal(val, a.redirect)
241
+ end
242
+
243
+ def test_tcp_option_length
244
+ afi = 'ipv4'
245
+ %w(0 16 28).each do |val|
246
+ a = ace_helper(afi, tcp_option_length: val)
247
+ assert_equal(val, a.tcp_option_length)
248
+ end
249
+ end
250
+
251
+ def test_time_range
252
+ val = 'my_range'
253
+ %w(ipv4 ipv6).each do |afi|
254
+ a = ace_helper(afi, time_range: val)
255
+ assert_equal(val, a.time_range)
256
+ end
257
+ end
258
+
259
+ def test_packet_length
260
+ val = 'range 80 1000'
261
+ %w(ipv4 ipv6).each do |afi|
262
+ a = ace_helper(afi, packet_length: val)
263
+ assert_equal(val, a.packet_length)
264
+ end
265
+ end
266
+
267
+ def test_ttl_ipv4
268
+ val = '3'
269
+ afi = 'ipv4'
270
+ a = ace_helper(afi, ttl: val)
271
+ skip("This property has a known defect on the platform itself -\n"\
272
+ 'CSCuy47463: access-list ttl does not nvgen') if a.ttl.nil?
273
+ assert_equal(val, a.ttl)
274
+ end
275
+
276
+ def test_ttl_ipv6
277
+ val = '3'
278
+ afi = 'ipv6'
279
+ a = ace_helper(afi, ttl: val)
280
+ skip("This property has a known defect on the platform itself -\n"\
281
+ 'CSCuy47463: access-list ttl does not nvgen') if a.ttl.nil?
282
+ assert_equal(val, a.ttl)
283
+ end
284
+
285
+ def test_set_erspan_dscp
286
+ afi = 'ipv4'
287
+ val = 'port-channel1,port-channel2'
288
+ a = ace_helper(afi, proto: 'icmp', proto_option: 'redirect',
289
+ redirect: val, log: true, set_erspan_dscp: '3', set_erspan_gre_proto: '33')
290
+ assert_equal('redirect', a.proto_option)
291
+ assert_equal(val, a.redirect)
292
+ assert_equal('3', a.set_erspan_dscp)
293
+ end
294
+
295
+ def test_set_erspan_gre_proto
296
+ afi = 'ipv4'
297
+ val = 'port-channel1,port-channel2'
298
+ a = ace_helper(afi, proto: 'icmp', proto_option: 'redirect',
299
+ redirect: val, log: true, set_erspan_gre_proto: '33')
300
+ assert_equal('redirect', a.proto_option)
301
+ assert_equal(val, a.redirect)
302
+ assert_equal('33', a.set_erspan_gre_proto)
303
+ end
304
+ end
data/tests/test_acl.rb ADDED
@@ -0,0 +1,185 @@
1
+ # Copyright (c) 2014-2016 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 'ciscotest'
16
+ require_relative '../lib/cisco_node_utils/acl'
17
+
18
+ # test client for acl creation and deletion
19
+ class TestAcl < CiscoTestCase
20
+ @skip_unless_supported = 'acl'
21
+ def setup
22
+ # setup runs at the beginning of each test
23
+ super
24
+ @acl_name_v4 = 'test-foo-v4-1'
25
+ @acl_name_v6 = 'test-foo-v6-1'
26
+ @permit = 'permit-all'
27
+ @deny = 'deny-all'
28
+ no_access_list_foo
29
+ end
30
+
31
+ def teardown
32
+ # teardown runs at the end of each test
33
+ no_access_list_foo
34
+ super
35
+ end
36
+
37
+ def no_access_list_foo
38
+ # Remove the test ACLs
39
+ %w(ipv4 ipv6).each do |afi|
40
+ acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
41
+ config('no ' + Acl.afi_cli(afi) + ' access-list ' + acl_name)
42
+ end
43
+ end
44
+
45
+ # TESTS
46
+ def create_acl(afi, acl_name)
47
+ rtr = Acl.new(afi, acl_name)
48
+ afi_cli = Acl.afi_cli(afi)
49
+
50
+ assert(Acl.acls[afi].key?(acl_name),
51
+ "ACL #{afi_cli} #{acl_name} is not configured")
52
+
53
+ @default_show_command =
54
+ "show runn aclmgr | i '#{afi_cli} access-list #{acl_name}'"
55
+ assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
56
+ msg: "failed to create acl '#{afi_cli} #{acl_name}'")
57
+ rtr.destroy
58
+ refute_show_match(pattern: /^#{afi} access-list #{acl_name}$/,
59
+ msg: "failed to destroy acl '#{afi_cli} #{acl_name}")
60
+ end
61
+
62
+ def test_create_acl
63
+ %w(ipv4 ipv6).each do |afi|
64
+ acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
65
+ create_acl(afi, acl_name)
66
+ end
67
+ end
68
+
69
+ def stats_enable(afi, acl_name)
70
+ rtr = Acl.new(afi, acl_name)
71
+ afi_cli = Acl.afi_cli(afi)
72
+
73
+ @default_show_command =
74
+ "show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
75
+ assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
76
+ msg: "failed to create acl #{acl_name}")
77
+
78
+ # set to true
79
+ rtr.stats_per_entry = true
80
+ assert_show_match(pattern: /statistics per-entry/,
81
+ msg: 'failed to enable stats')
82
+
83
+ assert(rtr.stats_per_entry)
84
+
85
+ # set to false
86
+ rtr.stats_per_entry = false
87
+ refute_show_match(pattern: /statistics per-entry/,
88
+ msg: 'failed to disable stats')
89
+ refute(rtr.stats_per_entry)
90
+
91
+ # default getter function
92
+ refute(rtr.default_stats_per_entry)
93
+
94
+ rtr.destroy
95
+ refute_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
96
+ msg: "failed to destroy acl #{acl_name}")
97
+ end
98
+
99
+ def test_stats_enable
100
+ %w(ipv4 ipv6).each do |afi|
101
+ acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
102
+ stats_enable(afi, acl_name)
103
+ end
104
+ end
105
+
106
+ def set_fragments(rtr, afi, acl_name, option)
107
+ afi_cli = Acl.afi_cli(afi)
108
+ @default_show_command =
109
+ "show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
110
+
111
+ # setter function
112
+ rtr.fragments = option
113
+ assert_show_match(pattern: /fragments #{option}/,
114
+ msg: 'failed to set fragments #{option} ' + option)
115
+
116
+ # getter function
117
+ assert_equal(option, rtr.fragments)
118
+ end
119
+
120
+ def unset_fragments(rtr, afi, acl_name)
121
+ afi_cli = Acl.afi_cli(afi)
122
+ @default_show_command =
123
+ "show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
124
+
125
+ # setter function
126
+ rtr.fragments = nil
127
+ refute_show_match(pattern: /fragments #{@permit}|fragments #{@deny}/,
128
+ msg: 'failed to unset set fragments')
129
+
130
+ # getter function
131
+ val = rtr.fragments
132
+ assert_nil(val)
133
+ end
134
+
135
+ def fragments(afi, acl_name)
136
+ rtr = Acl.new(afi, acl_name)
137
+ afi_cli = Acl.afi_cli(afi)
138
+
139
+ @default_show_command =
140
+ "show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
141
+ assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
142
+ msg: "failed to create acl #{acl_name}")
143
+
144
+ # set 'no fragments ...'
145
+ unset_fragments(rtr, afi, acl_name)
146
+
147
+ # set 'fragments permit-all' from nothing set
148
+ set_fragments(rtr, afi, acl_name, @permit)
149
+
150
+ # set 'no fragments ...'
151
+ unset_fragments(rtr, afi, acl_name)
152
+
153
+ # set 'fragments deny-all' from nothing set
154
+ set_fragments(rtr, afi, acl_name, @deny)
155
+
156
+ # set 'fragments permit-all' from 'fragments deny-all'
157
+ set_fragments(rtr, afi, acl_name, @permit)
158
+
159
+ # set 'fragments deny-all' from 'fragments permit-all'
160
+ set_fragments(rtr, afi, acl_name, @deny)
161
+
162
+ # default getter function
163
+ val = rtr.default_stats_per_entry
164
+ refute_equal(val, nil, 'value is not nil')
165
+
166
+ rtr.destroy
167
+ refute_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
168
+ msg: "failed to destroy acl #{acl_name}")
169
+ end
170
+
171
+ def test_fragments
172
+ if product_tag[/n(3k-f|5k|6k|9k-f)/]
173
+ a = Acl.new('ipv4', 'acl_fragments')
174
+ assert_nil(a.fragments)
175
+ assert_nil(a.default_fragments)
176
+ assert_raises(Cisco::UnsupportedError) { a.fragments = 'permit-all' }
177
+ return
178
+ end
179
+
180
+ %w(ipv4 ipv6).each do |afi|
181
+ acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
182
+ fragments(afi, acl_name)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,85 @@
1
+ #
2
+ # Minitest for Banner class
3
+ #
4
+ # Copyright (c) 2014-2018 Cisco and/or its affiliates.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require_relative 'ciscotest'
19
+ require_relative '../lib/cisco_node_utils/banner'
20
+
21
+ # TestBanner - Minitest for Banner node utility.
22
+ class TestBanner < CiscoTestCase
23
+ def setup
24
+ # setup runs at the beginning of each test
25
+ super
26
+ no_motd
27
+ end
28
+
29
+ def teardown
30
+ # teardown runs at the end of each test
31
+ no_motd
32
+ super
33
+ end
34
+
35
+ def no_motd
36
+ # Turn the feature off for a clean test.
37
+ config('no banner motd')
38
+ end
39
+
40
+ # TESTS
41
+
42
+ def test_single_motd
43
+ id = 'default'
44
+
45
+ banner = Cisco::Banner.new(id)
46
+ assert_includes(Cisco::Banner.banners, id)
47
+ assert_equal(Cisco::Banner.banners[id], banner)
48
+
49
+ assert_equal(banner.default_motd, Cisco::Banner.banners['default'].motd)
50
+ assert_equal(banner.default_motd, banner.motd)
51
+
52
+ banner.motd = 'Test banner!'
53
+ assert_equal(Cisco::Banner.banners['default'].motd,
54
+ 'Test banner!')
55
+ assert_equal(Cisco::Banner.banners['default'].motd,
56
+ banner.motd)
57
+
58
+ banner.motd = nil
59
+ assert_equal(banner.default_motd, Cisco::Banner.banners['default'].motd)
60
+ assert_equal(banner.default_motd, banner.motd)
61
+ end
62
+
63
+ def test_multiline_motd
64
+ skip_versions = ['7.0.3.I[2-6]', '7.0.3.I7.[1-3]', '7.3', '8.[1-3]']
65
+ skip_legacy_defect?(skip_versions, 'multiline banner configuration using nxapi not supported')
66
+ id = 'default'
67
+
68
+ banner = Cisco::Banner.new(id)
69
+ assert_includes(Cisco::Banner.banners, id)
70
+ assert_equal(Cisco::Banner.banners[id], banner)
71
+
72
+ assert_equal(banner.default_motd, Cisco::Banner.banners['default'].motd)
73
+ assert_equal(banner.default_motd, banner.motd)
74
+
75
+ banner.motd = 'This is\na sweet\n\nmultiline\nbanner!\n'
76
+ assert_equal(Cisco::Banner.banners['default'].motd,
77
+ "This is\na sweet\n\nmultiline\nbanner!\n")
78
+ assert_equal(Cisco::Banner.banners['default'].motd,
79
+ banner.motd)
80
+
81
+ banner.motd = nil
82
+ assert_equal(banner.default_motd, Cisco::Banner.banners['default'].motd)
83
+ assert_equal(banner.default_motd, banner.motd)
84
+ end
85
+ end