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,1193 @@
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
+ require 'rbeapi/utils'
34
+
35
+ module Rbeapi
36
+
37
+ module Api
38
+
39
+ class Interfaces < Entity
40
+
41
+ METHODS = [:create, :delete, :default]
42
+
43
+ def initialize(node)
44
+ super(node)
45
+ @instances = {}
46
+ end
47
+
48
+ def get(name)
49
+ get_instance(name).get(name)
50
+ end
51
+
52
+ def getall
53
+ interfaces = config.scan(/(?<=^interface\s).+$/)
54
+
55
+ interfaces.each_with_object({}) do |name, hsh|
56
+ data = get(name)
57
+ hsh[name] = data if data
58
+ end
59
+ end
60
+
61
+ def get_instance(name)
62
+ name = name[0,2].upcase
63
+ case name
64
+ when 'ET'
65
+ cls = 'Rbeapi::Api::EthernetInterface'
66
+ when 'PO'
67
+ cls = 'Rbeapi::Api::PortchannelInterface'
68
+ when 'VX'
69
+ cls = 'Rbeapi::Api::VxlanInterface'
70
+ else
71
+ cls = 'Rbeapi::Api::BaseInterface'
72
+ end
73
+
74
+ return @instances[name] if @instances.include?(cls)
75
+ instance = Rbeapi::Utils.class_from_string(cls).new(@node)
76
+ @instances[name] = instance
77
+ instance
78
+ end
79
+
80
+ def method_missing(method_name, *args, &block)
81
+ if method_name.to_s =~ /set_(.*)/ || METHODS.include?(method_name)
82
+ instance = get_instance(args[0])
83
+ instance.send(method_name.to_sym, *args, &block)
84
+ end
85
+ end
86
+
87
+ def respond_to?(method_name, name = nil)
88
+ return super unless name
89
+ instance = get_instance(name)
90
+ instance.respond_to?(method_name) || super
91
+ end
92
+
93
+ end
94
+
95
+ ##
96
+ # The BaseInterface class extends Entity and provides an implementation
97
+ # that is common to all interfaces configured in EOS.
98
+ class BaseInterface < Entity
99
+
100
+ DEFAULT_INTF_DESCRIPTION = ''
101
+
102
+ ##
103
+ # get returns the specified interface resource hash that represents the
104
+ # node's current interface configuration. The BaseInterface class
105
+ # provides all the set of attributres that are common to all interfaces
106
+ # in EOS. This method will return an interface type of generic
107
+ #
108
+ # @example
109
+ # {
110
+ # name: <string>
111
+ # type: 'generic'
112
+ # description: <string>
113
+ # shutdown: [true, false]
114
+ # }
115
+ #
116
+ # @param [String] :name The name of the interface to return from the
117
+ # running-configuration
118
+ #
119
+ # @return [nil, Hash<String, Object>] Returns a hash of the interface
120
+ # properties if the interface name was found in the running
121
+ # configuration. If the interface was not found, nil is returned
122
+ def get(name)
123
+ config = get_block("^interface #{name}")
124
+ return nil unless config
125
+
126
+ response = { name: name, type: 'generic' }
127
+ response.merge!(parse_description(config))
128
+ response.merge!(parse_shutdown(config))
129
+ response
130
+ end
131
+
132
+ ##
133
+ # parse_description scans the provided configuration block and parses
134
+ # the description value if it exists in the cofiguration. If the
135
+ # description value is not configured, then the DEFALT_INTF_DESCRIPTION
136
+ # value is returned. The hash returned by this method is inteded to be
137
+ # merged into the interface resource hash returned by the get method.
138
+ #
139
+ # @api private
140
+ #
141
+ # @eturn [Hash<Symbol, Object>] resource hash attribute
142
+ def parse_description(config)
143
+ mdata = /^\s{3}description\s(.+)$/.match(config)
144
+ { description: mdata.nil? ? DEFAULT_INTF_DESCRIPTION : mdata[1] }
145
+ end
146
+ private :parse_description
147
+
148
+ ##
149
+ # parse_shutdown scans the provided configuration block and parses
150
+ # the shutdown value. If the shutdown value is configured then true
151
+ # is returned as its value otherwise false is returned. The hash
152
+ # returned by this method is intended to be merged into the interface
153
+ # ressource hash returned by the get method.
154
+ #
155
+ # @api private
156
+ #
157
+ # @return [Hash<Symbol, Object>] resource hash attribute
158
+ def parse_shutdown(config)
159
+ value = /no shutdown/ =~ config
160
+ { shutdown: value.nil? }
161
+ end
162
+ private :parse_shutdown
163
+
164
+ ##
165
+ # create will create a new interface resource in the node's current
166
+ # configuration with the specified interface name. If the create
167
+ # method is called and the interface already exists, this method will
168
+ # return successful
169
+ #
170
+ # @eos_version 4.13.7M
171
+ #
172
+ # @commands
173
+ # interface <value>
174
+ #
175
+ # @param [String] :value The interface name to create on the node. The
176
+ # interface name must be the full interface identifier (ie Loopback,
177
+ # not Lo)
178
+ #
179
+ # @return [Boolean] returns true if the command completed succesfully
180
+ def create(value)
181
+ configure("interface #{value}")
182
+ end
183
+
184
+ ##
185
+ # delete will delete an existing interface resource in the node's
186
+ # current configuration with the specified interface name. If the
187
+ # delete method is called and interface does not exist, this method
188
+ # will return successful
189
+ #
190
+ # @eos_version 4.13.7M
191
+ #
192
+ # @commands
193
+ # no interface <value>
194
+ #
195
+ # @param [String] :value The interface name to delete from the node.
196
+ # The interface name must be the full interface identifier
197
+ # (ie Loopback, no Lo)
198
+ #
199
+ # @return [Boolean] returns true if the command completed successfully
200
+ def delete(value)
201
+ configure("no interface #{value}")
202
+ end
203
+
204
+ ##
205
+ # default will configure the interface using the default keyword. For
206
+ # virtual interfaces this is equivalent to deleting the interface. For
207
+ # physical interfaces, the entire interface configuration will be set
208
+ # to defaults.
209
+ #
210
+ # @eos_version 4.13.7M
211
+ #
212
+ # @commands
213
+ # default interface <value>
214
+ #
215
+ # @param [String] :value The interface name to default in the node. The
216
+ # interface name must be the full interface identifier (ie Loopback,
217
+ # not Lo)
218
+ #
219
+ # @return [Boolean] returns true if the command completed successfully
220
+ def default(value)
221
+ configure("default interface #{value}")
222
+ end
223
+
224
+ ##
225
+ # set_description configures the description value for the specified
226
+ # interface name in the nodes running configuration. If the value is
227
+ # not provided in the opts keyword hash then the description value is
228
+ # negated using the no keyword. If the default keyword is set to
229
+ # true, then the description value is defaulted using the default
230
+ # keyword. The default keyword takes precedence over the value
231
+ # keyword if both are provided.
232
+ #
233
+ # @eos_version 4.13.7M
234
+ #
235
+ # @commands
236
+ # interface <name>
237
+ # description <value>
238
+ # no description
239
+ # default description
240
+ #
241
+ # @param [String] :name The interface name to apply the configuration
242
+ # to. The name value must be the full interface identifier
243
+ #
244
+ # @param [hash] :opts Optional keyword arguments
245
+ #
246
+ # @option :opts [String] :value The value to configure the description
247
+ # to in the node's configuration.
248
+ #
249
+ # @option :opts [Boolean] :default Configure the interface description
250
+ # using the default keyword
251
+ #
252
+ # @return [Boolean] returns true if the command completed successfully
253
+ def set_description(name, opts = {})
254
+ value = opts[:value]
255
+ value = nil if value.empty?
256
+ default = opts.fetch(:default, false)
257
+
258
+ cmds = ["interface #{name}"]
259
+ case default
260
+ when true
261
+ cmds << 'default description'
262
+ when false
263
+ cmds << (value.nil? ? 'no description' : "description #{value}")
264
+ end
265
+ configure(cmds)
266
+ end
267
+
268
+ ##
269
+ # set_shutdown configures the adminstrative state of the specified
270
+ # interface in the node. If the value is true, then the interface
271
+ # is adminstratively disabled. If the value is false, then the
272
+ # interface is adminstratively enabled. If no value is provided, then
273
+ # the interface is configured with the no keyword which is equivalent
274
+ # to false. If the default keyword is set to true, then the interface
275
+ # shutdown value is configured using the default keyword. The default
276
+ # keyword takes precedence over the value keyword if both are provided.
277
+ #
278
+ # @eos_version 4.13.7M
279
+ #
280
+ # @commands
281
+ # interface <name<
282
+ # shutdown
283
+ # no shutdown
284
+ # default shutdown
285
+ #
286
+ # @param [String] :name The interface name to apply the configuration
287
+ # to. The name value must be the full interface identifier
288
+ #
289
+ # @param [hash] :opts Optional keyword arguments
290
+ #
291
+ # @option :opts [Boolean] :value True if the interface should be
292
+ # administratively disabled or false if the interface should be
293
+ # administratively enabled
294
+ #
295
+ # @option :opts [Boolean] :default Configure the interface shutdown
296
+ # using the default keyword
297
+ #
298
+ # @return [Boolean] returns true if the command completed successfully
299
+ def set_shutdown(name, opts = {})
300
+ value = opts[:value]
301
+ default = opts.fetch(:default, false)
302
+
303
+ cmds = ["interface #{name}"]
304
+ case default
305
+ when true
306
+ cmds << 'default shutdown'
307
+ when false
308
+ cmds << (value ? 'shutdown' : 'no shutdown')
309
+ end
310
+ configure(cmds)
311
+ end
312
+ end
313
+
314
+ class EthernetInterface < BaseInterface
315
+
316
+ DEFAULT_ETH_FLOWC_TX = 'off'
317
+ DEFAULT_ETH_FLOWC_RX = 'off'
318
+ DEFAULT_SPEED = 'auto'
319
+ DEFAULT_FORCED = false
320
+
321
+ ##
322
+ # get returns the specified Etherent interface resource hash that
323
+ # respresents the interface's current configuration in th e node.
324
+ #
325
+ # The resource hash returned contains the following information:
326
+ #
327
+ # * name (string): the interface name (eg Ethernet1)
328
+ # * type (string): will always be 'ethernet'
329
+ # * description (string): the interface description value
330
+ # * speed (string): the current speed setting for the interface speed
331
+ # * forced (boolean): true if autonegotiation is disabled otherwise
332
+ # false
333
+ # * sflow (boolean): true if sflow is enabled on the interface
334
+ # otherwise false
335
+ # * flowcontrol_send (string): the inteface flowcontrol send value.
336
+ # Valid values are 'on' or 'off'
337
+ # * flowconrol_receive (string): the interface flowcontrol receive
338
+ # value. Valid values are 'on' or 'off'
339
+ #
340
+ # @param [String] :name The interface name to return a resource hash
341
+ # for from the node's running configuration
342
+ #
343
+ # @return [nil, Hash<Symbol, Object>] Returns the interface resource as
344
+ # a hash. If the specified interface name is not found in the node's
345
+ # configuration a nil object is returned
346
+ def get(name)
347
+ config = get_block("^interface #{name}")
348
+ return nil unless config
349
+
350
+ response = super(name)
351
+ response[:type] = 'ethernet'
352
+
353
+ response.merge!(parse_speed(config))
354
+ response.merge!(parse_sflow(config))
355
+ response.merge!(parse_flowcontrol_send(config))
356
+ response.merge!(parse_flowcontrol_receive(config))
357
+
358
+ response
359
+ end
360
+
361
+ ##
362
+ # parse_speed scans the provided configuration block and parses the speed
363
+ # value. If the speed value is not found in the interface configuration
364
+ # block provided, DEFAULT_SPEED and DEFAULT_FORCED are used. The
365
+ # returned hash is intended to be merged into the interface resource hash
366
+ #
367
+ # @api private
368
+ #
369
+ # @return [Hash<Symbol, Object>] resource hash attribute
370
+ def parse_speed(config)
371
+ value = config.scan(/speed (forced)?[ ]?(\w+)/).first
372
+ return { speed: DEFAULT_SPEED, forced: DEFAULT_FORCED } unless value
373
+ (forced, value) = value.first
374
+ { speed: value, forced: forced != nil }
375
+ end
376
+ private :parse_speed
377
+
378
+ ##
379
+ # parse_sflow scans the provided configuration block and parse the
380
+ # sflow value. The sflow values true if sflow is enabled on the
381
+ # interface or returns false if it is not enabled. The hash returned
382
+ # is intended to be merged into the interface hash.
383
+ #
384
+ # @api private
385
+ #
386
+ # @return [Hash<Symbol, Object>] resource hash attribute
387
+ def parse_sflow(config)
388
+ value = /no sflow enable/ =~ config
389
+ { sflow: value.nil? }
390
+ end
391
+ private :parse_sflow
392
+
393
+ ##
394
+ # parse_flowcontrol_send scans the provided configuration block and
395
+ # parses the flowcontrol send value. If the interface flowcontrol value
396
+ # is not configured, then this method will return the value of
397
+ # DEFAULT_ETH_FLOWC_TX. The hash returned is intended to be merged into
398
+ # the interface resource hash.
399
+ #
400
+ # @api private
401
+ #
402
+ # @return [Hash<Symbol, Object>] resource hash attribute
403
+ def parse_flowcontrol_send(config)
404
+ mdata = /flowcontrol send (\w+)$/.match(config)
405
+ { flowcontrol_send: mdata.nil? ? DEFAULT_ETH_FLOWC_TX : mdata[1] }
406
+ end
407
+ private :parse_flowcontrol_send
408
+
409
+ ##
410
+ # parse_flowcontrol_receive scans the provided configuration block and
411
+ # parse the flowcontrol receive value. If the interface flowcontrol
412
+ # value is not configured, then this method will return the value of
413
+ # DEFAULT_ETH_FLOWC_RX. The hash returned is intended to be merged into
414
+ # the interface resource hash.
415
+ #
416
+ # @api private
417
+ #
418
+ # @return [Hash<Symbol, Object>] resource hash attribute
419
+ def parse_flowcontrol_receive(config)
420
+ mdata = /flowcontrol receive (\w+)$/.match(config)
421
+ { flowcontrol_receive: mdata.nil? ? DEFAULT_ETH_FLOWC_RX : mdata[1] }
422
+ end
423
+ private :parse_flowcontrol_receive
424
+
425
+ ##
426
+ # create overrides the create method from the BaseInterface and raises
427
+ # an exception because Ethernet interface creation is not supported.
428
+ #
429
+ # @param [String] :name The name of the interface
430
+ #
431
+ # @raise [NotImplementedError] Creation of physical Ethernet interfaces
432
+ # is not supported
433
+ def create(name)
434
+ raise NotImplementedError, 'creating Ethernet interfaces is '\
435
+ 'not supported'
436
+ end
437
+
438
+ ##
439
+ # delete overrides the delete method fro the BaseInterface instance and
440
+ # raises an exception because Ethernet interface deletion is not
441
+ # supported.
442
+ #
443
+ # @param [String] :name The name of the interface
444
+ #
445
+ # @raise [NotImplementedError] Deletion of physical Ethernet interfaces
446
+ # is not supported
447
+ def delete(name)
448
+ raise NotImplementedError, 'deleting Ethernet interfaces is '\
449
+ 'not supported'
450
+ end
451
+
452
+ ##
453
+ # set_speed configures the interface speed and negotiation values on the
454
+ # specified interface. If the value option is not provide, the speed
455
+ # setting is configured using the no keyword. If the default options is
456
+ # set to true, then the speed setting is configured using the default
457
+ # keyword. If both options are specified, the default keyword takes
458
+ # precedence.
459
+ #
460
+ # @eos_version 4.13.7M
461
+ #
462
+ # @commands
463
+ # interface <name>
464
+ # speed [forced] <value>
465
+ # no speed
466
+ # default speed
467
+ #
468
+ # @param [String] :name The interface name to apply the configuration
469
+ # values to. The name must be the full interface identifier.
470
+ #
471
+ # @param [Hash] :opts optional keyword arguments
472
+ #
473
+ # @option [String] :value The value to configure the speed setting to in
474
+ # the nodes running configuration
475
+ #
476
+ # @option [Boolean] :forced Specifies if autonegotiation should be
477
+ # enabled (true) or disabled (false)
478
+ #
479
+ # @option :opts [Boolean] :default Configures the sflow value on the
480
+ # interface using the default keyword
481
+ #
482
+ # @return [Boolean] returns true if the command completed successfully
483
+ def set_speed(name, opts = {})
484
+ value = opts[:value]
485
+ forced = opts.fetch(:forced, false)
486
+ default = opts.fetch(:default, false)
487
+
488
+ forced = 'forced' if forced
489
+ forced = '' if value == 'auto'
490
+
491
+ cmds = ["interface #{name}"]
492
+ case default
493
+ when true
494
+ cmds << 'default speed'
495
+ when false
496
+ cmds << value ? "speed #{forced} #{value}" : 'no speed'
497
+ end
498
+ configure cmds
499
+ end
500
+
501
+ ##
502
+ # set_sflow configures the administrative state of sflow on the
503
+ # interface. Setting the value to true enables sflow on the interface
504
+ # and setting the value to false disables sflow on the interface. If the
505
+ # value is not provided, the sflow state is negated using the no keyword.
506
+ # If the default keyword is set to true, then the sflow value is
507
+ # defaulted using the default keyword. The default keyword takes
508
+ # precedence over the value keyword
509
+ #
510
+ # @eos_version 4.13.7M
511
+ #
512
+ # @commands
513
+ # interface <name>
514
+ # sflow enable
515
+ # no sflow enable
516
+ # default sflow
517
+ #
518
+ # @param [String] :name The interface name to apply the configuration
519
+ # values to. The name must be the full interface identifier.
520
+ #
521
+ # @param [Hash] :opts optional keyword arguments
522
+ #
523
+ # @option :opts [Boolean] :value Enables sflow if the value is true or
524
+ # disables sflow on the interface if false
525
+ #
526
+ # @option :opts [Boolean] :default Configures the sflow value on the
527
+ # interface using the default keyword
528
+ #
529
+ # @return [Boolean] returns true if the command completed successfully
530
+ def set_sflow(name, opts = {})
531
+ value = opts[:value]
532
+ default = opts.fetch(:default, false)
533
+
534
+ cmds = ["interface #{name}"]
535
+ case default
536
+ when true
537
+ cmds << 'default sflow'
538
+ when false
539
+ cmds << (value ? 'sflow enable' : 'no sflow enable')
540
+ end
541
+ configure(cmds)
542
+ end
543
+
544
+ ##
545
+ # set_flowcontrol configures the flowcontrol value either on or off for
546
+ # the for the specified interface in the specified direction (either send
547
+ # or receive). If the value is not provided then the configuration is
548
+ # negated using the no keyword. If the default keyword is set to true,
549
+ # then the state value is defaulted using the default keyword. The
550
+ # default keyword takes precedence over the value keyword
551
+ #
552
+ # @eos_version 4.13.7M
553
+ #
554
+ # @commands
555
+ # interface <name>
556
+ # flowcontrol [send | receive] [on, off]
557
+ # no flowcontrol [send | receive]
558
+ # default flowcontrol [send | receive]
559
+ #
560
+ # @param [String] :name The interface name to apply the configuration
561
+ # values to. The name must be the full interface identifier.
562
+ #
563
+ # @param [String] :direction Specifies the flowcontrol direction to
564
+ # configure. Valid values include send and receive.
565
+ #
566
+ # @param [Hash] :opts optional keyword arguments
567
+ #
568
+ # @option :opts [String] :value Specifies the value to configure the
569
+ # flowcontrol setting for. Valid values include on or off
570
+ #
571
+ # @option :opts [Boolean] :default Configures the flowcontrol value on
572
+ # the interface using the default keyword
573
+ #
574
+ # @return [Boolean] returns true if the command completed successfully
575
+ def set_flowcontrol(name, direction, opts = {})
576
+ value = opts[:value]
577
+ default = opts.fetch(:default, false)
578
+
579
+ commands = ["interface #{name}"]
580
+ case default
581
+ when true
582
+ commands << "default flowcontrol #{direction}"
583
+ when false
584
+ commands << (value.nil? ? "no flowcontrol #{direction}" :
585
+ "flowcontrol #{direction} #{value}")
586
+ end
587
+ configure(commands)
588
+ end
589
+
590
+ ##
591
+ # set_flowcontrol_send is a convenience function for configuring the
592
+ # value of interface flowcontrol.
593
+ #
594
+ # @see set_flowcontrol
595
+ #
596
+ # @eos_version 4.13.7M
597
+ #
598
+ # @commands
599
+ # interface <name>
600
+ # flowcontrol [send | receive] [on, off]
601
+ # no flowcontrol [send | receive]
602
+ # default flowcontrol [send | receive]
603
+ #
604
+ # @param [String] :name The interface name to apply the configuration
605
+ # values to. The name must be the full interface identifier.
606
+ #
607
+ # @param [Hash] :opts optional keyword arguments
608
+ #
609
+ # @option :opts [String] :value Specifies the value to configure the
610
+ # flowcontrol setting for. Valid values include on or off
611
+ #
612
+ # @option :opts [Boolean] :default Configures the flowcontrol value on
613
+ # the interface using the default keyword
614
+ #
615
+ # @return [Boolean] returns true if the command completed successfully
616
+ def set_flowcontrol_send(name, opts = {})
617
+ set_flowcontrol(name, 'send', opts)
618
+ end
619
+
620
+ ##
621
+ # set_flowcontrol_receive is a convenience function for configuring th e
622
+ # value of interface flowcontrol
623
+ #
624
+ # @see set_flowcontrol
625
+ #
626
+ # @eos_version 4.13.7M
627
+ #
628
+ # @commands
629
+ # interface <name>
630
+ # flowcontrol [send | receive] [on, off]
631
+ # no flowcontrol [send | receive]
632
+ # default flowcontrol [send | receive]
633
+ #
634
+ # @param [String] :name The interface name to apply the configuration
635
+ # values to. The name must be the full interface identifier.
636
+ #
637
+ # @param [Hash] :opts optional keyword arguments
638
+ #
639
+ # @option :opts [String] :value Specifies the value to configure the
640
+ # flowcontrol setting for. Valid values include on or off
641
+ #
642
+ # @option :opts [Boolean] :default Configures the flowcontrol value on
643
+ # the interface using the default keyword
644
+ #
645
+ # @return [Boolean] returns true if the command completed successfully
646
+ def set_flowcontrol_receive(name, opts = {})
647
+ set_flowcontrol(name, 'receive', opts)
648
+ end
649
+ end
650
+
651
+ class PortchannelInterface < BaseInterface
652
+
653
+ DEFAULT_LACP_FALLBACK = 'disabled'
654
+ DEFAULT_LACP_MODE = 'on'
655
+ DEFAULT_MIN_LINKS = '0'
656
+
657
+ ##
658
+ # get returns the specified port-channel interface configuration from
659
+ # the nodes running configuration as a resource hash. The resource
660
+ # hash returned extends the BaseInterface resource hash, sets the type
661
+ # value to portchannel and adds the portchannel specific attributes
662
+ #
663
+ # @example
664
+ # {
665
+ # type: 'portchannel'
666
+ # description: <string>
667
+ # shutdown: [true, false]
668
+ # members: array[<strings>]
669
+ # lacp_mode: [active, passive, on]
670
+ # minimum_links: <string>
671
+ # lacp_timeout: <string>
672
+ # lacp_fallback: [static, individual, disabled]
673
+ # }
674
+ #
675
+ # @see BaseInterface Interface get example
676
+ #
677
+ # @param [String] :name The name of the portchannel interface to return
678
+ # a resource hash for. The name must be the full interface name of
679
+ # the desired interface.
680
+ #
681
+ # @return [nil, Hash<Symbol, Object>] returns the interface resource as
682
+ # a hash object. If the specified interface does not exist in the
683
+ # running configuration, a nil object is returned
684
+ def get(name)
685
+ config = get_block("^interface #{name}")
686
+ return nil unless config
687
+ response = super(name)
688
+ response[:type] = 'portchannel'
689
+ response.merge!(parse_members(name))
690
+ response.merge!(parse_lacp_mode(name))
691
+ response.merge!(parse_minimum_links(config))
692
+ response.merge!(parse_lacp_fallback(config))
693
+ response.merge!(parse_lacp_timeout(config))
694
+ response
695
+ end
696
+
697
+ ##
698
+ # parse_members scans the nodes running config and returns all of the
699
+ # ethernet members for the port-channel interface specified. If the
700
+ # port-channel interface has no members configured, then this method will
701
+ # assign an empty array as the value for members. The hash returned is
702
+ # intended to be merged into the interface resource hash
703
+ #
704
+ # @api private
705
+ #
706
+ # @param [String] :name The name of the portchannel interface to extract
707
+ # the members for
708
+ #
709
+ # @return [Hash<Symbol, Object>] resource hash attribute
710
+ def parse_members(name)
711
+ grpid = name.scan(/(?<=Port-Channel)\d+/)[0]
712
+ command = "show port-channel #{grpid} all-ports"
713
+ config = node.enable(command, format: 'text')
714
+ values = config.first[:result]['output'].scan(/Ethernet[\d\/]*/)
715
+ { members: values }
716
+ end
717
+ private :parse_members
718
+
719
+ ##
720
+ # parse_lacp_mode scans the member interfaces and returns the configured
721
+ # lacp mode. The lacp mode value must be common across every member
722
+ # in the port channel interface. If no members are configured, the value
723
+ # for lacp_mode will be set using DEFAULT_LACP_MODE. The hash returned is
724
+ # intended to be merged into the interface resource hash
725
+ #
726
+ # @api private
727
+ #
728
+ # @param [String] :name The name of the portchannel interface to extract
729
+ # the members from in order to get the configured lacp_mode
730
+ #
731
+ # @return [Hash<Symbol, Object>] resource hash attribute
732
+ def parse_lacp_mode(name)
733
+ members = parse_members(name)[:members]
734
+ return { lacp_mode: DEFAULT_LACP_MODE } unless members
735
+ config = get_block("interface #{members.first}")
736
+ mdata = /channel-group \d+ mode (\w+)/.match(config)
737
+ { lacp_mode: mdata.nil? ? DEFAULT_LACP_MODE : mdata[1] }
738
+ end
739
+ private :parse_lacp_mode
740
+
741
+ ##
742
+ # parse_minimum_links scans the port-channel configuration and returns
743
+ # the value for port-channel minimum-links. If the value is not found
744
+ # in the interface configuration, then DEFAULT_MIN_LINKS value is used.
745
+ # The hash returned is intended to be merged into the interface
746
+ # resource hash
747
+ #
748
+ # @api private
749
+ #
750
+ # @param [String] :config The interface configuration blcok to extract
751
+ # the minimum links value from
752
+ #
753
+ # @return [Hash<Symbol, Object>] resource hash attribute
754
+ def parse_minimum_links(config)
755
+ mdata = /port-channel min-links (\d+)$/.match(config)
756
+ { minimum_links: mdata.nil? ? DEFAULT_MIN_LINKS : mdata[1] }
757
+ end
758
+ private :parse_minimum_links
759
+
760
+ ##
761
+ # parse_lacp_fallback scans the interface config block and returns the
762
+ # confiured value of the lacp fallback attribute. If the value is not
763
+ # configured, then the method will return the value of
764
+ # DEFAULT_LACP_FALLBACK. The hash returned is intended to be merged into
765
+ # the interface resource hash
766
+ #
767
+ # @api private
768
+ #
769
+ # @param [String] :config The interface configuration block to extract
770
+ # the lacp fallback value from
771
+ #
772
+ # @return [Hash<Symbol, Object>] resource hash attribute
773
+ def parse_lacp_fallback(config)
774
+ mdata = /lacp fallback (static|individual)/.match(config)
775
+ { lacp_fallback: mdata.nil? ? DEFAULT_LACP_FALLBACK : mdata[1] }
776
+ end
777
+ private :parse_lacp_fallback
778
+
779
+ ##
780
+ # parse_lacp_timeout scans the interface config block and returns the
781
+ # value of the lacp fallback timeout value. The value is expected to be
782
+ # found in the interface configuration block. The hash returned is
783
+ # intended to be merged into the interface resource hash
784
+ #
785
+ # @api private
786
+ #
787
+ # @param [String] :config The interface configuration block to extract
788
+ # the lacp timeout value from
789
+ #
790
+ # @return [Hash<Symbol, Object>] resource hash attribute
791
+ def parse_lacp_timeout(config)
792
+ mdata = /lacp fallback timeout (\d+)$/.match(config)
793
+ { lacp_timeout: mdata[1] }
794
+ end
795
+ private :parse_lacp_timeout
796
+
797
+ ##
798
+ # set_minimum_links configures the minimum physical links up required to
799
+ # consider the logical portchannel interface operationally up. If no
800
+ # value is provided then the minimum-links is configured using the no
801
+ # keyword argument. If the default keyword argument is provided and set
802
+ # to true, the minimum-links value is defaulted using the default
803
+ # keyword. The default keyword takes precedence over the value keyword
804
+ # argument if both are provided.
805
+ #
806
+ # @eos_version 4.13.7M
807
+ #
808
+ # @commands
809
+ # interface <name>
810
+ # port-channel min-links <value>
811
+ # no port-channel min-links
812
+ # default port-channel min-links
813
+ #
814
+ # @param [String] :name The interface name to apply the configuration
815
+ # values to. The name must be the full interface identifier.
816
+ #
817
+ # @param [Hash] :opts optional keyword arguments
818
+ #
819
+ # @option :opts [String, Integer] :value Specifies the value to
820
+ # configure the minimum-links to in the configuration. Valid values
821
+ # are in the range of 1 to 16.
822
+ #
823
+ # @option :opts [Boolean] :default Configures the minimum links value on
824
+ # the interface using the default keyword
825
+ #
826
+ # @return [Boolean] returns true if the command completed successfully
827
+ def set_minimum_links(name, opts = {})
828
+ value = opts[:value]
829
+ default = opts.fetch(:default, false)
830
+
831
+ cmds = ["interface #{name}"]
832
+ case default
833
+ when true
834
+ cmds << 'default port-channel min-links'
835
+ when false
836
+ cmds << (value ? "port-channel min-links #{value}" : \
837
+ 'no port-channel min-links')
838
+ end
839
+ configure(cmds)
840
+ end
841
+
842
+ ##
843
+ # set_members configures the set of physical interfaces that comprise the
844
+ # logical port-channel interface. The members value passed should be an
845
+ # array of physical interface names that comprise the port-channel
846
+ # interface. This method will add and remove individual members as
847
+ # required to sync the provided members array
848
+ #
849
+ # @see add_member Adds member links to the port-channel interface
850
+ # @see remove_member Removes member links from the port-channel interface
851
+ #
852
+ # @param [String] :name The name of the port-channel interface to apply
853
+ # the members to. If the port-channel interface does not already exist
854
+ # it will be created
855
+ #
856
+ # @param [Array] :members The array of physical interface members to add
857
+ # to the port-channel logical interface.
858
+ #
859
+ # @return [Boolean] returns true if the command completed successfully
860
+ def set_members(name, members)
861
+ current_members = Set.new parse_members(name)[:members]
862
+ members = Set.new members
863
+
864
+ # remove members from the current port-channel interface
865
+ current_members.difference(members).each do |intf|
866
+ result = remove_member(name, intf)
867
+ return false unless result
868
+ end
869
+
870
+ # add new member interfaces to the port-channel
871
+ members.difference(current_members).each do |intf|
872
+ result = add_member(name, intf)
873
+ return false unless result
874
+ end
875
+
876
+ return true
877
+ end
878
+
879
+ ##
880
+ # add_member adds the interface specified in member to the port-channel
881
+ # interface specified by name in the nodes running-configuration. If
882
+ # the port-channel interface does not already exist, it will be created.
883
+ #
884
+ # @eos_version 4.13.7M
885
+ #
886
+ # @commands
887
+ # interface <name>
888
+ # channel-group <grpid> mode <lacp_mode>
889
+ #
890
+ # @param [String] :name The name of the port-channel interface to apply
891
+ # the configuration to.
892
+ #
893
+ # @param [String] :member The name of the physical ethernet interface to
894
+ # add to the logical port-channel interface.
895
+ #
896
+ # @return [Boolean] returns true if the command completed successfully
897
+ def add_member(name, member)
898
+ lacp = parse_lacp_mode(name)[:lacp_mode]
899
+ grpid = /(\d+)/.match(name)[0]
900
+ configure ["interface #{member}", "channel-group #{grpid} mode #{lacp}"]
901
+ end
902
+
903
+ ##
904
+ # remove_member removes the interface specified in member from the
905
+ # port-channel interface specified by name in the nodes
906
+ # running-configuration.
907
+ #
908
+ # @eos_version 4.13.7M
909
+ #
910
+ # @commands
911
+ # interface <name>
912
+ # no channel-group <grpid>
913
+ #
914
+ # @param [String] :name The name of the port-channel interface to apply
915
+ # the configuration to.
916
+ #
917
+ # @param [String] :member The name of the physical ethernet interface to
918
+ # remove from the logical port-channel interface.
919
+ #
920
+ # @return [Boolean] returns true if the command completed successfully
921
+ def remove_member(name, member)
922
+ grpid = /(\d+)/.match(name)[0]
923
+ configure ["interface #{member}", "no channel-group #{grpid}"]
924
+ end
925
+
926
+ ##
927
+ # set_lacp_mode configures the lacp mode on the port-channel interface
928
+ # by configuring the lacp mode value for each member interface. This
929
+ # method will find all member interfaces for a port-channel and
930
+ # reconfigure them using the mode argument.
931
+ #
932
+ # @eos_version 4.13.7M
933
+ #
934
+ # @commands
935
+ # interface <name>
936
+ # no channel-group <grpid>
937
+ # channge-group <grpid> mode <lacp_mode>
938
+ #
939
+ # @param [String] :name The interface name to apply the configuration
940
+ # values to. The name must be the full interface identifier.
941
+ #
942
+ # @param [String] :mode The lacp mode to configure on the member
943
+ # interfaces for the port-channel. Valid values include active,
944
+ # passive or on
945
+ #
946
+ # @return [Boolean] returns true if the command completed successfully
947
+ def set_lacp_mode(name, mode)
948
+ return false unless %w(on passive active).include?(mode)
949
+ grpid = /(\d+)/.match(name)[0]
950
+
951
+ remove_commands = []
952
+ add_commands = []
953
+
954
+ parse_members(name)[:members].each do |member|
955
+ remove_commands << "interface #{member}"
956
+ remove_commands << "no channel-group #{grpid}"
957
+ add_commands << "interface #{member}"
958
+ add_commands << "channel-group #{grpid} mode #{mode}"
959
+ end
960
+ configure remove_commands + add_commands
961
+ end
962
+
963
+ ##
964
+ # set_lacp_fallback configures the lacp fallback mode for the
965
+ # port-channel interface. If no value is provided, lacp fallback is
966
+ # configured using the no keyword argument. If the default option is
967
+ # specified and set to true, the lacp fallback value is configured using
968
+ # the default keyword. The default keyword takes precedence over the
969
+ # value keyword if both options are provided.
970
+ #
971
+ # @eos_version 4.13.7M
972
+ #
973
+ # @commands
974
+ # interface <name>
975
+ # port-channel lacp fallback <value>
976
+ # no port-channel lacp fallback
977
+ # default port-channel lacp fallback
978
+ #
979
+ # @param [String] :name The interface name to apply the configuration
980
+ # values to. The name must be the full interface identifier.
981
+ #
982
+ # @param [Hash] :opts optional keyword arguments
983
+ #
984
+ # @option :opts [String] :value Specifies the value to configure for
985
+ # the port-channel lacp fallback. Valid values are individual and
986
+ # static
987
+ #
988
+ # @option :opts [Boolean] :default Configures the lacp fallback value on
989
+ # the interface using the default keyword
990
+ #
991
+ # @return [Boolean] returns true if the command completed successfully
992
+ def set_lacp_fallback(name, opts = {})
993
+ value = opts[:value]
994
+ default = opts.fetch(:default, false)
995
+
996
+ cmds = ["interface #{name}"]
997
+ case default
998
+ when true
999
+ cmds << 'default port-channel lacp fallback'
1000
+ when false
1001
+ if [nil, 'disabled'].include?(value)
1002
+ cmds << 'no port-channel lacp fallback'
1003
+ else
1004
+ cmds << "port-channel lacp fallback #{value}"
1005
+ end
1006
+ end
1007
+ configure(cmds)
1008
+ end
1009
+
1010
+ ##
1011
+ # set_lacp_timeout configures the lacp fallback timeou for the
1012
+ # port-channel interface. If no value is provided, lacp fallback timeout
1013
+ # is configured using the no keyword argument. If the default option is
1014
+ # specified and set to true, the lacp fallback timeout value is
1015
+ # configured using the default keyword. The default keyword takes
1016
+ # precedence over the value keyword if both options are provided.
1017
+ #
1018
+ # @eos_version 4.13.7M
1019
+ #
1020
+ # @commands
1021
+ # interface <name>
1022
+ # port-channel lacp fallback timeout <value>
1023
+ # no port-channel lacp fallback timeout
1024
+ # default port-channel lacp fallback timeout
1025
+ #
1026
+ # @param [String] :name The interface name to apply the configuration
1027
+ # values to. The name must be the full interface identifier.
1028
+ #
1029
+ # @param [Hash] :opts optional keyword arguments
1030
+ #
1031
+ # @option :opts [String] :value Specifies the value to configure for
1032
+ # the port-channel lacp fallback timeout. Valid values range from
1033
+ # 1 to 100 seconds
1034
+ #
1035
+ # @option :opts [Boolean] :default Configures the lacp fallback timeout
1036
+ # value on the interface using the default keyword
1037
+ #
1038
+ # @return [Boolean] returns true if the command completed successfully
1039
+ def set_lacp_timeout(name, opts = {})
1040
+ value = opts[:value]
1041
+ default = opts.fetch(:default, false)
1042
+
1043
+ cmds = ["interface #{name}"]
1044
+ case default
1045
+ when true
1046
+ cmds << 'default port-channel lacp fallback timeout'
1047
+ when false
1048
+ cmds << (value ? "port-channel lacp fallback timeout #{value}" : \
1049
+ 'no port-channel lacp fallback timeout')
1050
+ end
1051
+ configure(cmds)
1052
+ end
1053
+ end
1054
+
1055
+ class VxlanInterface < BaseInterface
1056
+
1057
+ DEFAULT_SRC_INTF = ''
1058
+ DEFAULT_MCAST_GRP = ''
1059
+
1060
+ ##
1061
+ # Returns the Vxlan interface configuration as a Ruby hash of key/value
1062
+ # pairs from the nodes running configuration. This method extends the
1063
+ # BaseInterface get method and adds the Vxlan specific attributes to
1064
+ # the hash
1065
+ #
1066
+ # @example
1067
+ # {
1068
+ # "name": <string>,
1069
+ # "type": 'vxlan',
1070
+ # "description": <string>,
1071
+ # "shutdown": [true, false],
1072
+ # "source_interface": <string>,
1073
+ # "multicast_group": <string>
1074
+ # }
1075
+ #
1076
+ # @param [String] :name The interface name to return from the nodes
1077
+ # configuration. This optional parameter defaults to Vxlan1
1078
+ #
1079
+ # @return [nil, Hash<String, String>] Returns the interface configuration
1080
+ # as a Ruby hash object. If the provided interface name is not found
1081
+ # then this method will return nil
1082
+ def get(name = 'Vxlan1')
1083
+ config = get_block("interface #{name}")
1084
+ return nil unless config
1085
+
1086
+ response = super(name)
1087
+ response[:type] = 'vxlan'
1088
+ response.merge!(parse_source_interface(config))
1089
+ response.merge!(parse_multicast_group(config))
1090
+ response
1091
+ end
1092
+
1093
+ ##
1094
+ # parse_source_interface scans the interface config block and returns the
1095
+ # value of the vxlan source-interace. If the source-interface is not
1096
+ # configured then the value of DEFAULT_SRC_INTF is used. The hash
1097
+ # returned is intended to be merged into the interface resource hash
1098
+ #
1099
+ # @api private
1100
+ #
1101
+ # @param [String] :config The interface configuration block to extract
1102
+ # the vxlan source-interface value from
1103
+ #
1104
+ # @return [Hash<Symbol, Object>] resource hash attribute
1105
+ def parse_source_interface(config)
1106
+ mdata = /source-interface ([^\s]+)$/.match(config)
1107
+ { source_interface: mdata.nil? ? DEFAULT_SRC_INTF : mdata[1] }
1108
+ end
1109
+ private :parse_source_interface
1110
+
1111
+ ##
1112
+ # parse_multicast_group scans the interface config block and returns the
1113
+ # value of the vxlan multicast-group. If the multicast-group is not
1114
+ # configured then the value of DEFAULT_MCAST_GRP is used. The hash
1115
+ # returned is intended to be merged into the interface resource hash
1116
+ #
1117
+ # @api private
1118
+ #
1119
+ # @param [String] :config The interface configuration block to extract
1120
+ # the vxlan multicast-group value from
1121
+ #
1122
+ # @return [Hash<Symbol, Object>] resource hash attribute
1123
+ def parse_multicast_group(config)
1124
+ mdata = /multicast-group ([^\s]+)$/.match(config)
1125
+ { multicast_group: mdata.nil? ? DEFAULT_MCAST_GRP : mdata[1] }
1126
+ end
1127
+ private :parse_multicast_group
1128
+
1129
+ ##
1130
+ # Configures the vxlan source-interface to the specified value. This
1131
+ # parameter should be a the interface identifier of the interface to act
1132
+ # as the source for all Vxlan traffic
1133
+ #
1134
+ # @param [String] :name The name of the interface to apply the
1135
+ # configuration values to
1136
+ # @param [Hash] :opt Optional keyword arguments
1137
+ # @option :opts [String] :value Configures the vxlan source-interface to
1138
+ # the spcified value. If no value is provided and the
1139
+ # default keyword is not specified then the value is negated
1140
+ # @option :opts [Boolean] :default Specifies whether or not the
1141
+ # multicast-group command is configured as default. The value of this
1142
+ # option has a higher precedence than :value
1143
+ #
1144
+ # @return [Boolean] This method returns true if the commands were
1145
+ # successful otherwise it returns false
1146
+ def set_source_interface(name = 'Vxlan1', opts = {})
1147
+ value = opts[:value]
1148
+ default = opts.fetch(:default, false)
1149
+
1150
+ cmds = ["interface #{name}"]
1151
+ case default
1152
+ when true
1153
+ cmds << 'default vxlan source-interface'
1154
+ when false
1155
+ cmds << (value ? "vxlan source-interface #{value}" : \
1156
+ 'no vxlan source-interface')
1157
+ end
1158
+ configure(cmds)
1159
+ end
1160
+
1161
+ ##
1162
+ # Configures the vxlan multcast-group flood address to the specified
1163
+ # value. The value should be a valid multicast address
1164
+ #
1165
+ # @param [String] :name The name of the interface to apply the
1166
+ # configuration values to
1167
+ # @param [Hash] :opt Optional keyword arguments
1168
+ # @option :opts [String] :value Configures the mutlicast-group flood
1169
+ # address to the specified value. If no value is provided and the
1170
+ # default keyword is not specified then the value is negated
1171
+ # @option :opts [Boolean] :default Specifies whether or not the
1172
+ # multicast-group command is configured as default. The value of this
1173
+ # option has a higher precedence than :value
1174
+ #
1175
+ # @return [Boolean] This method returns true if the commands were
1176
+ # successful otherwise it returns false
1177
+ def set_multicast_group(name = 'Vxlan1', opts = {})
1178
+ value = opts[:value]
1179
+ default = opts.fetch(:default, false)
1180
+
1181
+ cmds = ["interface #{name}"]
1182
+ case default
1183
+ when true
1184
+ cmds << 'default vxlan multicast-group'
1185
+ when false
1186
+ cmds << (value ? "vxlan multicast-group #{value}" : \
1187
+ 'no vxlan multtcast-group')
1188
+ end
1189
+ configure(cmds)
1190
+ end
1191
+ end
1192
+ end
1193
+ end