cisco_node_utils 1.3.0 → 1.4.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +66 -0
  4. data/Gemfile +1 -0
  5. data/README.md +44 -43
  6. data/bin/.rubocop.yml +18 -0
  7. data/bin/show_running_yang.rb +233 -0
  8. data/cisco_node_utils.gemspec +1 -1
  9. data/docs/README-maintainers.md +1 -0
  10. data/docs/README-utilities.md +14 -0
  11. data/lib/.rubocop.yml +1 -1
  12. data/lib/cisco_node_utils/aaa_authentication_login_service.rb +8 -3
  13. data/lib/cisco_node_utils/aaa_authorization_service.rb +6 -0
  14. data/lib/cisco_node_utils/bfd_global.rb +300 -0
  15. data/lib/cisco_node_utils/bgp.rb +6 -4
  16. data/lib/cisco_node_utils/bgp_af.rb +2 -0
  17. data/lib/cisco_node_utils/bgp_neighbor.rb +14 -0
  18. data/lib/cisco_node_utils/bgp_neighbor_af.rb +4 -1
  19. data/lib/cisco_node_utils/cisco_cmn_utils.rb +126 -0
  20. data/lib/cisco_node_utils/client/client.rb +6 -2
  21. data/lib/cisco_node_utils/client/grpc/client.rb +120 -36
  22. data/lib/cisco_node_utils/client/nxapi/client.rb +6 -2
  23. data/lib/cisco_node_utils/cmd_ref/DEPRECATED.yaml +118 -0
  24. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +14 -0
  25. data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
  26. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +7 -7
  27. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +7 -0
  28. data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +125 -0
  29. data/lib/cisco_node_utils/cmd_ref/feature.yaml +10 -0
  30. data/lib/cisco_node_utils/cmd_ref/interface.yaml +141 -49
  31. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +44 -0
  32. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +6 -0
  33. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +6 -0
  34. data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
  35. data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
  36. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +0 -3
  37. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +3 -3
  38. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +39 -15
  39. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +43 -21
  40. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +48 -19
  41. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +0 -0
  42. data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +30 -0
  43. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +18 -6
  44. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +4 -0
  45. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +1 -0
  46. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +23 -10
  47. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +8 -2
  48. data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
  49. data/lib/cisco_node_utils/cmd_ref/yum.yaml +10 -1
  50. data/lib/cisco_node_utils/constants.rb +8 -1
  51. data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
  52. data/lib/cisco_node_utils/exceptions.rb +29 -0
  53. data/lib/cisco_node_utils/feature.rb +28 -0
  54. data/lib/cisco_node_utils/interface.rb +493 -402
  55. data/lib/cisco_node_utils/interface_DEPRECATED.rb +513 -0
  56. data/lib/cisco_node_utils/interface_ospf.rb +126 -0
  57. data/lib/cisco_node_utils/interface_portchannel.rb +16 -0
  58. data/lib/cisco_node_utils/logger.rb +3 -0
  59. data/lib/cisco_node_utils/node.rb +29 -1
  60. data/lib/cisco_node_utils/overlay_global.rb +1 -12
  61. data/lib/cisco_node_utils/pim.rb +1 -0
  62. data/lib/cisco_node_utils/pim_group_list.rb +1 -0
  63. data/lib/cisco_node_utils/pim_rp_address.rb +1 -0
  64. data/lib/cisco_node_utils/platform.rb +9 -2
  65. data/lib/cisco_node_utils/router_ospf.rb +1 -1
  66. data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
  67. data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
  68. data/lib/cisco_node_utils/router_ospf_vrf.rb +17 -0
  69. data/lib/cisco_node_utils/snmp_notification_receiver.rb +27 -9
  70. data/lib/cisco_node_utils/snmpcommunity.rb +34 -8
  71. data/lib/cisco_node_utils/snmpserver.rb +4 -4
  72. data/lib/cisco_node_utils/snmpuser.rb +0 -0
  73. data/lib/cisco_node_utils/tacacs_global.rb +102 -0
  74. data/lib/cisco_node_utils/tacacs_server.rb +8 -7
  75. data/lib/cisco_node_utils/vdc.rb +25 -7
  76. data/lib/cisco_node_utils/version.rb +1 -1
  77. data/lib/cisco_node_utils/vlan.rb +30 -56
  78. data/lib/cisco_node_utils/vlan_DEPRECATED.rb +108 -0
  79. data/lib/cisco_node_utils/yang.rb +160 -0
  80. data/lib/cisco_node_utils/yum.rb +25 -32
  81. data/tests/.rubocop.yml +3 -0
  82. data/tests/ciscotest.rb +136 -19
  83. data/tests/cmd_config_invalid.yaml +1 -1
  84. data/tests/noop.rb +7 -0
  85. data/tests/tacacs_server.yaml.example +6 -0
  86. data/tests/test_aaa_authentication_login.rb +24 -1
  87. data/tests/test_aaa_authentication_login_service.rb +9 -16
  88. data/tests/test_aaa_authorization_service.rb +111 -84
  89. data/tests/test_bfd_global.rb +278 -0
  90. data/tests/test_bgp_neighbor.rb +20 -0
  91. data/tests/test_bridge_domain_vni.rb +2 -9
  92. data/tests/test_cmn_utils.rb +76 -0
  93. data/tests/test_dhcp_relay_global.rb +284 -0
  94. data/tests/test_dns_domain.rb +4 -4
  95. data/tests/test_domain_name.rb +2 -2
  96. data/tests/test_encapsulation.rb +2 -4
  97. data/tests/test_evpn_vni.rb +14 -7
  98. data/tests/test_fabricpath_global.rb +12 -13
  99. data/tests/test_feature.rb +35 -17
  100. data/tests/test_interface.rb +352 -127
  101. data/tests/test_interface_bdi.rb +2 -2
  102. data/tests/test_interface_channel_group.rb +1 -1
  103. data/tests/test_interface_ospf.rb +153 -23
  104. data/tests/test_interface_portchannel.rb +15 -6
  105. data/tests/test_interface_private_vlan.rb +200 -576
  106. data/tests/test_interface_svi.rb +5 -52
  107. data/tests/test_interface_switchport.rb +80 -240
  108. data/tests/test_itd_device_group.rb +2 -2
  109. data/tests/test_itd_device_group_node.rb +2 -2
  110. data/tests/test_itd_service.rb +1 -1
  111. data/tests/test_name_server.rb +3 -3
  112. data/tests/test_node_ext.rb +15 -17
  113. data/tests/test_ntp_config.rb +1 -1
  114. data/tests/test_ntp_server.rb +3 -3
  115. data/tests/test_nxapi.rb +1 -0
  116. data/tests/test_overlay_global.rb +15 -19
  117. data/tests/test_pim.rb +5 -5
  118. data/tests/test_pim_group_list.rb +1 -37
  119. data/tests/test_pim_rp_address.rb +1 -1
  120. data/tests/test_platform.rb +9 -11
  121. data/tests/test_portchannel_global.rb +43 -3
  122. data/tests/test_radius_server.rb +1 -1
  123. data/tests/test_radius_server_group.rb +1 -1
  124. data/tests/test_router_bgp.rb +17 -30
  125. data/tests/test_router_ospf_area.rb +433 -0
  126. data/tests/test_router_ospf_area_vlink.rb +298 -0
  127. data/tests/test_router_ospf_vrf.rb +17 -0
  128. data/tests/test_snmp_notification_receiver.rb +11 -11
  129. data/tests/test_snmpcommunity.rb +177 -69
  130. data/tests/test_snmpgroup.rb +7 -7
  131. data/tests/test_snmpserver.rb +164 -253
  132. data/tests/test_snmpuser.rb +73 -69
  133. data/tests/test_stp_global.rb +15 -15
  134. data/tests/test_syslog_settings.rb +1 -1
  135. data/tests/test_tacacs_global.rb +80 -0
  136. data/tests/test_tacacs_server.rb +129 -51
  137. data/tests/test_tacacs_server_group.rb +3 -29
  138. data/tests/test_tacacs_server_host.rb +24 -27
  139. data/tests/test_vlan.rb +57 -59
  140. data/tests/test_vlan_private.rb +271 -284
  141. data/tests/test_vpc.rb +10 -4
  142. data/tests/test_vrf.rb +2 -0
  143. data/tests/test_vrf_af.rb +2 -5
  144. data/tests/test_vtp.rb +5 -2
  145. data/tests/test_vxlan_vtep.rb +20 -44
  146. data/tests/test_vxlan_vtep_vni.rb +23 -16
  147. data/tests/test_yang.rb +369 -0
  148. data/tests/test_yum.rb +34 -42
  149. data/tests/yum_package.yaml +35 -0
  150. metadata +31 -4
  151. data/tests/test_vlan_mt_full.rb +0 -85
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04e705a28917168a277c351451f63491ff3c1177
4
- data.tar.gz: 4e2be35191668158a0b757b831cd1ee135ae7525
3
+ metadata.gz: e72699d560ddb617cfe0a637565d0313ba7ba9f6
4
+ data.tar.gz: a25d1820c2a7bc3bf28ef1fdc79c2124bbb51b49
5
5
  SHA512:
6
- metadata.gz: 734d65543eeedb4f766a74c8d56f397e638f5fe446846bc4196ec3facfd1f5378f1eefe11364a67089f67a6851f2101438b87526536ab44477df6181281fb39b
7
- data.tar.gz: a0d7aaebf7dd5d00a432f4a6c4067860750dd61df4e1fa73da11e6c8440f859f32d1155a412a5a00791a15a1ed024d5e3a08129b6ce74abed9a326ef55cdddfc
6
+ metadata.gz: a5a0cbafbb485e2c47fa4ab9bab300c713ecaba4609fc23f8f8bcf940019d74c5cd054e7e637fd50ab381bdb1cf2a7d27eb7326ca236ccab6537f66a2e6494aa
7
+ data.tar.gz: 7ed873f928991caf6088cf48753af8bb0ec9afc5e1c005aa5da49f82cea8c3cfea52843fb7673173ffac940eb1c846b09100018a8f12a5bcd8bcdf59e3da2635
data/.gitignore CHANGED
@@ -3,6 +3,7 @@ pkg/*
3
3
  vendor/*
4
4
  coverage
5
5
  ext/Rakefile
6
+ tests/tacacs_server.yaml
6
7
  Gemfile.lock
7
8
  *.gem
8
9
  *.swp
data/CHANGELOG.md CHANGED
@@ -1,6 +1,71 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v1.4.0]
5
+
6
+ ### New feature support
7
+
8
+ #### Cisco Resources
9
+ * Bidirectional Forwarding Detection
10
+ * bfd (@saichint)
11
+ * Dynamic Host Configuration Protocol
12
+ * dhcp_relay_global (@saichint)
13
+ * OSPF
14
+ * ospf_area (@saichint)
15
+ * ospf_area_vlink (@saichint)
16
+
17
+ ### Added
18
+
19
+ * Extend interface with attributes:
20
+ * `bfd_echo`
21
+ * `ipv4_dhcp_relay_addr`
22
+ * `ipv4_dhcp_relay_info_trust`
23
+ * `ipv4_dhcp_relay_src_addr_hsrp`
24
+ * `ipv4_dhcp_relay_src_intf`
25
+ * `ipv4_dhcp_relay_subnet_broadcast`
26
+ * `ipv4_dhcp_smart_relay`
27
+ * `ipv6_dhcp_relay_addr`
28
+ * `ipv6_dhcp_relay_src_intf`
29
+ * `storm_control_broadcast`
30
+ * `storm_control_multicast`
31
+ * `storm_control_unicast`
32
+ * Extend interface_ospf with attributes:
33
+ * `bfd`
34
+ * `mtu_ignore`
35
+ * `network_type`
36
+ * `priority`
37
+ * `shutdown`
38
+ * `transmit_delay`
39
+ * Extend interface_portchannel with attributes:
40
+ * `bfd_per_link`
41
+ * Extend router_ospf_vrf with attributes:
42
+ * `bfd`
43
+ * Extend bgp_neighbor with attributes:
44
+ * `bfd`
45
+
46
+ ### Changed
47
+ * Deprecated `vlan` private-vlan properties and replaced with new methods. New file `vlan_DEPRECATED.rb` has been created to store the deprecated methods. The old -> new properties are:
48
+
49
+ | Old Name | New Name(s) |
50
+ |:---|:---:|
51
+ | `private_vlan_association` | `pvlan_association`
52
+ | `private_vlan_type` | `pvlan_type`
53
+
54
+ * Deprecated `interface` private-vlan properties and replaced with new methods. New files `interface_DEPRECATED.rb` and `DEPRECATED.yaml` have been created to store the deprecated methods. The old -> new properties are:
55
+
56
+ | Old Name | New Name(s) |
57
+ |:---|:---:|
58
+ | `private_vlan_mapping` | `pvlan_mapping`
59
+ | `switchport_mode_private_vlan_host` | `switchport_pvlan_host`, `switchport_pvlan_promiscuous`,
60
+ | `switchport_mode_private_vlan_host_association` | `switchport_pvlan_host_association`
61
+ | `switchport_mode_private_vlan_host_promiscous` | `switchport_pvlan_mapping`
62
+ | `switchport_mode_private_vlan_trunk_promiscuous`| `switchport_pvlan_trunk_promiscuous`
63
+ | `switchport_mode_private_vlan_trunk_secondary` | `switchport_pvlan_trunk_secondary`
64
+ | `switchport_private_vlan_association_trunk` | `switchport_pvlan_trunk_association`
65
+ | `switchport_private_vlan_mapping_trunk` | `switchport_pvlan_mapping_trunk`
66
+ | `switchport_private_vlan_trunk_allowed_vlan` | `switchport_pvlan_trunk_allowed_vlan`
67
+ | `switchport_private_vlan_trunk_native_vlan` | `switchport_pvlan_trunk_native_vlan`
68
+
4
69
  ## [v1.3.0]
5
70
 
6
71
  ### New feature support
@@ -294,6 +359,7 @@ Changelog
294
359
  [git-flow]: https://github.com/petervanderdoes/gitflow-avh
295
360
  [SimpleCov]: https://github.com/colszowka/simplecov
296
361
 
362
+ [v1.4.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.3.0...v1.4.0
297
363
  [v1.3.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.2.0...v1.3.0
298
364
  [v1.2.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.1.0...v1.2.0
299
365
  [v1.1.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.0.1...v1.1.0
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gemspec
7
7
  # but we need them for Bundler to use.
8
8
  gem 'net_http_unix'
9
9
  gem 'grpc'
10
+ gem 'pry'
data/README.md CHANGED
@@ -61,9 +61,9 @@ To install the CiscoNodeUtils, use the following command:
61
61
  Alternatively, if you've checked the source out directly, you can call
62
62
  `rake install` from the root project directory.
63
63
 
64
- ## Configuration
64
+ ## <a name="configuration">Configuration</a>
65
65
 
66
- This gem may require configuration in order to be used. Two configuration file locations are supported:
66
+ Depending on the installation environment (Linux, NX-OS), this gem may require configuration in order to be used. Two configuration file locations are supported:
67
67
 
68
68
  * `/etc/cisco_node_utils.yaml` (system and/or root user configuration)
69
69
  * `~/cisco_node_utils.yaml` (per-user configuration)
@@ -72,13 +72,16 @@ If both files exist and are readable, configuration in the user-specific file wi
72
72
 
73
73
  This file specifies the host, port, username, and/or password to be used to connect to one or more nodes.
74
74
 
75
+ * When installing this gem on NX-OS nodes, this file is generally not needed, as the default client behavior is sufficient.
75
76
  * When developing for or testing this gem, this file can specify one or more NX-OS nodes to run tests against. In this case:
76
- - A node labeled as `default` will be the default node to test against.
77
- - Nodes with other names can be selected at test execution time.
78
- - NX-OS nodes must be defined with a `host` (hostname or IP address), `username`, and `password`.
77
+ - A node labeled as `default` will be the default node to test against.
78
+ - Nodes with other names can be selected at test execution time.
79
+ - NX-OS nodes must be defined with a `host` (hostname or IP address), `username`, and `password`.
79
80
 
80
81
  An example configuration file (illustrating each of the above scenarios) is provided with this gem at [`docs/cisco_node_utils.yaml.example`](docs/cisco_node_utils.yaml.example).
81
82
 
83
+ *For security purposes, it is highly recommended that access to this file be restricted to only the owning user (`chmod 0600`).*
84
+
82
85
  ## <a name="documentation">Documentation</a>
83
86
 
84
87
  ### Client
@@ -119,49 +122,38 @@ provider classes, and not directly call into `CommandReference` or `Node`.
119
122
 
120
123
  ## <a name="examples">Examples</a>
121
124
 
122
-
123
125
  These utilities can be used directly on a Cisco device (as used by Puppet
124
126
  and Chef) or can run on a workstation and point to a Cisco device (as used
125
- by the included minitest suite).
127
+ by the included minitest suite). The Client and Node APIs will read
128
+ connection information (host, username, etc.) from a
129
+ [configuration file](#configuration). When creating a Client
130
+ you can choose which device in the config file to connect to by specifying a label
131
+ (if no label is specified, "default" is assumed). If a configuration file cannot be
132
+ found, the Client or Node will attempt to connect to the local device.
126
133
 
127
- ### Usage on a Cisco device
128
-
129
- #### Low-level Client API
130
-
131
- ```ruby
132
- require 'cisco_node_utils'
134
+ *Note: Entries in the configuration file can specify local or remote devices.*
133
135
 
134
- # get a connection to the local device
135
- client = Cisco::Client.create()
136
-
137
- client.get(command: 'show version')
138
- client.set(values: 'vtp domain mycompany.com')
139
- ```
140
-
141
- #### High-level Node API
142
-
143
- ```ruby
144
- require 'cisco_node_utils'
145
-
146
- # get a connection to the local device
147
- node = Cisco::Node.instance()
148
-
149
- version = node.config_get("show_version", "system_image")
150
-
151
- node.config_set("vtp", "domain", "mycompany.com")
152
- ```
153
-
154
- ### Remote usage
136
+ ### Cisco Nexus Device (supports CLI configuration)
155
137
 
156
138
  #### Low-level Client API
157
139
 
158
140
  ```ruby
159
141
  require 'cisco_node_utils'
160
142
 
161
- client = Cisco::Client.create('n3k.mycompany.com', 'username', 'password')
143
+ # Create a connection to the following nodes:
144
+ # - 'default' device defined in the cisco_node_utils.yaml file
145
+ # - 'n9k' device defined in the cisco_node_utils.yaml file
146
+ client1 = Cisco::Client.create()
147
+ client2 = Cisco::Client.create('n9k')
148
+ # Warning: Make sure to exclude devices using the 'no_proxy' environment variable
149
+ # to ensure successful remote connections.
150
+
151
+ # Use connections to get and set device state.
152
+ client1.set(values: 'feature vtp')
153
+ client1.set(values: 'vtp domain mycompany.com')
154
+ puts client1.get(command: 'show vtp status | inc Domain')
162
155
 
163
- client.get(command: 'show version')
164
- client.set(values: 'vtp domain mycompany.com')
156
+ puts client2.get(command: 'show version')
165
157
  ```
166
158
 
167
159
  #### High-level Node API
@@ -169,14 +161,23 @@ client.set(values: 'vtp domain mycompany.com')
169
161
  ```ruby
170
162
  require 'cisco_node_utils'
171
163
 
172
- node = Cisco::Node.new("n3k.mycompany.com", "username", "password")
173
-
174
- version = node.config_get("show_version", "system_image")
175
-
176
- node.config_set("vtp", "domain", "mycompany.com")
164
+ # Create a connection to the following:
165
+ # - 'default' device defined in the cisco_node_utils.yaml
166
+ node = Cisco::Node.instance()
167
+ # OR:
168
+ # - 'n9k' device defined in the cisco_node_utils.yaml file
169
+ # Cisco::Environment.default_environment_name = 'n9k'
170
+ # node = Cisco::Node.instance()
171
+
172
+ # Warning: Make sure to exclude devices using the 'no_proxy' environment variable
173
+ # to ensure successful remote connections.
174
+
175
+ # Use connection to get and set device state.
176
+ node.config_set('feature', 'vtp', state: '')
177
+ node.config_set('vtp', 'domain', domain: 'mycompany.com')
178
+ puts node.config_get('vtp', 'domain')
177
179
  ```
178
180
 
179
-
180
181
  ## <a name="changelog">Changelog</a>
181
182
 
182
183
 
data/bin/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ inherit_from: ../.rubocop.yml
2
+
3
+ # Baseline code complexity metrics for the bin/ subdirectory:
4
+
5
+ Metrics/AbcSize:
6
+ Max: 49
7
+
8
+ Metrics/CyclomaticComplexity:
9
+ Max: 23
10
+
11
+ Metrics/MethodLength:
12
+ Max: 50
13
+
14
+ Metrics/ParameterLists:
15
+ Max: 9
16
+
17
+ Metrics/PerceivedComplexity:
18
+ Max: 24
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # June 2016, Charles Burkett
4
+ #
5
+ # Copyright (c) 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
+ # This is a utility to output the current state of an XR configuration.
20
+ # In order to run, this utility needs access to one or more *.yang files
21
+ # (found in the /pkg/yang directory on the XR box, as well as from other
22
+ # sources).
23
+
24
+ require 'cisco_node_utils'
25
+ require 'optparse'
26
+
27
+ module Cisco
28
+ # Utility class to output the current state of an XR configuration.
29
+ class YangViewer
30
+ def process(options)
31
+ @options = options
32
+
33
+ client # initialize the client
34
+
35
+ dir_or_file = options[:path]
36
+
37
+ file = nil
38
+ dir = nil
39
+
40
+ if File.exist?(dir_or_file)
41
+ if File.directory?(dir_or_file)
42
+ dir = dir_or_file
43
+ else
44
+ file = dir_or_file
45
+ end
46
+ else
47
+ puts "Directory or file not found: #{dir_or_file}"
48
+ exit(-1)
49
+ end
50
+
51
+ puts "File found: #{file}" if file
52
+ puts "Directory found: #{dir}" if dir
53
+ puts 'Searching for configuration data...' unless @options[:oper]
54
+ puts 'Searching for operational data...' if @options[:oper]
55
+
56
+ t1 = Time.now
57
+
58
+ @files = 0
59
+ @cnrs = 0
60
+ @errors = 0
61
+ if file
62
+ process_file(file)
63
+ @files += 1
64
+ else
65
+ Dir.glob(dir + '/*.yang').sort.each do |item|
66
+ process_file(item)
67
+ @files += 1
68
+ end
69
+ end
70
+
71
+ delta = Time.now - t1
72
+ puts '---------------------------------------------'
73
+ puts "Files Processed: #{@files}"
74
+ puts "Containers Processed: #{@cnrs}"
75
+ puts "Errors: #{@errors}"
76
+ puts "Time: #{delta.round(2)} seconds"
77
+ puts # spacer
78
+ end
79
+
80
+ def process_file(file)
81
+ @module = nil
82
+ @containers = {}
83
+ puts "[ Processing file #{file} ]" if @options[:verbose]
84
+
85
+ File.open(file) do |f|
86
+ loop do
87
+ break if (line = f.gets).nil?
88
+ process_line(line, f)
89
+ end
90
+ end
91
+ end
92
+
93
+ def process_line(line, file)
94
+ if @module.nil?
95
+ @module = Regexp.last_match(1) if line =~ /^module (.+) {/
96
+ elsif line =~ /^ container (.+) {/
97
+ process_root_container(@module, Regexp.last_match(1), file)
98
+ end
99
+ end
100
+
101
+ def process_root_container(module_name, container, file)
102
+ operation = :get_config
103
+ loop do
104
+ line = file.gets
105
+ break if !line || line.strip == ''
106
+ if line =~ /^ config false;/ # abort cnr if not config
107
+ operation = :get_oper
108
+ break
109
+ end
110
+ end
111
+
112
+ # only output config or operational data, depending on options
113
+ if @options[:oper]
114
+ return if operation == :get_config
115
+ else
116
+ return if operation != :get_config
117
+ end
118
+
119
+ # guard against duplicate containers
120
+ if @containers.key?(container)
121
+ puts "[ Duplicate container #{container} ]" if @options[:verbose]
122
+ return
123
+ end
124
+
125
+ yang_path = "{\"#{module_name}:#{container}\": [null]}"
126
+
127
+ @containers[container] = true
128
+ @cnrs += 1
129
+
130
+ begin
131
+ data = client.get(data_format: :yang_json,
132
+ command: yang_path,
133
+ mode: operation)
134
+ if data && data.strip.length > 0
135
+ puts "[ Processing container #{container} ]"\
136
+ if @options[:verbose]
137
+ output_data(yang_path, data)
138
+ else
139
+ puts "[ Processing container #{container}: no data returned ]"\
140
+ if @options[:verbose]
141
+ end
142
+ rescue Cisco::ClientError, Cisco::YangError => e
143
+ puts "[ Processing container #{container} ]" if @options[:verbose]
144
+ @errors += 1
145
+ puts "!!Error on '#{yang_path}': #{e}"
146
+ debug e.backtrace
147
+ puts # spacer
148
+ end
149
+ end
150
+
151
+ def output_data(yang_path, data)
152
+ if @options[:manifest]
153
+ puts " cisco_yang { '#{yang_path}':\n"\
154
+ " ensure => present,\n"\
155
+ " source => '#{data.chomp.gsub(/\n/, "\n ")}'\n"\
156
+ ' }'
157
+ else
158
+ puts data
159
+ end
160
+ puts # spacer
161
+ end
162
+
163
+ def client
164
+ unless @client
165
+ puts "[ Connecting to client environment: #{@options[:environment]} ]"\
166
+ if @options[:verbose]
167
+
168
+ @client = Cisco::Client.create(@options[:environment])
169
+
170
+ puts "[ Connected to client: #{@client} ]"\
171
+ if @options[:verbose]
172
+ end
173
+ @client
174
+ rescue Cisco::AuthenticationFailed
175
+ abort 'Unauthorized to connect'
176
+ rescue Cisco::ClientError, TypeError, ArgumentError => e
177
+ abort "Error in establishing connection: #{e}"
178
+ end
179
+ end # YangViewer
180
+ end # Cisco
181
+
182
+ options = { path: '/pkg/yang', environment: 'default' }
183
+ optparse = OptionParser.new do |opts|
184
+ opts.banner = 'Usage: ruby show_running_yang.rb '\
185
+ '[options] [file_or_directory_path]'
186
+
187
+ opts.on('-m', '--manifest', 'Output config in a form suitable '\
188
+ 'for inclusion in a Puppet manifest') do |_arg|
189
+ options[:manifest] = true
190
+ end
191
+
192
+ opts.on('-o', '--oper',
193
+ 'Retrieve operational data instead of configuration '\
194
+ '(warning: possibly returns a lot of data; use at own risk)') do
195
+ options[:oper] = true
196
+ end
197
+
198
+ opts.on('-e', '--environment node', 'The node in cisco_node_utils.yaml '\
199
+ 'from which to retrieve data') do |env|
200
+ options[:environment] = env
201
+ end
202
+
203
+ opts.on('-d', '--debug', 'Enable debug-level logging') do
204
+ Cisco::Logger.level = Logger::DEBUG
205
+ end
206
+
207
+ opts.on('-v', '--verbose', 'Enable verbose messages') do
208
+ options[:verbose] = true
209
+ end
210
+
211
+ opts.on('-h', '--help', 'Print this help') do
212
+ puts optparse
213
+ exit(0)
214
+ end
215
+ end
216
+ optparse.parse!
217
+
218
+ if options[:oper] && options[:manifest]
219
+ STDERR.puts '!! Operational data cannot be set in a manifest, '\
220
+ 'so option -m does not make sense in conjunction with -o.'
221
+ exit(-1)
222
+ end
223
+
224
+ # If there is a single ARGV left, use is as the file/dir path
225
+ if ARGV.length == 1
226
+ options[:path] = ARGV[0]
227
+ elsif ARGV.length > 1
228
+ puts optparse
229
+ exit(-1)
230
+ end
231
+
232
+ ycv = Cisco::YangViewer.new
233
+ ycv.process(options)