cisco_node_utils 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +4 -1
  6. data/CHANGELOG.md +81 -2
  7. data/CONTRIBUTING.md +2 -17
  8. data/Gemfile +5 -0
  9. data/README.md +92 -47
  10. data/Rakefile +23 -1
  11. data/bin/git/hooks/hook_lib +7 -0
  12. data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
  13. data/bin/git/hooks/pre-commit/rubocop +7 -2
  14. data/bin/git/hooks/pre-commit/validate-diffs +18 -4
  15. data/bin/git/hooks/pre-commit/validate-yaml +18 -0
  16. data/bin/git/update-hooks +64 -6
  17. data/cisco_node_utils.gemspec +9 -6
  18. data/docs/README-develop-best-practices.md +149 -50
  19. data/docs/README-develop-node-utils-APIs.md +92 -42
  20. data/docs/README-maintainers.md +7 -4
  21. data/docs/README-test-execution.md +57 -0
  22. data/docs/cisco_node_utils.yaml.example +30 -0
  23. data/docs/template-router.rb +4 -0
  24. data/ext/mkrf_conf.rb +63 -0
  25. data/lib/.rubocop.yml +2 -2
  26. data/lib/cisco_node_utils.rb +5 -0
  27. data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
  28. data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
  29. data/lib/cisco_node_utils/ace.rb +165 -12
  30. data/lib/cisco_node_utils/acl.rb +2 -1
  31. data/lib/cisco_node_utils/bgp.rb +184 -21
  32. data/lib/cisco_node_utils/bgp_af.rb +94 -249
  33. data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
  34. data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
  35. data/lib/cisco_node_utils/bridge_domain.rb +183 -0
  36. data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
  37. data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
  38. data/lib/cisco_node_utils/client.rb +35 -0
  39. data/lib/cisco_node_utils/client/client.rb +234 -0
  40. data/lib/cisco_node_utils/client/grpc.rb +33 -0
  41. data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
  42. data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
  43. data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
  44. data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
  45. data/lib/cisco_node_utils/client/nxapi.rb +31 -0
  46. data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
  47. data/lib/cisco_node_utils/client/utils.rb +164 -0
  48. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
  49. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
  50. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
  51. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
  52. data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
  53. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
  54. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
  55. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
  56. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
  57. data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
  58. data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
  59. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
  60. data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
  61. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
  62. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
  63. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
  64. data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
  65. data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
  66. data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
  67. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
  68. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
  69. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
  70. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
  71. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
  72. data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
  73. data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
  74. data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
  75. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
  76. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
  77. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
  78. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
  79. data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
  80. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
  81. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
  82. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
  83. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
  84. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
  85. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
  86. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
  87. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
  88. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
  89. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
  90. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
  91. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
  92. data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
  93. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
  94. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
  95. data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
  96. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
  97. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
  98. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
  99. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
  100. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
  101. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
  102. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
  103. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
  104. data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
  105. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
  106. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
  107. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
  108. data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
  109. data/lib/cisco_node_utils/command_reference.rb +261 -142
  110. data/lib/cisco_node_utils/constants.rb +33 -0
  111. data/lib/cisco_node_utils/encapsulation.rb +112 -0
  112. data/lib/cisco_node_utils/environment.rb +102 -0
  113. data/lib/cisco_node_utils/evpn_vni.rb +5 -3
  114. data/lib/cisco_node_utils/exceptions.rb +111 -0
  115. data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
  116. data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
  117. data/lib/cisco_node_utils/feature.rb +165 -3
  118. data/lib/cisco_node_utils/interface.rb +1051 -260
  119. data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
  120. data/lib/cisco_node_utils/interface_ospf.rb +1 -2
  121. data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
  122. data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
  123. data/lib/cisco_node_utils/itd_device_group.rb +248 -0
  124. data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
  125. data/lib/cisco_node_utils/itd_service.rb +523 -0
  126. data/lib/cisco_node_utils/logger.rb +75 -0
  127. data/lib/cisco_node_utils/node.rb +62 -192
  128. data/lib/cisco_node_utils/node_util.rb +56 -10
  129. data/lib/cisco_node_utils/overlay_global.rb +2 -2
  130. data/lib/cisco_node_utils/pim.rb +2 -13
  131. data/lib/cisco_node_utils/pim_group_list.rb +1 -1
  132. data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
  133. data/lib/cisco_node_utils/platform.rb +52 -21
  134. data/lib/cisco_node_utils/portchannel_global.rb +89 -19
  135. data/lib/cisco_node_utils/radius_server.rb +168 -37
  136. data/lib/cisco_node_utils/router_ospf.rb +20 -35
  137. data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
  138. data/lib/cisco_node_utils/snmpserver.rb +1 -6
  139. data/lib/cisco_node_utils/snmpuser.rb +6 -4
  140. data/lib/cisco_node_utils/stp_global.rb +676 -0
  141. data/lib/cisco_node_utils/syslog_server.rb +77 -18
  142. data/lib/cisco_node_utils/syslog_settings.rb +1 -1
  143. data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
  144. data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
  145. data/lib/cisco_node_utils/vdc.rb +12 -0
  146. data/lib/cisco_node_utils/version.rb +1 -1
  147. data/lib/cisco_node_utils/vlan.rb +147 -29
  148. data/lib/cisco_node_utils/vpc.rb +55 -3
  149. data/lib/cisco_node_utils/vrf.rb +72 -11
  150. data/lib/cisco_node_utils/vrf_af.rb +114 -29
  151. data/lib/cisco_node_utils/vtp.rb +34 -52
  152. data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
  153. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
  154. data/lib/minitest/environment_plugin.rb +31 -0
  155. data/lib/minitest/log_level_plugin.rb +41 -0
  156. data/spec/client_spec.rb +7 -0
  157. data/spec/environment_spec.rb +263 -0
  158. data/spec/grpc_client_spec.rb +23 -0
  159. data/spec/isolate/all_clients_spec.rb +9 -0
  160. data/spec/isolate/grpc_only_spec.rb +16 -0
  161. data/spec/isolate/no_clients_spec.rb +26 -0
  162. data/spec/isolate/nxapi_only_spec.rb +16 -0
  163. data/spec/nxapi_client_spec.rb +42 -0
  164. data/spec/schema.yaml +75 -0
  165. data/spec/shared_examples_for_clients.rb +14 -0
  166. data/spec/spec_helper.rb +91 -0
  167. data/spec/whitespace_spec.rb +10 -0
  168. data/spec/yaml_spec.rb +42 -0
  169. data/tests/.rubocop.yml +2 -2
  170. data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
  171. data/tests/basetest.rb +96 -36
  172. data/tests/ciscotest.rb +220 -12
  173. data/tests/cmd_config.yaml +71 -49
  174. data/tests/cmd_config_invalid.yaml +1 -1
  175. data/tests/test_aaa_authentication_login.rb +1 -0
  176. data/tests/test_aaa_authentication_login_service.rb +9 -0
  177. data/tests/test_aaa_authorization_service.rb +173 -367
  178. data/tests/test_ace.rb +171 -100
  179. data/tests/test_acl.rb +10 -1
  180. data/tests/test_bgp_af.rb +395 -728
  181. data/tests/test_bgp_neighbor.rb +274 -115
  182. data/tests/test_bgp_neighbor_af.rb +178 -77
  183. data/tests/test_bridge_domain.rb +191 -0
  184. data/tests/test_bridge_domain_vni.rb +116 -0
  185. data/tests/test_client_utils.rb +111 -0
  186. data/tests/test_command_config.rb +9 -5
  187. data/tests/test_command_reference.rb +380 -102
  188. data/tests/test_dns_domain.rb +13 -3
  189. data/tests/test_domain_name.rb +13 -3
  190. data/tests/test_encapsulation.rb +77 -0
  191. data/tests/test_evpn_vni.rb +25 -7
  192. data/tests/test_fabricpath_global.rb +167 -163
  193. data/tests/test_fabricpath_topology.rb +12 -33
  194. data/tests/test_feature.rb +215 -0
  195. data/tests/test_grpc.rb +166 -0
  196. data/tests/test_interface.rb +585 -344
  197. data/tests/test_interface_bdi.rb +80 -0
  198. data/tests/test_interface_channel_group.rb +6 -3
  199. data/tests/test_interface_ospf.rb +26 -24
  200. data/tests/test_interface_portchannel.rb +1 -0
  201. data/tests/test_interface_private_vlan.rb +724 -0
  202. data/tests/test_interface_service_vni.rb +37 -66
  203. data/tests/test_interface_svi.rb +98 -101
  204. data/tests/test_interface_switchport.rb +419 -549
  205. data/tests/test_itd_device_group.rb +145 -0
  206. data/tests/test_itd_device_group_node.rb +199 -0
  207. data/tests/test_itd_service.rb +298 -0
  208. data/tests/test_logger.rb +43 -0
  209. data/tests/test_name_server.rb +11 -2
  210. data/tests/test_node.rb +16 -75
  211. data/tests/test_node_ext.rb +174 -163
  212. data/tests/test_node_util.rb +119 -0
  213. data/tests/test_ntp_config.rb +5 -1
  214. data/tests/test_ntp_server.rb +2 -2
  215. data/tests/test_nxapi.rb +221 -0
  216. data/tests/test_overlay_global.rb +47 -38
  217. data/tests/test_pim.rb +2 -0
  218. data/tests/test_pim_group_list.rb +2 -0
  219. data/tests/test_pim_rp_address.rb +2 -0
  220. data/tests/test_platform.rb +86 -39
  221. data/tests/test_portchannel_global.rb +211 -135
  222. data/tests/test_radius_global.rb +13 -5
  223. data/tests/test_radius_server.rb +256 -104
  224. data/tests/test_radius_server_group.rb +2 -0
  225. data/tests/test_router_bgp.rb +781 -485
  226. data/tests/test_router_ospf.rb +26 -103
  227. data/tests/test_router_ospf_vrf.rb +52 -57
  228. data/tests/test_snmp_notification_receiver.rb +2 -0
  229. data/tests/test_snmpcommunity.rb +2 -0
  230. data/tests/test_snmpgroup.rb +2 -0
  231. data/tests/test_snmpnotification.rb +40 -21
  232. data/tests/test_snmpserver.rb +2 -0
  233. data/tests/test_snmpuser.rb +2 -0
  234. data/tests/test_stp_global.rb +563 -0
  235. data/tests/test_syslog_server.rb +32 -8
  236. data/tests/test_syslog_settings.rb +22 -9
  237. data/tests/test_tacacs_server.rb +32 -27
  238. data/tests/test_tacacs_server_group.rb +100 -45
  239. data/tests/test_tacacs_server_host.rb +135 -43
  240. data/tests/test_vdc.rb +2 -16
  241. data/tests/test_vlan.rb +106 -54
  242. data/tests/test_vlan_mt_full.rb +11 -21
  243. data/tests/test_vlan_private.rb +669 -0
  244. data/tests/test_vpc.rb +312 -159
  245. data/tests/test_vrf.rb +122 -113
  246. data/tests/test_vrf_af.rb +238 -0
  247. data/tests/test_vtp.rb +58 -102
  248. data/tests/test_vxlan_vtep.rb +38 -17
  249. data/tests/test_vxlan_vtep_vni.rb +61 -9
  250. data/tests/test_yum.rb +49 -25
  251. metadata +122 -36
  252. data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
  253. data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
  254. data/lib/cisco_node_utils/vni.rb +0 -227
  255. data/tests/test_vni.rb +0 -106
@@ -0,0 +1,111 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: ems.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "IOSXRExtensibleManagabilityService.ConfigGetArgs" do
8
+ optional :ReqId, :int64, 1
9
+ optional :yangpathjson, :string, 2
10
+ end
11
+ add_message "IOSXRExtensibleManagabilityService.ConfigGetReply" do
12
+ optional :ResReqId, :int64, 1
13
+ optional :yangjson, :string, 2
14
+ optional :errors, :string, 3
15
+ end
16
+ add_message "IOSXRExtensibleManagabilityService.GetOperArgs" do
17
+ optional :ReqId, :int64, 1
18
+ optional :yangpathjson, :string, 2
19
+ end
20
+ add_message "IOSXRExtensibleManagabilityService.GetOperReply" do
21
+ optional :ResReqId, :int64, 1
22
+ optional :yangjson, :string, 2
23
+ optional :errors, :string, 3
24
+ end
25
+ add_message "IOSXRExtensibleManagabilityService.ConfigArgs" do
26
+ optional :ReqId, :int64, 1
27
+ optional :yangjson, :string, 2
28
+ end
29
+ add_message "IOSXRExtensibleManagabilityService.ConfigReply" do
30
+ optional :ResReqId, :int64, 1
31
+ optional :errors, :string, 2
32
+ end
33
+ add_message "IOSXRExtensibleManagabilityService.CliConfigArgs" do
34
+ optional :ReqId, :int64, 1
35
+ optional :cli, :string, 2
36
+ end
37
+ add_message "IOSXRExtensibleManagabilityService.CliConfigReply" do
38
+ optional :ResReqId, :int64, 1
39
+ optional :errors, :string, 2
40
+ end
41
+ add_message "IOSXRExtensibleManagabilityService.CommitReplaceArgs" do
42
+ optional :ReqId, :int64, 1
43
+ optional :cli, :string, 2
44
+ optional :yangjson, :string, 3
45
+ end
46
+ add_message "IOSXRExtensibleManagabilityService.CommitReplaceReply" do
47
+ optional :ResReqId, :int64, 1
48
+ optional :errors, :string, 2
49
+ end
50
+ add_message "IOSXRExtensibleManagabilityService.CommitMsg" do
51
+ optional :label, :string, 1
52
+ optional :comment, :string, 2
53
+ end
54
+ add_message "IOSXRExtensibleManagabilityService.CommitArgs" do
55
+ optional :msg, :message, 1, "IOSXRExtensibleManagabilityService.CommitMsg"
56
+ optional :ReqId, :int64, 2
57
+ end
58
+ add_message "IOSXRExtensibleManagabilityService.CommitReply" do
59
+ optional :result, :enum, 1, "IOSXRExtensibleManagabilityService.CommitResult"
60
+ optional :ResReqId, :int64, 2
61
+ optional :errors, :string, 3
62
+ end
63
+ add_message "IOSXRExtensibleManagabilityService.DiscardChangesArgs" do
64
+ optional :ReqId, :int64, 1
65
+ end
66
+ add_message "IOSXRExtensibleManagabilityService.DiscardChangesReply" do
67
+ optional :ResReqId, :int64, 1
68
+ optional :errors, :string, 2
69
+ end
70
+ add_message "IOSXRExtensibleManagabilityService.ShowCmdArgs" do
71
+ optional :ReqId, :int64, 1
72
+ optional :cli, :string, 2
73
+ end
74
+ add_message "IOSXRExtensibleManagabilityService.ShowCmdTextReply" do
75
+ optional :ResReqId, :int64, 1
76
+ optional :output, :string, 2
77
+ optional :errors, :string, 3
78
+ end
79
+ add_message "IOSXRExtensibleManagabilityService.ShowCmdJSONReply" do
80
+ optional :ResReqId, :int64, 1
81
+ optional :jsonoutput, :string, 2
82
+ optional :errors, :string, 3
83
+ end
84
+ add_enum "IOSXRExtensibleManagabilityService.CommitResult" do
85
+ value :CHANGE, 0
86
+ value :NO_CHANGE, 1
87
+ value :FAIL, 2
88
+ end
89
+ end
90
+
91
+ module IOSXRExtensibleManagabilityService
92
+ ConfigGetArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ConfigGetArgs").msgclass
93
+ ConfigGetReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ConfigGetReply").msgclass
94
+ GetOperArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.GetOperArgs").msgclass
95
+ GetOperReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.GetOperReply").msgclass
96
+ ConfigArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ConfigArgs").msgclass
97
+ ConfigReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ConfigReply").msgclass
98
+ CliConfigArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CliConfigArgs").msgclass
99
+ CliConfigReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CliConfigReply").msgclass
100
+ CommitReplaceArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitReplaceArgs").msgclass
101
+ CommitReplaceReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitReplaceReply").msgclass
102
+ CommitMsg = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitMsg").msgclass
103
+ CommitArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitArgs").msgclass
104
+ CommitReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitReply").msgclass
105
+ DiscardChangesArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.DiscardChangesArgs").msgclass
106
+ DiscardChangesReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.DiscardChangesReply").msgclass
107
+ ShowCmdArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ShowCmdArgs").msgclass
108
+ ShowCmdTextReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ShowCmdTextReply").msgclass
109
+ ShowCmdJSONReply = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.ShowCmdJSONReply").msgclass
110
+ CommitResult = Google::Protobuf::DescriptorPool.generated_pool.lookup("IOSXRExtensibleManagabilityService.CommitResult").enummodule
111
+ end
@@ -0,0 +1,49 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: ems.proto for package 'IOSXRExtensibleManagabilityService'
3
+
4
+ require 'grpc'
5
+ require_relative 'ems'
6
+
7
+ module IOSXRExtensibleManagabilityService
8
+ module GRPCConfigOper
9
+
10
+ # TODO: add proto service documentation here
11
+ class Service
12
+
13
+ include GRPC::GenericService
14
+
15
+ self.marshal_class_method = :encode
16
+ self.unmarshal_class_method = :decode
17
+ self.service_name = 'IOSXRExtensibleManagabilityService.gRPCConfigOper'
18
+
19
+ rpc :GetConfig, ConfigGetArgs, stream(ConfigGetReply)
20
+ rpc :MergeConfig, ConfigArgs, ConfigReply
21
+ rpc :DeleteConfig, ConfigArgs, ConfigReply
22
+ rpc :ReplaceConfig, ConfigArgs, ConfigReply
23
+ rpc :CliConfig, CliConfigArgs, CliConfigReply
24
+ rpc :CommitReplace, CommitReplaceArgs, CommitReplaceReply
25
+ rpc :CommitConfig, CommitArgs, CommitReply
26
+ rpc :ConfigDiscardChanges, DiscardChangesArgs, DiscardChangesReply
27
+ rpc :GetOper, GetOperArgs, stream(GetOperReply)
28
+ end
29
+
30
+ Stub = Service.rpc_stub_class
31
+ end
32
+ module GRPCExec
33
+
34
+ # TODO: add proto service documentation here
35
+ class Service
36
+
37
+ include GRPC::GenericService
38
+
39
+ self.marshal_class_method = :encode
40
+ self.unmarshal_class_method = :decode
41
+ self.service_name = 'IOSXRExtensibleManagabilityService.gRPCExec'
42
+
43
+ rpc :ShowCmdTextOutput, ShowCmdArgs, stream(ShowCmdTextReply)
44
+ rpc :ShowCmdJSONOutput, ShowCmdArgs, stream(ShowCmdJSONReply)
45
+ end
46
+
47
+ Stub = Service.rpc_stub_class
48
+ end
49
+ 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,305 @@
1
+ # NXAPI client library.
2
+ #
3
+ # November 2014, Glenn F. Matthews
4
+ #
5
+ # Copyright (c) 2014-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 '../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
+ else
60
+ # Remote connection. This is primarily expected
61
+ # when running e.g. from a Unix server as part of Minitest.
62
+ @http = Net::HTTP.new(@host)
63
+ end
64
+ # The default read time out is 60 seconds, which may be too short for
65
+ # scaled configuration to apply. Change it to 300 seconds, which is
66
+ # also used as the default config by firefox.
67
+ @http.read_timeout = 300
68
+ @address = @http.address
69
+
70
+ # Make sure we can actually connect to the socket
71
+ get(command: 'show hostname')
72
+ end
73
+
74
+ def self.validate_args(**kwargs)
75
+ super
76
+ if kwargs[:host].nil?
77
+ # Connection to UDS - no username or password either
78
+ fail ArgumentError unless kwargs[:username].nil? && kwargs[:password].nil?
79
+ else
80
+ # Connection to remote system - username and password are required
81
+ fail TypeError, 'username is required' if kwargs[:username].nil?
82
+ fail TypeError, 'password is required' if kwargs[:password].nil?
83
+ end
84
+ end
85
+
86
+ # Clear the cache of CLI output results.
87
+ #
88
+ # If cache_auto is true (default) then this will be performed automatically
89
+ # whenever a set() is called, but providers may also call this
90
+ # to explicitly force the cache to be cleared.
91
+ def cache_flush
92
+ @cache_hash = {
93
+ 'cli_conf' => {},
94
+ 'cli_show' => {},
95
+ 'cli_show_ascii' => {},
96
+ }
97
+ end
98
+
99
+ # Configure the given CLI command(s) on the device.
100
+ #
101
+ # @raise [RequestNotSupported] if this client doesn't support CLI config
102
+ #
103
+ # @param data_format one of Cisco::DATA_FORMATS. Default is :cli
104
+ # @param context [String, Array<String>] Zero or more configuration commands
105
+ # used to enter the desired CLI sub-mode
106
+ # @param values [String, Array<String>] One or more commands
107
+ # to enter within the CLI sub-mode.
108
+ def set(data_format: :cli,
109
+ context: nil,
110
+ values: nil)
111
+ # we don't currently support nxapi_structured for configuration
112
+ fail Cisco::RequestNotSupported if data_format == :nxapi_structured
113
+ context = munge_to_array(context)
114
+ values = munge_to_array(values)
115
+ super
116
+ req('cli_conf', context + values)
117
+ end
118
+
119
+ # Get the given state from the device.
120
+ #
121
+ # Unlike set() this will not clear the CLI cache;
122
+ # multiple calls with the same parameters may return cached data
123
+ # rather than querying the device repeatedly.
124
+ #
125
+ # @raise [Cisco::RequestNotSupported] if
126
+ # structured output is requested but the given command can't provide it.
127
+ # @raise [Cisco::CliError] if the command is rejected by the device
128
+ #
129
+ # @param data_format one of Cisco::DATA_FORMATS. Default is :cli
130
+ # @param command [String] the show command to execute
131
+ # @param context [String, Array<String>] Context to refine the results
132
+ # @param value [String] Specific key to look up
133
+ # @return [String, Hash]
134
+ def get(data_format: :cli,
135
+ command: nil,
136
+ context: nil,
137
+ value: nil)
138
+ context = munge_to_array(context)
139
+ super
140
+ if data_format == :cli
141
+ output = req('cli_show_ascii', command)
142
+ return self.class.filter_cli(cli_output: output,
143
+ context: context,
144
+ value: value)
145
+ elsif data_format == :nxapi_structured
146
+ output = req('cli_show', command)
147
+ return self.class.filter_data(data: output,
148
+ keys: context + munge_to_array(value))
149
+ else
150
+ fail TypeError
151
+ end
152
+ end
153
+
154
+ # Sends a request to the NX API and returns the body of the request or
155
+ # handles errors that happen.
156
+ # @raise Cisco::ConnectionRefused if NXAPI is disabled
157
+ # @raise Cisco::AuthenticationFailed if username/password are invalid
158
+ # @raise Cisco::ClientError (should never occur)
159
+ # @raise Cisco::RequestNotSupported
160
+ # @raise Cisco::RequestFailed if any command is rejected as invalid
161
+ #
162
+ # @param type ["cli_show", "cli_show_ascii"] Specifies the type of command
163
+ # to be executed.
164
+ # @param command_or_list [String, Array<String>] The command or array of
165
+ # commands which should be run.
166
+ # @return [Hash, Array<Hash>] output when type == "cli_show"
167
+ # @return [String, Array<String>] output when type == "cli_show_ascii"
168
+ def req(type, command_or_list)
169
+ if command_or_list.is_a?(Array)
170
+ # NXAPI wants config lines to be separated by ' ; '
171
+ command = command_or_list.join(' ; ')
172
+ else
173
+ command = command_or_list
174
+ command_or_list = [command]
175
+ end
176
+
177
+ debug("Input (#{type}): \'#{command}\'")
178
+ if cache_enable? && @cache_hash[type] && @cache_hash[type][command]
179
+ return @cache_hash[type][command]
180
+ end
181
+
182
+ # form the request
183
+ request = build_http_request(type, command)
184
+
185
+ # send the request and get the response
186
+ debug("Sending HTTP request to NX-API at #{@http.address}:\n" \
187
+ "#{request.to_hash}\n#{request.body}")
188
+ begin
189
+ # Explicitly use http to avoid EOFError
190
+ # http://stackoverflow.com/a/23080693
191
+ @http.use_ssl = false
192
+ response = @http.request(request)
193
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
194
+ emsg = 'Connection refused or reset. Is the NX-API feature enabled?'
195
+ raise Cisco::ConnectionRefused, emsg
196
+ end
197
+ handle_http_response(response)
198
+ output = parse_response(response)
199
+
200
+ prev_cmds = []
201
+ if output.is_a?(Array)
202
+ output.zip(command_or_list) do |o, cmd|
203
+ handle_output(prev_cmds, cmd, o)
204
+ prev_cmds << cmd
205
+ end
206
+ output = output.each { |o| o['body'] }
207
+ else
208
+ handle_output(prev_cmds, command, output)
209
+ output = output['body']
210
+ end
211
+
212
+ output = '' if type == 'cli_show_ascii' && output.empty?
213
+
214
+ @cache_hash[type][command] = output if cache_enable?
215
+ output
216
+ end
217
+ private :req
218
+
219
+ def build_http_request(type, command_string)
220
+ if @username.nil? || @password.nil?
221
+ request = Net::HTTP::Post.new(NXAPI_UDS_URI_PATH)
222
+ request['Cookie'] = 'nxapi_auth=admin:local'
223
+ else
224
+ request = Net::HTTP::Post.new(NXAPI_REMOTE_URI_PATH)
225
+ request.basic_auth("#{@username}", "#{@password}")
226
+ end
227
+ request.content_type = 'application/json'
228
+ request.body = {
229
+ 'ins_api' => {
230
+ 'version' => NXAPI_VERSION,
231
+ 'type' => "#{type}",
232
+ 'chunk' => '0',
233
+ 'sid' => '1',
234
+ 'input' => "#{command_string}",
235
+ 'output_format' => 'json',
236
+ }
237
+ }.to_json
238
+ request
239
+ end
240
+ private :build_http_request
241
+
242
+ def handle_http_response(response)
243
+ debug("HTTP Response: #{response.message}\n#{response.body}")
244
+ case response
245
+ when Net::HTTPUnauthorized
246
+ emsg = 'HTTP 401 Unauthorized. Are your NX-API credentials correct?'
247
+ fail Cisco::AuthenticationFailed, emsg
248
+ when Net::HTTPBadRequest
249
+ emsg = "HTTP 400 Bad Request\n#{response.body}"
250
+ fail Cisco::ClientError, emsg
251
+ end
252
+ end
253
+ private :handle_http_response
254
+
255
+ def parse_response(response)
256
+ body = JSON.parse(response.body)
257
+
258
+ # In case of an error the JSON may not be complete, so we need to
259
+ # proceed carefully, as blindly doing body["ins_api"]["outputs"]["output"]
260
+ # could throw an error otherwise.
261
+ output = body['ins_api']
262
+ fail Cisco::ClientError, "unexpected JSON output:\n#{body}" if output.nil?
263
+ output = output['outputs'] if output['outputs']
264
+ output = output['output'] if output['output']
265
+
266
+ output
267
+ rescue JSON::ParserError
268
+ raise Cisco::ClientError, "response is not JSON:\n#{response.body}"
269
+ end
270
+ private :parse_response
271
+
272
+ def handle_output(prev_cmds, command, output)
273
+ if output['code'] == '400'
274
+ # CLI error.
275
+ # Examples: "Invalid input", "Incomplete command", etc.
276
+ fail Cisco::CliError.new( # rubocop:disable Style/RaiseArgs
277
+ rejected_input: command,
278
+ clierror: output['clierror'],
279
+ msg: output['msg'],
280
+ code: output['code'],
281
+ successful_input: prev_cmds,
282
+ )
283
+ elsif output['code'] == '413'
284
+ # Request too large
285
+ fail Cisco::RequestNotSupported, "Error 413: #{output['msg']}"
286
+ elsif output['code'] == '501'
287
+ # if structured output is not supported for this command,
288
+ # raise an exception so that the calling function can
289
+ # handle accordingly
290
+ fail Cisco::RequestNotSupported, \
291
+ "Structured output not supported for #{command}"
292
+ # Error 432: Requested object does not exist
293
+ # Ignore 432 errors because it means that a property is not configured
294
+ elsif output['code'] =~ /[45]\d\d/ && output['code'] != '432'
295
+ fail Cisco::RequestFailed, \
296
+ "#{output['code']} Error: #{output['msg']}"
297
+ else
298
+ debug("Result for '#{command}': #{output['msg']}")
299
+ if output['body'] && !output['body'].empty?
300
+ debug("Output: #{output['body']}")
301
+ end
302
+ end
303
+ end
304
+ private :handle_output
305
+ end