cisco_node_utils 0.9.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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +5 -0
  6. data/CONTRIBUTING.md +31 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +201 -0
  9. data/README.md +113 -0
  10. data/Rakefile +4 -0
  11. data/cisco_node_utils.gemspec +30 -0
  12. data/lib/cisco_node_utils.rb +33 -0
  13. data/lib/cisco_node_utils/README_YAML.md +333 -0
  14. data/lib/cisco_node_utils/cisco_cmn_utils.rb +92 -0
  15. data/lib/cisco_node_utils/command_reference.rb +415 -0
  16. data/lib/cisco_node_utils/command_reference_common.yaml +845 -0
  17. data/lib/cisco_node_utils/command_reference_n3064.yaml +13 -0
  18. data/lib/cisco_node_utils/command_reference_n7k.yaml +48 -0
  19. data/lib/cisco_node_utils/command_reference_n9k.yaml +35 -0
  20. data/lib/cisco_node_utils/configparser_lib.rb +196 -0
  21. data/lib/cisco_node_utils/interface.rb +501 -0
  22. data/lib/cisco_node_utils/interface_ospf.rb +241 -0
  23. data/lib/cisco_node_utils/node.rb +673 -0
  24. data/lib/cisco_node_utils/platform.rb +184 -0
  25. data/lib/cisco_node_utils/platform_info.rb +58 -0
  26. data/lib/cisco_node_utils/platform_info.yaml +10 -0
  27. data/lib/cisco_node_utils/router_ospf.rb +96 -0
  28. data/lib/cisco_node_utils/router_ospf_vrf.rb +258 -0
  29. data/lib/cisco_node_utils/snmpcommunity.rb +91 -0
  30. data/lib/cisco_node_utils/snmpgroup.rb +55 -0
  31. data/lib/cisco_node_utils/snmpserver.rb +150 -0
  32. data/lib/cisco_node_utils/snmpuser.rb +342 -0
  33. data/lib/cisco_node_utils/tacacs_server.rb +175 -0
  34. data/lib/cisco_node_utils/tacacs_server_host.rb +128 -0
  35. data/lib/cisco_node_utils/version.rb +17 -0
  36. data/lib/cisco_node_utils/vlan.rb +153 -0
  37. data/lib/cisco_node_utils/vtp.rb +127 -0
  38. data/lib/cisco_node_utils/yum.rb +84 -0
  39. data/tests/basetest.rb +93 -0
  40. data/tests/ciscotest.rb +136 -0
  41. data/tests/cmd_config.yaml +51 -0
  42. data/tests/cmd_config_invalid.yaml +16 -0
  43. data/tests/test_all_cisco.rb +46 -0
  44. data/tests/test_command_config.rb +192 -0
  45. data/tests/test_command_reference.rb +222 -0
  46. data/tests/test_interface.rb +1017 -0
  47. data/tests/test_interface_ospf.rb +763 -0
  48. data/tests/test_interface_svi.rb +267 -0
  49. data/tests/test_interface_switchport.rb +722 -0
  50. data/tests/test_node.rb +108 -0
  51. data/tests/test_node_ext.rb +450 -0
  52. data/tests/test_platform.rb +188 -0
  53. data/tests/test_router_ospf.rb +164 -0
  54. data/tests/test_router_ospf_vrf.rb +753 -0
  55. data/tests/test_snmpcommunity.rb +344 -0
  56. data/tests/test_snmpgroup.rb +71 -0
  57. data/tests/test_snmpserver.rb +443 -0
  58. data/tests/test_snmpuser.rb +803 -0
  59. data/tests/test_tacacs_server.rb +388 -0
  60. data/tests/test_tacacs_server_host.rb +391 -0
  61. data/tests/test_vlan.rb +264 -0
  62. data/tests/test_vtp.rb +319 -0
  63. data/tests/test_yum.rb +106 -0
  64. metadata +188 -0
@@ -0,0 +1,113 @@
1
+ # CiscoNodeUtils - Cisco Node Utilities
2
+
3
+ The CiscoNodeUtils gem provides utilities for management of Cisco network
4
+ nodes. It is designed to work with Puppet and Chef as well as other
5
+ open source management tools. This release supports Cisco NX-OS nodes
6
+ running NX-OS 7.0(3)I2(1) and later.
7
+
8
+ ## Installation
9
+
10
+ To install the CiscoNodeUtils, use the following command:
11
+
12
+ $ gem install cisco_node_utils
13
+
14
+ (Add `sudo` if you're installing under a POSIX system as root)
15
+
16
+ Alternatively, if you've checked the source out directly, you can call
17
+ `rake install` from the root project directory.
18
+
19
+ ## Examples
20
+
21
+ These utilities can be used directly on a Cisco device (as used by Puppet
22
+ and Chef) or can run on a workstation and point to a Cisco device (as used
23
+ by the included minitest suite).
24
+
25
+ ### Usage on a Cisco device
26
+
27
+ ```ruby
28
+ require 'cisco_node_utils'
29
+
30
+ # get a connection to the local device
31
+ node = Cisco::Node.instance()
32
+
33
+ version = node.config_get("show_version", "system_image")
34
+
35
+ node.config_set("vtp", "domain", "mycompany.com")
36
+ ```
37
+
38
+ ### Remote usage
39
+
40
+ ```ruby
41
+ require 'cisco_node_utils'
42
+
43
+ Cisco::Node.lazy_connect = true
44
+
45
+ node = Cisco::Node.instance()
46
+ node.connect("n3k.mycompany.com", "username", "password")
47
+
48
+ version = node.config_get("show_version", "system_image")
49
+
50
+ node.config_set("vtp", "domain", "mycompany.com")
51
+ ```
52
+
53
+ ## Documentation
54
+
55
+ ### Node
56
+
57
+ The `Node` class is a singleton which provides for management of a given Cisco
58
+ network node. It provides the base APIs `config_set`, `config_get`, and
59
+ `config_get_default`.
60
+
61
+ ### CommandReference
62
+
63
+ The `CommandReference` module provides for the abstraction of NX-OS CLI,
64
+ especially to handle its variance between hardware platforms.
65
+ A series of YAML files are used to describe the CLI corresponding to a given
66
+ `(feature, attribute)` tuple for any given platform. When a `Node` is
67
+ connected, the platform identification of the Node is used to construct a
68
+ `CmdRef` object that corresponds to this platform. The `Node` APIs
69
+ `config_set`, `config_get`, and `config_get_default` all rely on the `CmdRef`.
70
+
71
+ See also [README_YAML](lib/cisco_node_utils/README_YAML.md).
72
+
73
+ ### Feature Providers
74
+
75
+ Each feature supported by CiscoNodeUtils has its own class. For example,
76
+ `Cisco::RouterOspf` is the class used to manage OSPF router configuration on
77
+ a `Node`. Each feature class has getters and setters which are wrappers around
78
+ the Node APIs `config_set`, `config_get`, and `config_get_default`.
79
+
80
+ ### Puppet and Chef
81
+
82
+ This library is designed as a shared backend between Puppet and Chef for the
83
+ management of Cisco nodes. Puppet providers and Chef providers alike can use
84
+ the feature provider classes from this module to do the majority of work in
85
+ actually managing device configuration and state. This reduces the amount of
86
+ code duplication between the Cisco Puppet modules and the Cisco Chef cookbooks.
87
+
88
+ Generally speaking, Puppet and Chef should only interact with the feature
89
+ provider classes, and not directly call into `CommandReference` or `Node`.
90
+
91
+ ## Changelog
92
+
93
+ See [CHANGELOG](CHANGELOG.md) for a list of changes.
94
+
95
+ ## Contributing
96
+
97
+ See [CONTRIBUTING](CONTRIBUTING.md) for developer and contributor guidelines.
98
+
99
+ ## License
100
+
101
+ Copyright (c) 2013-2015 Cisco and/or its affiliates.
102
+
103
+ Licensed under the Apache License, Version 2.0 (the "License");
104
+ you may not use this file except in compliance with the License.
105
+ You may obtain a copy of the License at
106
+
107
+ http://www.apache.org/licenses/LICENSE-2.0
108
+
109
+ Unless required by applicable law or agreed to in writing, software
110
+ distributed under the License is distributed on an "AS IS" BASIS,
111
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112
+ See the License for the specific language governing permissions and
113
+ limitations under the License.
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rubocop/rake_task'
3
+
4
+ RuboCop::RakeTask.new
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cisco_node_utils/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cisco_node_utils'
8
+ spec.version = CiscoNodeUtils::VERSION
9
+ spec.authors = ['Alex Hunsberger', 'Glenn Matthews',
10
+ 'Chris Van Heuveln', 'Mike Wiebe', 'Jie Yang']
11
+ spec.email = 'cisco_agent_gem@cisco.com'
12
+ spec.summary = 'Utilities for management of Cisco network nodes'
13
+ spec.description = <<-EOF
14
+ Utilities for management of Cisco network nodes.
15
+ Designed to work with Puppet and Chef.
16
+ Currently supports NX-OS nodes.
17
+ EOF
18
+ spec.license = 'Apache-2.0'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_development_dependency 'minitest', '>= 2.5.1', '< 5.0.0'
26
+ spec.add_development_dependency 'bundler', '~> 1.7'
27
+ spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rubocop', '>= 0.32'
29
+ spec.add_runtime_dependency 'cisco_nxapi', '>= 0.9'
30
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2014-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
+ require "cisco_node_utils/cisco_cmn_utils"
16
+ require "cisco_node_utils/command_reference"
17
+ require "cisco_node_utils/configparser_lib"
18
+ require "cisco_node_utils/interface"
19
+ require "cisco_node_utils/interface_ospf"
20
+ require "cisco_node_utils/node"
21
+ require "cisco_node_utils/platform"
22
+ require "cisco_node_utils/router_ospf"
23
+ require "cisco_node_utils/router_ospf_vrf"
24
+ require "cisco_node_utils/snmpcommunity"
25
+ require "cisco_node_utils/snmpgroup"
26
+ require "cisco_node_utils/snmpserver"
27
+ require "cisco_node_utils/snmpuser"
28
+ require "cisco_node_utils/tacacs_server"
29
+ require "cisco_node_utils/tacacs_server_host"
30
+ require "cisco_node_utils/version"
31
+ require "cisco_node_utils/vlan"
32
+ require "cisco_node_utils/vtp"
33
+ require "cisco_node_utils/yum"
@@ -0,0 +1,333 @@
1
+ # Command Reference YAML
2
+
3
+ The `command_reference_*.yaml` files in this directory are used with the
4
+ `CommandReference` module as a way to abstract away platform CLI differences.
5
+
6
+ This document describes the structure and semantics of these files.
7
+
8
+ ## Structure
9
+
10
+ ```yaml
11
+ FEATURE_1:
12
+ _template:
13
+ # base parameters for all attributes of this feature go here
14
+
15
+ ATTRIBUTE_1:
16
+ config_get: 'string'
17
+ config_get_token: 'string'
18
+ config_get_token_append: 'string'
19
+ config_set: 'string'
20
+ config_set_append: 'string'
21
+ default_value: string, boolean, integer, or constant
22
+ test_config_get: 'string'
23
+ test_config_get_regexp: '/regexp/'
24
+ test_config_result:
25
+ input_1: output_1
26
+ input_2: output_2
27
+
28
+ ATTRIBUTE_2:
29
+ ...
30
+
31
+ ATTRIBUTE_3:
32
+ ...
33
+
34
+ FEATURE_2:
35
+ ...
36
+ ```
37
+
38
+ All parameters are optional and may be omitted if not needed.
39
+
40
+ ### Wildcard substitution
41
+
42
+ The `config_get_token` and `config_set` (and their associated `_append`
43
+ variants) all support two forms of wildcarding - printf-style and key-value.
44
+
45
+ #### Printf-style wildcards
46
+
47
+ ```yaml
48
+ tacacs_server_host:
49
+ encryption:
50
+ config_set: '%s tacacs-server host %s key %s %s'
51
+ ```
52
+
53
+ This permits parameter values to be passed as a simple sequence:
54
+
55
+ ```ruby
56
+ config_set('tacacs_server_host', 'encryption', 'no', 'user', 'md5', 'password')
57
+
58
+ # this becomes 'no tacacs-server host user key md5 password'
59
+ # ^^ ^^^^ ^^^ ^^^^^^^^
60
+ ```
61
+
62
+ This approach is quick to implement and concise, but less flexible - in
63
+ particular it cannot handle a case where different platforms take parameters
64
+ in a different order - and less readable in the ruby code.
65
+
66
+ #### Key-value wildcards
67
+
68
+ ```yaml
69
+ ospf:
70
+ auto_cost:
71
+ config_set: ['router ospf <name>', 'auto-cost reference-bandwidth <cost> <type>']
72
+ ```
73
+
74
+ This requires parameter values to be passed as a hash:
75
+
76
+ ```ruby
77
+ config_set('ospf', 'auto_cost', {:name => 'red',
78
+ :cost => '40',
79
+ :type => 'Gbps'})
80
+
81
+ # this becomes the config sequence:
82
+ # router ospf red
83
+ # auto-cost reference-bandwidth 40 Gbps
84
+ ```
85
+
86
+ This approach is moderately more complex to implement but is more readable in
87
+ the ruby code and is flexible enough to handle significant platform
88
+ differences in CLI. It is therefore the recommended approach for new
89
+ development.
90
+
91
+ ### `_template`
92
+
93
+ The optional `_template` section can be used to define base parameters for all
94
+ attributes of a given feature. For example, all interface attributes might be
95
+ checked with the `show running-config interface all` command, and all
96
+ attributes might be set by first entering the interface configuration submode
97
+ with the `interface <name>` configuration command. Thus, you might have:
98
+
99
+ ```yaml
100
+ interface:
101
+ _template:
102
+ config_get: 'show running-config interface all'
103
+ config_get_token: '/^interface <name>$/'
104
+ config_set: 'interface <name>'
105
+
106
+ access_vlan:
107
+ config_get_token_append: '/^switchport access vlan (.*)$/'
108
+ config_set_append: 'switchport access vlan <number>'
109
+
110
+ description:
111
+ config_get_token_append: '/^description (.*)$/'
112
+ config_set_append: 'description <desc>'
113
+
114
+ ...
115
+ ```
116
+
117
+ instead of the more repetitive (but equally valid):
118
+
119
+ ```yaml
120
+ interface:
121
+ access_vlan:
122
+ config_get: 'show running interface all'
123
+ config_get_token: ['/^interface %s$/i', '/^switchport access vlan (.*)$/']
124
+ config_set: ['interface %s', 'switchport access vlan %s']
125
+
126
+ description:
127
+ config_get: 'show running-config interface all'
128
+ config_get_token: ['/^interface <name>$/i', '/^description (.*)$/']
129
+ config_set: ['interface <name>', 'description <desc>']
130
+
131
+ ...
132
+ ```
133
+
134
+ ### `config_get`
135
+
136
+ `config_get` must be a single string representing the CLI command (usually a
137
+ `show` command) to be used to display the information needed to get the
138
+ current value of this attribute.
139
+
140
+ ```yaml
141
+ config_get: 'show running-config interface <name> all'
142
+ ```
143
+
144
+ ### `config_get_token`
145
+
146
+ `config_get_token` can be a single string, a single regex, an array of strings,
147
+ or an array of regexs.
148
+
149
+ If this value is a string or array of strings, then the `config_get` command
150
+ will be executed to produce _structured_ output and the string(s) will be
151
+ used as lookup keys.
152
+
153
+ ```yaml
154
+ show_version
155
+ cpu:
156
+ config_get: 'show version'
157
+ config_get_token: 'cpu_name'
158
+ # config_get('show_version', 'cpu') returns structured_output['cpu_name']
159
+ ```
160
+
161
+ ```yaml
162
+ inventory:
163
+ productid:
164
+ config_get: 'show inventory'
165
+ config_get_token: ['TABLE_inv', 'ROW_inv', 0, 'productid']
166
+ # config_get('inventory', 'productid') returns
167
+ # structured_output['TABLE_inv']['ROW_inv'][0]['productid']
168
+ ```
169
+
170
+ If this value is a regex or array or regexs, then the `config_get` command
171
+ will be executed to produce _plaintext_ output.
172
+
173
+ For a single regex, it will be used to match against the plaintext.
174
+
175
+ ```yaml
176
+ memory:
177
+ total:
178
+ config_get: 'show system resources'
179
+ config_get_token: '/Memory.* (\S+) total/'
180
+ # config_get('memory', 'total') returns
181
+ # plaintext_output.scan(/Memory.* (\S+) total/)
182
+ ```
183
+
184
+ For an array of regex, then the plaintext is assumed to be hierarchical in
185
+ nature (like `show running-config`) and the regexs are used to filter down
186
+ through the hierarchy.
187
+
188
+ ```yaml
189
+ interface:
190
+ description:
191
+ config_get: 'show running interface all'
192
+ config_get_token: ['/^interface %s$/i', '/^description (.*)/']
193
+ # config_get('interface', 'description', 'Ethernet1/1') gets the plaintext
194
+ # output, finds the subsection under /^interface Ethernet1/1$/i, then finds
195
+ # the line matching /^description (.*)$/ in that subsection
196
+ ```
197
+
198
+ ### `config_get_token_append`
199
+
200
+ When using a `_template` section, an attribute can use
201
+ `config_get_token_append` to extend the `config_get_token` value provided by
202
+ the template instead of replacing it:
203
+
204
+ ```yaml
205
+ interface:
206
+ _template:
207
+ config_get: 'show running-config interface all'
208
+ config_get_token: '/^interface <name>$/'
209
+
210
+ description:
211
+ config_get_token_append: '/^description (.*)$/'
212
+ # config_get_token value for 'description' is now:
213
+ # ['/^interface %s$/i', '/^description (.*)$/']
214
+ ```
215
+
216
+ This can also be used to specify conditional tokens which may or may not be
217
+ used depending on the set of parameters passed into `config_get()`:
218
+
219
+ ```yaml
220
+ bgp:
221
+ _template:
222
+ config_get: 'show running bgp all'
223
+ config_get_token: '/^router bgp <asnum>$/'
224
+ config_get_token_append:
225
+ - '/^vrf <vrf>$/'
226
+
227
+ router_id:
228
+ config_get_token_append: '/^router-id (\S+)$/'
229
+ ```
230
+
231
+ In this example, both `config_get('bgp', 'router_id', {:asnum => '1'})` and
232
+ `config_get('bgp', 'router_id', {:asnum => '1', :vrf => 'red'})` are valid -
233
+ the former will match 'router bgp 1' followed by 'router-id', while the latter
234
+ will match 'router bgp 1' followed by 'vrf red' followed by 'router-id'.
235
+
236
+ ### `config_set`
237
+
238
+ The `config_set` parameter is a string or array of strings representing the
239
+ configuration CLI command(s) used to set the value of the attribute.
240
+
241
+ ```yaml
242
+ interface:
243
+ create:
244
+ config_set: 'interface <name>'
245
+
246
+ description:
247
+ config_set: ['interface <name>', 'description <desc>']
248
+ ```
249
+
250
+ ### `config_set_append`
251
+
252
+ When using a `_template` section, an attribute can use `config_set_append` to
253
+ extend the `config_set` value provided by the template instead of replacing it:
254
+
255
+ ```yaml
256
+ interface:
257
+ _template:
258
+ config_set: 'interface <name>'
259
+
260
+ access_vlan:
261
+ config_set_append: 'switchport access vlan <number>'
262
+ # config_set value for 'access_vlan' is now:
263
+ # ['interface <name>', 'switchport access vlan <number>']
264
+ ```
265
+
266
+ Much like `config_get_token_append`, this can also be used to specify optional
267
+ commands that can be included or omitted as needed:
268
+
269
+ ```yaml
270
+ bgp:
271
+ _template:
272
+ config_set: 'router bgp <asnum>'
273
+ config_set_append:
274
+ - 'vrf <vrf>'
275
+ ```
276
+
277
+ ### `default_value`
278
+
279
+ If there is a default value for this attribute when not otherwise specified by
280
+ the user, the `default_value` parameter describes it. This can be a string,
281
+ boolean, integer, or array.
282
+
283
+ ```yaml
284
+ interface:
285
+ description:
286
+ default_value: ''
287
+
288
+ interface_ospf:
289
+ hello_interval:
290
+ default_value: 10
291
+
292
+ ospf:
293
+ auto_cost:
294
+ default_value: [40, 'Gbps']
295
+ ```
296
+
297
+ ### `test_config_get` and `test_config_get_regex`
298
+
299
+ Test-only equivalents to `config_get` and `config_get_token` - a show command
300
+ to be executed over telnet by the minitest unit test scripts, and a regex
301
+ (or array thereof) to match in the resulting plaintext output.
302
+ Should only be referenced by test scripts, never by a feature provider itself.
303
+
304
+ ```yaml
305
+ show_version:
306
+ boot_image:
307
+ test_config_get: 'show version | no-more'
308
+ test_config_get_regex: '/NXOS image file is: (.*)$/'
309
+ ```
310
+
311
+ ### `test_config_result`
312
+
313
+ Test-only container for input-result pairs that might differ by platform.
314
+ Should only be referenced by test scripts, never by a feature provider itself.
315
+
316
+ ```yaml
317
+ vtp:
318
+ version:
319
+ test_config_result:
320
+ 3: 'Cisco::CliError'
321
+ ```
322
+
323
+ ## Style Guide
324
+
325
+ Please keep all feature names in alphabetical order, and all options under a
326
+ feature in alphabetical order as well. As YAML permits duplicate entries
327
+ (in which case the last entry overrides any earlier entries), keeping a
328
+ consistent order helps to prevent accidentally introducing such duplication.
329
+
330
+ Note that `~` is the YAML syntax that corresponds to Ruby's `nil`.
331
+
332
+ Use the key-value wildcarding style wherever possible, as it's more flexible
333
+ than the printf-style wildcarding.