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,206 @@
|
|
|
1
|
+
# NXAPI implementation of BridgeDomainVNI class
|
|
2
|
+
#
|
|
3
|
+
# February 2016, Rohan Gandhi Korlepara
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require_relative 'node_util'
|
|
20
|
+
require_relative 'feature'
|
|
21
|
+
|
|
22
|
+
module Cisco
|
|
23
|
+
# node_utils class for bridge_domain_vni
|
|
24
|
+
class BridgeDomainVNI < NodeUtil
|
|
25
|
+
attr_reader :bd_ids, :bd_ids_list
|
|
26
|
+
|
|
27
|
+
def initialize(bds, instantiate=true)
|
|
28
|
+
# Spaces are removed as bridge-domain cli doesn't accept value with
|
|
29
|
+
# space
|
|
30
|
+
@bd_ids = bds.to_s.gsub(/\s+/, '')
|
|
31
|
+
fail 'bridge-domain value is empty' if @bd_ids.empty? # no empty strings
|
|
32
|
+
|
|
33
|
+
@bd_ids_list = BridgeDomainVNI.string_to_array(@bd_ids)
|
|
34
|
+
create if instantiate
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
"Bridge Domain #{bd_ids}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.range_bds
|
|
42
|
+
hash = {}
|
|
43
|
+
bd_list = config_get('bridge_domain_vni', 'range_bds')
|
|
44
|
+
return hash if bd_list.nil?
|
|
45
|
+
|
|
46
|
+
bd_list.each do |id|
|
|
47
|
+
hash[id] = BridgeDomainVNI.new(id, false)
|
|
48
|
+
end
|
|
49
|
+
hash
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# This will expand the string to a list of bds as integers
|
|
53
|
+
def self.string_to_array(string)
|
|
54
|
+
list = []
|
|
55
|
+
narray = string.split(',')
|
|
56
|
+
narray.each do |elem|
|
|
57
|
+
if elem.include?('-')
|
|
58
|
+
es = elem.gsub('-', '..')
|
|
59
|
+
ea = es.split('..').map { |d| Integer(d) }
|
|
60
|
+
er = ea[0]..ea[1]
|
|
61
|
+
list << er.to_a
|
|
62
|
+
else
|
|
63
|
+
list << elem.to_i
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
list.flatten
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Example clis;
|
|
70
|
+
# system bridge-domain 101-200
|
|
71
|
+
# bridge-domain 101-200
|
|
72
|
+
# bridge-domain 101-110,120,141-145,180
|
|
73
|
+
# member vni 6001-6011,5041-5044,8000,9000
|
|
74
|
+
#
|
|
75
|
+
# config_get('bridge_domain_vni', 'member_vni')
|
|
76
|
+
# will get the current member vni in this case
|
|
77
|
+
# 6001-6011,5041-5044,8000,9000
|
|
78
|
+
#
|
|
79
|
+
# config_get('bridge_domain_vni', 'member_vni_bd')
|
|
80
|
+
# will get the current bd's mapped to member vni in this case
|
|
81
|
+
# 101-110,120,141-145,180
|
|
82
|
+
#
|
|
83
|
+
# The @bd_ids_list which is created when the BridgeDomainVNI object is
|
|
84
|
+
# initialized which could be 101-110 bd range.
|
|
85
|
+
# hash_map will have 101=>6001,102=>6002...120=>6011,141=>5041...180=>9000
|
|
86
|
+
# And the final_bd_vni hash will be based of the initialized list
|
|
87
|
+
# 101=>6001,102=>6002,103=>6003....110=>6010 only.
|
|
88
|
+
def curr_bd_vni_hash
|
|
89
|
+
final_bd_vni = {}
|
|
90
|
+
curr_vni = config_get('bridge_domain_vni', 'member_vni')
|
|
91
|
+
curr_bd_vni = config_get('bridge_domain_vni', 'member_vni_bd')
|
|
92
|
+
return final_bd_vni if curr_vni.empty? || curr_bd_vni.empty?
|
|
93
|
+
|
|
94
|
+
curr_vni_list = BridgeDomainVNI.string_to_array(curr_vni)
|
|
95
|
+
curr_bd_vni_list = BridgeDomainVNI.string_to_array(curr_bd_vni)
|
|
96
|
+
|
|
97
|
+
hash_map = Hash[curr_bd_vni_list.zip(curr_vni_list.map)]
|
|
98
|
+
@bd_ids_list.each do |bd|
|
|
99
|
+
final_bd_vni[bd.to_i] = hash_map[bd.to_i] if hash_map.key?(bd.to_i)
|
|
100
|
+
end
|
|
101
|
+
final_bd_vni
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# This function will first add bds to the system bridge-domain and then
|
|
105
|
+
# create the bds. If bds already existing then just create. Else add the
|
|
106
|
+
# non added bds to system range first then create all. This is to avoid the
|
|
107
|
+
# idempotency issue as system add command throws error if a bd is already
|
|
108
|
+
# present in the system range.
|
|
109
|
+
def create
|
|
110
|
+
sys_bds_array = BridgeDomainVNI.string_to_array(system_bridge_domain)
|
|
111
|
+
if (@bd_ids_list - sys_bds_array).any?
|
|
112
|
+
add_bds = Utils
|
|
113
|
+
.array_to_str((@bd_ids_list - sys_bds_array), false)
|
|
114
|
+
config_set('bridge_domain_vni', 'system_bridge_domain', oper: 'add',
|
|
115
|
+
bd: add_bds)
|
|
116
|
+
end
|
|
117
|
+
config_set('bridge_domain_vni', 'create', bd: @bd_ids)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def destroy
|
|
121
|
+
bd_vni = curr_bd_vni_hash
|
|
122
|
+
bd_val = bd_vni.keys.join(',')
|
|
123
|
+
vni_val = bd_vni.values.join(',')
|
|
124
|
+
return '' if vni_val.empty?
|
|
125
|
+
config_set('bridge_domain_vni', 'member_vni', bd: bd_val,
|
|
126
|
+
membstate: 'no', membvni: vni_val)
|
|
127
|
+
config_set('bridge_domain_vni', 'vni', state: 'no', vni: vni_val)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
########################################################
|
|
131
|
+
# PROPERTIES #
|
|
132
|
+
########################################################
|
|
133
|
+
|
|
134
|
+
# Bridge-Domain member vni assigning case
|
|
135
|
+
# Not all the bds created or initialized in this class context can have the
|
|
136
|
+
# member vni's mapped. So will get the vnis of the ones which are mapped to
|
|
137
|
+
# the bds.
|
|
138
|
+
# Eg: Suppose the bd mapping is as below on the switch
|
|
139
|
+
# bridge-domain 100,105,107-109,150
|
|
140
|
+
# member vni 5000, 8000, 5007-5008, 7000, 5050
|
|
141
|
+
# If puppet layer tries to get values of 100,105,107 bds as defined in
|
|
142
|
+
# manifest then the final_bd_vni map which is returned will contain only
|
|
143
|
+
# these mappings as below;
|
|
144
|
+
# '5000,8000,5007'
|
|
145
|
+
# This is also to handle the idempotence case, and if any mismatch then set
|
|
146
|
+
# the member_vni
|
|
147
|
+
def member_vni
|
|
148
|
+
bd_vni_hash = curr_bd_vni_hash
|
|
149
|
+
ret_list = []
|
|
150
|
+
@bd_ids_list.each do |bd|
|
|
151
|
+
ret_list << bd_vni_hash[bd]
|
|
152
|
+
end
|
|
153
|
+
Utils.array_to_str(ret_list, false)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# This member_vni mapping will be executed only when the val is not empty
|
|
157
|
+
# else it will be treated as a 'no' cli and executed as required.
|
|
158
|
+
# If the mappings do not match in any fashion then cli normally returns a
|
|
159
|
+
# failure which will be handled.
|
|
160
|
+
# During set of member vni we first see if any bd is mapped to some other
|
|
161
|
+
# vni, if yes then remove that one and apply the new vni.
|
|
162
|
+
# Eg: bridge-domain 100-110
|
|
163
|
+
# member vni 5100-5110
|
|
164
|
+
# Now the manifest is changed to 5100-5105,6106-6110, so hence first
|
|
165
|
+
# 5106-5110 mapping is removed and then 6106-6110 is applied.
|
|
166
|
+
def member_vni=(val)
|
|
167
|
+
val = val.to_s
|
|
168
|
+
Feature.vni_enable
|
|
169
|
+
bd_vni = curr_bd_vni_hash
|
|
170
|
+
if val.empty?
|
|
171
|
+
bd_val = bd_vni.keys.join(',')
|
|
172
|
+
vni_val = bd_vni.values.join(',')
|
|
173
|
+
return '' if vni_val.empty?
|
|
174
|
+
config_set('bridge_domain_vni', 'member_vni', bd: bd_val,
|
|
175
|
+
membstate: 'no', membvni: vni_val)
|
|
176
|
+
config_set('bridge_domain_vni', 'vni', state: 'no', vni: vni_val)
|
|
177
|
+
else
|
|
178
|
+
unless bd_vni.empty?
|
|
179
|
+
inp_vni_list = BridgeDomainVNI.string_to_array(val.to_s)
|
|
180
|
+
inp_bd_vni_hash = Hash[@bd_ids_list.zip(inp_vni_list)]
|
|
181
|
+
|
|
182
|
+
temp_hash = bd_vni.to_a.keep_if { |k, _v| inp_bd_vni_hash.key? k }
|
|
183
|
+
rem_hash = (temp_hash.to_a - inp_bd_vni_hash.to_a).to_h
|
|
184
|
+
|
|
185
|
+
rm_bd = rem_hash.keys.join(',')
|
|
186
|
+
rm_vni = rem_hash.values.join(',')
|
|
187
|
+
config_set('bridge_domain_vni', 'member_vni', bd: rm_bd,
|
|
188
|
+
membstate: 'no', membvni: rm_vni)
|
|
189
|
+
config_set('bridge_domain_vni', 'vni', state: 'no', vni: rm_vni)
|
|
190
|
+
end
|
|
191
|
+
config_set('bridge_domain_vni', 'vni', state: '', vni: val)
|
|
192
|
+
config_set('bridge_domain_vni', 'member_vni', bd: @bd_ids,
|
|
193
|
+
membstate: '', membvni: val)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def default_member_vni
|
|
198
|
+
config_get_default('bridge_domain_vni', 'member_vni')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# getter for system bridge-domain
|
|
202
|
+
def system_bridge_domain
|
|
203
|
+
config_get('bridge_domain_vni', 'system_bridge_domain')
|
|
204
|
+
end
|
|
205
|
+
end # Class
|
|
206
|
+
end # Module
|
|
@@ -24,11 +24,11 @@ module Cisco
|
|
|
24
24
|
# password encryption types
|
|
25
25
|
def self.cli_to_symbol(cli)
|
|
26
26
|
case cli
|
|
27
|
-
when '0', 0
|
|
27
|
+
when '0', 0, 'clear'
|
|
28
28
|
:cleartext
|
|
29
29
|
when '3', 3
|
|
30
30
|
:"3des" # yuck :-(
|
|
31
|
-
when '5', 5
|
|
31
|
+
when '5', 5, 'encrypted'
|
|
32
32
|
:md5
|
|
33
33
|
when '6', 6
|
|
34
34
|
:aes
|
|
@@ -96,6 +96,13 @@ module Cisco
|
|
|
96
96
|
# General utility class
|
|
97
97
|
class Utils
|
|
98
98
|
require 'ipaddr'
|
|
99
|
+
|
|
100
|
+
# Helper utility to check for older Nexus I2 images
|
|
101
|
+
def self.nexus_i2_image
|
|
102
|
+
require_relative 'platform'
|
|
103
|
+
true if Platform.image_version[/7.0.3.I2/]
|
|
104
|
+
end
|
|
105
|
+
|
|
99
106
|
# Helper utility method for ip/prefix format networks.
|
|
100
107
|
# For ip/prefix format '1.1.1.1/24' or '2000:123:38::34/64',
|
|
101
108
|
# we need to mask the address using the prefix length so that they
|
|
@@ -117,6 +124,9 @@ module Cisco
|
|
|
117
124
|
end
|
|
118
125
|
|
|
119
126
|
def self.delta_add_remove(should, current=[], opt=nil)
|
|
127
|
+
current = [] if current.nil?
|
|
128
|
+
should = [] if should.nil?
|
|
129
|
+
|
|
120
130
|
# Remove nil entries from array
|
|
121
131
|
should.each(&:compact!) if depth(should) > 1
|
|
122
132
|
delta = { add: should - current, remove: current - should }
|
|
@@ -126,6 +136,8 @@ module Cisco
|
|
|
126
136
|
|
|
127
137
|
# Delete entries from :remove if f1 is an update to an existing command
|
|
128
138
|
delta[:add].each do |id, _|
|
|
139
|
+
# Differentiate between comparing nested and unnested arrays by
|
|
140
|
+
# checking the depth of the array.
|
|
129
141
|
if depth(should) == 1
|
|
130
142
|
delta[:remove].delete_if { |f1| [f1] if f1.to_s == id.to_s }
|
|
131
143
|
else
|
|
@@ -135,11 +147,82 @@ module Cisco
|
|
|
135
147
|
delta
|
|
136
148
|
end # delta_add_remove
|
|
137
149
|
|
|
150
|
+
def self.length_to_bitmask(length)
|
|
151
|
+
IPAddr.new('255.255.255.255').mask(length).to_s
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def self.bitmask_to_length(bitmask)
|
|
155
|
+
# Convert bitmask to a 32-bit integer,
|
|
156
|
+
# convert that to binary, and count the 1s
|
|
157
|
+
IPAddr.new(bitmask).to_i.to_s(2).count('1')
|
|
158
|
+
rescue IPAddr::InvalidAddressError => e
|
|
159
|
+
raise ArgumentError, "bitmask '#{bitmask}' is not valid: #{e}"
|
|
160
|
+
end
|
|
161
|
+
|
|
138
162
|
# Helper to 0-pad a mac address.
|
|
139
163
|
def self.zero_pad_macaddr(mac)
|
|
140
164
|
return nil if mac.nil? || mac.empty?
|
|
141
165
|
o1, o2, o3 = mac.split('.').map { |o| o.to_i(16).to_s(10) }
|
|
142
166
|
sprintf('%04x.%04x.%04x', o1, o2, o3)
|
|
143
167
|
end
|
|
168
|
+
|
|
169
|
+
# For spanning tree range based parameters, the range
|
|
170
|
+
# is very dynamic and so before the parameters are set,
|
|
171
|
+
# the rest of the range needs to be reset
|
|
172
|
+
# For ex: if the ranges 2-42 and 83-200 are getting set,
|
|
173
|
+
# and the total range of the given parameter is 1-4000
|
|
174
|
+
# then 1,43-82,201-4000 needs to be reset. This method
|
|
175
|
+
# takes the set ranges and gives back the range to be reset
|
|
176
|
+
def self.get_reset_range(total_range, remove_ranges)
|
|
177
|
+
fail 'invalid range' unless total_range.include?('-')
|
|
178
|
+
return total_range if remove_ranges.empty?
|
|
179
|
+
|
|
180
|
+
trs = total_range.gsub('-', '..')
|
|
181
|
+
tra = trs.split('..').map { |d| Integer(d) }
|
|
182
|
+
tr = tra[0]..tra[1]
|
|
183
|
+
tarray = tr.to_a
|
|
184
|
+
remove_ranges.each do |rr, _val|
|
|
185
|
+
rarray = rr.gsub('-', '..').split(',')
|
|
186
|
+
rarray.each do |elem|
|
|
187
|
+
if elem.include?('..')
|
|
188
|
+
elema = elem.split('..').map { |d| Integer(d) }
|
|
189
|
+
ele = elema[0]..elema[1]
|
|
190
|
+
tarray -= ele.to_a
|
|
191
|
+
else
|
|
192
|
+
tarray.delete(elem.to_i)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
Utils.array_to_str(tarray)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# This method converts an array to string form
|
|
200
|
+
# for ex: if the array has 1, 2 to 10, 83 to 2014, 3022
|
|
201
|
+
# and the string will be "1,2-10,83-2014,3022"
|
|
202
|
+
def self.array_to_str(array, sort=true)
|
|
203
|
+
farray = sort ? array.compact.uniq.sort : array.compact
|
|
204
|
+
lranges = []
|
|
205
|
+
unless farray.empty?
|
|
206
|
+
l = array.first
|
|
207
|
+
r = nil
|
|
208
|
+
farray.each do |aelem|
|
|
209
|
+
if r && aelem != r.succ
|
|
210
|
+
if l == r
|
|
211
|
+
lranges << l
|
|
212
|
+
else
|
|
213
|
+
lranges << Range.new(l, r)
|
|
214
|
+
end
|
|
215
|
+
l = aelem
|
|
216
|
+
end
|
|
217
|
+
r = aelem
|
|
218
|
+
end
|
|
219
|
+
if l == r
|
|
220
|
+
lranges << l
|
|
221
|
+
else
|
|
222
|
+
lranges << Range.new(l, r)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
lranges.to_s.gsub('..', '-').delete('[').delete(']').delete(' ')
|
|
226
|
+
end
|
|
144
227
|
end # class Utils
|
|
145
228
|
end # module Cisco
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Copyright (c) 2015 Cisco and/or its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# Namespace for Cisco-specific code
|
|
16
|
+
module Cisco
|
|
17
|
+
# Namespace for Cisco Client shim
|
|
18
|
+
class Client
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require_relative 'client/client'
|
|
23
|
+
|
|
24
|
+
# Try to load known extensions
|
|
25
|
+
extensions = ['client/nxapi',
|
|
26
|
+
'client/grpc',
|
|
27
|
+
]
|
|
28
|
+
extensions.each do |ext|
|
|
29
|
+
begin
|
|
30
|
+
require_relative ext
|
|
31
|
+
rescue LoadError => e
|
|
32
|
+
# ignore missing client-(grpc|nxapi), they're not always required
|
|
33
|
+
raise unless e.message =~ /#{Regexp.escape(ext)}/
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# October 2015, Glenn F. Matthews
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require_relative '../environment'
|
|
20
|
+
require_relative '../exceptions'
|
|
21
|
+
require_relative 'utils'
|
|
22
|
+
require_relative '../constants'
|
|
23
|
+
require_relative '../logger'
|
|
24
|
+
|
|
25
|
+
include Cisco::Logger
|
|
26
|
+
|
|
27
|
+
# Base class for clients of various RPC formats
|
|
28
|
+
class Cisco::Client
|
|
29
|
+
@@clients = [] # rubocop:disable Style/ClassVars
|
|
30
|
+
|
|
31
|
+
def self.clients
|
|
32
|
+
@@clients
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Each subclass should call this method to register itself.
|
|
36
|
+
def self.register_client(client)
|
|
37
|
+
@@clients << client
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
attr_reader :data_formats, :platform
|
|
41
|
+
|
|
42
|
+
def initialize(data_formats: [],
|
|
43
|
+
platform: nil,
|
|
44
|
+
**kwargs)
|
|
45
|
+
if self.class == Cisco::Client
|
|
46
|
+
fail NotImplementedError, 'Cisco::Client is an abstract class. ' \
|
|
47
|
+
"Instantiate one of #{@@clients} or use Cisco::Client.create() instead"
|
|
48
|
+
end
|
|
49
|
+
self.class.validate_args(**kwargs)
|
|
50
|
+
@host = kwargs[:host]
|
|
51
|
+
@port = kwargs[:port]
|
|
52
|
+
@address = @port.nil? ? @host : "#{@host}:#{@port}"
|
|
53
|
+
@username = kwargs[:username]
|
|
54
|
+
@password = kwargs[:password]
|
|
55
|
+
self.data_formats = data_formats
|
|
56
|
+
self.platform = platform
|
|
57
|
+
@cache_enable = true
|
|
58
|
+
@cache_auto = true
|
|
59
|
+
cache_flush
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.validate_args(**kwargs)
|
|
63
|
+
host = kwargs[:host]
|
|
64
|
+
unless host.nil?
|
|
65
|
+
fail TypeError, 'invalid address' unless host.is_a?(String)
|
|
66
|
+
fail ArgumentError, 'empty address' if host.empty?
|
|
67
|
+
end
|
|
68
|
+
username = kwargs[:username]
|
|
69
|
+
unless username.nil?
|
|
70
|
+
fail TypeError, 'invalid username' unless username.is_a?(String)
|
|
71
|
+
fail ArgumentError, 'empty username' if username.empty?
|
|
72
|
+
end
|
|
73
|
+
password = kwargs[:password]
|
|
74
|
+
unless password.nil?
|
|
75
|
+
fail TypeError, 'invalid password' unless password.is_a?(String)
|
|
76
|
+
fail ArgumentError, 'empty password' if password.empty?
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def supports?(data_format)
|
|
81
|
+
data_formats.include?(data_format)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Try to create an instance of an appropriate subclass
|
|
85
|
+
def self.create(environment_name=nil)
|
|
86
|
+
fail 'No client implementations available!' if clients.empty?
|
|
87
|
+
debug "Trying to establish client connection. clients = #{clients}"
|
|
88
|
+
environment = Cisco::Environment.environment(environment_name)
|
|
89
|
+
host = environment[:host]
|
|
90
|
+
errors = []
|
|
91
|
+
clients.each do |client_class|
|
|
92
|
+
begin
|
|
93
|
+
debug "Trying to connect to #{host} as #{client_class}"
|
|
94
|
+
client = client_class.new(**environment)
|
|
95
|
+
debug "#{client_class} connected successfully"
|
|
96
|
+
return client
|
|
97
|
+
rescue Cisco::ClientError, TypeError, ArgumentError => e
|
|
98
|
+
debug "Unable to connect to #{host} as #{client_class}: #{e.message}"
|
|
99
|
+
debug e.backtrace.join("\n ")
|
|
100
|
+
errors << e
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
handle_errors(errors)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def self.handle_errors(errors)
|
|
107
|
+
# ClientError means we tried to connect but failed,
|
|
108
|
+
# so it's 'more significant' than input validation errors.
|
|
109
|
+
client_errors = errors.select { |e| e.kind_of? Cisco::ClientError }
|
|
110
|
+
if !client_errors.empty?
|
|
111
|
+
# Reraise the specific error if just one
|
|
112
|
+
fail client_errors[0] if client_errors.length == 1
|
|
113
|
+
# Otherwise clump them together into a new error
|
|
114
|
+
e_cls = client_errors[0].class
|
|
115
|
+
unless client_errors.all? { |e| e.class == e_cls }
|
|
116
|
+
e_cls = Cisco::ClientError
|
|
117
|
+
end
|
|
118
|
+
fail e_cls, ("Unable to establish any client connection:\n" +
|
|
119
|
+
errors.each(&:message).join("\n"))
|
|
120
|
+
elsif errors.any? { |e| e.kind_of? ArgumentError }
|
|
121
|
+
fail ArgumentError, ("Invalid arguments:\n" +
|
|
122
|
+
errors.each(&:message).join("\n"))
|
|
123
|
+
elsif errors.any? { |e| e.kind_of? TypeError }
|
|
124
|
+
fail TypeError, ("Invalid arguments:\n" +
|
|
125
|
+
errors.each(&:message).join("\n"))
|
|
126
|
+
end
|
|
127
|
+
fail Cisco::ClientError, 'No client connected, but no errors were reported?'
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def to_s
|
|
131
|
+
@address.to_s
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def inspect
|
|
135
|
+
"<#{self.class} of #{@address}>"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def cache_enable?
|
|
139
|
+
@cache_enable
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def cache_enable=(enable)
|
|
143
|
+
@cache_enable = enable
|
|
144
|
+
cache_flush unless enable
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def cache_auto?
|
|
148
|
+
@cache_auto
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
attr_writer :cache_auto
|
|
152
|
+
|
|
153
|
+
# Clear the cache of CLI output results.
|
|
154
|
+
#
|
|
155
|
+
# If cache_auto is true (default) then this will be performed automatically
|
|
156
|
+
# whenever a set() is called, but providers may also call this
|
|
157
|
+
# to explicitly force the cache to be cleared.
|
|
158
|
+
def cache_flush
|
|
159
|
+
# to be implemented by subclasses
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Configure the given state on the device.
|
|
163
|
+
#
|
|
164
|
+
# @raise [RequestNotSupported] if this client doesn't support the given
|
|
165
|
+
# data_format
|
|
166
|
+
#
|
|
167
|
+
# @param data_format one of Cisco::DATA_FORMATS. Default is :cli
|
|
168
|
+
# @param context [String, Array<String>] Context for the configuration
|
|
169
|
+
# @param values [String, Array<String>] Actual configuration to set
|
|
170
|
+
def set(data_format: :cli,
|
|
171
|
+
context: nil,
|
|
172
|
+
values: nil)
|
|
173
|
+
# subclasses will generally want to call Client.munge_to_array()
|
|
174
|
+
# on context and/or values before calling super()
|
|
175
|
+
fail Cisco::RequestNotSupported unless self.supports?(data_format)
|
|
176
|
+
cache_flush if cache_auto?
|
|
177
|
+
Cisco::Logger.debug("Set state using data format '#{data_format}'")
|
|
178
|
+
Cisco::Logger.debug(" with context:\n #{context.join("\n ")}") \
|
|
179
|
+
unless context.nil? || context.empty?
|
|
180
|
+
Cisco::Logger.debug(" to value(s):\n #{values.join("\n ")}") \
|
|
181
|
+
unless values.nil? || values.empty?
|
|
182
|
+
# to be implemented by subclasses
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Get the given state from the device.
|
|
186
|
+
#
|
|
187
|
+
# Unlike set() this will not clear the CLI cache;
|
|
188
|
+
# multiple calls with the same parameters may return cached data
|
|
189
|
+
# rather than querying the device repeatedly.
|
|
190
|
+
#
|
|
191
|
+
# @raise [RequestNotSupported] if the client doesn't support the data_format
|
|
192
|
+
# @raise [RequestFailed] if the command is rejected by the device
|
|
193
|
+
#
|
|
194
|
+
# @param data_format one of Cisco::DATA_FORMATS. Default is :cli
|
|
195
|
+
# @param command [String] the get command to execute
|
|
196
|
+
# @param context [String, Array<String>] Context to refine/filter the results
|
|
197
|
+
# @param value [String, Regexp] Specific key or regexp to look up
|
|
198
|
+
# @return [String, Hash, nil] The state found, or nil if not found.
|
|
199
|
+
def get(data_format: :cli,
|
|
200
|
+
command: nil,
|
|
201
|
+
context: nil,
|
|
202
|
+
value: nil)
|
|
203
|
+
# subclasses will generally want to call Client.munge_to_array()
|
|
204
|
+
# on context and/or value before calling super()
|
|
205
|
+
fail Cisco::RequestNotSupported unless self.supports?(data_format)
|
|
206
|
+
Cisco::Logger.debug("Get state using data format '#{data_format}'")
|
|
207
|
+
Cisco::Logger.debug(" executing command:\n #{command}") \
|
|
208
|
+
unless command.nil? || command.empty?
|
|
209
|
+
Cisco::Logger.debug(" with context:\n #{context.join("\n ")}") \
|
|
210
|
+
unless context.nil? || context.empty?
|
|
211
|
+
Cisco::Logger.debug(" to get value: #{value}") \
|
|
212
|
+
unless value.nil?
|
|
213
|
+
# to be implemented by subclasses
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
private
|
|
217
|
+
|
|
218
|
+
# Set the list of data formats supported by this client.
|
|
219
|
+
# If the client supports multiple formats, and a given feature or property
|
|
220
|
+
# can be managed by multiple formats, the list order indicates preference.
|
|
221
|
+
def data_formats=(data_formats)
|
|
222
|
+
data_formats = [data_formats] unless data_formats.is_a?(Array)
|
|
223
|
+
unknown = data_formats - Cisco::DATA_FORMATS
|
|
224
|
+
fail ArgumentError, "unknown data formats: #{unknown}" unless unknown.empty?
|
|
225
|
+
@data_formats = data_formats
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Set the platform of the node managed by this client.
|
|
229
|
+
def platform=(platform)
|
|
230
|
+
fail ArgumentError, "unknown platform #{platform}" \
|
|
231
|
+
unless Cisco::PLATFORMS.include?(platform)
|
|
232
|
+
@platform = platform
|
|
233
|
+
end
|
|
234
|
+
end
|