cisco_node_utils 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +4 -1
  6. data/CHANGELOG.md +81 -2
  7. data/CONTRIBUTING.md +2 -17
  8. data/Gemfile +5 -0
  9. data/README.md +92 -47
  10. data/Rakefile +23 -1
  11. data/bin/git/hooks/hook_lib +7 -0
  12. data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
  13. data/bin/git/hooks/pre-commit/rubocop +7 -2
  14. data/bin/git/hooks/pre-commit/validate-diffs +18 -4
  15. data/bin/git/hooks/pre-commit/validate-yaml +18 -0
  16. data/bin/git/update-hooks +64 -6
  17. data/cisco_node_utils.gemspec +9 -6
  18. data/docs/README-develop-best-practices.md +149 -50
  19. data/docs/README-develop-node-utils-APIs.md +92 -42
  20. data/docs/README-maintainers.md +7 -4
  21. data/docs/README-test-execution.md +57 -0
  22. data/docs/cisco_node_utils.yaml.example +30 -0
  23. data/docs/template-router.rb +4 -0
  24. data/ext/mkrf_conf.rb +63 -0
  25. data/lib/.rubocop.yml +2 -2
  26. data/lib/cisco_node_utils.rb +5 -0
  27. data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
  28. data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
  29. data/lib/cisco_node_utils/ace.rb +165 -12
  30. data/lib/cisco_node_utils/acl.rb +2 -1
  31. data/lib/cisco_node_utils/bgp.rb +184 -21
  32. data/lib/cisco_node_utils/bgp_af.rb +94 -249
  33. data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
  34. data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
  35. data/lib/cisco_node_utils/bridge_domain.rb +183 -0
  36. data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
  37. data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
  38. data/lib/cisco_node_utils/client.rb +35 -0
  39. data/lib/cisco_node_utils/client/client.rb +234 -0
  40. data/lib/cisco_node_utils/client/grpc.rb +33 -0
  41. data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
  42. data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
  43. data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
  44. data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
  45. data/lib/cisco_node_utils/client/nxapi.rb +31 -0
  46. data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
  47. data/lib/cisco_node_utils/client/utils.rb +164 -0
  48. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
  49. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
  50. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
  51. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
  52. data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
  53. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
  54. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
  55. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
  56. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
  57. data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
  58. data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
  59. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
  60. data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
  61. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
  62. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
  63. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
  64. data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
  65. data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
  66. data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
  67. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
  68. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
  69. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
  70. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
  71. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
  72. data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
  73. data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
  74. data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
  75. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
  76. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
  77. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
  78. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
  79. data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
  80. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
  81. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
  82. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
  83. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
  84. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
  85. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
  86. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
  87. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
  88. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
  89. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
  90. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
  91. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
  92. data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
  93. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
  94. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
  95. data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
  96. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
  97. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
  98. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
  99. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
  100. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
  101. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
  102. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
  103. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
  104. data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
  105. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
  106. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
  107. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
  108. data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
  109. data/lib/cisco_node_utils/command_reference.rb +261 -142
  110. data/lib/cisco_node_utils/constants.rb +33 -0
  111. data/lib/cisco_node_utils/encapsulation.rb +112 -0
  112. data/lib/cisco_node_utils/environment.rb +102 -0
  113. data/lib/cisco_node_utils/evpn_vni.rb +5 -3
  114. data/lib/cisco_node_utils/exceptions.rb +111 -0
  115. data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
  116. data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
  117. data/lib/cisco_node_utils/feature.rb +165 -3
  118. data/lib/cisco_node_utils/interface.rb +1051 -260
  119. data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
  120. data/lib/cisco_node_utils/interface_ospf.rb +1 -2
  121. data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
  122. data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
  123. data/lib/cisco_node_utils/itd_device_group.rb +248 -0
  124. data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
  125. data/lib/cisco_node_utils/itd_service.rb +523 -0
  126. data/lib/cisco_node_utils/logger.rb +75 -0
  127. data/lib/cisco_node_utils/node.rb +62 -192
  128. data/lib/cisco_node_utils/node_util.rb +56 -10
  129. data/lib/cisco_node_utils/overlay_global.rb +2 -2
  130. data/lib/cisco_node_utils/pim.rb +2 -13
  131. data/lib/cisco_node_utils/pim_group_list.rb +1 -1
  132. data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
  133. data/lib/cisco_node_utils/platform.rb +52 -21
  134. data/lib/cisco_node_utils/portchannel_global.rb +89 -19
  135. data/lib/cisco_node_utils/radius_server.rb +168 -37
  136. data/lib/cisco_node_utils/router_ospf.rb +20 -35
  137. data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
  138. data/lib/cisco_node_utils/snmpserver.rb +1 -6
  139. data/lib/cisco_node_utils/snmpuser.rb +6 -4
  140. data/lib/cisco_node_utils/stp_global.rb +676 -0
  141. data/lib/cisco_node_utils/syslog_server.rb +77 -18
  142. data/lib/cisco_node_utils/syslog_settings.rb +1 -1
  143. data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
  144. data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
  145. data/lib/cisco_node_utils/vdc.rb +12 -0
  146. data/lib/cisco_node_utils/version.rb +1 -1
  147. data/lib/cisco_node_utils/vlan.rb +147 -29
  148. data/lib/cisco_node_utils/vpc.rb +55 -3
  149. data/lib/cisco_node_utils/vrf.rb +72 -11
  150. data/lib/cisco_node_utils/vrf_af.rb +114 -29
  151. data/lib/cisco_node_utils/vtp.rb +34 -52
  152. data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
  153. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
  154. data/lib/minitest/environment_plugin.rb +31 -0
  155. data/lib/minitest/log_level_plugin.rb +41 -0
  156. data/spec/client_spec.rb +7 -0
  157. data/spec/environment_spec.rb +263 -0
  158. data/spec/grpc_client_spec.rb +23 -0
  159. data/spec/isolate/all_clients_spec.rb +9 -0
  160. data/spec/isolate/grpc_only_spec.rb +16 -0
  161. data/spec/isolate/no_clients_spec.rb +26 -0
  162. data/spec/isolate/nxapi_only_spec.rb +16 -0
  163. data/spec/nxapi_client_spec.rb +42 -0
  164. data/spec/schema.yaml +75 -0
  165. data/spec/shared_examples_for_clients.rb +14 -0
  166. data/spec/spec_helper.rb +91 -0
  167. data/spec/whitespace_spec.rb +10 -0
  168. data/spec/yaml_spec.rb +42 -0
  169. data/tests/.rubocop.yml +2 -2
  170. data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
  171. data/tests/basetest.rb +96 -36
  172. data/tests/ciscotest.rb +220 -12
  173. data/tests/cmd_config.yaml +71 -49
  174. data/tests/cmd_config_invalid.yaml +1 -1
  175. data/tests/test_aaa_authentication_login.rb +1 -0
  176. data/tests/test_aaa_authentication_login_service.rb +9 -0
  177. data/tests/test_aaa_authorization_service.rb +173 -367
  178. data/tests/test_ace.rb +171 -100
  179. data/tests/test_acl.rb +10 -1
  180. data/tests/test_bgp_af.rb +395 -728
  181. data/tests/test_bgp_neighbor.rb +274 -115
  182. data/tests/test_bgp_neighbor_af.rb +178 -77
  183. data/tests/test_bridge_domain.rb +191 -0
  184. data/tests/test_bridge_domain_vni.rb +116 -0
  185. data/tests/test_client_utils.rb +111 -0
  186. data/tests/test_command_config.rb +9 -5
  187. data/tests/test_command_reference.rb +380 -102
  188. data/tests/test_dns_domain.rb +13 -3
  189. data/tests/test_domain_name.rb +13 -3
  190. data/tests/test_encapsulation.rb +77 -0
  191. data/tests/test_evpn_vni.rb +25 -7
  192. data/tests/test_fabricpath_global.rb +167 -163
  193. data/tests/test_fabricpath_topology.rb +12 -33
  194. data/tests/test_feature.rb +215 -0
  195. data/tests/test_grpc.rb +166 -0
  196. data/tests/test_interface.rb +585 -344
  197. data/tests/test_interface_bdi.rb +80 -0
  198. data/tests/test_interface_channel_group.rb +6 -3
  199. data/tests/test_interface_ospf.rb +26 -24
  200. data/tests/test_interface_portchannel.rb +1 -0
  201. data/tests/test_interface_private_vlan.rb +724 -0
  202. data/tests/test_interface_service_vni.rb +37 -66
  203. data/tests/test_interface_svi.rb +98 -101
  204. data/tests/test_interface_switchport.rb +419 -549
  205. data/tests/test_itd_device_group.rb +145 -0
  206. data/tests/test_itd_device_group_node.rb +199 -0
  207. data/tests/test_itd_service.rb +298 -0
  208. data/tests/test_logger.rb +43 -0
  209. data/tests/test_name_server.rb +11 -2
  210. data/tests/test_node.rb +16 -75
  211. data/tests/test_node_ext.rb +174 -163
  212. data/tests/test_node_util.rb +119 -0
  213. data/tests/test_ntp_config.rb +5 -1
  214. data/tests/test_ntp_server.rb +2 -2
  215. data/tests/test_nxapi.rb +221 -0
  216. data/tests/test_overlay_global.rb +47 -38
  217. data/tests/test_pim.rb +2 -0
  218. data/tests/test_pim_group_list.rb +2 -0
  219. data/tests/test_pim_rp_address.rb +2 -0
  220. data/tests/test_platform.rb +86 -39
  221. data/tests/test_portchannel_global.rb +211 -135
  222. data/tests/test_radius_global.rb +13 -5
  223. data/tests/test_radius_server.rb +256 -104
  224. data/tests/test_radius_server_group.rb +2 -0
  225. data/tests/test_router_bgp.rb +781 -485
  226. data/tests/test_router_ospf.rb +26 -103
  227. data/tests/test_router_ospf_vrf.rb +52 -57
  228. data/tests/test_snmp_notification_receiver.rb +2 -0
  229. data/tests/test_snmpcommunity.rb +2 -0
  230. data/tests/test_snmpgroup.rb +2 -0
  231. data/tests/test_snmpnotification.rb +40 -21
  232. data/tests/test_snmpserver.rb +2 -0
  233. data/tests/test_snmpuser.rb +2 -0
  234. data/tests/test_stp_global.rb +563 -0
  235. data/tests/test_syslog_server.rb +32 -8
  236. data/tests/test_syslog_settings.rb +22 -9
  237. data/tests/test_tacacs_server.rb +32 -27
  238. data/tests/test_tacacs_server_group.rb +100 -45
  239. data/tests/test_tacacs_server_host.rb +135 -43
  240. data/tests/test_vdc.rb +2 -16
  241. data/tests/test_vlan.rb +106 -54
  242. data/tests/test_vlan_mt_full.rb +11 -21
  243. data/tests/test_vlan_private.rb +669 -0
  244. data/tests/test_vpc.rb +312 -159
  245. data/tests/test_vrf.rb +122 -113
  246. data/tests/test_vrf_af.rb +238 -0
  247. data/tests/test_vtp.rb +58 -102
  248. data/tests/test_vxlan_vtep.rb +38 -17
  249. data/tests/test_vxlan_vtep_vni.rb +61 -9
  250. data/tests/test_yum.rb +49 -25
  251. metadata +122 -36
  252. data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
  253. data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
  254. data/lib/cisco_node_utils/vni.rb +0 -227
  255. data/tests/test_vni.rb +0 -106
@@ -0,0 +1,33 @@
1
+ # January 2016, Glenn F. Matthews
2
+ #
3
+ # Copyright (c) 2014-2016 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Shared constants for the Cisco module
18
+ module Cisco
19
+ PLATFORMS = [
20
+ # Cisco IOS XR
21
+ :ios_xr,
22
+ # Cisco NX-OS (Nexus switches)
23
+ :nexus,
24
+ ]
25
+
26
+ DATA_FORMATS = [
27
+ # Cisco CLI. Indentation is significant.
28
+ :cli,
29
+ # Structured data format specific to NX-API
30
+ :nxapi_structured,
31
+ # TODO: :yang,
32
+ ]
33
+ end
@@ -0,0 +1,112 @@
1
+ # NXAPI implementation of encapsulation profile class
2
+ #
3
+ # March 2016, Rohan Gandhi Korlepara
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 'node_util'
20
+ require_relative 'feature'
21
+
22
+ module Cisco
23
+ # Encapsulation - node utility class for Encapsulation config mgmt.
24
+ class Encapsulation < NodeUtil
25
+ attr_reader :encap_name
26
+
27
+ # name: name of the encap instance
28
+ # instantiate: true = create encap instance
29
+ def initialize(name, instantiate=true)
30
+ fail ArgumentError unless name.length > 0
31
+ @encap_name = name
32
+ create if instantiate
33
+ end
34
+
35
+ def to_s
36
+ "Encapsulation #{encap_name}"
37
+ end
38
+
39
+ # Create a hash of all current encap instances.
40
+ def self.encaps
41
+ return {} unless Feature.vni_enabled?
42
+ instances = config_get('encapsulation', 'all_encaps')
43
+ return {} if instances.nil?
44
+ hash = {}
45
+ instances.each do |name|
46
+ hash[name] = Encapsulation.new(name, false)
47
+ end
48
+ hash
49
+ end
50
+
51
+ # This will expand the string to a list of bds as integers
52
+ def self.string_to_array(string)
53
+ list = []
54
+ narray = string.split(',')
55
+ narray.each do |elem|
56
+ if elem.include?('-')
57
+ es = elem.gsub('-', '..')
58
+ ea = es.split('..').map { |d| Integer(d) }
59
+ er = ea[0]..ea[1]
60
+ list << er.to_a
61
+ else
62
+ list << elem.to_i
63
+ end
64
+ end
65
+ list.flatten
66
+ end
67
+
68
+ # Enable feature and create encap instance
69
+ def create
70
+ Feature.vni_enable
71
+ config_set('encapsulation', 'create', profile: @encap_name)
72
+ end
73
+
74
+ # Destroy an encap instance
75
+ def destroy
76
+ config_set('encapsulation', 'destroy', profile: @encap_name)
77
+ end
78
+
79
+ # ----------
80
+ # PROPERTIES
81
+ # ----------
82
+
83
+ def range_summarize(string)
84
+ Utils.array_to_str(Encapsulation.string_to_array(string.to_s), false)
85
+ end
86
+
87
+ def dot1q_map
88
+ result = config_get('encapsulation', 'dot1q_map', profile: @encap_name)
89
+ return default_dot1q_map if result.empty?
90
+
91
+ result[0] = range_summarize(result[0])
92
+ result[1] = range_summarize(result[1])
93
+ result
94
+ end
95
+
96
+ def dot1q_map=(map)
97
+ state = ''
98
+ if map.empty?
99
+ state = 'no'
100
+ map = dot1q_map
101
+ return if map.empty?
102
+ end
103
+ vlans, vnis = map
104
+ config_set('encapsulation', 'dot1q_map', profile: @encap_name,
105
+ state: state, vlans: vlans, vnis: vnis)
106
+ end
107
+
108
+ def default_dot1q_map
109
+ config_get_default('encapsulation', 'dot1q_map')
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,102 @@
1
+ # March 2016, Glenn F. Matthews
2
+ #
3
+ # Copyright (c) 2016 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'yaml'
18
+ require_relative 'logger'
19
+
20
+ module Cisco
21
+ # Class representing the configuration environment
22
+ class Environment
23
+ @environments = {}
24
+ @default_environment_name = 'default'
25
+
26
+ # Autogenerate Cisco::Environment.default_environment_name and
27
+ # Cisco::Environment.default_environment_name= class methods.
28
+ class << self
29
+ attr_accessor :default_environment_name
30
+ end
31
+
32
+ # We have three tiers of configuration:
33
+ # 1) default (defined in this file)
34
+ # 2) System-wide gem configuration in /etc/cisco_node_utils.yaml
35
+ # 3) User configuration in ~/cisco_node_utils.yaml
36
+
37
+ DEFAULT_ENVIRONMENT = {
38
+ host: nil, # localhost by default
39
+ port: nil, # only applicable to gRPC
40
+ username: nil,
41
+ password: nil,
42
+ }
43
+
44
+ def self.environments
45
+ if @environments.empty?
46
+ @environments = merge_config('/etc/cisco_node_utils.yaml',
47
+ @environments)
48
+ @environments = merge_config('~/cisco_node_utils.yaml',
49
+ @environments)
50
+ @environments.each do |name, config|
51
+ Cisco::Logger.debug("Environment '#{name}': #{config}")
52
+ end
53
+ end
54
+ @environments
55
+ end
56
+
57
+ def self.merge_config(path, current_config)
58
+ data = data_from_file(path)
59
+ data.each do |name, config|
60
+ # in case config is nil:
61
+ config ||= {}
62
+ # in case current_config has no entry for this name:
63
+ current_config[name] ||= DEFAULT_ENVIRONMENT.clone
64
+ # merge it on in!
65
+ current_config[name].merge!(strings_to_symbols(config))
66
+ end
67
+ current_config
68
+ end
69
+
70
+ def self.data_from_file(path)
71
+ begin
72
+ path = File.expand_path(path)
73
+ rescue ArgumentError => e
74
+ # Can happen if path includes '~' but $HOME is not defined
75
+ Cisco::Logger.debug "Failed to load #{path}: #{e}"
76
+ return {}
77
+ end
78
+ unless File.file?(path)
79
+ Cisco::Logger.debug "No file found at #{path}"
80
+ return {}
81
+ end
82
+ unless File.readable?(path)
83
+ Cisco::Logger.debug "No permissions to read #{path}"
84
+ return {}
85
+ end
86
+ YAML.load_file(path)
87
+ rescue Psych::SyntaxError => e
88
+ Cisco::Logger.error("Error loading #{path}: #{e}")
89
+ {}
90
+ end
91
+
92
+ def self.strings_to_symbols(hash)
93
+ Hash[hash.map { |k, v| [k.to_sym, v] }]
94
+ end
95
+
96
+ def self.environment(name=nil)
97
+ name ||= @default_environment_name
98
+ Cisco::Logger.debug("Getting environment '#{name}'")
99
+ environments.fetch(name, DEFAULT_ENVIRONMENT)
100
+ end
101
+ end
102
+ end
@@ -84,11 +84,13 @@ module Cisco
84
84
  def route_distinguisher=(rd)
85
85
  if rd == default_route_distinguisher
86
86
  @set_args[:state] = 'no'
87
- @set_args[:rd] = ''
87
+ # I2 images require an rd for removal
88
+ rd = route_distinguisher
89
+ return if rd.to_s.empty?
88
90
  else
89
91
  @set_args[:state] = ''
90
- @set_args[:rd] = rd
91
92
  end
93
+ @set_args[:rd] = rd
92
94
  config_set('evpn_vni', 'route_distinguisher', @set_args)
93
95
  set_args_keys_default
94
96
  end
@@ -143,7 +145,7 @@ module Cisco
143
145
  delta_hash = Utils.delta_add_remove(should, is)
144
146
  return if delta_hash.values.flatten.empty?
145
147
  [:add, :remove].each do |action|
146
- CiscoLogger.debug("#{prop}" \
148
+ Cisco::Logger.debug("#{prop}" \
147
149
  "#{@get_args}\n #{action}: #{delta_hash[action]}")
148
150
  delta_hash[action].each do |community|
149
151
  state = (action == :add) ? '' : 'no'
@@ -0,0 +1,111 @@
1
+ # March 2016, Glenn F. Matthews
2
+ #
3
+ # Copyright (c) 2014-2016 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Add generic exception classes to the Cisco module
18
+ # The hierarchy is:
19
+ # RuntimeError
20
+ # Cisco::CiscoError
21
+ # Cisco::ClientError
22
+ # Cisco::ConnectionRefused
23
+ # Cisco::AuthenticationFailed
24
+ # Cisco::RequestFailed
25
+ # Cisco::CliError
26
+ # Cisco::RequestNotSupported
27
+ # Cisco::UnsupportedError
28
+ module Cisco
29
+ # Generic class for exceptions raised by this module
30
+ class CiscoError < RuntimeError
31
+ attr_reader :kwargs
32
+
33
+ def initialize(message=nil, **kwargs)
34
+ @kwargs = kwargs
35
+ super(message)
36
+ end
37
+
38
+ def respond_to?(method_sym, include_private=false)
39
+ @kwargs.key?(method_sym) ? true : super
40
+ end
41
+
42
+ def method_missing(method_sym, *args, **kwargs, &block)
43
+ @kwargs.key?(method_sym) ? @kwargs[method_sym] : super
44
+ end
45
+ end
46
+
47
+ # Exception class for fundamental client failures
48
+ class ClientError < CiscoError
49
+ end
50
+
51
+ # ConnectionRefused means the server isn't listening
52
+ class ConnectionRefused < ClientError
53
+ end
54
+
55
+ # AuthenticationFailed means we were able to connect but not login
56
+ class AuthenticationFailed < ClientError
57
+ end
58
+
59
+ # Exception class for failures of a specific request to the client
60
+ class RequestFailed < CiscoError
61
+ end
62
+
63
+ # Extension of RequestFailed class specifically for CLI errors
64
+ class CliError < RequestFailed
65
+ def initialize(message=nil,
66
+ clierror: nil,
67
+ rejected_input: nil,
68
+ successful_input: [],
69
+ **kwargs)
70
+ unless message
71
+ if rejected_input.is_a?(Array)
72
+ if rejected_input.length > 1
73
+ message = "The following commands were rejected:\n"
74
+ message += " #{rejected_input.join("\n ")}\n"
75
+ else
76
+ message = "The command '#{rejected_input.first}' was rejected "
77
+ end
78
+ else
79
+ message = "The command '#{rejected_input}' was rejected "
80
+ end
81
+ message += "with error:\n#{clierror}"
82
+ end
83
+ super(message,
84
+ :clierror => clierror,
85
+ :rejected_input => rejected_input,
86
+ :successful_input => successful_input,
87
+ **kwargs)
88
+ end
89
+ end
90
+
91
+ # RequestNotSupported means we made a request that was validly
92
+ # constructed but includes options that are unsupported.
93
+ #
94
+ # An example would be requesting structured output on a CLI command
95
+ # that only supports ASCII output.
96
+ class RequestNotSupported < RequestFailed
97
+ end
98
+
99
+ # Exception class raised by CommandReference to indicate that
100
+ # a particular feature/attribute is explicitly excluded on the given node.
101
+ class UnsupportedError < CiscoError
102
+ def initialize(feature, name, oper=nil, msg=nil)
103
+ message = "Feature '#{feature}'"
104
+ message += ", attribute '#{name}'" unless name.nil?
105
+ message += ", operation '#{oper}'" unless oper.nil?
106
+ message += ' is unsupported on this node'
107
+ message += ": #{msg}" unless msg.nil?
108
+ super(message, feature: feature, name: name, oper: oper)
109
+ end
110
+ end
111
+ end
@@ -18,6 +18,7 @@
18
18
  # limitations under the License.
19
19
 
20
20
  require_relative 'node_util'
21
+ require_relative 'vdc'
21
22
 
22
23
  module Cisco
23
24
  # node_utils class for fabricpath_global
@@ -33,23 +34,49 @@ module Cisco
33
34
 
34
35
  def self.globals
35
36
  hash = {}
36
- is_fabricpath_feature = config_get('fabricpath', 'feature')
37
- return hash if (:enabled != is_fabricpath_feature.to_sym)
37
+ feature = config_get('fabricpath', 'feature')
38
+ return hash if feature.nil? || feature.to_sym != :enabled
38
39
  hash['default'] = FabricpathGlobal.new('default', false)
39
40
  hash
41
+ rescue Cisco::CliError => e
42
+ # cmd will syntax reject when feature is not enabled
43
+ raise unless e.clierror =~ /Syntax error/
44
+ return {}
40
45
  end
41
46
 
42
47
  def self.fabricpath_feature
43
48
  fabricpath = config_get('fabricpath', 'feature')
44
- fail 'fabricpath_feature not found' if fabricpath.nil?
45
49
  return :disabled if fabricpath.nil?
46
50
  fabricpath.to_sym
51
+ rescue Cisco::CliError => e
52
+ # cmd will syntax reject when feature is not enabled
53
+ raise unless e.clierror =~ /Syntax error/
54
+ return :disabled
55
+ end
56
+
57
+ def self.fabricpath_enable
58
+ # TBD: Move to Feature provider
59
+ FabricpathGlobal.fabricpath_feature_set(:enabled) unless
60
+ FabricpathGlobal.fabricpath_feature == :enabled
47
61
  end
48
62
 
49
63
  def self.fabricpath_feature_set(fabricpath_set)
50
64
  curr = FabricpathGlobal.fabricpath_feature
51
65
  return if curr == fabricpath_set
52
66
 
67
+ # NOTE: Add this in future if we want to automatically move only supported
68
+ # interfaces into the VDC
69
+ # if Vdc.vdc_support
70
+ # # For modular platforms, make sure to limit the feature to
71
+ # # modules which support this feature
72
+ # if fabricpath_set == :installed || fabricpath_set == :enabled
73
+ # v = Vdc.new('default')
74
+ # v.limit_resource_module_type =
75
+ # config_get('fabricpath', 'supported_modules')
76
+ # # exception will be raised for un-supported platforms/modules
77
+ # end
78
+ # end
79
+
53
80
  case fabricpath_set
54
81
  when :enabled
55
82
  config_set('fabricpath', 'feature_install',
@@ -68,8 +95,7 @@ module Cisco
68
95
  end
69
96
 
70
97
  def create
71
- FabricpathGlobal.fabricpath_feature_set(:enabled) unless
72
- :enabled == FabricpathGlobal.fabricpath_feature
98
+ FabricpathGlobal.fabricpath_enable
73
99
  end
74
100
 
75
101
  def destroy
@@ -77,22 +103,15 @@ module Cisco
77
103
  FabricpathGlobal.fabricpath_feature_set(:disabled)
78
104
  end
79
105
 
80
- def my_munge(property, set_val)
81
- val = config_get_default('fabricpath', property)
106
+ def loadbalance_munge(property, set_val)
82
107
  case property
83
108
  when /loadbalance_algorithm/
84
- if (val == 'source-destination') &&
85
- (set_val == 'symmetric' || set_val == 'xor')
86
- val
87
- else
88
- set_val
89
- end
109
+ val = config_get_default('fabricpath', property)
110
+ return val if (val == 'source-destination') && set_val[/symmetric|xor/]
111
+ set_val
90
112
  when /loadbalance_.*_rotate/
91
- if val == false || set_val == ''
92
- ''
93
- else
94
- "rotate-amount 0x#{set_val.to_s(16)}"
95
- end
113
+ return '' if set_val == ''
114
+ "rotate-amount 0x#{set_val.to_i.to_s(16)}"
96
115
  else
97
116
  set_val
98
117
  end
@@ -200,13 +219,18 @@ module Cisco
200
219
  config_get_default('fabricpath', 'linkup_delay_enable')
201
220
  end
202
221
 
222
+ def loadbalance_algorithm_symmetric_support
223
+ config_get_default('fabricpath',
224
+ 'loadbalance_algorithm_symmetric_support')
225
+ end
226
+
203
227
  def loadbalance_algorithm
204
228
  algo = config_get('fabricpath', 'loadbalance_algorithm')
205
229
  algo.downcase
206
230
  end
207
231
 
208
232
  def loadbalance_algorithm=(val)
209
- val = my_munge('loadbalance_algorithm', val)
233
+ val = loadbalance_munge('loadbalance_algorithm', val)
210
234
  state = val ? '' : 'no'
211
235
  algo = val ? val : ''
212
236
  config_set('fabricpath', 'loadbalance_algorithm', state: state,
@@ -230,16 +254,14 @@ module Cisco
230
254
  if rotate == '' && (has_vlan == '' || has_vlan == false)
231
255
  config_set('fabricpath', 'loadbalance_multicast_reset')
232
256
  else
233
- rotate = my_munge('loadbalance_multicast_rotate', rotate)
257
+ rotate = loadbalance_munge('loadbalance_multicast_rotate', rotate)
234
258
  has_vlan = (has_vlan == true) ? 'include-vlan' : ''
235
259
  config_set('fabricpath', 'loadbalance_multicast_set',
236
- rotate_amt: rotate, inc_vlan: has_vlan)
260
+ rotate: rotate, has_vlan: has_vlan)
237
261
  end
238
262
  end
239
263
 
240
- def default_loadbalance_multicast_rotate
241
- config_get_default('fabricpath', 'loadbalance_multicast_rotate')
242
- end
264
+ # default_loadbalance_multicast_rotate: n/a
243
265
 
244
266
  def default_loadbalance_multicast_has_vlan
245
267
  config_get_default('fabricpath', 'loadbalance_multicast_has_vlan')
@@ -269,9 +291,9 @@ module Cisco
269
291
 
270
292
  def split_loadbalance_unicast_layer=(val)
271
293
  state = val ? '' : 'no'
272
- pref = val ? val : ''
273
- config_set('fabricpath', 'loadbalance_unicast_layer', state: state,
274
- pref: pref)
294
+ layer = val ? val : ''
295
+ config_set('fabricpath', 'loadbalance_unicast_layer',
296
+ state: state, layer: layer)
275
297
  end
276
298
 
277
299
  def split_loadbalance_unicast_has_vlan=(val)
@@ -289,10 +311,10 @@ module Cisco
289
311
  if layer == '' && rotate == '' && (has_vlan == '' || has_vlan == false)
290
312
  config_set('fabricpath', 'loadbalance_unicast_reset')
291
313
  else
292
- rotate = my_munge('loadbalance_unicast_rotate', rotate)
314
+ rotate = loadbalance_munge('loadbalance_unicast_rotate', rotate)
293
315
  has_vlan = (has_vlan == true) ? 'include-vlan' : ''
294
316
  config_set('fabricpath', 'loadbalance_unicast_set',
295
- pref: layer, rotate_amt: rotate, inc_vlan: has_vlan)
317
+ layer: layer, rotate: rotate, has_vlan: has_vlan)
296
318
  end
297
319
  else
298
320
  self.split_loadbalance_unicast_layer = layer
@@ -304,9 +326,7 @@ module Cisco
304
326
  config_get_default('fabricpath', 'loadbalance_unicast_layer')
305
327
  end
306
328
 
307
- def default_loadbalance_unicast_rotate
308
- config_get_default('fabricpath', 'loadbalance_unicast_rotate')
309
- end
329
+ # default_loadbalance_unicast_rotate: n/a
310
330
 
311
331
  def default_loadbalance_unicast_has_vlan
312
332
  config_get_default('fabricpath', 'loadbalance_unicast_has_vlan')
@@ -321,9 +341,6 @@ module Cisco
321
341
  state = 'no'
322
342
  else
323
343
  state = ''
324
- vdc = config_get('limit_resource', 'vdc')
325
- # for vdc unsupported platforms, this will be nil
326
- config_set('limit_resource', 'fabricpath_transit', vdc) unless vdc.nil?
327
344
  end
328
345
  config_set('fabricpath', 'mode', state: state)
329
346
  end