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,75 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Cisco Logger Library.
|
|
3
|
+
#
|
|
4
|
+
# January 2015, Jie Yang
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2015 Cisco and/or its affiliates.
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
|
|
20
|
+
require 'logger'
|
|
21
|
+
|
|
22
|
+
# Ensure module Cisco is defined
|
|
23
|
+
module Cisco
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Module for logging in CiscoNodeUtils. Will automatically
|
|
27
|
+
# tie into Puppet or Chef logging modules if available.
|
|
28
|
+
module Cisco::Logger
|
|
29
|
+
module_function
|
|
30
|
+
|
|
31
|
+
# Figure out what provider logging utility we
|
|
32
|
+
# should use: Puppet or Chef.
|
|
33
|
+
# If not found use the Ruby Logger/STDOUT/INFO.
|
|
34
|
+
if defined? (Puppet::Util::Logging)
|
|
35
|
+
@@logger = Puppet # rubocop:disable Style/ClassVars
|
|
36
|
+
def error(string)
|
|
37
|
+
@@logger.err(string)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def warn(string)
|
|
41
|
+
@@logger.warning(string)
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
if defined? (Chef::Log)
|
|
45
|
+
@@logger = Chef::Log # rubocop:disable Style/ClassVars
|
|
46
|
+
else
|
|
47
|
+
@@logger = Logger.new(STDOUT) # rubocop:disable Style/ClassVars
|
|
48
|
+
@@logger.level = Logger::INFO
|
|
49
|
+
|
|
50
|
+
def level
|
|
51
|
+
@@logger.level
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def level=(level)
|
|
55
|
+
@@logger.level = level
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def error(string)
|
|
60
|
+
@@logger.error(string)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def warn(string)
|
|
64
|
+
@@logger.warn(string)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def debug(string)
|
|
69
|
+
@@logger.debug(string)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def info(string)
|
|
73
|
+
@@logger.info(string)
|
|
74
|
+
end
|
|
75
|
+
end # module
|
|
@@ -18,47 +18,31 @@
|
|
|
18
18
|
# See the License for the specific language governing permissions and
|
|
19
19
|
# limitations under the License.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
require 'cisco_nxapi'
|
|
21
|
+
require_relative 'client'
|
|
24
22
|
require_relative 'command_reference'
|
|
23
|
+
require_relative 'exceptions'
|
|
24
|
+
require_relative 'logger'
|
|
25
25
|
|
|
26
26
|
# Add node management classes and APIs to the Cisco namespace.
|
|
27
27
|
module Cisco
|
|
28
|
-
# Error class raised by the config_set and config_get APIs if the
|
|
29
|
-
# device encounters an issue trying to act on the requested CLI.
|
|
30
|
-
#
|
|
31
|
-
# command - the specific CLI that was rejected
|
|
32
|
-
# clierror - any error string from the device
|
|
33
|
-
class CliError < RuntimeError
|
|
34
|
-
attr_reader :command, :clierror, :previous
|
|
35
|
-
def initialize(command, clierror, previous)
|
|
36
|
-
@command = command
|
|
37
|
-
@clierror = clierror.rstrip if clierror.kind_of? String
|
|
38
|
-
@previous = previous
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def to_s
|
|
42
|
-
"CliError: '#{@command}' rejected with message:\n'#{@clierror}'"
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
28
|
# class Cisco::Node
|
|
47
29
|
# Singleton representing the network node (switch/router) that is
|
|
48
30
|
# running this code. The singleton is lazily instantiated, meaning that
|
|
49
31
|
# it doesn't exist until some client requests it (with Node.instance())
|
|
50
32
|
class Node
|
|
51
|
-
|
|
33
|
+
@instance = nil
|
|
52
34
|
|
|
53
|
-
# Convenience wrapper for
|
|
35
|
+
# Convenience wrapper for get()
|
|
54
36
|
# Uses CommandReference to look up the given show command and key
|
|
55
37
|
# of interest, executes that command, and returns the value corresponding
|
|
56
38
|
# to that key.
|
|
57
39
|
#
|
|
58
40
|
# @raise [IndexError] if the given (feature, name) pair is not in the
|
|
59
41
|
# CommandReference data or if the data doesn't have values defined
|
|
60
|
-
# for the '
|
|
61
|
-
# @raise [Cisco::
|
|
42
|
+
# for the 'get_command' and (optional) 'get_value' fields.
|
|
43
|
+
# @raise [Cisco::UnsupportedError] if the (feature, name) pair is flagged
|
|
44
|
+
# in the YAML as unsupported on this device.
|
|
45
|
+
# @raise [Cisco::RequestFailed] if the command is rejected by the device.
|
|
62
46
|
#
|
|
63
47
|
# @param feature [String]
|
|
64
48
|
# @param name [String]
|
|
@@ -66,43 +50,30 @@ module Cisco
|
|
|
66
50
|
# @example config_get("show_version", "system_image")
|
|
67
51
|
# @example config_get("ospf", "router_id",
|
|
68
52
|
# {name: "green", vrf: "one"})
|
|
69
|
-
def config_get(feature,
|
|
70
|
-
|
|
71
|
-
ref = @cmd_ref.lookup(feature, name)
|
|
53
|
+
def config_get(feature, property, *args)
|
|
54
|
+
ref = @cmd_ref.lookup(feature, property)
|
|
72
55
|
|
|
73
|
-
return
|
|
56
|
+
# If we have a default value but no getter, just return the default
|
|
57
|
+
return ref.default_value if ref.default_value? && !ref.getter?
|
|
74
58
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if token.nil?
|
|
82
|
-
# Just get the whole output
|
|
83
|
-
return massage(show(ref.config_get, :structured), ref)
|
|
84
|
-
elsif token[0].kind_of?(Regexp)
|
|
85
|
-
return massage(Cisco.find_ascii(show(ref.config_get, :ascii),
|
|
86
|
-
token[-1],
|
|
87
|
-
*token[0..-2]), ref)
|
|
88
|
-
else
|
|
89
|
-
return massage(
|
|
90
|
-
config_get_handle_structured(token,
|
|
91
|
-
show(ref.config_get, :structured)),
|
|
92
|
-
ref)
|
|
93
|
-
end
|
|
59
|
+
get_args = ref.getter(*args)
|
|
60
|
+
massage(get(command: ref.get_command,
|
|
61
|
+
data_format: get_args[:data_format],
|
|
62
|
+
context: get_args[:context],
|
|
63
|
+
value: get_args[:value]),
|
|
64
|
+
ref)
|
|
94
65
|
end
|
|
95
66
|
|
|
96
67
|
# Attempt to massage the given value into the format specified by the
|
|
97
68
|
# given CmdRef object.
|
|
98
69
|
def massage(value, ref)
|
|
99
|
-
|
|
70
|
+
Cisco::Logger.debug "Massaging '#{value}' (#{value.inspect})"
|
|
100
71
|
if value.is_a?(Array) && !ref.multiple
|
|
101
72
|
fail "Expected zero/one value but got '#{value}'" if value.length > 1
|
|
102
73
|
value = value[0]
|
|
103
74
|
end
|
|
104
75
|
if (value.nil? || value.empty?) && ref.default_value? && ref.auto_default
|
|
105
|
-
|
|
76
|
+
Cisco::Logger.debug "Default: #{ref.default_value}"
|
|
106
77
|
return ref.default_value
|
|
107
78
|
end
|
|
108
79
|
return value unless ref.kind
|
|
@@ -112,6 +83,8 @@ module Cisco
|
|
|
112
83
|
value = false
|
|
113
84
|
elsif /^no / =~ value
|
|
114
85
|
value = false
|
|
86
|
+
elsif /disable$/ =~ value
|
|
87
|
+
value = false
|
|
115
88
|
else
|
|
116
89
|
value = true
|
|
117
90
|
end
|
|
@@ -120,8 +93,10 @@ module Cisco
|
|
|
120
93
|
when :string
|
|
121
94
|
value = '' if value.nil?
|
|
122
95
|
value = value.to_s.strip
|
|
96
|
+
when :symbol
|
|
97
|
+
value = value.to_sym unless value.nil?
|
|
123
98
|
end
|
|
124
|
-
|
|
99
|
+
Cisco::Logger.debug "Massaged to '#{value}'"
|
|
125
100
|
value
|
|
126
101
|
end
|
|
127
102
|
|
|
@@ -134,10 +109,10 @@ module Cisco
|
|
|
134
109
|
# @param feature [String]
|
|
135
110
|
# @param name [String]
|
|
136
111
|
# @return [String]
|
|
112
|
+
# @return [nil] if this feature/name pair is marked as unsupported
|
|
137
113
|
# @example config_get_default("vtp", "file")
|
|
138
|
-
def config_get_default(feature,
|
|
139
|
-
|
|
140
|
-
ref = @cmd_ref.lookup(feature, name)
|
|
114
|
+
def config_get_default(feature, property)
|
|
115
|
+
ref = @cmd_ref.lookup(feature, property)
|
|
141
116
|
ref.default_value
|
|
142
117
|
end
|
|
143
118
|
|
|
@@ -146,7 +121,8 @@ module Cisco
|
|
|
146
121
|
#
|
|
147
122
|
# @raise [IndexError] if no relevant cmd_ref config_set exists
|
|
148
123
|
# @raise [ArgumentError] if too many or too few args are provided.
|
|
149
|
-
# @raise [Cisco::
|
|
124
|
+
# @raise [Cisco::UnsupportedError] if this feature/name is unsupported
|
|
125
|
+
# @raise [Cisco::RequestFailed] if any command is rejected by the device.
|
|
150
126
|
#
|
|
151
127
|
# @param feature [String]
|
|
152
128
|
# @param name [String]
|
|
@@ -155,10 +131,10 @@ module Cisco
|
|
|
155
131
|
# @example config_set("ospf", "router_id",
|
|
156
132
|
# {:name => "green", :vrf => "one", :state => "",
|
|
157
133
|
# :router_id => "192.0.0.1"})
|
|
158
|
-
def config_set(feature,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
134
|
+
def config_set(feature, property, *args)
|
|
135
|
+
ref = @cmd_ref.lookup(feature, property)
|
|
136
|
+
set_args = ref.setter(*args)
|
|
137
|
+
set(**set_args)
|
|
162
138
|
end
|
|
163
139
|
|
|
164
140
|
# Clear the cache of CLI output results.
|
|
@@ -175,40 +151,25 @@ module Cisco
|
|
|
175
151
|
|
|
176
152
|
attr_reader :cmd_ref, :client
|
|
177
153
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
class << self
|
|
182
|
-
attr_reader :lazy_connect
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
class << self
|
|
186
|
-
attr_writer :lazy_connect
|
|
154
|
+
def self.instance
|
|
155
|
+
@instance ||= new
|
|
187
156
|
end
|
|
188
157
|
|
|
189
158
|
def initialize
|
|
190
|
-
@client =
|
|
159
|
+
@client = Cisco::Client.create
|
|
191
160
|
@cmd_ref = nil
|
|
192
|
-
|
|
161
|
+
@cmd_ref = CommandReference.new(product: product_id,
|
|
162
|
+
platform: @client.platform,
|
|
163
|
+
data_formats: @client.data_formats)
|
|
164
|
+
cache_flush
|
|
193
165
|
end
|
|
194
166
|
|
|
195
167
|
def to_s
|
|
196
|
-
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
# "hidden" API - used for UT but shouldn't be used elsewhere
|
|
200
|
-
def connect(*args)
|
|
201
|
-
@client = CiscoNxapi::NxapiClient.new(*args)
|
|
202
|
-
# Hard-code platform and cli for now
|
|
203
|
-
@cmd_ref = CommandReference.new(product: product_id,
|
|
204
|
-
platform: :nexus,
|
|
205
|
-
cli: true)
|
|
206
|
-
cache_flush
|
|
168
|
+
client.to_s
|
|
207
169
|
end
|
|
208
170
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
@client.reload
|
|
171
|
+
def inspect
|
|
172
|
+
"Node: client:'#{client.inspect}' cmd_ref:'#{cmd_ref.inspect}'"
|
|
212
173
|
end
|
|
213
174
|
|
|
214
175
|
def cache_enable?
|
|
@@ -227,54 +188,22 @@ module Cisco
|
|
|
227
188
|
@client.cache_auto = enable
|
|
228
189
|
end
|
|
229
190
|
|
|
230
|
-
# Helper method for config_get().
|
|
231
|
-
# @param token [Array, Hash] lookup sequence
|
|
232
|
-
# @param result [Array, Hash] structured output from node
|
|
233
|
-
def config_get_handle_structured(token, result)
|
|
234
|
-
token.each do |t|
|
|
235
|
-
# if token is a hash and result is an array, check each
|
|
236
|
-
# array index (which should return another hash) to see if
|
|
237
|
-
# it contains the matching key/value pairs specified in token,
|
|
238
|
-
# and return the first match (or nil)
|
|
239
|
-
if t.kind_of?(Hash)
|
|
240
|
-
fail "Expected array, got #{result.class}" unless result.is_a? Array
|
|
241
|
-
result = result.select { |x| t.all? { |k, v| x[k] == v } }
|
|
242
|
-
fail "Multiple matches found for #{t}" if result.length > 1
|
|
243
|
-
fail "No match found for #{t}" if result.length == 0
|
|
244
|
-
result = result[0]
|
|
245
|
-
else # result is array or hash
|
|
246
|
-
fail "No key \"#{t}\" in #{result}" if result[t].nil?
|
|
247
|
-
result = result[t]
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
result
|
|
251
|
-
rescue RuntimeError
|
|
252
|
-
# TODO: logging user story, Syslog isn't available here
|
|
253
|
-
# Syslog.debug(e.message)
|
|
254
|
-
nil
|
|
255
|
-
end
|
|
256
|
-
|
|
257
191
|
# Send a config command to the device.
|
|
258
192
|
# In general, clients should use config_set() rather than calling
|
|
259
193
|
# this function directly.
|
|
260
194
|
#
|
|
261
|
-
# @raise [Cisco::
|
|
262
|
-
def
|
|
263
|
-
|
|
264
|
-
@client.config(commands)
|
|
265
|
-
rescue CiscoNxapi::CliError => e
|
|
266
|
-
raise Cisco::CliError.new(e.input, e.clierror, e.previous)
|
|
195
|
+
# @raise [Cisco::RequestFailed] if any command is rejected by the device.
|
|
196
|
+
def set(**kwargs)
|
|
197
|
+
@client.set(**kwargs)
|
|
267
198
|
end
|
|
268
199
|
|
|
269
200
|
# Send a show command to the device.
|
|
270
201
|
# In general, clients should use config_get() rather than calling
|
|
271
202
|
# this function directly.
|
|
272
203
|
#
|
|
273
|
-
# @raise [Cisco::
|
|
274
|
-
def
|
|
275
|
-
@client.
|
|
276
|
-
rescue CiscoNxapi::CliError => e
|
|
277
|
-
raise Cisco::CliError.new(e.input, e.clierror, e.previous)
|
|
204
|
+
# @raise [Cisco::RequestFailed] if any command is rejected by the device.
|
|
205
|
+
def get(**kwargs)
|
|
206
|
+
@client.get(**kwargs)
|
|
278
207
|
end
|
|
279
208
|
|
|
280
209
|
# @return [String] such as "Cisco Nexus Operating System (NX-OS) Software"
|
|
@@ -300,8 +229,16 @@ module Cisco
|
|
|
300
229
|
return config_get('inventory', 'productid')
|
|
301
230
|
else
|
|
302
231
|
# We use this function to *find* the appropriate CommandReference
|
|
303
|
-
|
|
304
|
-
|
|
232
|
+
if @client.platform == :nexus
|
|
233
|
+
entries = get(command: 'show inventory',
|
|
234
|
+
data_format: :nxapi_structured)
|
|
235
|
+
return entries['TABLE_inv']['ROW_inv'][0]['productid']
|
|
236
|
+
elsif @client.platform == :ios_xr
|
|
237
|
+
# No support for structured output for this command yet
|
|
238
|
+
output = get(command: 'show inventory',
|
|
239
|
+
data_format: :cli)
|
|
240
|
+
return /NAME: "Rack 0".*\nPID: (\S+)/.match(output)[1]
|
|
241
|
+
end
|
|
305
242
|
end
|
|
306
243
|
end
|
|
307
244
|
|
|
@@ -349,7 +286,7 @@ module Cisco
|
|
|
349
286
|
# @return [Float] combined user/kernel CPU utilization
|
|
350
287
|
def system_cpu_utilization
|
|
351
288
|
output = config_get('system', 'resources')
|
|
352
|
-
|
|
289
|
+
return output if output.nil?
|
|
353
290
|
output['cpu_state_user'].to_f + output['cpu_state_kernel'].to_f
|
|
354
291
|
end
|
|
355
292
|
|
|
@@ -365,71 +302,4 @@ module Cisco
|
|
|
365
302
|
config_get('show_version', 'system_image')
|
|
366
303
|
end
|
|
367
304
|
end
|
|
368
|
-
|
|
369
|
-
# Method for working with hierarchical show command output such as
|
|
370
|
-
# "show running-config". Searches the given multi-line string
|
|
371
|
-
# for all matches to the given regex_query. If parents is provided,
|
|
372
|
-
# the matches will be filtered to only those that are located "under"
|
|
373
|
-
# the given parent sequence (as determined by indentation).
|
|
374
|
-
#
|
|
375
|
-
# @param body [String] The body of text to search
|
|
376
|
-
# @param regex_query [Regex] The regular expression to match
|
|
377
|
-
# @param parents [*Regex] zero or more regular expressions defining
|
|
378
|
-
# the parent configs to filter by.
|
|
379
|
-
# @return [[String], nil] array of matching (sub)strings, else nil.
|
|
380
|
-
#
|
|
381
|
-
# @example Find all OSPF router names in the running-config
|
|
382
|
-
# ospf_names = find_ascii(running_cfg, /^router ospf (\d+)/)
|
|
383
|
-
#
|
|
384
|
-
# @example Find all address-family types under the given BGP router
|
|
385
|
-
# bgp_afs = find_ascii(show_run_bgp, /^address-family (.*)/,
|
|
386
|
-
# /^router bgp #{ASN}/)
|
|
387
|
-
def find_ascii(body, regex_query, *parent_cfg)
|
|
388
|
-
return nil if body.nil? || regex_query.nil?
|
|
389
|
-
|
|
390
|
-
# get subconfig
|
|
391
|
-
parent_cfg.each { |p| body = find_subconfig(body, p) }
|
|
392
|
-
if body.nil? || body.empty?
|
|
393
|
-
return nil
|
|
394
|
-
else
|
|
395
|
-
# find matches and return as array of String if it only does one
|
|
396
|
-
# match in the regex. Otherwise return array of array
|
|
397
|
-
match = body.split("\n").map { |s| s.scan(regex_query) }
|
|
398
|
-
match = match.flatten(1)
|
|
399
|
-
return nil if match.empty?
|
|
400
|
-
match = match.flatten if match[0].is_a?(Array) && match[0].length == 1
|
|
401
|
-
return match
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
module_function :find_ascii
|
|
405
|
-
|
|
406
|
-
# Returns the subsection associated with the given
|
|
407
|
-
# line of config
|
|
408
|
-
# @param [String] the body of text to search
|
|
409
|
-
# @param [Regex] the regex key of the config for which
|
|
410
|
-
# to retrieve the subsection
|
|
411
|
-
# @return [String, nil] the subsection of body, de-indented
|
|
412
|
-
# appropriately, or nil if no such subsection exists.
|
|
413
|
-
def find_subconfig(body, regex_query)
|
|
414
|
-
return nil if body.nil? || regex_query.nil?
|
|
415
|
-
|
|
416
|
-
rows = body.split("\n")
|
|
417
|
-
match_row_index = rows.index { |row| regex_query =~ row }
|
|
418
|
-
return nil if match_row_index.nil?
|
|
419
|
-
|
|
420
|
-
cur = match_row_index + 1
|
|
421
|
-
subconfig = []
|
|
422
|
-
|
|
423
|
-
until (/\A\s+.*/ =~ rows[cur]).nil? || cur == rows.length
|
|
424
|
-
subconfig << rows[cur]
|
|
425
|
-
cur += 1
|
|
426
|
-
end
|
|
427
|
-
return nil if subconfig.empty?
|
|
428
|
-
# Strip an appropriate minimal amount of leading whitespace from
|
|
429
|
-
# all lines in the subconfig
|
|
430
|
-
min_leading = subconfig.map { |line| line[/\A */].size }.min
|
|
431
|
-
subconfig = subconfig.map { |line| line[min_leading..-1] }
|
|
432
|
-
subconfig.join("\n")
|
|
433
|
-
end
|
|
434
|
-
module_function :find_subconfig
|
|
435
305
|
end
|