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,181 @@
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 Varp class provides an instance for working with the global
40
+ # VARP configuration of the node
41
+ class Varp < Entity
42
+
43
+ ##
44
+ # Returns the global VARP configuration from the node
45
+ #
46
+ # Example
47
+ # {
48
+ # "mac_address": <string>,
49
+ # "interfaces": {...}
50
+ # }
51
+ #
52
+ # @return [Hash] A Ruby hash object that provides the Varp settings as
53
+ # key / value pairs.
54
+ def get
55
+ response = {}
56
+
57
+ regex = %r{
58
+ (?<=^ip\svirtual-router\smac-address\s)
59
+ ((?:[a-f0-9]{2}:){5}[a-f0-9]{2})$
60
+ }x
61
+
62
+ mdata = regex.match(config)
63
+ response['mac_address'] = mdata.nil? ? '' : mdata[1]
64
+ response['interfaces'] = interfaces.getall
65
+ response
66
+ end
67
+
68
+ def interfaces
69
+ return @interfaces if @interfaces
70
+ @interfaces = VarpInterfaces.new(node)
71
+ @interfaces
72
+ end
73
+
74
+ ##
75
+ # Configure the VARP virtual-router mac-address value
76
+ #
77
+ # @param [Hash] opts The configuration parameters
78
+ # @option opts [string] :value The value to set the mac-address to
79
+ # @option opts [Boolean] :default The value should be set to default
80
+ #
81
+ # @return [Boolean] returns true if the command completed successfully
82
+ def set_mac_address(opts = {})
83
+ value = opts[:value]
84
+ default = opts[:default] || false
85
+
86
+ case default
87
+ when true
88
+ cmds = ['default ip virtual-router mac-address']
89
+ when false
90
+ cmds = (value ? "ip virtual-router mac-address #{value}" : \
91
+ 'no ip virtual-router mac-address')
92
+ end
93
+ configure(cmds)
94
+ end
95
+ end
96
+
97
+ class VarpInterfaces < Entity
98
+ ##
99
+ # Returns a single VARP interface configuration
100
+ #
101
+ # Example
102
+ # {
103
+ # "name": <string>,
104
+ # "addresses": array<string>
105
+ # }
106
+ #
107
+ # @param [String] :name The interface name to return the configuration
108
+ # values for. This must be the full interface identifier.
109
+ #
110
+ # @return [nil, Hash<String, String>] A Ruby hash that represents the
111
+ # VARP interface confguration. A nil object is returned if the
112
+ # specified interface is not configured
113
+ def get(name)
114
+ config = get_block("^interface #{name}")
115
+ return nil unless config
116
+ addrs = config.scan(/(?<=\s{3}ip\svirtual-router\saddress\s).+$/)
117
+ { 'addresses' => addrs }
118
+ end
119
+
120
+ ##
121
+ # Returns the collection of MLAG interfaces as a hash index by the
122
+ # interface name
123
+ #
124
+ # Example
125
+ # {
126
+ # <name>: {...},
127
+ # <name>: {...}
128
+ # }
129
+ #
130
+ # @return [nil, Hash<String, String>] A Ruby hash that represents the
131
+ # MLAG interface confguration. A nil object is returned if no
132
+ # interfaces are configured.
133
+ def getall
134
+ interfaces = config.scan(/(?<=^interface\s)(Vl.+)$/)
135
+ interfaces.first.each_with_object({}) do |name, resp|
136
+ data = get(name)
137
+ resp[name] = data if data
138
+ end
139
+ end
140
+
141
+ ##
142
+ # Creates a new MLAG interface with the specified mlag id
143
+ #
144
+ # @param [String] :name The name of the interface to create. The
145
+ # name argument must be the full interface name. Valid interfaces
146
+ # are restricted to Port-Channel interfaces
147
+ # @param [String] :id The MLAG ID to confgure for the specified
148
+ # interface name
149
+ #
150
+ # @return [Boolean] True if the commands succeeds otherwise False
151
+ def set_addresses(name, opts = {})
152
+ value = opts[:value]
153
+ default = opts[:default] || false
154
+
155
+ case default
156
+ when true
157
+ return configure('default ip virtual-router address')
158
+ when false
159
+ get(name)['addresses'].each do |addr|
160
+ result = remove_address(name, addr)
161
+ return result unless result
162
+ end
163
+ value.each do |addr|
164
+ result = add_address(name, addr)
165
+ return result unless result
166
+ end
167
+ end
168
+ return true
169
+ end
170
+
171
+ def add_address(name, value)
172
+ configure(["interface #{name}", "ip virtual-router address #{value}"])
173
+ end
174
+
175
+ def remove_address(name, value)
176
+ configure(["interface #{name}",
177
+ "no ip virtual-router address #{value}"])
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,338 @@
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
+ ##
37
+ # Api is module namesapce for working with the EOS command API
38
+ module Api
39
+
40
+ ##
41
+ # The Vlan class provides a class implementation for working with the
42
+ # collection of Vlans on the node. This class presents an abstraction
43
+ # of the nodes configured vlan id's from the running configuration.
44
+ #
45
+ # @eos_version 4.13.7M
46
+ class Vlans < Entity
47
+
48
+ ##
49
+ # get returns the specified vlan resource Hash that represents the
50
+ # nodes current vlan configuration.
51
+ #
52
+ # @example
53
+ # {
54
+ # name: <string>
55
+ # state: <string>
56
+ # trunk_groups: array[<string]
57
+ # }
58
+ #
59
+ # @param [String] id The vlan id to return a resource for from the
60
+ # nodes configuration
61
+ #
62
+ # @return [nil, Hash<Symbol, Object>] Returns the vlan resource as a
63
+ # Hash. If the specified vlan id is not found in the nodes current
64
+ # configuration a nil object is returned
65
+ def get(id)
66
+ config = get_block("vlan #{id}")
67
+ return nil unless config
68
+ response = {}
69
+ response.merge!(parse_name(config))
70
+ response.merge!(parse_state(config))
71
+ response.merge!(parse_trunk_groups(config))
72
+ response
73
+ end
74
+
75
+ ##
76
+ # getall returns the collection of vlan resources from the nodes
77
+ # running configuration as a hash. The vlan resource collection
78
+ # hash is keyed by the unique vlan id
79
+ #
80
+ # @example
81
+ # {
82
+ # <vlanid>: {...}
83
+ # }
84
+ #
85
+ # @see get Vlan resource example
86
+ #
87
+ # @return [Hash<Symbol, Object>] returns a hash that represents the
88
+ # entire vlan collection from the nodes running configuration. If
89
+ # there are no vlans configured, this method will return an empty
90
+ # hash
91
+ def getall
92
+ vlans = config.scan(/(?<=^vlan\s)\d+$/)
93
+ vlans.each_with_object({}) do |vid, hsh|
94
+ resource = get vid
95
+ hsh[vid] = resource if resource
96
+ end
97
+ end
98
+
99
+ ##
100
+ # parse_name scans the provided configuration block and parses the
101
+ # vlan name value. The vlan name should always return a value
102
+ # from the running conifguration. The return value is intended to
103
+ # be merged into the resource hash
104
+ #
105
+ # @api private
106
+ #
107
+ # @return [Hash<Symbol, Object>] resource hash attribute
108
+ def parse_name(config)
109
+ mdata = /name (\w+)$/.match(config)
110
+ { name: mdata[1] }
111
+ end
112
+ private :parse_name
113
+
114
+ ##
115
+ # parse_state scans the provided configuration block and parses the
116
+ # vlan state value. The vlan state should always return a value from
117
+ # the nodes running configuration. The return hash is intended to be
118
+ # merged into the resource hash
119
+ #
120
+ # @api private
121
+ #
122
+ # @return [Hash<Symbol, Object>] resource hash attribute
123
+ def parse_state(config)
124
+ mdata = /state (\w+)$/.match(config)
125
+ { state: mdata[1] }
126
+ end
127
+ private :parse_state
128
+
129
+ ##
130
+ # parse_trunk_groups scans the provided configuration block and parses
131
+ # the trunk groups. If no trunk groups are found in the nodes
132
+ # running configuration then an empty array is returned as the value.
133
+ # The return hash is intedned to be merged into the resource hash.
134
+ #
135
+ # @api private
136
+ #
137
+ # @return [Hash<Symbol, Object>] resource hash attribute
138
+ def parse_trunk_groups(config)
139
+ values = config.scan(/trunk group (.+)$/).first
140
+ values = [] unless values
141
+ { trunk_groups: values }
142
+ end
143
+ private :parse_trunk_groups
144
+
145
+ ##
146
+ # create will create a new vlan resource in the nodes current
147
+ # configuration with the specified vlan id. If the create method
148
+ # is called and the vlan id already exists, this method will still
149
+ # return true.
150
+ #
151
+ # @eos_version 4.13.7M
152
+ #
153
+ # @commands
154
+ # vlan <value>
155
+ #
156
+ # @param [String, Integer] :id The vlan id to create on the node. The
157
+ # vlan id must be in the valid range of 1 to 4094
158
+ #
159
+ # @return [Boolean] returns true if the command completed successfully
160
+ def create(id)
161
+ configure("vlan #{id}")
162
+ end
163
+
164
+ ##
165
+ # delete will delete an existing vlan resource from the nodes current
166
+ # running configuration. If the delete method is called and the vlan
167
+ # id does not exist, this method will succeed.
168
+ #
169
+ # @eos_version 4.13.7M
170
+ #
171
+ # @commands
172
+ # no vlan <value>
173
+ #
174
+ # @param [String, Integer] :id The vlan id to delete from the node. The
175
+ # id value should be in the valid range of 1 to 4094
176
+ #
177
+ # @return [Boolean] returns true if the command completed successfully
178
+ def delete(id)
179
+ configure("no vlan #{id}")
180
+ end
181
+
182
+ ##
183
+ # default will configure the vlan using the default keyword. This
184
+ # command has the same effect as deleting the vlan from the nodes
185
+ # running configuration.
186
+ #
187
+ # @eos_version 4.13.7M
188
+ #
189
+ # @commands
190
+ # default vlan <value>
191
+ #
192
+ # @param [String, Integer] :id The vlan id to default in the nodes
193
+ # configuration. Ths vid value should be in the valid range of 1
194
+ # to 4094
195
+ #
196
+ # @return [Boolean] returns true if the command complete successfully
197
+ def default(id)
198
+ configure("default vlan #{id}")
199
+ end
200
+
201
+ ##
202
+ # set_name configures the name value for the specified vlan id in the
203
+ # nodes running configuration. If the value is not provided in the
204
+ # opts keyword Hash then the name value is negated using the no
205
+ # keyword. If the default keyword is set to true, then the name value
206
+ # is defaulted using the default keyword. The default keyword takes
207
+ # precedence over the value keyword
208
+ #
209
+ # @eos_version 4.13.7M
210
+ #
211
+ # @commands
212
+ # vlan <id>
213
+ # name <value>
214
+ # no name
215
+ # defaul name
216
+ #
217
+ # @param [String, Integer] :id The vlan id to apply the configuration
218
+ # to. The id value should be in the valid range of 1 to 4094
219
+ #
220
+ # @param [Hash] :opts Optional keyword arguments
221
+ #
222
+ # @option :opts [String] :value The value to configure the vlan name
223
+ # to in the node configuration. The name parameter accepts a-z, 0-9
224
+ # and _.
225
+ #
226
+ # @option :opts [Boolean] :default Configure the vlan name value using
227
+ # the default keyword
228
+ #
229
+ # @return [Boolean] returns true if the command completed successfully
230
+ def set_name(id, opts = {})
231
+ value = opts[:value]
232
+ default = opts[:default] || false
233
+
234
+ cmds = ["vlan #{id}"]
235
+ case default
236
+ when true
237
+ cmds << 'default name'
238
+ when false
239
+ cmds << (value.nil? ? 'no name' : "name #{value}")
240
+ end
241
+ configure(cmds)
242
+ end
243
+
244
+ ##
245
+ # set_state configures the state value for the specified vlan id in
246
+ # the nodes running configuration. If the value is not provided in
247
+ # the opts keyword Hash then the state value is negated using the no
248
+ # keyword. If the default keyword is set to true, then the state
249
+ # value is defaulted using the default keyword. The default keyword
250
+ # takes precedence over the value keyword
251
+ #
252
+ # @eos_version 4.13.7M
253
+ #
254
+ # @commands
255
+ # vlan <id>
256
+ # state [active, suspend]
257
+ # no state
258
+ # default state
259
+ #
260
+ # @param [String, Integer] :id The vlan id to apply the configuration
261
+ # to. The id value should be in the valid range of 1 to 4094
262
+ #
263
+ # @param [Hash] :opts Optional keyword arguments
264
+ #
265
+ # @option :opts [String] :value The value to configure the vlan state
266
+ # to in the node's configuration. Accepted values are 'active' or
267
+ # 'suspend'
268
+ #
269
+ # @option :opts [Boolean] :deafult Configure the vlan state value using
270
+ # the default keyword
271
+ #
272
+ # @return [Boolean] returns true if the command completed successfully
273
+ #
274
+ # @raise [ArgumentError] if the value is not in the accept list of
275
+ # values
276
+ def set_state(id, opts = {})
277
+ value = opts[:value]
278
+ default = opts[:default] || false
279
+
280
+ unless ['active', 'suspend', nil].include?(value)
281
+ raise ArgumentError, 'state must be active, suspend or nil'
282
+ end
283
+
284
+ cmds = ["vlan #{id}"]
285
+ case default
286
+ when true
287
+ cmds << 'default state'
288
+ when false
289
+ cmds << (value.nil? ? 'no state' : "state #{value}")
290
+ end
291
+ configure(cmds)
292
+ end
293
+
294
+ ##
295
+ # add_trunk_group adds a new trunk group value to the specified vlan
296
+ # id in the nodes running configuration. The trunk group name value
297
+ # accepts a-z 0-9 and _
298
+ #
299
+ # @version 4.13.7M
300
+ #
301
+ # @commands
302
+ # vlan <id>
303
+ # trunk group <value>
304
+ #
305
+ # @param [String, Integer] :id The vlan id to apply the configuration
306
+ # to. the id value should be in the range of 1 to 4094
307
+ #
308
+ # @param [String] :value The value to add to the vlan id configuration
309
+ # on the node.
310
+ #
311
+ # @return [Boolean] returns true if the command completed successfully
312
+ def add_trunk_group(id, value)
313
+ configure(["vlan #{id}", "trunk group #{value}"])
314
+ end
315
+
316
+ ##
317
+ # remove_trunk_group removes the specified trunk group value from the
318
+ # specified vlan id in the node's configuration. If the trunk group
319
+ # name does not exist, this method will return success
320
+ #
321
+ # @eos_version 4.13.7M
322
+ #
323
+ # @commands
324
+ # vlan <id>
325
+ # no trunk group <value>
326
+ #
327
+ # @param [String, Integer] :id The vlan id to apply the configuration
328
+ # to. the id value should be in the range of 1 to 4094
329
+ #
330
+ # @param [String] :value The value to remove from the list of trunk
331
+ # group names configured for the specified vlan
332
+ #
333
+ def remove_trunk_group(id, value)
334
+ configure(["vlan #{id}", "no trunk group #{value}"])
335
+ end
336
+ end
337
+ end
338
+ end