rbeapi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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