rbeapi 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/.gitignore +5 -0
  2. data/.rubocop.yml +21 -0
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +3 -1
  5. data/Guardfile +3 -3
  6. data/README.md +92 -17
  7. data/Rakefile +99 -4
  8. data/gems/README.rst +4 -0
  9. data/gems/inifile/.gitignore +2 -0
  10. data/gems/inifile/README.rst +5 -0
  11. data/gems/inifile/inifile.spec.tmpl +84 -0
  12. data/gems/net_http_unix/.gitignore +2 -0
  13. data/gems/net_http_unix/README.rst +5 -0
  14. data/gems/net_http_unix/net_http_unix.spec.tmpl +54 -0
  15. data/gems/netaddr/README.rst +5 -0
  16. data/gems/netaddr/netaddr.spec.tmpl +50 -0
  17. data/lib/rbeapi/api/aaa.rb +14 -17
  18. data/lib/rbeapi/api/acl.rb +276 -0
  19. data/lib/rbeapi/api/dns.rb +7 -4
  20. data/lib/rbeapi/api/interfaces.rb +239 -239
  21. data/lib/rbeapi/api/ipinterfaces.rb +5 -3
  22. data/lib/rbeapi/api/logging.rb +8 -5
  23. data/lib/rbeapi/api/mlag.rb +45 -127
  24. data/lib/rbeapi/api/ntp.rb +1 -4
  25. data/lib/rbeapi/api/ospf.rb +16 -13
  26. data/lib/rbeapi/api/prefixlists.rb +4 -4
  27. data/lib/rbeapi/api/radius.rb +34 -25
  28. data/lib/rbeapi/api/routemaps.rb +16 -10
  29. data/lib/rbeapi/api/snmp.rb +26 -13
  30. data/lib/rbeapi/api/staticroutes.rb +6 -5
  31. data/lib/rbeapi/api/stp.rb +77 -18
  32. data/lib/rbeapi/api/switchports.rb +20 -12
  33. data/lib/rbeapi/api/system.rb +6 -6
  34. data/lib/rbeapi/api/tacacs.rb +9 -6
  35. data/lib/rbeapi/api/varp.rb +15 -10
  36. data/lib/rbeapi/api/vlans.rb +5 -6
  37. data/lib/rbeapi/api.rb +56 -16
  38. data/lib/rbeapi/client.rb +85 -50
  39. data/lib/rbeapi/eapilib.rb +95 -56
  40. data/lib/rbeapi/netdev/snmp.rb +7 -16
  41. data/lib/rbeapi/utils.rb +3 -5
  42. data/lib/rbeapi/version.rb +1 -1
  43. data/rbeapi.gemspec +4 -2
  44. data/rbeapi.spec.tmpl +72 -0
  45. data/spec/support/fixtures.rb +6 -4
  46. data/spec/support/shared_examples_for_api_modules.rb +3 -18
  47. data/spec/system/api_acl_spec.rb +128 -0
  48. data/spec/system/api_ospf_interfaces_spec.rb +17 -14
  49. data/spec/system/api_ospf_spec.rb +8 -8
  50. data/spec/system/api_varp_interfaces_spec.rb +22 -13
  51. data/spec/system/api_varp_spec.rb +1 -4
  52. data/spec/system/rbeapi/api/interfaces_base_spec.rb +3 -4
  53. data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +13 -9
  54. data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +43 -26
  55. data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +7 -6
  56. data/spec/system/rbeapi/api/ipinterfaces_spec.rb +34 -21
  57. data/spec/system/rbeapi/api/mlag_interfaces_spec.rb +15 -38
  58. data/spec/system/rbeapi/api/mlag_spec.rb +26 -30
  59. data/spec/system/rbeapi/api/snmp_spec.rb +0 -3
  60. data/spec/system/rbeapi/api/stp_instances_spec.rb +20 -12
  61. data/spec/system/rbeapi/api/stp_interfaces_spec.rb +1 -3
  62. data/spec/system/rbeapi/api/switchports_spec.rb +14 -12
  63. data/spec/system/rbeapi/api/system_spec.rb +0 -3
  64. data/spec/system/rbeapi/api/vlans_spec.rb +19 -9
  65. data/spec/unit/rbeapi/api/acl/default_spec.rb +158 -0
  66. data/spec/unit/rbeapi/api/acl/fixture_acl_standard.text +22 -0
  67. data/spec/unit/rbeapi/api/interfaces/base_spec.rb +123 -0
  68. data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +89 -0
  69. data/spec/unit/rbeapi/api/interfaces/fixture_interfaces.text +219 -0
  70. data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +149 -0
  71. data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +243 -0
  72. data/spec/unit/rbeapi/api/mlag/default_spec.rb +218 -0
  73. data/spec/unit/rbeapi/api/mlag/fixture_mlag.text +238 -0
  74. data/spec/unit/rbeapi/api/vlans/default_spec.rb +135 -0
  75. data/spec/unit/rbeapi/api/vlans/fixture_vlans.text +5 -0
  76. metadata +79 -4
  77. data/lib/rbeapi/api/radius.rb.old +0 -399
@@ -32,14 +32,16 @@
32
32
  require 'rbeapi/api'
33
33
  require 'rbeapi/utils'
34
34
 
35
+ ##
36
+ # Rbeapi toplevel namespace
35
37
  module Rbeapi
36
-
38
+ ##
39
+ # Api module namespace
37
40
  module Api
38
-
41
+ ##
42
+ # The Interfaces class manages all physical and logical interfaces on an
43
+ # EOS node.
39
44
  class Interfaces < Entity
40
-
41
- METHODS = [:create, :delete, :default]
42
-
43
45
  def initialize(node)
44
46
  super(node)
45
47
  @instances = {}
@@ -59,7 +61,7 @@ module Rbeapi
59
61
  end
60
62
 
61
63
  def get_instance(name)
62
- name = name[0,2].upcase
64
+ name = name[0, 2].upcase
63
65
  case name
64
66
  when 'ET'
65
67
  cls = 'Rbeapi::Api::EthernetInterface'
@@ -78,10 +80,8 @@ module Rbeapi
78
80
  end
79
81
 
80
82
  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
83
+ instance = get_instance(args[0])
84
+ instance.send(method_name.to_sym, *args, &block)
85
85
  end
86
86
 
87
87
  def respond_to?(method_name, name = nil)
@@ -89,14 +89,12 @@ module Rbeapi
89
89
  instance = get_instance(name)
90
90
  instance.respond_to?(method_name) || super
91
91
  end
92
-
93
92
  end
94
93
 
95
94
  ##
96
95
  # The BaseInterface class extends Entity and provides an implementation
97
96
  # that is common to all interfaces configured in EOS.
98
97
  class BaseInterface < Entity
99
-
100
98
  DEFAULT_INTF_DESCRIPTION = ''
101
99
 
102
100
  ##
@@ -169,9 +167,6 @@ module Rbeapi
169
167
  #
170
168
  # @eos_version 4.13.7M
171
169
  #
172
- # @commands
173
- # interface <value>
174
- #
175
170
  # @param [String] :value The interface name to create on the node. The
176
171
  # interface name must be the full interface identifier (ie Loopback,
177
172
  # not Lo)
@@ -189,9 +184,6 @@ module Rbeapi
189
184
  #
190
185
  # @eos_version 4.13.7M
191
186
  #
192
- # @commands
193
- # no interface <value>
194
- #
195
187
  # @param [String] :value The interface name to delete from the node.
196
188
  # The interface name must be the full interface identifier
197
189
  # (ie Loopback, no Lo)
@@ -209,9 +201,6 @@ module Rbeapi
209
201
  #
210
202
  # @eos_version 4.13.7M
211
203
  #
212
- # @commands
213
- # default interface <value>
214
- #
215
204
  # @param [String] :value The interface name to default in the node. The
216
205
  # interface name must be the full interface identifier (ie Loopback,
217
206
  # not Lo)
@@ -232,12 +221,6 @@ module Rbeapi
232
221
  #
233
222
  # @eos_version 4.13.7M
234
223
  #
235
- # @commands
236
- # interface <name>
237
- # description <value>
238
- # no description
239
- # default description
240
- #
241
224
  # @param [String] :name The interface name to apply the configuration
242
225
  # to. The name value must be the full interface identifier
243
226
  #
@@ -251,18 +234,8 @@ module Rbeapi
251
234
  #
252
235
  # @return [Boolean] returns true if the command completed successfully
253
236
  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)
237
+ commands = command_builder('description', opts)
238
+ configure_interface(name, commands)
266
239
  end
267
240
 
268
241
  ##
@@ -277,12 +250,6 @@ module Rbeapi
277
250
  #
278
251
  # @eos_version 4.13.7M
279
252
  #
280
- # @commands
281
- # interface <name<
282
- # shutdown
283
- # no shutdown
284
- # default shutdown
285
- #
286
253
  # @param [String] :name The interface name to apply the configuration
287
254
  # to. The name value must be the full interface identifier
288
255
  #
@@ -297,22 +264,15 @@ module Rbeapi
297
264
  #
298
265
  # @return [Boolean] returns true if the command completed successfully
299
266
  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)
267
+ commands = command_builder('shutdown', opts)
268
+ configure_interface(name, commands)
311
269
  end
312
270
  end
313
271
 
272
+ ##
273
+ # The EthernetInterface class manages all Ethernet interfaces on an
274
+ # EOS node.
314
275
  class EthernetInterface < BaseInterface
315
-
316
276
  DEFAULT_ETH_FLOWC_TX = 'off'
317
277
  DEFAULT_ETH_FLOWC_RX = 'off'
318
278
  DEFAULT_SPEED = 'auto'
@@ -324,18 +284,18 @@ module Rbeapi
324
284
  #
325
285
  # The resource hash returned contains the following information:
326
286
  #
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'
287
+ # * name (string): the interface name (eg Ethernet1)
288
+ # * type (string): will always be 'ethernet'
289
+ # * description (string): the interface description value
290
+ # * speed (string): the current speed setting for the interface speed
291
+ # * forced (boolean): true if autonegotiation is disabled otherwise
292
+ # false
293
+ # * sflow (boolean): true if sflow is enabled on the interface
294
+ # otherwise false
295
+ # * flowcontrol_send (string): the inteface flowcontrol send value.
296
+ # Valid values are 'on' or 'off'
297
+ # * flowconrol_receive (string): the interface flowcontrol receive
298
+ # value. Valid values are 'on' or 'off'
339
299
  #
340
300
  # @param [String] :name The interface name to return a resource hash
341
301
  # for from the node's running configuration
@@ -371,7 +331,7 @@ module Rbeapi
371
331
  value = config.scan(/speed (forced)?[ ]?(\w+)/).first
372
332
  return { speed: DEFAULT_SPEED, forced: DEFAULT_FORCED } unless value
373
333
  (forced, value) = value.first
374
- { speed: value, forced: forced != nil }
334
+ { speed: value, forced: !forced.nil? }
375
335
  end
376
336
  private :parse_speed
377
337
 
@@ -430,8 +390,8 @@ module Rbeapi
430
390
  #
431
391
  # @raise [NotImplementedError] Creation of physical Ethernet interfaces
432
392
  # is not supported
433
- def create(name)
434
- raise NotImplementedError, 'creating Ethernet interfaces is '\
393
+ def create(_name)
394
+ fail NotImplementedError, 'creating Ethernet interfaces is '\
435
395
  'not supported'
436
396
  end
437
397
 
@@ -444,8 +404,8 @@ module Rbeapi
444
404
  #
445
405
  # @raise [NotImplementedError] Deletion of physical Ethernet interfaces
446
406
  # is not supported
447
- def delete(name)
448
- raise NotImplementedError, 'deleting Ethernet interfaces is '\
407
+ def delete(_name)
408
+ fail NotImplementedError, 'deleting Ethernet interfaces is '\
449
409
  'not supported'
450
410
  end
451
411
 
@@ -459,12 +419,6 @@ module Rbeapi
459
419
  #
460
420
  # @eos_version 4.13.7M
461
421
  #
462
- # @commands
463
- # interface <name>
464
- # speed [forced] <value>
465
- # no speed
466
- # default speed
467
- #
468
422
  # @param [String] :name The interface name to apply the configuration
469
423
  # values to. The name must be the full interface identifier.
470
424
  #
@@ -509,12 +463,6 @@ module Rbeapi
509
463
  #
510
464
  # @eos_version 4.13.7M
511
465
  #
512
- # @commands
513
- # interface <name>
514
- # sflow enable
515
- # no sflow enable
516
- # default sflow
517
- #
518
466
  # @param [String] :name The interface name to apply the configuration
519
467
  # values to. The name must be the full interface identifier.
520
468
  #
@@ -531,14 +479,18 @@ module Rbeapi
531
479
  value = opts[:value]
532
480
  default = opts.fetch(:default, false)
533
481
 
534
- cmds = ["interface #{name}"]
535
482
  case default
536
483
  when true
537
- cmds << 'default sflow'
484
+ command = 'default sflow enable'
538
485
  when false
539
- cmds << (value ? 'sflow enable' : 'no sflow enable')
486
+ case value
487
+ when true
488
+ command = 'sflow enable'
489
+ when false
490
+ command = 'no sflow enable'
491
+ end
540
492
  end
541
- configure(cmds)
493
+ configure_interface(name, command)
542
494
  end
543
495
 
544
496
  ##
@@ -551,12 +503,6 @@ module Rbeapi
551
503
  #
552
504
  # @eos_version 4.13.7M
553
505
  #
554
- # @commands
555
- # interface <name>
556
- # flowcontrol [send | receive] [on, off]
557
- # no flowcontrol [send | receive]
558
- # default flowcontrol [send | receive]
559
- #
560
506
  # @param [String] :name The interface name to apply the configuration
561
507
  # values to. The name must be the full interface identifier.
562
508
  #
@@ -573,18 +519,8 @@ module Rbeapi
573
519
  #
574
520
  # @return [Boolean] returns true if the command completed successfully
575
521
  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)
522
+ commands = command_builder("flowcontrol #{direction}", opts)
523
+ configure_interface(name, commands)
588
524
  end
589
525
 
590
526
  ##
@@ -595,12 +531,6 @@ module Rbeapi
595
531
  #
596
532
  # @eos_version 4.13.7M
597
533
  #
598
- # @commands
599
- # interface <name>
600
- # flowcontrol [send | receive] [on, off]
601
- # no flowcontrol [send | receive]
602
- # default flowcontrol [send | receive]
603
- #
604
534
  # @param [String] :name The interface name to apply the configuration
605
535
  # values to. The name must be the full interface identifier.
606
536
  #
@@ -625,12 +555,6 @@ module Rbeapi
625
555
  #
626
556
  # @eos_version 4.13.7M
627
557
  #
628
- # @commands
629
- # interface <name>
630
- # flowcontrol [send | receive] [on, off]
631
- # no flowcontrol [send | receive]
632
- # default flowcontrol [send | receive]
633
- #
634
558
  # @param [String] :name The interface name to apply the configuration
635
559
  # values to. The name must be the full interface identifier.
636
560
  #
@@ -648,8 +572,10 @@ module Rbeapi
648
572
  end
649
573
  end
650
574
 
575
+ ##
576
+ # The PortchannelInterface class manages all port channel interfaces on an
577
+ # EOS node.
651
578
  class PortchannelInterface < BaseInterface
652
-
653
579
  DEFAULT_LACP_FALLBACK = 'disabled'
654
580
  DEFAULT_LACP_MODE = 'on'
655
581
  DEFAULT_MIN_LINKS = '0'
@@ -711,7 +637,7 @@ module Rbeapi
711
637
  grpid = name.scan(/(?<=Port-Channel)\d+/)[0]
712
638
  command = "show port-channel #{grpid} all-ports"
713
639
  config = node.enable(command, format: 'text')
714
- values = config.first[:result]['output'].scan(/Ethernet[\d\/]*/)
640
+ values = config.first[:result]['output'].scan(%r{\bEthernet[\d\/]*})
715
641
  { members: values }
716
642
  end
717
643
  private :parse_members
@@ -734,7 +660,7 @@ module Rbeapi
734
660
  return { lacp_mode: DEFAULT_LACP_MODE } unless members
735
661
  config = get_block("interface #{members.first}")
736
662
  mdata = /channel-group \d+ mode (\w+)/.match(config)
737
- { lacp_mode: mdata.nil? ? DEFAULT_LACP_MODE : mdata[1] }
663
+ { lacp_mode: mdata ? mdata[1] : DEFAULT_LACP_MODE }
738
664
  end
739
665
  private :parse_lacp_mode
740
666
 
@@ -753,7 +679,7 @@ module Rbeapi
753
679
  # @return [Hash<Symbol, Object>] resource hash attribute
754
680
  def parse_minimum_links(config)
755
681
  mdata = /port-channel min-links (\d+)$/.match(config)
756
- { minimum_links: mdata.nil? ? DEFAULT_MIN_LINKS : mdata[1] }
682
+ { minimum_links: mdata ? mdata[1] : DEFAULT_MIN_LINKS }
757
683
  end
758
684
  private :parse_minimum_links
759
685
 
@@ -772,7 +698,7 @@ module Rbeapi
772
698
  # @return [Hash<Symbol, Object>] resource hash attribute
773
699
  def parse_lacp_fallback(config)
774
700
  mdata = /lacp fallback (static|individual)/.match(config)
775
- { lacp_fallback: mdata.nil? ? DEFAULT_LACP_FALLBACK : mdata[1] }
701
+ { lacp_fallback: mdata ? mdata[1] : DEFAULT_LACP_FALLBACK }
776
702
  end
777
703
  private :parse_lacp_fallback
778
704
 
@@ -805,12 +731,6 @@ module Rbeapi
805
731
  #
806
732
  # @eos_version 4.13.7M
807
733
  #
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
734
  # @param [String] :name The interface name to apply the configuration
815
735
  # values to. The name must be the full interface identifier.
816
736
  #
@@ -825,18 +745,8 @@ module Rbeapi
825
745
  #
826
746
  # @return [Boolean] returns true if the command completed successfully
827
747
  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)
748
+ commands = command_builder('port-channel min-links', opts)
749
+ configure_interface(name, commands)
840
750
  end
841
751
 
842
752
  ##
@@ -873,7 +783,7 @@ module Rbeapi
873
783
  return false unless result
874
784
  end
875
785
 
876
- return true
786
+ true
877
787
  end
878
788
 
879
789
  ##
@@ -883,10 +793,6 @@ module Rbeapi
883
793
  #
884
794
  # @eos_version 4.13.7M
885
795
  #
886
- # @commands
887
- # interface <name>
888
- # channel-group <grpid> mode <lacp_mode>
889
- #
890
796
  # @param [String] :name The name of the port-channel interface to apply
891
797
  # the configuration to.
892
798
  #
@@ -897,7 +803,7 @@ module Rbeapi
897
803
  def add_member(name, member)
898
804
  lacp = parse_lacp_mode(name)[:lacp_mode]
899
805
  grpid = /(\d+)/.match(name)[0]
900
- configure ["interface #{member}", "channel-group #{grpid} mode #{lacp}"]
806
+ configure_interface(member, "channel-group #{grpid} mode #{lacp}")
901
807
  end
902
808
 
903
809
  ##
@@ -907,10 +813,6 @@ module Rbeapi
907
813
  #
908
814
  # @eos_version 4.13.7M
909
815
  #
910
- # @commands
911
- # interface <name>
912
- # no channel-group <grpid>
913
- #
914
816
  # @param [String] :name The name of the port-channel interface to apply
915
817
  # the configuration to.
916
818
  #
@@ -920,7 +822,7 @@ module Rbeapi
920
822
  # @return [Boolean] returns true if the command completed successfully
921
823
  def remove_member(name, member)
922
824
  grpid = /(\d+)/.match(name)[0]
923
- configure ["interface #{member}", "no channel-group #{grpid}"]
825
+ configure_interface(member, "no channel-group #{grpid}")
924
826
  end
925
827
 
926
828
  ##
@@ -931,11 +833,6 @@ module Rbeapi
931
833
  #
932
834
  # @eos_version 4.13.7M
933
835
  #
934
- # @commands
935
- # interface <name>
936
- # no channel-group <grpid>
937
- # channge-group <grpid> mode <lacp_mode>
938
- #
939
836
  # @param [String] :name The interface name to apply the configuration
940
837
  # values to. The name must be the full interface identifier.
941
838
  #
@@ -970,12 +867,6 @@ module Rbeapi
970
867
  #
971
868
  # @eos_version 4.13.7M
972
869
  #
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
870
  # @param [String] :name The interface name to apply the configuration
980
871
  # values to. The name must be the full interface identifier.
981
872
  #
@@ -990,21 +881,9 @@ module Rbeapi
990
881
  #
991
882
  # @return [Boolean] returns true if the command completed successfully
992
883
  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)
884
+ opts[:value] = nil if opts[:value] == 'disabled'
885
+ commands = command_builder('port-channel lacp fallback', opts)
886
+ configure_interface(name, commands)
1008
887
  end
1009
888
 
1010
889
  ##
@@ -1017,12 +896,6 @@ module Rbeapi
1017
896
  #
1018
897
  # @eos_version 4.13.7M
1019
898
  #
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
899
  # @param [String] :name The interface name to apply the configuration
1027
900
  # values to. The name must be the full interface identifier.
1028
901
  #
@@ -1037,23 +910,14 @@ module Rbeapi
1037
910
  #
1038
911
  # @return [Boolean] returns true if the command completed successfully
1039
912
  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)
913
+ commands = command_builder('port-channel lacp fallback timeout', opts)
914
+ configure_interface(name, commands)
1052
915
  end
1053
916
  end
1054
917
 
918
+ ##
919
+ # The VxlanInterface class manages all Vxlan interfaces on an EOS node.
1055
920
  class VxlanInterface < BaseInterface
1056
-
1057
921
  DEFAULT_SRC_INTF = ''
1058
922
  DEFAULT_MCAST_GRP = ''
1059
923
 
@@ -1063,15 +927,16 @@ module Rbeapi
1063
927
  # BaseInterface get method and adds the Vxlan specific attributes to
1064
928
  # the hash
1065
929
  #
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
- # }
930
+ # The returned resource hash contains the following
931
+ #
932
+ # * name: (String) The full interface name identifier
933
+ # * type: (String) 'vxlan'
934
+ # * descripition: (String) The configured interface description
935
+ # * shutdown: (Boolean) The admin state of the interface
936
+ # * source_interface: (String) The vxlan source-interface value
937
+ # * multicast_group: (String) The vxlan multicast-group value
938
+ # * udp_port: (Fixnum) The vxlan udp-port value
939
+ # * flood_list: (Array) The list of VTEPs to flood traffic towards
1075
940
  #
1076
941
  # @param [String] :name The interface name to return from the nodes
1077
942
  # configuration. This optional parameter defaults to Vxlan1
@@ -1087,6 +952,9 @@ module Rbeapi
1087
952
  response[:type] = 'vxlan'
1088
953
  response.merge!(parse_source_interface(config))
1089
954
  response.merge!(parse_multicast_group(config))
955
+ response.merge!(parse_udp_port(config))
956
+ response.merge!(parse_flood_list(config))
957
+ response.merge!(parse_vlans(config))
1090
958
  response
1091
959
  end
1092
960
 
@@ -1101,10 +969,10 @@ module Rbeapi
1101
969
  # @param [String] :config The interface configuration block to extract
1102
970
  # the vxlan source-interface value from
1103
971
  #
1104
- # @return [Hash<Symbol, Object>] resource hash attribute
972
+ # @return [Hash<Symbol, Object>]
1105
973
  def parse_source_interface(config)
1106
974
  mdata = /source-interface ([^\s]+)$/.match(config)
1107
- { source_interface: mdata.nil? ? DEFAULT_SRC_INTF : mdata[1] }
975
+ { source_interface: mdata ? mdata[1] : DEFAULT_SRC_INTF }
1108
976
  end
1109
977
  private :parse_source_interface
1110
978
 
@@ -1119,13 +987,71 @@ module Rbeapi
1119
987
  # @param [String] :config The interface configuration block to extract
1120
988
  # the vxlan multicast-group value from
1121
989
  #
1122
- # @return [Hash<Symbol, Object>] resource hash attribute
990
+ # @return [Hash<Symbol, Object>]
1123
991
  def parse_multicast_group(config)
1124
992
  mdata = /multicast-group ([^\s]+)$/.match(config)
1125
- { multicast_group: mdata.nil? ? DEFAULT_MCAST_GRP : mdata[1] }
993
+ { multicast_group: mdata ? mdata[1] : DEFAULT_MCAST_GRP }
1126
994
  end
1127
995
  private :parse_multicast_group
1128
996
 
997
+ ##
998
+ # parse_udp_port scans the interface config block and returns the value
999
+ # of the vxlan udp-port setting. The vxlan udp-port value is expected to
1000
+ # always be present in the configuration. The returned value is intended
1001
+ # to be merged into the interface resource Hash
1002
+ #
1003
+ # @api private
1004
+ #
1005
+ # @param [String] :config The interface configuration block to parse the
1006
+ # vxlan udp-port value from
1007
+ #
1008
+ # @return [Hash<Symbol, Object>]
1009
+ def parse_udp_port(config)
1010
+ value = config.scan(/(?<=vxlan udp-port )\d+/)
1011
+ { udp_port: value.first.to_i }
1012
+ end
1013
+ private :parse_udp_port
1014
+
1015
+ ##
1016
+ # parse_flood_list scans the interface config block and returns the list
1017
+ # of configured VTEPs that comprise the flood list. If there are no
1018
+ # flood list values configured, the value will return DEFAULT_FLOOD_LIST.
1019
+ # The returned value is intended to be merged into the inteface resource
1020
+ # Hash.
1021
+ #
1022
+ # @api private
1023
+ #
1024
+ # @param [String] :config The interface configuration block to parse the
1025
+ # vxlan flood list values from
1026
+ #
1027
+ # @return [Hash<Symbol, Object>]
1028
+ def parse_flood_list(config)
1029
+ values = config.scan(/(?<=\s{3}vxlan flood vtep ).+$/)
1030
+ values = values.first.split(' ') unless values.empty?
1031
+ { flood_list: values }
1032
+ end
1033
+ private :parse_flood_list
1034
+
1035
+ ##
1036
+ # parse_vlans scans the interface config block and returns the set of
1037
+ # configured vlan to vni mappings. if there are no vlans configured, the
1038
+ # value will return an empty Hash
1039
+ #
1040
+ # @api private
1041
+ #
1042
+ # @param [String] :config The interface configuration block to parse the
1043
+ # vxlan flood list values from
1044
+ #
1045
+ # @return [Hash<Symbol, Object>]
1046
+ def parse_vlans(config)
1047
+ values = config.scan(/vxlan vlan (\d+) vni (\d+)/)
1048
+ values = values.each_with_object({}) do |v, hsh|
1049
+ hsh[v.first] = { vni: v.last }
1050
+ end
1051
+ { vlans: values }
1052
+ end
1053
+ private :parse_vlans
1054
+
1129
1055
  ##
1130
1056
  # Configures the vxlan source-interface to the specified value. This
1131
1057
  # parameter should be a the interface identifier of the interface to act
@@ -1133,29 +1059,21 @@ module Rbeapi
1133
1059
  #
1134
1060
  # @param [String] :name The name of the interface to apply the
1135
1061
  # configuration values to
1062
+ #
1136
1063
  # @param [Hash] :opt Optional keyword arguments
1064
+ #
1137
1065
  # @option :opts [String] :value Configures the vxlan source-interface to
1138
1066
  # the spcified value. If no value is provided and the
1139
1067
  # default keyword is not specified then the value is negated
1068
+ #
1140
1069
  # @option :opts [Boolean] :default Specifies whether or not the
1141
1070
  # multicast-group command is configured as default. The value of this
1142
1071
  # option has a higher precedence than :value
1143
1072
  #
1144
- # @return [Boolean] This method returns true if the commands were
1145
- # successful otherwise it returns false
1073
+ # @return [Boolean] Returns true if the commands complete successfully
1146
1074
  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)
1075
+ commands = command_builder('vxlan source-interface', opts)
1076
+ configure_interface(name, commands)
1159
1077
  end
1160
1078
 
1161
1079
  ##
@@ -1164,29 +1082,111 @@ module Rbeapi
1164
1082
  #
1165
1083
  # @param [String] :name The name of the interface to apply the
1166
1084
  # configuration values to
1085
+ #
1167
1086
  # @param [Hash] :opt Optional keyword arguments
1087
+ #
1168
1088
  # @option :opts [String] :value Configures the mutlicast-group flood
1169
1089
  # address to the specified value. If no value is provided and the
1170
1090
  # default keyword is not specified then the value is negated
1091
+ #
1171
1092
  # @option :opts [Boolean] :default Specifies whether or not the
1172
1093
  # multicast-group command is configured as default. The value of this
1173
1094
  # option has a higher precedence than :value
1174
1095
  #
1175
- # @return [Boolean] This method returns true if the commands were
1176
- # successful otherwise it returns false
1096
+ # @return [Boolean] Returns true if the commands complete successfully
1177
1097
  def set_multicast_group(name = 'Vxlan1', opts = {})
1178
- value = opts[:value]
1179
- default = opts.fetch(:default, false)
1098
+ commands = command_builder('vxlan multicast-group', opts)
1099
+ configure_interface(name, commands)
1100
+ end
1180
1101
 
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)
1102
+ ##
1103
+ # set_udp_port configures the Vxlan udp-port value in EOS for the
1104
+ # specified interface name. If the value option is not provided then the
1105
+ # no keyword is used to configure the value. If the default option is
1106
+ # provided and set to true, then the default keyword is used. If both
1107
+ # options are provided, the default keyword will take precedence.
1108
+ #
1109
+ # @eos_version 4.13.7M
1110
+ #
1111
+ # @param [String] :name The name of the vxlan interface to configure
1112
+ #
1113
+ # @param [Hash] :opts optional keyword arguments
1114
+ #
1115
+ # @option :opts [String] :value Specifies the value to configure the
1116
+ # udp-port setting to. Valid values are in the range of 1024 to
1117
+ # 65535
1118
+ #
1119
+ # @option :opts [Boolean] :default Configures the udp-port value on
1120
+ # the interface using the default keyword
1121
+ #
1122
+ # @return [Boolean] returns true if the command completed successfully
1123
+ def set_udp_port(name, opts = {})
1124
+ commands = command_builder('vxlan udp-port', opts)
1125
+ configure_interface(name, commands)
1126
+ end
1127
+
1128
+ ##
1129
+ # add_vtep adds a new VTEP endpoint to the global flood list for the
1130
+ # specified interface. If the VTEP endpoint is already configured, this
1131
+ # method will still return successfully.
1132
+ #
1133
+ # @eos_version 4.13.7M
1134
+ #
1135
+ # @param [String] :name The name of the interface to configure
1136
+ # @param [String] :vtep The IP address of the remote VTEP endpoint
1137
+ #
1138
+ # @return [Boolean] Returns true if the commands completed successfully
1139
+ def add_vtep(name, vtep)
1140
+ configure_interface(name, "vxlan flood vtep add #{vtep}")
1141
+ end
1142
+
1143
+ ##
1144
+ # remove_vtep deletes a VTEP endpoint from the global flood list for the
1145
+ # specified interface. If the VTEP endpoint specified is not configured,
1146
+ # this method will still return successfully.
1147
+ #
1148
+ # @eos_version 4.13.7M
1149
+ #
1150
+ # @param [String] :name The name of the interface to configure
1151
+ # @param [String] :vtep The IP address of the remote VTEP endpoint
1152
+ #
1153
+ # @return [Boolean] Returns true if the commands completed successfully
1154
+ def remove_vtep(name, vtep)
1155
+ configure_interface(name, "vxlan flood vtep remove #{vtep}")
1156
+ end
1157
+
1158
+ ##
1159
+ # update_vlan creates a new vlan to vni mapping for the specified
1160
+ # interface in the nodes current configuration
1161
+ #
1162
+ # @eos_verson 4.13.7M
1163
+ #
1164
+ # @param [String] :name The name of the interface to configure
1165
+ #
1166
+ # @param [Fixnum] :vlan The VLAN ID to configure.
1167
+ #
1168
+ # @param [Fixnum] :vni The VNI value to map the VLAN into
1169
+ #
1170
+ # @return [Boolean] returns true if the command completed successfully
1171
+ def update_vlan(name, vlan, vni)
1172
+ configure_interface(name, "vxlan vlan #{vlan} vni #{vni}")
1173
+ end
1174
+
1175
+ ##
1176
+ # remove_vlan deletes a previously configured VLAN to VNI mapping on the
1177
+ # specified interface.
1178
+ #
1179
+ # @eos_version 4.13.7M
1180
+ #
1181
+ # @param [String] :name the name of the interface to configure
1182
+ #
1183
+ # @param [Fixnum] :vlan The VLAN ID to remove from the configuration. If
1184
+ # the VLAN ID does not exist, this method will still return
1185
+ # successfully
1186
+ #
1187
+ # @return [Boolean] returns true if the command completed successfully
1188
+ def remove_vlan(name, vlan)
1189
+ configure_interface(name, "no vxlan vlan #{vlan} vni")
1190
1190
  end
1191
1191
  end
1192
1192
  end