rbeapi 0.1.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 (60) hide show
  1. data/.gitignore +35 -0
  2. data/Gemfile +25 -0
  3. data/Guardfile +15 -0
  4. data/LICENSE +28 -0
  5. data/README.md +218 -0
  6. data/Rakefile +12 -0
  7. data/lib/rbeapi.rb +32 -0
  8. data/lib/rbeapi/api.rb +135 -0
  9. data/lib/rbeapi/api/aaa.rb +410 -0
  10. data/lib/rbeapi/api/dns.rb +198 -0
  11. data/lib/rbeapi/api/interfaces.rb +1193 -0
  12. data/lib/rbeapi/api/ipinterfaces.rb +328 -0
  13. data/lib/rbeapi/api/logging.rb +157 -0
  14. data/lib/rbeapi/api/mlag.rb +519 -0
  15. data/lib/rbeapi/api/ntp.rb +201 -0
  16. data/lib/rbeapi/api/ospf.rb +214 -0
  17. data/lib/rbeapi/api/prefixlists.rb +98 -0
  18. data/lib/rbeapi/api/radius.rb +317 -0
  19. data/lib/rbeapi/api/radius.rb.old +399 -0
  20. data/lib/rbeapi/api/routemaps.rb +100 -0
  21. data/lib/rbeapi/api/snmp.rb +427 -0
  22. data/lib/rbeapi/api/staticroutes.rb +88 -0
  23. data/lib/rbeapi/api/stp.rb +381 -0
  24. data/lib/rbeapi/api/switchports.rb +272 -0
  25. data/lib/rbeapi/api/system.rb +87 -0
  26. data/lib/rbeapi/api/tacacs.rb +236 -0
  27. data/lib/rbeapi/api/varp.rb +181 -0
  28. data/lib/rbeapi/api/vlans.rb +338 -0
  29. data/lib/rbeapi/client.rb +454 -0
  30. data/lib/rbeapi/eapilib.rb +334 -0
  31. data/lib/rbeapi/netdev/snmp.rb +370 -0
  32. data/lib/rbeapi/utils.rb +70 -0
  33. data/lib/rbeapi/version.rb +37 -0
  34. data/rbeapi.gemspec +32 -0
  35. data/spec/fixtures/dut.conf +5 -0
  36. data/spec/spec_helper.rb +22 -0
  37. data/spec/support/fixtures.rb +114 -0
  38. data/spec/support/shared_examples_for_api_modules.rb +124 -0
  39. data/spec/system/api_ospf_interfaces_spec.rb +58 -0
  40. data/spec/system/api_ospf_spec.rb +111 -0
  41. data/spec/system/api_varp_interfaces_spec.rb +60 -0
  42. data/spec/system/api_varp_spec.rb +44 -0
  43. data/spec/system/rbeapi/api/dns_spec.rb +77 -0
  44. data/spec/system/rbeapi/api/interfaces_base_spec.rb +94 -0
  45. data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +135 -0
  46. data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +188 -0
  47. data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +115 -0
  48. data/spec/system/rbeapi/api/ipinterfaces_spec.rb +97 -0
  49. data/spec/system/rbeapi/api/logging_spec.rb +65 -0
  50. data/spec/system/rbeapi/api/mlag_interfaces_spec.rb +80 -0
  51. data/spec/system/rbeapi/api/mlag_spec.rb +94 -0
  52. data/spec/system/rbeapi/api/ntp_spec.rb +76 -0
  53. data/spec/system/rbeapi/api/snmp_spec.rb +68 -0
  54. data/spec/system/rbeapi/api/stp_instances_spec.rb +61 -0
  55. data/spec/system/rbeapi/api/stp_interfaces_spec.rb +71 -0
  56. data/spec/system/rbeapi/api/stp_spec.rb +57 -0
  57. data/spec/system/rbeapi/api/switchports_spec.rb +135 -0
  58. data/spec/system/rbeapi/api/system_spec.rb +38 -0
  59. data/spec/system/rbeapi/api/vlans_spec.rb +121 -0
  60. metadata +274 -0
@@ -0,0 +1,519 @@
1
+ #
2
+ # Copyright (c) 2014, Arista Networks, Inc.
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # Neither the name of Arista Networks nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
24
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+ require 'rbeapi/api'
33
+
34
+ module Rbeapi
35
+
36
+ module Api
37
+
38
+ ##
39
+ # The Mlag class provides a configuration instance for working with
40
+ # the global MLAG configuration of the node
41
+ class Mlag < Entity
42
+
43
+ DEFAULT_DOMAIN_ID = ''
44
+ DEFAULT_LOCAL_INTF = ''
45
+ DEFAULT_PEER_ADDR = ''
46
+ DEFAULT_PEER_LINK = ''
47
+
48
+ ##
49
+ # get returns the mlag configuration from the node as a resource hash
50
+ #
51
+ # @example
52
+ # {
53
+ # domain_id: <string>
54
+ # local_interface: <string>
55
+ # peer_address: <string>
56
+ # peer_link: <string>
57
+ # shutdown: [true, false]
58
+ # interfaces: {...}
59
+ # }
60
+ #
61
+ # @see MlagInterfaces interface resource message
62
+ #
63
+ # @return [nil, Hash<Symbol, Object] returns the nodes current running
64
+ # configuration as a Hash. If mlag is not configured on the node this
65
+ # method will return nil
66
+ def get()
67
+ config = get_block('mlag configuration')
68
+ response = {}
69
+ response.merge!(parse_domain_id(config))
70
+ response.merge!(parse_local_interface(config))
71
+ response.merge!(parse_peer_address(config))
72
+ response.merge!(parse_peer_link(config))
73
+ response.merge!(parse_shutdown(config))
74
+ response[:interfaces] = interfaces.getall
75
+ response
76
+ end
77
+
78
+ ##
79
+ # parse_domain_id scans the current nodes running configuration and
80
+ # extracts the mlag domain-id value. If the mlag domain-id has not been
81
+ # configured, then this method will return DEFAULT_DOMAIN_ID. The return
82
+ # value is intended to be merged into the resource hash
83
+ #
84
+ # @api private
85
+ #
86
+ # @param [String] :config The mlag configuration block retrieved from the
87
+ # nodes current running configuration.
88
+ #
89
+ # @return [Hash<Symbol, Object>] resource hash attribute
90
+ def parse_domain_id(config)
91
+ mdata = /(?<=\s{3}domain-id\s)(.+)$/.match(config)
92
+ { domain_id: mdata.nil? ? DEFAULT_DOMAIN_ID : mdata[1] }
93
+ end
94
+ private :parse_domain_id
95
+
96
+ ##
97
+ # parse_local_interface scans the current nodes running configuration and
98
+ # extracts the mlag local-interface value. If the mlag local-interface
99
+ # has not been configured, this method will return DEFAULT_LOCAL_INTF.
100
+ # The return value is intended to be merged into the resource hash
101
+ #
102
+ # @api private
103
+ #
104
+ # @param [String] :config The mlag configuration block retrieved from the
105
+ # nodes current running configuration.
106
+ #
107
+ # @return [Hash<Symbol, Object>] resource hash attribute
108
+ def parse_local_interface(config)
109
+ mdata = /(?<=\s{3}local-interface\s)(.+)$/.match(config)
110
+ { local_interface: mdata.nil? ? DEFAULT_LOCAL_INTF : mdata[1] }
111
+ end
112
+ private :parse_local_interface
113
+
114
+ ##
115
+ # parse_peer_address scans the current nodes running configuration and
116
+ # extracts the mlag peer-address value. If the mlag peer-address has not
117
+ # been configured, this method will return DEFAULT_PEER_ADDR. The return
118
+ # value is intended to be merged into the resource hash.
119
+ #
120
+ # @api private
121
+ #
122
+ # @param [String] :config The mlag configuration block retrieved from the
123
+ # nodes current running configuration.
124
+ #
125
+ # @return [Hash<Symbol, Object>] resource hash attribute
126
+ def parse_peer_address(config)
127
+ mdata = /(?<=\s{3}peer-address\s)(.+)$/.match(config)
128
+ { peer_address: mdata.nil? ? DEFAULT_PEER_ADDR : mdata[1] }
129
+ end
130
+ private :parse_peer_address
131
+
132
+ ##
133
+ # parse_peer_link scans the current nodes running configuration and
134
+ # extracts the mlag peer-link value. If the mlag peer-link hash not been
135
+ # configure, this method will return DEFAULT_PEER_LINK. The return value
136
+ # is intended to be merged into the resource hash.
137
+ #
138
+ # @api private
139
+ #
140
+ # @param [String] :config The mlag configuration block retrieved from the
141
+ # nodes current running configuration.
142
+ #
143
+ # @return [Hash<Symbol, Object>] resource hash attribute
144
+ def parse_peer_link(config)
145
+ mdata = /(?<=\s{3}peer-link\s)(.+)$/.match(config)
146
+ { peer_link: mdata.nil? ? DEFAULT_PEER_LINK : mdata[1] }
147
+ end
148
+ private :parse_peer_link
149
+
150
+ ##
151
+ # parse_shutdown scans the current nodes mlag configuration and extracts
152
+ # the mlag shutdown value. The mlag configuration should always return
153
+ # the value of shutdown from the configuration block. Ths return value
154
+ # is intended to be merged into the resource hash.
155
+ #
156
+ # @api private
157
+ #
158
+ # @param [String] :config The mlag configuration block retrieved from the
159
+ # nodes current running configuration.
160
+ #
161
+ # @return [Hash<Symbol, Object>] resource hash attribute
162
+ def parse_shutdown(config)
163
+ value = /\s{3}no shutdown/ !~ config
164
+ { shutdown: value }
165
+ end
166
+ private :parse_shutdown
167
+
168
+ ##
169
+ # interfaces returns a memoized instance of MlagInterfaces that provide
170
+ # an api for working with mlag interfaces in the nodes current
171
+ # configuration.
172
+ #
173
+ # @see MlagInterfaces
174
+ #
175
+ # @return [Object] returns an instance of MlagInterfaces
176
+ def interfaces
177
+ return @interfaces if @interfaces
178
+ @interfaces = MlagInterfaces.new(node)
179
+ @interfaces
180
+ end
181
+
182
+ ##
183
+ # set_domain_id configures the mlag domain-id value in the current nodes
184
+ # running configuration. If the value keyword is not provided, the
185
+ # domain-id is configured with the no keyword. If the default keyword is
186
+ # provided, the configuration is defaulted using the default keyword.
187
+ # The default keyword takes precedence over the value keywork if both
188
+ # options are specified
189
+ #
190
+ # @eos_version 4.13.7M
191
+ #
192
+ # @commands
193
+ # mlag configuration
194
+ # domain-id <value>
195
+ # no domain-id
196
+ # default domain-id
197
+ #
198
+ # @param [Hash] :opts Optional keyword arguments
199
+ #
200
+ # @option :opts [String] :value The value to configurue the mlag
201
+ # domain-id to.
202
+ #
203
+ # @option :opts [Boolean] :default Configure the domain-id value using
204
+ # the default keyword
205
+ #
206
+ # @return [Boolean] returns true if the command completed successfully
207
+ def set_domain_id(opts = {})
208
+ value = opts[:value]
209
+ default = opts[:default] || false
210
+
211
+ cmds = ['mlag configuration']
212
+ case default
213
+ when true
214
+ cmds << 'default domain-id'
215
+ when false
216
+ cmds << (value ? "domain-id #{value}" : 'no domain-id')
217
+ end
218
+ configure(cmds)
219
+ end
220
+
221
+ ##
222
+ # set_local_interface configures the mlag local-interface value in the
223
+ # current nodes running configuration. If the value keyword is not
224
+ # provided, the local-interface is configured with the no keyword. If
225
+ # the default keyword is provided, the configuration is defaulted using
226
+ # the default keyword. The default keyword takes precedence over the
227
+ # value keywork if both options are specified
228
+ #
229
+ # @eos_version 4.13.7M
230
+ #
231
+ # @commands
232
+ # mlag configuration
233
+ # local-interface <value>
234
+ # no local-interface
235
+ # default local-interface
236
+ #
237
+ # @param [Hash] :opts Optional keyword arguments
238
+ #
239
+ # @option :opts [String] :value The value to configurue the mlag
240
+ # local-interface to. The local-interface accepts full interface
241
+ # identifiers and expects a Vlan interface
242
+ #
243
+ # @option :opts [Boolean] :default Configure the local-interface value
244
+ # using the default keyword
245
+ #
246
+ # @return [Boolean] returns true if the command completed successfully
247
+ def set_local_interface(opts = {})
248
+ value = opts[:value]
249
+ default = opts[:default] || false
250
+
251
+ cmds = ['mlag configuration']
252
+ case default
253
+ when true
254
+ cmds << 'default local-interface'
255
+ when false
256
+ cmds << (value ? "local-interface #{value}" : 'no local-interface')
257
+ end
258
+ configure(cmds)
259
+ end
260
+
261
+ ##
262
+ # set_peer_link configures the mlag peer-link value in the current nodes
263
+ # running configuration. If the value keyword is not provided, the
264
+ # peer-link is configured with the no keyword. If the default keyword
265
+ # is provided, the configuration is defaulted using the default keyword.
266
+ # The default keyword takes precedence over the value keywork if both
267
+ # options are specified
268
+ #
269
+ # @eos_version 4.13.7M
270
+ #
271
+ # @commands
272
+ # mlag configuration
273
+ # peer-link <value>
274
+ # no peer-link
275
+ # default peer-link
276
+ #
277
+ # @param [Hash] :opts Optional keyword arguments
278
+ #
279
+ # @option :opts [String] :value The value to configurue the mlag
280
+ # peer-link to. The peer-link accepts full interface identifiers
281
+ # and expects an Ethernet or Port-Channel interface
282
+ #
283
+ # @option :opts [Boolean] :default Configure the peer-link using the
284
+ # default keyword
285
+ #
286
+ # @return [Boolean] returns true if the command completed successfully
287
+ def set_peer_link(opts = {})
288
+ value = opts[:value]
289
+ default = opts[:default] || false
290
+
291
+ cmds = ['mlag configuration']
292
+ case default
293
+ when true
294
+ cmds << 'default peer-link'
295
+ when false
296
+ cmds << (value ? "peer-link #{value}" : 'no peer-link')
297
+ end
298
+ configure(cmds)
299
+ end
300
+
301
+ ##
302
+ # set_peer_address configures the mlag peer-address value in the current
303
+ # nodes running configuration. If the value keyword is not provided, the
304
+ # peer-address is configured with the no keyword. If the default keyword
305
+ # is provided, the configuration is defaulted using the default keyword.
306
+ # The default keyword takes precedence over the value keywork if both
307
+ # options are specified
308
+ #
309
+ # @eos_version 4.13.7M
310
+ #
311
+ # @commands
312
+ # mlag configuration
313
+ # peer-address <value>
314
+ # no peer-address
315
+ # default peer-address
316
+ #
317
+ # @param [Hash] :opts Optional keyword arguments
318
+ #
319
+ # @option :opts [String] :value The value to configurue the mlag
320
+ # peer-address to. The peer-address accepts an IP address in the form
321
+ # of A.B.C.D/E
322
+ #
323
+ # @option :opts [Boolean] :default Configure the peer-address using the
324
+ # default keyword
325
+ #
326
+ # @return [Boolean] returns true if the command completed successfully
327
+ def set_peer_address(opts = {})
328
+ value = opts[:value]
329
+ default = opts[:default] || false
330
+
331
+ cmds = ['mlag configuration']
332
+ case default
333
+ when true
334
+ cmds << 'default peer-address'
335
+ when false
336
+ cmds << (value ? "peer-address #{value}" : 'no peer-address')
337
+ end
338
+ configure(cmds)
339
+ end
340
+
341
+ ##
342
+ # set_shutdown configures the administrative state of the mlag process on
343
+ # the current node. If the value is true, then mlag is enabled and if
344
+ # the value is false, then mlag is disabled. If no value is provided,
345
+ # the shutdown command is configured using the no keyword argument. If
346
+ # the default keyword is provided, the configuration is defaulted using
347
+ # the default keyword. The default keyword takes precedence over the
348
+ # value keywork if both options are specified
349
+ #
350
+ # @eos_version 4.13.7M
351
+ #
352
+ # @commands
353
+ # mlag configuration
354
+ # shutdown
355
+ # no shutdown
356
+ # default shutdown
357
+ #
358
+ # @param [Hash] :opts Optional keyword arguments
359
+ #
360
+ # @option :opts [Boolean] :value Enables the mlag configuration if value
361
+ # is true or disables the mlag configuration if value is false.
362
+ #
363
+ # @option :opts [Boolean] :default Configure the shutdown value using the
364
+ # default keyword
365
+ #
366
+ # @return [Boolean] returns true if the command completed successfully
367
+ def set_shutdown(opts = {})
368
+ value = opts[:value]
369
+ default = opts[:default] || false
370
+
371
+ cmds = ['mlag configuration']
372
+ case default
373
+ when true
374
+ cmds << 'default shutdown'
375
+ when false
376
+ cmds << (value ? 'shutdown' : 'no shutdown')
377
+ end
378
+ configure(cmds)
379
+ end
380
+ end
381
+
382
+ class MlagInterfaces < Entity
383
+
384
+ ##
385
+ # get returns the mlag interface configuration as a hash object. If the
386
+ # specified interface name is not configured as an mlag interface this
387
+ # method will return nil
388
+ #
389
+ # @example
390
+ # {
391
+ # mlag_id: <string>
392
+ # }
393
+ #
394
+ # @param [String] :name The full interface name of the interface to
395
+ # return the mlag interface hash for.
396
+ #
397
+ # @return [nil, Hash<Symbol, Object>] returns the interface configuration
398
+ # as a resource hash. If the interface is not configured as an mlag
399
+ # interface nil is returned.
400
+ def get(name)
401
+ config = get_block("^interface #{name}")
402
+ return nil unless config
403
+ mdata = /(?<=\s{3}mlag\s)(.+)$/.match(config)
404
+ return nil unless mdata
405
+ { mlag_id: mdata[1] }
406
+ end
407
+
408
+ ##
409
+ # getall scans the nodes current running configuration and returns a
410
+ # hash of all mlag interfaces keyed by the interface name. If no
411
+ # interfaces are configured, an empty hash object is returned
412
+ #
413
+ # @see get Interface resource example
414
+ #
415
+ # @return [Hash<String, Hash>] returns the nodes mlag interface
416
+ # configurations as a hash
417
+ def getall
418
+ names = config.scan(/(?<=^interface\s)Po.+/)
419
+ names.each_with_object({}) do |name, response|
420
+ data = get name
421
+ response[name] = data if data
422
+ end
423
+ end
424
+
425
+ ##
426
+ # create adds a new mlag interface to the nodes current running
427
+ # configuration. If the specified interface already exists, then this
428
+ # method will return successfully with the updated mlag id.
429
+ #
430
+ # @see set_mlag_id
431
+ #
432
+ # @param [String] :name The name of of the interface to create. The name
433
+ # must be the full interface name. The value of name is expected to
434
+ # be a Port-Channel interface.
435
+ #
436
+ # @param [String, Integer] :id The value of the mlag id to configure for
437
+ # the specified interface. Valid mlag ids are in the range of 1 to
438
+ # 2000.
439
+ #
440
+ # @return [Boolean] returns true if the command completed successfully
441
+ def create(name, id)
442
+ set_mlag_id(name, value: id)
443
+ end
444
+
445
+ ##
446
+ # delete removes a mlag interface from the nodes current running
447
+ # configuration. If the specified interface does not exist as a mlag
448
+ # interface this method will return successfully
449
+ #
450
+ # @see set_mlag_id
451
+ #
452
+ # @param [String] :name The name of of the interface to remove. The name
453
+ # must be the full interface name.
454
+ #
455
+ # @return [Boolean] returns true if the command completed successfully
456
+ def delete(name)
457
+ set_mlag_id(name)
458
+ end
459
+
460
+ ##
461
+ # default configures a mlag interface using the default keyword. If the
462
+ # specified interface does not exist as a mlag interface this method
463
+ # will return successfully
464
+ #
465
+ # @see set_mlag_id
466
+ #
467
+ # @param [String] :name The name of of the interface to create. The name
468
+ # must be the full interface name.
469
+ #
470
+ # @return [Boolean] returns true if the command completed successfully
471
+ def default(name)
472
+ set_mlag_id(name, default: true)
473
+ end
474
+
475
+ ##
476
+ # set_mlag_id configures the mlag id on the interface in the nodes
477
+ # current running configuration. If the value is not specified, then the
478
+ # interface mlag id is configured using the no keyword. If the default
479
+ # keyword is provided and set to true, the interface mlag id is
480
+ # configured using the default keyword. The default keyword takes
481
+ # precedence over the value keyword if both options are specified
482
+ #
483
+ # @eos_version 4.13.7M
484
+ #
485
+ # @commands
486
+ # interface <name>
487
+ # mlag <value>
488
+ # no mlag
489
+ # default mlag
490
+ #
491
+ # @param [String] :name The full interface identifier of the interface
492
+ # to confgure th mlag id for.
493
+ #
494
+ # @param [Hash] :opts Optional keyword arguments
495
+ #
496
+ # @option :opts [String, Integer] :value The value to configure the
497
+ # interface mlag to. The mlag id should be in the valid range of 1 to
498
+ # 2000
499
+ #
500
+ # @option :opts [Boolean] :default Configure the mlag value using the
501
+ # default keyword
502
+ #
503
+ # @return [Boolean] returns true if the command completed successfully
504
+ def set_mlag_id(name, opts = {})
505
+ value = opts[:value]
506
+ default = opts[:default] || false
507
+
508
+ cmds = ["interface #{name}"]
509
+ case default
510
+ when true
511
+ cmds << 'default mlag'
512
+ when false
513
+ cmds << (value ? "mlag #{value}" : 'no mlag')
514
+ end
515
+ configure(cmds)
516
+ end
517
+ end
518
+ end
519
+ end