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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +1 -0
- data/README.md +44 -43
- data/bin/.rubocop.yml +18 -0
- data/bin/show_running_yang.rb +233 -0
- data/cisco_node_utils.gemspec +1 -1
- data/docs/README-maintainers.md +1 -0
- data/docs/README-utilities.md +14 -0
- data/lib/.rubocop.yml +1 -1
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +8 -3
- data/lib/cisco_node_utils/aaa_authorization_service.rb +6 -0
- data/lib/cisco_node_utils/bfd_global.rb +300 -0
- data/lib/cisco_node_utils/bgp.rb +6 -4
- data/lib/cisco_node_utils/bgp_af.rb +2 -0
- data/lib/cisco_node_utils/bgp_neighbor.rb +14 -0
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +4 -1
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +126 -0
- data/lib/cisco_node_utils/client/client.rb +6 -2
- data/lib/cisco_node_utils/client/grpc/client.rb +120 -36
- data/lib/cisco_node_utils/client/nxapi/client.rb +6 -2
- data/lib/cisco_node_utils/cmd_ref/DEPRECATED.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +14 -0
- data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +7 -7
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +125 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +141 -49
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +44 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +0 -3
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +3 -3
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +39 -15
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +43 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +48 -19
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +0 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +30 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +4 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +1 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +23 -10
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +8 -2
- data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +10 -1
- data/lib/cisco_node_utils/constants.rb +8 -1
- data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
- data/lib/cisco_node_utils/exceptions.rb +29 -0
- data/lib/cisco_node_utils/feature.rb +28 -0
- data/lib/cisco_node_utils/interface.rb +493 -402
- data/lib/cisco_node_utils/interface_DEPRECATED.rb +513 -0
- data/lib/cisco_node_utils/interface_ospf.rb +126 -0
- data/lib/cisco_node_utils/interface_portchannel.rb +16 -0
- data/lib/cisco_node_utils/logger.rb +3 -0
- data/lib/cisco_node_utils/node.rb +29 -1
- data/lib/cisco_node_utils/overlay_global.rb +1 -12
- data/lib/cisco_node_utils/pim.rb +1 -0
- data/lib/cisco_node_utils/pim_group_list.rb +1 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -0
- data/lib/cisco_node_utils/platform.rb +9 -2
- data/lib/cisco_node_utils/router_ospf.rb +1 -1
- data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
- data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +17 -0
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +27 -9
- data/lib/cisco_node_utils/snmpcommunity.rb +34 -8
- data/lib/cisco_node_utils/snmpserver.rb +4 -4
- data/lib/cisco_node_utils/snmpuser.rb +0 -0
- data/lib/cisco_node_utils/tacacs_global.rb +102 -0
- data/lib/cisco_node_utils/tacacs_server.rb +8 -7
- data/lib/cisco_node_utils/vdc.rb +25 -7
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +30 -56
- data/lib/cisco_node_utils/vlan_DEPRECATED.rb +108 -0
- data/lib/cisco_node_utils/yang.rb +160 -0
- data/lib/cisco_node_utils/yum.rb +25 -32
- data/tests/.rubocop.yml +3 -0
- data/tests/ciscotest.rb +136 -19
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/noop.rb +7 -0
- data/tests/tacacs_server.yaml.example +6 -0
- data/tests/test_aaa_authentication_login.rb +24 -1
- data/tests/test_aaa_authentication_login_service.rb +9 -16
- data/tests/test_aaa_authorization_service.rb +111 -84
- data/tests/test_bfd_global.rb +278 -0
- data/tests/test_bgp_neighbor.rb +20 -0
- data/tests/test_bridge_domain_vni.rb +2 -9
- data/tests/test_cmn_utils.rb +76 -0
- data/tests/test_dhcp_relay_global.rb +284 -0
- data/tests/test_dns_domain.rb +4 -4
- data/tests/test_domain_name.rb +2 -2
- data/tests/test_encapsulation.rb +2 -4
- data/tests/test_evpn_vni.rb +14 -7
- data/tests/test_fabricpath_global.rb +12 -13
- data/tests/test_feature.rb +35 -17
- data/tests/test_interface.rb +352 -127
- data/tests/test_interface_bdi.rb +2 -2
- data/tests/test_interface_channel_group.rb +1 -1
- data/tests/test_interface_ospf.rb +153 -23
- data/tests/test_interface_portchannel.rb +15 -6
- data/tests/test_interface_private_vlan.rb +200 -576
- data/tests/test_interface_svi.rb +5 -52
- data/tests/test_interface_switchport.rb +80 -240
- data/tests/test_itd_device_group.rb +2 -2
- data/tests/test_itd_device_group_node.rb +2 -2
- data/tests/test_itd_service.rb +1 -1
- data/tests/test_name_server.rb +3 -3
- data/tests/test_node_ext.rb +15 -17
- data/tests/test_ntp_config.rb +1 -1
- data/tests/test_ntp_server.rb +3 -3
- data/tests/test_nxapi.rb +1 -0
- data/tests/test_overlay_global.rb +15 -19
- data/tests/test_pim.rb +5 -5
- data/tests/test_pim_group_list.rb +1 -37
- data/tests/test_pim_rp_address.rb +1 -1
- data/tests/test_platform.rb +9 -11
- data/tests/test_portchannel_global.rb +43 -3
- data/tests/test_radius_server.rb +1 -1
- data/tests/test_radius_server_group.rb +1 -1
- data/tests/test_router_bgp.rb +17 -30
- data/tests/test_router_ospf_area.rb +433 -0
- data/tests/test_router_ospf_area_vlink.rb +298 -0
- data/tests/test_router_ospf_vrf.rb +17 -0
- data/tests/test_snmp_notification_receiver.rb +11 -11
- data/tests/test_snmpcommunity.rb +177 -69
- data/tests/test_snmpgroup.rb +7 -7
- data/tests/test_snmpserver.rb +164 -253
- data/tests/test_snmpuser.rb +73 -69
- data/tests/test_stp_global.rb +15 -15
- data/tests/test_syslog_settings.rb +1 -1
- data/tests/test_tacacs_global.rb +80 -0
- data/tests/test_tacacs_server.rb +129 -51
- data/tests/test_tacacs_server_group.rb +3 -29
- data/tests/test_tacacs_server_host.rb +24 -27
- data/tests/test_vlan.rb +57 -59
- data/tests/test_vlan_private.rb +271 -284
- data/tests/test_vpc.rb +10 -4
- data/tests/test_vrf.rb +2 -0
- data/tests/test_vrf_af.rb +2 -5
- data/tests/test_vtp.rb +5 -2
- data/tests/test_vxlan_vtep.rb +20 -44
- data/tests/test_vxlan_vtep_vni.rb +23 -16
- data/tests/test_yang.rb +369 -0
- data/tests/test_yum.rb +34 -42
- data/tests/yum_package.yaml +35 -0
- metadata +31 -4
- data/tests/test_vlan_mt_full.rb +0 -85
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e72699d560ddb617cfe0a637565d0313ba7ba9f6
|
|
4
|
+
data.tar.gz: a25d1820c2a7bc3bf28ef1fdc79c2124bbb51b49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5a0cbafbb485e2c47fa4ab9bab300c713ecaba4609fc23f8f8bcf940019d74c5cd054e7e637fd50ab381bdb1cf2a7d27eb7326ca236ccab6537f66a2e6494aa
|
|
7
|
+
data.tar.gz: 7ed873f928991caf6088cf48753af8bb0ec9afc5e1c005aa5da49f82cea8c3cfea52843fb7673173ffac940eb1c846b09100018a8f12a5bcd8bcdf59e3da2635
|
data/.gitignore
CHANGED
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
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
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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)
|