rbeapi 1.0 → 1.1

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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +25 -2
  4. data/Gemfile +13 -7
  5. data/Rakefile +8 -7
  6. data/lib/rbeapi/api/alias.rb +160 -0
  7. data/lib/rbeapi/api/bgp.rb +9 -9
  8. data/lib/rbeapi/api/dns.rb +3 -1
  9. data/lib/rbeapi/api/interfaces.rb +194 -32
  10. data/lib/rbeapi/api/ipinterfaces.rb +5 -3
  11. data/lib/rbeapi/api/managementdefaults.rb +119 -0
  12. data/lib/rbeapi/api/mlag.rb +6 -6
  13. data/lib/rbeapi/api/ntp.rb +1 -1
  14. data/lib/rbeapi/api/ospf.rb +171 -12
  15. data/lib/rbeapi/api/prefixlists.rb +19 -9
  16. data/lib/rbeapi/api/radius.rb +5 -5
  17. data/lib/rbeapi/api/routemaps.rb +12 -12
  18. data/lib/rbeapi/api/snmp.rb +6 -4
  19. data/lib/rbeapi/api/stp.rb +24 -24
  20. data/lib/rbeapi/api/switchports.rb +15 -9
  21. data/lib/rbeapi/api/tacacs.rb +1 -1
  22. data/lib/rbeapi/api/users.rb +4 -4
  23. data/lib/rbeapi/api/varp.rb +7 -3
  24. data/lib/rbeapi/api/vlans.rb +2 -2
  25. data/lib/rbeapi/api/vrrp.rb +61 -61
  26. data/lib/rbeapi/client.rb +9 -6
  27. data/lib/rbeapi/eapilib.rb +3 -3
  28. data/lib/rbeapi/netdev/snmp.rb +8 -6
  29. data/lib/rbeapi/switchconfig.rb +9 -10
  30. data/lib/rbeapi/version.rb +1 -1
  31. data/spec/support/fixtures.rb +4 -4
  32. data/spec/support/matchers/switch_config_sections.rb +2 -2
  33. data/spec/system/rbeapi/api/acl_spec.rb +2 -4
  34. data/spec/system/rbeapi/api/alias_spec.rb +168 -0
  35. data/spec/system/rbeapi/api/bgp_spec.rb +1 -2
  36. data/spec/system/rbeapi/api/interfaces_base_spec.rb +7 -8
  37. data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +36 -3
  38. data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +35 -3
  39. data/spec/system/rbeapi/api/interfaces_vlan_spec.rb +90 -0
  40. data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +3 -4
  41. data/spec/system/rbeapi/api/managementdefaults_spec.rb +31 -0
  42. data/spec/system/rbeapi/api/ospf_interfaces_spec.rb +36 -11
  43. data/spec/system/rbeapi/api/ospf_spec.rb +240 -17
  44. data/spec/system/rbeapi/api/prefixlists_spec.rb +105 -89
  45. data/spec/system/rbeapi/api/routemaps_spec.rb +15 -10
  46. data/spec/system/rbeapi/api/users_spec.rb +4 -5
  47. data/spec/system/rbeapi/api/vrrp_spec.rb +2 -5
  48. data/spec/system/rbeapi/client_spec.rb +1 -2
  49. data/spec/unit/rbeapi/api/acl/default_spec.rb +1 -2
  50. data/spec/unit/rbeapi/api/alias/default_spec.rb +119 -0
  51. data/spec/unit/rbeapi/api/alias/fixture_alias.text +3 -0
  52. data/spec/unit/rbeapi/api/bgp/bgp_neighbors_spec.rb +1 -2
  53. data/spec/unit/rbeapi/api/bgp/bgp_spec.rb +1 -2
  54. data/spec/unit/rbeapi/api/interfaces/base_spec.rb +1 -1
  55. data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +35 -1
  56. data/spec/unit/rbeapi/api/interfaces/fixture_interfaces.text +68 -0
  57. data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +41 -4
  58. data/spec/unit/rbeapi/api/interfaces/vlan_spec.rb +72 -0
  59. data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +2 -2
  60. data/spec/unit/rbeapi/api/managementdefaults/default_spec.rb +50 -0
  61. data/spec/unit/rbeapi/api/managementdefaults/fixture_managementdefaults.yaml +1 -0
  62. data/spec/unit/rbeapi/api/prefixlists/default_spec.rb +98 -80
  63. data/spec/unit/rbeapi/api/prefixlists/fixture_prefixlists.text +9 -4
  64. data/spec/unit/rbeapi/api/users/default_spec.rb +2 -4
  65. data/spec/unit/rbeapi/api/vrrp/default_spec.rb +2 -5
  66. data/spec/unit/rbeapi/client_spec.rb +21 -14
  67. data/spec/unit/rbeapi/switchconfig_spec.rb +10 -3
  68. metadata +49 -59
@@ -41,8 +41,8 @@ module Rbeapi
41
41
  # The Ipinterface class provides an instance for managing logical
42
42
  # IP interfaces configured using eAPI.
43
43
  class Ipinterfaces < Entity
44
- DEFAULT_ADDRESS = ''
45
- DEFAULT_LOAD_INTERVAL = ''
44
+ DEFAULT_ADDRESS = ''.freeze
45
+ DEFAULT_LOAD_INTERVAL = ''.freeze
46
46
 
47
47
  ##
48
48
  # get returns a resource hash that represents the configuration of the IP
@@ -336,7 +336,9 @@ module Rbeapi
336
336
  default = opts[:default] || false
337
337
 
338
338
  if value
339
- fail ArgumentError, 'value must be an Array' unless value.is_a?(Array)
339
+ unless value.is_a?(Array)
340
+ raise ArgumentError, 'value must be an Array'
341
+ end
340
342
  end
341
343
 
342
344
  case default
@@ -0,0 +1,119 @@
1
+ #
2
+ # Copyright (c) 2014,2015, 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
+ ##
35
+ # Rbeapi toplevel namespace.
36
+ module Rbeapi
37
+ ##
38
+ # Api is module namespace for working with the EOS command API.
39
+ module Api
40
+ ##
41
+ # The Managementdefaults class provides a configuration instance for
42
+ # configuring management defaults of the node.
43
+ class Managementdefaults < Entity
44
+ DEFAULT_SECRET_HASH = 'md5'.freeze
45
+
46
+ ##
47
+ # get scans the current nodes configuration and returns the values as
48
+ # a Hash describing the current state.
49
+ #
50
+ # @example
51
+ # {
52
+ # secret_hash: <string>
53
+ # }
54
+ #
55
+ # @return [nil, Hash<Symbol, Object] returns the nodes current running
56
+ # configuration as a Hash. If management defaults are not configured
57
+ # on the node this method will return nil.
58
+ def get
59
+ config = get_block('management defaults')
60
+
61
+ settings = {}
62
+ settings.merge!(parse_secret_hash(config))
63
+ end
64
+
65
+ ##
66
+ # parse_secret_hash scans the current nodes running configuration and
67
+ # extracts the value of secret hash from the management defaults.
68
+ # If the parse_secret has not been configured, then this method will
69
+ # return DEFAULT_SECRET_HASH. The return
70
+ # value is intended to be merged into the resource hash.
71
+ #
72
+ # @api private
73
+ #
74
+ # @param config [String] The management defaults configuration block
75
+ # retrieved from the nodes current running configuration.
76
+ #
77
+ # @return [Hash<Symbol, Object>] Returns the resource hash attribute.
78
+ def parse_secret_hash(config)
79
+ mdata = /(?<=\s{3}secret hash\s)(md5|sha512)$/.match(config)
80
+ { secret_hash: mdata.nil? ? DEFAULT_SECRET_HASH : mdata[1] }
81
+ end
82
+ private :parse_secret_hash
83
+
84
+ ##
85
+ # set_secret_hash configures the management defaults secret hash value
86
+ # in the current nodes running configuration.
87
+ # If the default keyword is provided, the configuration is defaulted
88
+ # using the default keyword.
89
+ #
90
+ # @since eos_version 4.13.7M
91
+ #
92
+ # ===Commands
93
+ # management defaults
94
+ # secret hash <value>
95
+ # no secret hash
96
+ # default secret hash
97
+ #
98
+ # @param opts [Hash] Optional keyword arguments
99
+ #
100
+ # @option opts value [String] The value to configure the secret hash to.
101
+ #
102
+ # @option opts enable [Boolean] If false then the command is
103
+ # negated. Default is true.
104
+ #
105
+ # @option opts default [Boolean] Configure the secret hash value using
106
+ # the default keyword.
107
+ #
108
+ # @return [Boolean] Returns true if the command completed successfully.
109
+ def set_secret_hash(opts = {})
110
+ unless ['md5', 'sha512', nil].include?(opts[:value])
111
+ raise ArgumentError, 'secret hash must be md5 or sha512'
112
+ end
113
+ cmd = command_builder("secret hash #{opts[:value]}")
114
+ cmds = ['management defaults', cmd]
115
+ configure(cmds)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -41,10 +41,10 @@ module Rbeapi
41
41
  # The Mlag class provides a configuration instance for working with
42
42
  # the global MLAG configuration of the node.
43
43
  class Mlag < Entity
44
- DEFAULT_DOMAIN_ID = ''
45
- DEFAULT_LOCAL_INTF = ''
46
- DEFAULT_PEER_ADDR = ''
47
- DEFAULT_PEER_LINK = ''
44
+ DEFAULT_DOMAIN_ID = ''.freeze
45
+ DEFAULT_LOCAL_INTF = ''.freeze
46
+ DEFAULT_PEER_ADDR = ''.freeze
47
+ DEFAULT_PEER_LINK = ''.freeze
48
48
 
49
49
  ##
50
50
  # get scans the current nodes configuration and returns the values as
@@ -367,10 +367,10 @@ module Rbeapi
367
367
  #
368
368
  # @return [Boolean] Returns true if the command completed successfully.
369
369
  def set_shutdown(opts = {})
370
- fail 'set_shutdown has the value option set' if opts[:value]
370
+ raise 'set_shutdown has the value option set' if opts[:value]
371
371
  # Shutdown semantics are opposite of enable semantics so invert enable
372
372
  value = !opts[:enable]
373
- opts.merge!(enable: value)
373
+ opts[:enable] = value
374
374
  cmd = command_builder('shutdown', opts)
375
375
  cmds = ['mlag configuration', cmd]
376
376
  configure(cmds)
@@ -41,7 +41,7 @@ module Rbeapi
41
41
  # The Ntp class provides an instance for working with the nodes
42
42
  # NTP configuration.
43
43
  class Ntp < Entity
44
- DEFAULT_SRC_INTF = ''
44
+ DEFAULT_SRC_INTF = ''.freeze
45
45
 
46
46
  ##
47
47
  # get returns the nodes current ntp configure as a resource hash.
@@ -48,11 +48,18 @@ module Rbeapi
48
48
  #
49
49
  # @example
50
50
  # {
51
- # router_id: <string>
51
+ # router_id: <string>,
52
+ # max_lsa: <integer>,
53
+ # maximum_paths: <integer>,
54
+ # passive_interface_default <boolean>,
55
+ # passive_interfaces: array<string>,
56
+ # active_interfaces: array<string>,
52
57
  # areas: {
53
58
  # <string>: array<string>
54
59
  # },
55
- # redistribute: {}
60
+ # redistribute: {
61
+ # <string>: {route_map: <string>}
62
+ # }
56
63
  # }
57
64
  #
58
65
  # @param inst [String] The ospf instance name.
@@ -65,7 +72,23 @@ module Rbeapi
65
72
 
66
73
  response = {}
67
74
  mdata = /(?<=^\s{3}router-id\s)(.+)$/.match(config)
68
- response['router_id'] = mdata.nil? ? '' : mdata[0]
75
+ response[:router_id] = mdata.nil? ? '' : mdata[0]
76
+
77
+ mdata = /(?<=^\s{3}max-lsa\s)(\d+)(?=.*$)/.match(config)
78
+ response[:max_lsa] = mdata.nil? ? '' : mdata[0].to_i
79
+
80
+ mdata = /(?<=^\s{3}maximum-paths\s)(\d+)$/.match(config)
81
+ response[:maximum_paths] = mdata.nil? ? '' : mdata[0].to_i
82
+
83
+ mdata = /^\s{3}passive-interface default$/ =~ config
84
+ response[:passive_interface_default] = !mdata.nil?
85
+
86
+ response[:passive_interfaces] =
87
+ config.scan(/(?<=^\s{3}passive-interface\s)(?!default)(.*)$/)
88
+ .flatten!.to_a
89
+
90
+ response[:active_interfaces] =
91
+ config.scan(/(?<=^\s{3}no passive-interface\s)(.*)$/).flatten!.to_a
69
92
 
70
93
  networks = config.scan(/^\s{3}network\s(.+)\sarea\s(.+)$/)
71
94
  areas = networks.each_with_object({}) do |cfg, hsh|
@@ -76,13 +99,13 @@ module Rbeapi
76
99
  hsh[area] = [net]
77
100
  end
78
101
  end
79
- response['areas'] = areas
102
+ response[:areas] = areas
80
103
 
81
104
  values = \
82
105
  config.scan(/(?<=^\s{3}redistribute\s)(\w+)[\s|$]*(route-map\s(.+))?/)
83
106
 
84
- response['redistribute'] = values.each_with_object({}) do |value, hsh|
85
- hsh[value[0]] = { 'route_map' => value[2] }
107
+ response[:redistribute] = values.each_with_object({}) do |value, hsh|
108
+ hsh[value[0]] = { route_map: value[2] }
86
109
  end
87
110
  response
88
111
  end
@@ -94,6 +117,11 @@ module Rbeapi
94
117
  # {
95
118
  # <pid>: {
96
119
  # router_id: <string>,
120
+ # max_lsa: <integer>,
121
+ # maximum_paths: <integer>,
122
+ # passive_interface_default <boolean>,
123
+ # passive_interfaces: array<string>,
124
+ # active_interfaces: array<string>,
97
125
  # areas: {},
98
126
  # redistribute: {}
99
127
  # },
@@ -107,7 +135,7 @@ module Rbeapi
107
135
  response = instances.each_with_object({}) do |inst, hsh|
108
136
  hsh[inst] = get inst
109
137
  end
110
- response['interfaces'] = interfaces.getall
138
+ response[:interfaces] = interfaces.getall
111
139
  response
112
140
  end
113
141
 
@@ -156,6 +184,133 @@ module Rbeapi
156
184
  configure cmds
157
185
  end
158
186
 
187
+ ##
188
+ # set_max_lsa sets router ospf max-lsa with pid and options.
189
+ #
190
+ # @param pid [String] The router ospf name.
191
+ #
192
+ # @param opts [hash] Optional keyword arguments.
193
+ #
194
+ # @option opts enable [Boolean] If false then the command is
195
+ # negated. Default is true.
196
+ #
197
+ # @option opts default [Boolean] Configure the max-lsa to default.
198
+ #
199
+ # @return [Boolean] Returns true if the command completed successfully.
200
+ def set_max_lsa(pid, opts = {})
201
+ cmd = command_builder('max-lsa', opts)
202
+ cmds = ["router ospf #{pid}", cmd]
203
+ configure cmds
204
+ end
205
+
206
+ ##
207
+ # set_maximum_paths sets router ospf maximum-paths with pid and options.
208
+ #
209
+ # @param pid [String] The router ospf name.
210
+ #
211
+ # @param opts [hash] Optional keyword arguments.
212
+ #
213
+ # @option opts enable [Boolean] If false then the command is
214
+ # negated. Default is true.
215
+ #
216
+ # @option opts default [Boolean] Configure the maximum-paths to default.
217
+ #
218
+ # @return [Boolean] Returns true if the command completed successfully.
219
+ def set_maximum_paths(pid, opts = {})
220
+ cmd = command_builder('maximum-paths', opts)
221
+ cmds = ["router ospf #{pid}", cmd]
222
+ configure cmds
223
+ end
224
+
225
+ ##
226
+ # set_passive_interface_default sets router ospf passive-interface
227
+ # default with pid and options. If the passive-interface default keyword
228
+ # is false, then the
229
+ # passive-interface default is disabled. If the enable keyword is true,
230
+ # then the passive-interface default is enabled. If the default keyword
231
+ # is set to true, then the passive-interface default is configured using
232
+ # the default keyword. The default keyword takes precedence ver the
233
+ # enable keyword if both are provided.
234
+ #
235
+ # @param pid [String] The router ospf name.
236
+ #
237
+ # @param opts [hash] Optional keyword arguments.
238
+ #
239
+ # @option opts enable [Boolean] If false then the command is
240
+ # negated. Default is true.
241
+ #
242
+ # @option opts default [Boolean] Configure the passive-interface default
243
+ # to default.
244
+ #
245
+ # @return [Boolean] Returns true if the command completed successfully.
246
+ def set_passive_interface_default(pid, opts = {})
247
+ opts[:enable] = opts[:value] | false
248
+ opts[:value] = nil
249
+ cmd = command_builder('passive-interface default', opts)
250
+ cmds = ["router ospf #{pid}", cmd]
251
+ configure cmds
252
+ end
253
+
254
+ ##
255
+ # set_active_interfaces sets router ospf no passive interface with pid
256
+ # and options, when passive interfaces default is configured.
257
+ #
258
+ # @param pid [String] The router ospf name.
259
+ #
260
+ # @param opts [hash] Optional keyword arguments.
261
+ #
262
+ # @option opts enable [Boolean] If false then the command is
263
+ # negated. Default is true.
264
+ #
265
+ # @option opts default [Boolean] Configure the active interface to
266
+ # default.
267
+ #
268
+ # @return [Boolean] Returns true if the command completed successfully.
269
+ def set_active_interfaces(pid, opts = {})
270
+ values = opts[:value]
271
+ current = get(pid)[:active_interfaces]
272
+ cmds = ["router ospf #{pid}"]
273
+ current.each do |name|
274
+ unless Array(values).include?(name)
275
+ cmds << "passive-interface #{name}"
276
+ end
277
+ end
278
+ Array(values).each do |name|
279
+ cmds << "no passive-interface #{name}"
280
+ end
281
+ configure cmds
282
+ end
283
+
284
+ ##
285
+ # set_passive_interfaces sets router ospf passive interface with pid
286
+ # and options.
287
+ #
288
+ # @param pid [String] The router ospf name.
289
+ #
290
+ # @param opts [hash] Optional keyword arguments.
291
+ #
292
+ # @option opts enable [Boolean] If false then the command is
293
+ # negated. Default is true.
294
+ #
295
+ # @option opts default [Boolean] Configure the passive interface to
296
+ # default.
297
+ #
298
+ # @return [Boolean] Returns true if the command completed successfully.
299
+ def set_passive_interfaces(pid, opts = {})
300
+ values = opts[:value]
301
+ current = get(pid)[:passive_interfaces]
302
+ cmds = ["router ospf #{pid}"]
303
+ current.each do |name|
304
+ unless Array(values).include?(name)
305
+ cmds << "no passive-interface #{name}"
306
+ end
307
+ end
308
+ Array(values).each do |name|
309
+ cmds << "passive-interface #{name}"
310
+ end
311
+ configure cmds
312
+ end
313
+
159
314
  ##
160
315
  # add_network adds network settings for router ospf and network area.
161
316
  #
@@ -203,9 +358,11 @@ module Rbeapi
203
358
  #
204
359
  # @return [Boolean] Returns true if the command completed successfully.
205
360
  def set_redistribute(pid, proto, opts = {})
206
- routemap = opts[:routemap]
207
- cmds = ["router ospf #{pid}", "redistribute #{proto}"]
208
- cmds[1] << " route-map #{routemap}" if routemap
361
+ routemap = opts[:route_map]
362
+ redistribute = "redistribute #{proto}"
363
+ redistribute << " route-map #{routemap}" if routemap
364
+ cmd = command_builder(redistribute, opts)
365
+ cmds = ["router ospf #{pid}", cmd]
209
366
  configure cmds
210
367
  end
211
368
  end
@@ -231,11 +388,13 @@ module Rbeapi
231
388
  def get(name)
232
389
  config = get_block("interface #{name}")
233
390
  return nil unless config
234
- return nil unless /no switchport$/ =~ config
391
+ unless /no switchport$/ =~ config || /^interface (Lo|Vl)/ =~ config
392
+ return nil
393
+ end
235
394
 
236
395
  response = {}
237
396
  nettype = /ip ospf network point-to-point/ =~ config
238
- response['network_type'] = nettype.nil? ? 'broadcast' : 'point-to-point'
397
+ response[:network_type] = nettype.nil? ? 'broadcast' : 'point-to-point'
239
398
  response
240
399
  end
241
400
 
@@ -67,12 +67,22 @@ module Rbeapi
67
67
  # array of hashes, where each prefix is a hash object.
68
68
  # If the prefix list is not found, a nil object is returned.
69
69
  def get(name)
70
- config = get_block("ip prefix-list #{name}")
71
- return nil unless config
70
+ return nil unless config =~ /ip prefix-list #{name}/
71
+
72
+ # single-line prefix list
73
+ if config =~ /ip prefix-list #{name}\sseq/
74
+ entries = config.scan(/^(?:ip\sprefix-list\s#{name}\sseq\s)(\d+)\s
75
+ (permit|deny)\s(.+)$/x)
76
+ # or multi-line
77
+ else
78
+ prefix_list = get_block("ip prefix-list #{name}")
79
+ entries = prefix_list.scan(/^\s+(?:seq\s)(\d+)\s
80
+ (permit|deny)\s(.+)$/x)
81
+ end
72
82
 
73
- entries = config.scan(/^\s{3}(?:seq\s)(\d+)\s(permit|deny)\s(.+)$/)
74
83
  entries.each_with_object([]) do |entry, arry|
75
- arry << { 'seq' => entry[0], 'action' => entry[1],
84
+ arry << { 'seq' => entry[0],
85
+ 'action' => entry[1],
76
86
  'prefix' => entry[2] }
77
87
  end
78
88
  end
@@ -116,15 +126,15 @@ module Rbeapi
116
126
  # If there are no prefix lists configured, an empty hash will
117
127
  # be returned.
118
128
  def getall
119
- lists = config.scan(/(?<=^ip\sprefix-list\s).+/)
120
- lists.each_with_object({}) do |name, hsh|
129
+ lists = config.scan(/(?<=^ip\sprefix-list\s)[^\s]+(?=\sseq.+)?/)
130
+ lists.uniq.each_with_object({}) do |name, hsh|
121
131
  values = get name
122
132
  hsh[name] = values if values
123
133
  end
124
134
  end
125
135
 
126
136
  ##
127
- # create will create a new ip prefix-list with designated name.
137
+ # Creates a new ip prefix-list with the designated name.
128
138
  #
129
139
  # @param name [String] The name of the ip prefix-list.
130
140
  #
@@ -134,7 +144,7 @@ module Rbeapi
134
144
  end
135
145
 
136
146
  ##
137
- # add_rule will create an ip prefix-list with the designated name,
147
+ # Creates an ip prefix-list with the designated name,
138
148
  # seqno, action and prefix.
139
149
  #
140
150
  # @param name [String] The name of the ip prefix-list.
@@ -154,7 +164,7 @@ module Rbeapi
154
164
  end
155
165
 
156
166
  ##
157
- # delete will remove the designated prefix-list.
167
+ # Removes the designated prefix-list.
158
168
  #
159
169
  # @param name [String] The name of the ip prefix-list.
160
170
  #