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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +4 -1
- data/CHANGELOG.md +81 -2
- data/CONTRIBUTING.md +2 -17
- data/Gemfile +5 -0
- data/README.md +92 -47
- data/Rakefile +23 -1
- data/bin/git/hooks/hook_lib +7 -0
- data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
- data/bin/git/hooks/pre-commit/rubocop +7 -2
- data/bin/git/hooks/pre-commit/validate-diffs +18 -4
- data/bin/git/hooks/pre-commit/validate-yaml +18 -0
- data/bin/git/update-hooks +64 -6
- data/cisco_node_utils.gemspec +9 -6
- data/docs/README-develop-best-practices.md +149 -50
- data/docs/README-develop-node-utils-APIs.md +92 -42
- data/docs/README-maintainers.md +7 -4
- data/docs/README-test-execution.md +57 -0
- data/docs/cisco_node_utils.yaml.example +30 -0
- data/docs/template-router.rb +4 -0
- data/ext/mkrf_conf.rb +63 -0
- data/lib/.rubocop.yml +2 -2
- data/lib/cisco_node_utils.rb +5 -0
- data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
- data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
- data/lib/cisco_node_utils/ace.rb +165 -12
- data/lib/cisco_node_utils/acl.rb +2 -1
- data/lib/cisco_node_utils/bgp.rb +184 -21
- data/lib/cisco_node_utils/bgp_af.rb +94 -249
- data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
- data/lib/cisco_node_utils/bridge_domain.rb +183 -0
- data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
- data/lib/cisco_node_utils/client.rb +35 -0
- data/lib/cisco_node_utils/client/client.rb +234 -0
- data/lib/cisco_node_utils/client/grpc.rb +33 -0
- data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
- data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
- data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
- data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
- data/lib/cisco_node_utils/client/nxapi.rb +31 -0
- data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
- data/lib/cisco_node_utils/client/utils.rb +164 -0
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
- data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
- data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
- data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
- data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
- data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
- data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
- data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
- data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
- data/lib/cisco_node_utils/command_reference.rb +261 -142
- data/lib/cisco_node_utils/constants.rb +33 -0
- data/lib/cisco_node_utils/encapsulation.rb +112 -0
- data/lib/cisco_node_utils/environment.rb +102 -0
- data/lib/cisco_node_utils/evpn_vni.rb +5 -3
- data/lib/cisco_node_utils/exceptions.rb +111 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
- data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
- data/lib/cisco_node_utils/feature.rb +165 -3
- data/lib/cisco_node_utils/interface.rb +1051 -260
- data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
- data/lib/cisco_node_utils/interface_ospf.rb +1 -2
- data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
- data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
- data/lib/cisco_node_utils/itd_device_group.rb +248 -0
- data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
- data/lib/cisco_node_utils/itd_service.rb +523 -0
- data/lib/cisco_node_utils/logger.rb +75 -0
- data/lib/cisco_node_utils/node.rb +62 -192
- data/lib/cisco_node_utils/node_util.rb +56 -10
- data/lib/cisco_node_utils/overlay_global.rb +2 -2
- data/lib/cisco_node_utils/pim.rb +2 -13
- data/lib/cisco_node_utils/pim_group_list.rb +1 -1
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
- data/lib/cisco_node_utils/platform.rb +52 -21
- data/lib/cisco_node_utils/portchannel_global.rb +89 -19
- data/lib/cisco_node_utils/radius_server.rb +168 -37
- data/lib/cisco_node_utils/router_ospf.rb +20 -35
- data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
- data/lib/cisco_node_utils/snmpserver.rb +1 -6
- data/lib/cisco_node_utils/snmpuser.rb +6 -4
- data/lib/cisco_node_utils/stp_global.rb +676 -0
- data/lib/cisco_node_utils/syslog_server.rb +77 -18
- data/lib/cisco_node_utils/syslog_settings.rb +1 -1
- data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
- data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
- data/lib/cisco_node_utils/vdc.rb +12 -0
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +147 -29
- data/lib/cisco_node_utils/vpc.rb +55 -3
- data/lib/cisco_node_utils/vrf.rb +72 -11
- data/lib/cisco_node_utils/vrf_af.rb +114 -29
- data/lib/cisco_node_utils/vtp.rb +34 -52
- data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
- data/lib/minitest/environment_plugin.rb +31 -0
- data/lib/minitest/log_level_plugin.rb +41 -0
- data/spec/client_spec.rb +7 -0
- data/spec/environment_spec.rb +263 -0
- data/spec/grpc_client_spec.rb +23 -0
- data/spec/isolate/all_clients_spec.rb +9 -0
- data/spec/isolate/grpc_only_spec.rb +16 -0
- data/spec/isolate/no_clients_spec.rb +26 -0
- data/spec/isolate/nxapi_only_spec.rb +16 -0
- data/spec/nxapi_client_spec.rb +42 -0
- data/spec/schema.yaml +75 -0
- data/spec/shared_examples_for_clients.rb +14 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/whitespace_spec.rb +10 -0
- data/spec/yaml_spec.rb +42 -0
- data/tests/.rubocop.yml +2 -2
- data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
- data/tests/basetest.rb +96 -36
- data/tests/ciscotest.rb +220 -12
- data/tests/cmd_config.yaml +71 -49
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/test_aaa_authentication_login.rb +1 -0
- data/tests/test_aaa_authentication_login_service.rb +9 -0
- data/tests/test_aaa_authorization_service.rb +173 -367
- data/tests/test_ace.rb +171 -100
- data/tests/test_acl.rb +10 -1
- data/tests/test_bgp_af.rb +395 -728
- data/tests/test_bgp_neighbor.rb +274 -115
- data/tests/test_bgp_neighbor_af.rb +178 -77
- data/tests/test_bridge_domain.rb +191 -0
- data/tests/test_bridge_domain_vni.rb +116 -0
- data/tests/test_client_utils.rb +111 -0
- data/tests/test_command_config.rb +9 -5
- data/tests/test_command_reference.rb +380 -102
- data/tests/test_dns_domain.rb +13 -3
- data/tests/test_domain_name.rb +13 -3
- data/tests/test_encapsulation.rb +77 -0
- data/tests/test_evpn_vni.rb +25 -7
- data/tests/test_fabricpath_global.rb +167 -163
- data/tests/test_fabricpath_topology.rb +12 -33
- data/tests/test_feature.rb +215 -0
- data/tests/test_grpc.rb +166 -0
- data/tests/test_interface.rb +585 -344
- data/tests/test_interface_bdi.rb +80 -0
- data/tests/test_interface_channel_group.rb +6 -3
- data/tests/test_interface_ospf.rb +26 -24
- data/tests/test_interface_portchannel.rb +1 -0
- data/tests/test_interface_private_vlan.rb +724 -0
- data/tests/test_interface_service_vni.rb +37 -66
- data/tests/test_interface_svi.rb +98 -101
- data/tests/test_interface_switchport.rb +419 -549
- data/tests/test_itd_device_group.rb +145 -0
- data/tests/test_itd_device_group_node.rb +199 -0
- data/tests/test_itd_service.rb +298 -0
- data/tests/test_logger.rb +43 -0
- data/tests/test_name_server.rb +11 -2
- data/tests/test_node.rb +16 -75
- data/tests/test_node_ext.rb +174 -163
- data/tests/test_node_util.rb +119 -0
- data/tests/test_ntp_config.rb +5 -1
- data/tests/test_ntp_server.rb +2 -2
- data/tests/test_nxapi.rb +221 -0
- data/tests/test_overlay_global.rb +47 -38
- data/tests/test_pim.rb +2 -0
- data/tests/test_pim_group_list.rb +2 -0
- data/tests/test_pim_rp_address.rb +2 -0
- data/tests/test_platform.rb +86 -39
- data/tests/test_portchannel_global.rb +211 -135
- data/tests/test_radius_global.rb +13 -5
- data/tests/test_radius_server.rb +256 -104
- data/tests/test_radius_server_group.rb +2 -0
- data/tests/test_router_bgp.rb +781 -485
- data/tests/test_router_ospf.rb +26 -103
- data/tests/test_router_ospf_vrf.rb +52 -57
- data/tests/test_snmp_notification_receiver.rb +2 -0
- data/tests/test_snmpcommunity.rb +2 -0
- data/tests/test_snmpgroup.rb +2 -0
- data/tests/test_snmpnotification.rb +40 -21
- data/tests/test_snmpserver.rb +2 -0
- data/tests/test_snmpuser.rb +2 -0
- data/tests/test_stp_global.rb +563 -0
- data/tests/test_syslog_server.rb +32 -8
- data/tests/test_syslog_settings.rb +22 -9
- data/tests/test_tacacs_server.rb +32 -27
- data/tests/test_tacacs_server_group.rb +100 -45
- data/tests/test_tacacs_server_host.rb +135 -43
- data/tests/test_vdc.rb +2 -16
- data/tests/test_vlan.rb +106 -54
- data/tests/test_vlan_mt_full.rb +11 -21
- data/tests/test_vlan_private.rb +669 -0
- data/tests/test_vpc.rb +312 -159
- data/tests/test_vrf.rb +122 -113
- data/tests/test_vrf_af.rb +238 -0
- data/tests/test_vtp.rb +58 -102
- data/tests/test_vxlan_vtep.rb +38 -17
- data/tests/test_vxlan_vtep_vni.rb +61 -9
- data/tests/test_yum.rb +49 -25
- metadata +122 -36
- data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
- data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
- data/lib/cisco_node_utils/vni.rb +0 -227
- 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
|