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,88 @@
1
+ #
2
+ # Copyright (c) 2014, Arista Networks, Inc.
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # Neither the name of Arista Networks nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
24
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+ require 'rbeapi/api'
33
+
34
+ module Rbeapi
35
+
36
+ module Api
37
+
38
+ ##
39
+ # The Staticroute class provides a configuration instance for working
40
+ # with static routes in EOS.
41
+ #
42
+ class Staticroute < Entity
43
+
44
+ ##
45
+ # Returns the static routes configured on the node
46
+ #
47
+ # @example
48
+ # {
49
+ # <route>: {
50
+ # "next_hop": <string>,
51
+ # "name": <string, nil>
52
+ # }
53
+ # }
54
+ #
55
+ # @returns [Hash<String, String> The method will return all of the
56
+ # configured static routes on the node as a Ruby hash object. If
57
+ # there are no static routes configured, this method will return
58
+ # an empty hash
59
+ def getall
60
+ regex = %r{
61
+ (?<=^ip\sroute\s)
62
+ ([^\s]+)\s # captures network
63
+ ([^\s$]+) # captures next hop
64
+ (?:\s\d+) # non-capture metric
65
+ (?:\stag\s\d+) # non-catpure route tag
66
+ [\s|$]{1}(?:name\s(.+))? # capture route name
67
+ }x
68
+
69
+ routes = config.scan(regex)
70
+
71
+ routes.each_with_object({}) do |route, hsh|
72
+ hsh[route[0]] = { 'next_hop' => route[1],
73
+ 'name' => route[2] }
74
+ end
75
+ end
76
+
77
+ def create(route, nexthop, opts = {})
78
+ cmd = "ip route #{route} #{nexthop}"
79
+ opts.each { |param, value| cmds << "#{param} #{value}" }
80
+ configure cmd
81
+ end
82
+
83
+ def delete(route)
84
+ configure "no ip route #{route}"
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,381 @@
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
+
33
+ ##
34
+ # PuppetX is the toplevel namespace for working with Arista EOS nodes
35
+ module Rbeapi
36
+ ##
37
+ # Eos is module namesapce for working with the EOS command API
38
+ module Api
39
+ ##
40
+ # The Stp class provides a base class instance for working with
41
+ # the EOS spanning-tree configuration
42
+ #
43
+ class Stp < Entity
44
+
45
+ ##
46
+ # get returns the current stp configuration parsed from the nodes
47
+ # current running configuration.
48
+ #
49
+ # @example
50
+ # {
51
+ # mode: <string>
52
+ # instances: {...}
53
+ # interfaces: {...}
54
+ # }
55
+ #
56
+ # @see StpInstances instances get example
57
+ # @eee StpInterfaces interfaces get example
58
+ #
59
+ # @return [Hash] returns a Hash of attributes derived from eAPI
60
+ def get
61
+ response = {}
62
+ response.merge!(parse_mode)
63
+ response[:instances] = instances.getall
64
+ response[:interfaces] = interfaces.getall
65
+ response
66
+ end
67
+
68
+
69
+ ##
70
+ # parse_mode scans the nodes running configuration and extracts the
71
+ # value of the spanning-tree mode. The spanning tree mode is
72
+ # expected to be always be avaliable in the running config. The return
73
+ # value is intended to be merged into the stp resource hash
74
+ #
75
+ # @api private
76
+ #
77
+ # @return [Hash<Symbol, Object>] resource hash attribute
78
+ def parse_mode
79
+ mdata = /(?<=spanning-tree\smode\s)(\w+)$/.match(config)
80
+ { mode: mdata[1] }
81
+ end
82
+
83
+ ##
84
+ # instances returns a memoized instance of StpInstances for configuring
85
+ # individual stp instances.
86
+ #
87
+ # @return [StpInstances] an instance of StpInstances class
88
+ def instances
89
+ return @instances if @instances
90
+ @instances = StpInstances.new(node)
91
+ @instances
92
+ end
93
+
94
+ ##
95
+ # interfaces rereturns a memoized instance of StpInterfaces for
96
+ # configuring individual stp interfaces
97
+ #
98
+ # @return [StpInterfaces] an instance of StpInterfaces class
99
+ def interfaces
100
+ return @interfaces if @interfaces
101
+ @interfaces = StpInterfaces.new(node)
102
+ @interfaces
103
+ end
104
+
105
+ ##
106
+ # set_mode configures the stp mode in the global nodes running
107
+ # configuration. If the value option is not specified, then the stp
108
+ # mode is configured with the no keyword argument. If the default option
109
+ # is specified then the mode is configured with the default keyword
110
+ # argument. The default keyword argument takes precedence over the value
111
+ # option if both are provided
112
+ #
113
+ # @eos_version 4.13.7M
114
+ #
115
+ # @commands
116
+ # spanning-tree mode <value>
117
+ # no spanning-tree mode
118
+ # default spanning-tree mode
119
+ #
120
+ # @param [Hash] :opts Optional keyword arguments
121
+ #
122
+ # @option :opts [String] :value The value to configure the stp mode to
123
+ # in the nodes current running configuration
124
+ #
125
+ # @option :opts [Boolean] :deafult Configure the stp mode value using
126
+ # the default keyword
127
+ #
128
+ # @return [Boolean] returns true if the command completed successfully
129
+ #
130
+ def set_mode(opts = {})
131
+ value = opts[:value]
132
+ default = opts[:default] || false
133
+
134
+ case default
135
+ when true
136
+ cmd = 'default spanning-tree mode'
137
+ when false
138
+ cmd = (value ? "spanning-tree mode #{value}" : \
139
+ 'no spanning-tree mode')
140
+ end
141
+ configure cmd
142
+ end
143
+ end
144
+
145
+ ##
146
+ # The StpInstances class provides a class instance for working with
147
+ # spanning-tree instances in EOS
148
+ #
149
+ class StpInstances < Entity
150
+
151
+ DEFAULT_STP_PRIORITY = '32768'
152
+
153
+ ##
154
+ # get returns the specified stp intstance config parsed from the nodes
155
+ # current running configuration.
156
+ #
157
+ # @example
158
+ # {
159
+ # priority: <string>
160
+ # }
161
+ #
162
+ # @return [nil, Hash<Symbol, Object] returns the stp instance config as
163
+ # a resource hash. If the instances is not configured this method
164
+ # will return a nil object
165
+ def get(inst)
166
+ return nil unless parse_instances.include?(inst.to_s)
167
+ response = {}
168
+ response.merge!(parse_priority(inst))
169
+ response
170
+ end
171
+
172
+ ##
173
+ # getall returns all configured stp instances parsed from the nodes
174
+ # running configuration. The return hash is keyed by the instance
175
+ # identifier value
176
+ #
177
+ # @example
178
+ # {
179
+ # <inst>: {...}
180
+ # }
181
+ #
182
+ # @see get Instance get example
183
+ #
184
+ # @return [Hash<Symbol, Object>] returns all configured stp instances
185
+ # found in the nodes running configuration
186
+ def getall
187
+ parse_instances.each_with_object({}) do |inst, hsh|
188
+ values = get(inst)
189
+ hsh[inst] = values if values
190
+ end
191
+ end
192
+
193
+ ##
194
+ # parse_instances will scan the nodes current configuration and extract
195
+ # the list of configured mst instances. If no instances are configured
196
+ # then this method will return an empty array
197
+ #
198
+ # @api private
199
+ #
200
+ # @return [Array<String>] returns an Array of configured stp instances
201
+ def parse_instances
202
+ config = get_block('spanning-tree mst configuration')
203
+ config.scan(/(?<=^\s{3}instance\s)\d+/)
204
+ end
205
+ private :parse_instances
206
+
207
+ ##
208
+ # parse_priority will scan the nodes current configuration and extract
209
+ # the stp priority value for the given stp instance. If the stp
210
+ # instance prioirity is not configured, the priority value will be set
211
+ # using DEFAULT_STP_PRIORITY. The returned hash is intended to be merged
212
+ # into the resource hash
213
+ #
214
+ # @api private
215
+ #
216
+ # @return [Hash<Symbol, Object>] resource hash attribute
217
+ def parse_priority(inst)
218
+ priority_re = %r{
219
+ (?<=^spanning-tree\smst\s#{inst}\spriority\s)
220
+ (.+$)
221
+ }x
222
+ mdata = priority_re.match(config)
223
+ { priority: mdata.nil? ? DEFAULT_STP_PRIORITY : mdata[1] }
224
+ end
225
+ private :parse_priority
226
+
227
+ ##
228
+ # Deletes a configured MST instance
229
+ #
230
+ # @param [String] inst The MST instance to delete
231
+ #
232
+ # @return [Boolean] True if the commands succeed otherwise False
233
+ def delete(inst)
234
+ configure ['spanning-tree mst configuration', "no instance #{inst}",
235
+ 'exit']
236
+ end
237
+
238
+ ##
239
+ # Configures the spanning-tree MST priority
240
+ #
241
+ # @param [String] inst The MST instance to configure
242
+ # @param [Hash] opts The configuration parameters for the priority
243
+ # @option opts [string] :value The value to set the priority to
244
+ # @option opts [Boolean] :default The value should be set to default
245
+ #
246
+ # @return [Boolean] True if the commands succeed otherwise False
247
+ def set_priority(inst, opts = {})
248
+ value = opts[:value]
249
+ default = opts[:default] || false
250
+
251
+ case default
252
+ when true
253
+ cmd = "default spanning-tree mst #{inst} priority"
254
+ when false
255
+ cmd = (value ? "spanning-tree mst #{inst} priority #{value}" : \
256
+ "no spanning-tree mst #{inst} priority")
257
+ end
258
+ configure cmd
259
+ end
260
+ end
261
+
262
+ ##
263
+ # The StpInterfaces class provides a class instance for working with
264
+ # spanning-tree insterfaces in EOS
265
+ #
266
+ class StpInterfaces < Entity
267
+
268
+ ##
269
+ # get returns the configured stp interfaces from the nodes running
270
+ # configuration as a resource hash. If the specified interface is not
271
+ # configured as a switchport then this method will return nil
272
+ #
273
+ # @example
274
+ # {
275
+ # portfast: [true, false]
276
+ # bpduguard: [true, false]
277
+ # }
278
+ #
279
+ # @return [nil, Hash<Symbol, Object>] returns the stp interface as a
280
+ # resource hash
281
+ def get(name)
282
+ config = get_block("interface #{name}")
283
+ return nil unless config
284
+ return nil if /no switchport$/ =~ config
285
+ response = {}
286
+ response.merge!(parse_portfast(config))
287
+ response.merge!(parse_bpduguard(config))
288
+ response
289
+ end
290
+
291
+ ##
292
+ # getall returns all of the configured stp interfaces parsed from the
293
+ # nodes current running configuration. The returned hash is keyed by the
294
+ # interface name
295
+ #
296
+ # @example
297
+ # {
298
+ # <interface>: {...}
299
+ # }
300
+ #
301
+ # @see get Interface example
302
+ #
303
+ # @return [Hash<Symbol, Object>] returns the stp interfaces config as a
304
+ # resource hash from the nodes running configuration
305
+ def getall
306
+ interfaces = config.scan(/(?<=^interface\s)[Et|Po].+/)
307
+ resp = interfaces.each_with_object({}) do |name, hsh|
308
+ values = get(name)
309
+ hsh[name] = values if values
310
+ end
311
+ resp
312
+ end
313
+
314
+ ##
315
+ # parse_portfast scans the supplied interface configuration block and
316
+ # parses the value stp portfast. The value of portfast is either enabled
317
+ # (true) or disabled (false)
318
+ #
319
+ # @api private
320
+ #
321
+ # @return [Hash<Symbol, Object>] resource hash attribute
322
+ def parse_portfast(config)
323
+ val = /no spanning-tree portfast/ =~ config
324
+ { portfast: val.nil? }
325
+ end
326
+ private :parse_portfast
327
+
328
+ ##
329
+ # parse_bpduguard scans the supplied interface configuration block and
330
+ # parses the value of stp bpduguard. The value of bpduguard is either
331
+ # disabled (false) or enabled (true)
332
+ #
333
+ # @api private
334
+ #
335
+ # @return [Hash<Symbol, Object>] resource hash attribute
336
+ def parse_bpduguard(config)
337
+ val = /spanning-tree bpduguard enable/ =~ config
338
+ { bpduguard: !val.nil? }
339
+ end
340
+
341
+ ##
342
+ # Configures the interface portfast value
343
+ #
344
+ # @param [String] name The name of the interface to configure
345
+ # @param [Hash] opts The configuration parameters for portfast
346
+ # @option opts [Boolean] :value The value to set portfast
347
+ # @option opts [Boolean] :default The value should be set to default
348
+ #
349
+ # @return [Boolean] True if the commands succeed otherwise False
350
+ def set_portfast(name, opts = {})
351
+ value = opts[:value]
352
+ default = opts[:default] || false
353
+
354
+ cmds = ["interface #{name}"]
355
+ case default
356
+ when true
357
+ cmds << 'default spanning-tree portfast'
358
+ when false
359
+ cmds << (value ? 'spanning-tree portfast' :
360
+ 'no spanning-tree portfast')
361
+ end
362
+ configure(cmds)
363
+ end
364
+
365
+ def set_bpduguard(name, opts = {})
366
+ value = opts[:value]
367
+ default = opts[:default] || false
368
+
369
+ cmds = ["interface #{name}"]
370
+ case default
371
+ when true
372
+ cmds << 'default spanning-tree bpduguard'
373
+ when false
374
+ cmds << (value ? 'spanning-tree bpduguard enable' :
375
+ 'spanning-tree bpduguard disable')
376
+ end
377
+ configure(cmds)
378
+ end
379
+ end
380
+ end
381
+ end