rbeapi 0.1.0 → 0.2.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 (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
@@ -31,14 +31,16 @@
31
31
  #
32
32
  require 'rbeapi/api'
33
33
 
34
-
34
+ ##
35
+ # Rbeapi toplevel namespace
35
36
  module Rbeapi
36
37
  ##
37
- # Eos is module namesapce for working with the EOS command API
38
+ # Rbeapi::Api
38
39
  module Api
39
-
40
+ ##
41
+ # The Aaa class manages Authorization, Authentication and Accounting (AAA)
42
+ # on an EOS node.
40
43
  class Aaa < Entity
41
-
42
44
  def get
43
45
  response = {}
44
46
  response[:groups] = groups.getall
@@ -52,14 +54,12 @@ module Rbeapi
52
54
  end
53
55
  end
54
56
 
55
-
57
+ ##
58
+ # The AaaGroups class manages the server groups on a EOS node.
56
59
  class AaaGroups < Entity
57
-
58
-
59
60
  DEFAULT_RADIUS_AUTH_PORT = 1812
60
61
  DEFAULT_RADIUS_ACCT_PORT = 1813
61
62
 
62
-
63
63
  # Regular express that parses the radius servers from the aaa group
64
64
  # server radius configuration block
65
65
  RADIUS_GROUP_SERVER = /\s{3}server
@@ -74,7 +74,6 @@ module Rbeapi
74
74
  (?:[ ]vrf[ ](\w+))?
75
75
  (?:[ ]port[ ](\d+))?/x
76
76
 
77
-
78
77
  ##
79
78
  # get returns the aaa server group resource hash that describes the
80
79
  # current configuration for the specified server group name
@@ -200,7 +199,6 @@ module Rbeapi
200
199
  end
201
200
  private :parse_radius_server
202
201
 
203
-
204
202
  ##
205
203
  # find_type is a utility method to find the type of aaa server group for
206
204
  # the specified name. This method will scan the current running
@@ -241,7 +239,7 @@ module Rbeapi
241
239
  #
242
240
  # @return [Boolean] returns true if the commands complete successfully
243
241
  def create(name, type)
244
- configure ["aaa group server #{type} #{name}", "exit"]
242
+ configure ["aaa group server #{type} #{name}", 'exit']
245
243
  end
246
244
 
247
245
  ##
@@ -292,7 +290,7 @@ module Rbeapi
292
290
  hostname = srv[:name]
293
291
  return false unless add_server(name, hostname, srv)
294
292
  end
295
- return true
293
+ true
296
294
  end
297
295
 
298
296
  ##
@@ -349,10 +347,9 @@ module Rbeapi
349
347
  server << "auth-port #{opts[:auth_port]} " if opts[:auth_port]
350
348
  server << "acct-port #{opts[:acct_port]} " if opts[:acct_port]
351
349
  server << "vrf #{opts[:vrf]}" if opts[:vrf]
352
- configure ["aaa group server radius #{name}", server, "exit"]
350
+ configure ["aaa group server radius #{name}", server, 'exit']
353
351
  end
354
352
 
355
-
356
353
  ##
357
354
  # add_tacacs_server adds a new tacacs server to the nodes current
358
355
  # configuration. If the server already exists in the specified group
@@ -379,7 +376,7 @@ module Rbeapi
379
376
  server = "server #{server} "
380
377
  server << "vrf #{opts[:vrf]} " if opts[:vrf]
381
378
  server << "port #{opts[:port]} " if opts[:port]
382
- configure ["aaa group server tacacs+ #{name}", server, "exit"]
379
+ configure ["aaa group server tacacs+ #{name}", server, 'exit']
383
380
  end
384
381
 
385
382
  ##
@@ -398,12 +395,12 @@ module Rbeapi
398
395
  # @param [String] :server The IP address or host name of the server
399
396
  #
400
397
  # @return [Boolean] returns true if the commands complete successfully
401
- def remove_server(name, server, opts={})
398
+ def remove_server(name, server, opts = {})
402
399
  type = find_type(name)
403
400
  return false unless type
404
401
  server = "no server #{server} "
405
402
  server << "vrf #{opts[:vrf]}" if opts[:vrf]
406
- configure ["aaa group server #{type} #{name}", server, "exit"]
403
+ configure ["aaa group server #{type} #{name}", server, 'exit']
407
404
  end
408
405
  end
409
406
  end
@@ -0,0 +1,276 @@
1
+ #
2
+ # Copyright (c) 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 'netaddr'
33
+ require 'rbeapi/api'
34
+
35
+ ##
36
+ # Eos is the toplevel namespace for working with Arista EOS nodes
37
+ module Rbeapi
38
+ ##
39
+ # Api is module namespace for working with the EOS command API
40
+ module Api
41
+ ##
42
+ # The Acl class manages the set of standard ACLs.
43
+ class Acl < Entity
44
+ def initialize(node)
45
+ super(node)
46
+ @entry_re = Regexp.new(%r{(\d+)
47
+ (?:\ ([p|d]\w+))
48
+ (?:\ (any))?
49
+ (?:\ (host))?
50
+ (?:\ ([0-9]+(?:\.[0-9]+){3}))?
51
+ (?:/([0-9]{1,2}))?
52
+ (?:\ ([0-9]+(?:\.[0-9]+){3}))?
53
+ (?:\ (log))?}x)
54
+ end
55
+
56
+ ##
57
+ # get returns the specified ACL from the nodes current configuration.
58
+ #
59
+ # @param [String] :name The ACL name.
60
+ #
61
+ # @return [nil, Hash<Symbol, Object>] Returns the ACL resource as a
62
+ # Hash.
63
+ def get(name)
64
+ config = get_block("ip access-list standard #{name}")
65
+ return nil unless config
66
+
67
+ parse_entries(config)
68
+ end
69
+
70
+ ##
71
+ # getall returns the collection of ACLs from the nodes running
72
+ # configuration as a hash. The ACL resource collection hash is
73
+ # keyed by the ACL name.
74
+ #
75
+ # @return [nil, Hash<Symbol, Object>] Returns a hash that represents
76
+ # the entire ACL collection from the nodes running configuration.
77
+ # If there are no ACLs configured, this method will return an
78
+ # empty hash.
79
+ def getall
80
+ acls = config.scan(/ip access-list standard ([^\s]+)/)
81
+ acls.each_with_object({}) do |name, hsh|
82
+ resource = get(name[0])
83
+ hsh[name[0]] = resource if resource
84
+ end
85
+ end
86
+
87
+ ##
88
+ # mask_to_prefixlen converts a subnet mask from dotted decimal to
89
+ # bit length
90
+ #
91
+ # @param [String] :mask The dotted decimal subnet mask to convert
92
+ #
93
+ # @return [String] The subnet mask as a valid prefix length
94
+ def mask_to_prefixlen(mask)
95
+ mask = '255.255.255.255' unless mask
96
+ NetAddr::CIDR.create('0.0.0.0/' + mask).netmask_ext
97
+ end
98
+
99
+ ##
100
+ # parse_entries scans the nodes configurations and parses
101
+ # the entries within an ACL.
102
+ #
103
+ # @api private
104
+ #
105
+ # @param [String] :config The switch config.
106
+ #
107
+ # @return [Hash<Symbol, Object>] resource hash attribute
108
+
109
+ def parse_entries(config)
110
+ entries = {}
111
+
112
+ lines = config.scan(/\d+ [p|d].*$/)
113
+ lines.each do |line|
114
+ entry = line.scan(@entry_re).map \
115
+ do |(seqno, act, _anyip, _host, ip, mlen, mask, log)|
116
+ {
117
+ seqno: seqno,
118
+ action: act,
119
+ srcaddr: ip || '0.0.0.0',
120
+ srcprefixlen: mlen || mask_to_prefixlen(mask),
121
+ log: log
122
+ }
123
+ end
124
+ entries[entry[0][:seqno]] = entry[0]
125
+ end
126
+ entries
127
+ end
128
+ private :parse_entries
129
+
130
+ ##
131
+ # create will create a new ACL resource in the nodes current
132
+ # configuration with the specified name. If the create method
133
+ # is called and the ACL already exists, this method will still
134
+ # return true. The ACL will not have any entries. Use add_entry
135
+ # to add entries to the ACL.
136
+ #
137
+ # @eos_version 4.13.7M
138
+ #
139
+ # @commands
140
+ # ip access-list standard <name>
141
+ #
142
+ # @param [String] :name The ACL name to create on the node. Must
143
+ # begin with an alphabetic character. Cannot contain spaces or
144
+ # quotation marks.
145
+ #
146
+ # @return [Boolean] returns true if the command completed successfully
147
+ def create(name)
148
+ configure("ip access-list standard #{name}")
149
+ end
150
+
151
+ ##
152
+ # delete will delete an existing ACL resource from the nodes current
153
+ # running configuration. If the delete method is called and the ACL
154
+ # does not exist, this method will succeed.
155
+ #
156
+ # @eos_version 4.13.7M
157
+ #
158
+ # @commands
159
+ # no ip access-list standard <name>
160
+ #
161
+ # @param [String] :name The ACL name to delete on the node.
162
+ #
163
+ # @return [Boolean] returns true if the command completed successfully
164
+ def delete(name)
165
+ configure("no ip access-list standard #{name}")
166
+ end
167
+
168
+ ##
169
+ # default will configure the ACL using the default keyword. This
170
+ # command has the same effect as deleting the ACL from the nodes
171
+ # running configuration.
172
+ #
173
+ # @eos_version 4.13.7M
174
+ #
175
+ # @commands
176
+ # default no ip access-list standard <name>
177
+ #
178
+ # @param [String] :name The ACL name to set to the default value
179
+ # on the node.
180
+ #
181
+ # @return [Boolean] returns true if the command complete successfully
182
+ def default(name)
183
+ configure("default ip access-list standard #{name}")
184
+ end
185
+
186
+ ##
187
+ # build_entry will build the commands to add an entry.
188
+ #
189
+ # @api private
190
+ #
191
+ # @param [Hash] :opts the options for the entry
192
+ # @option :opts [String] :seqno The sequence number of the entry in
193
+ # the ACL to add. Default is nil, will be assigned.
194
+ # @option :opts [String] :action The action triggered by the ACL. Valid
195
+ # values are 'permit', 'deny', or 'remark'
196
+ # @option :opts [String] :addr The IP address to permit or deny.
197
+ # @option :opts [String] :prefixlen The prefixlen for the IP address.
198
+ # @option :opts [Boolean] :log Triggers an informational log message
199
+ # to the console about the matching packet.
200
+ #
201
+ # @return [String] returns commands to create an entry
202
+ def build_entry(entry)
203
+ cmds = "#{entry[:seqno]} " if entry[:seqno]
204
+ cmds << "#{entry[:action]} #{entry[:srcaddr]}/#{entry[:srcprefixlen]}"
205
+ cmds << ' log' if entry[:log]
206
+ cmds
207
+ end
208
+ private :build_entry
209
+
210
+ ##
211
+ # update_entry will update an entry, identified by the seqno
212
+ # in the ACL specified by name, with the passed in parameters.
213
+ #
214
+ # @eos_version 4.13.7M
215
+ #
216
+ # @param [String] :name The ACL name to update on the node.
217
+ # @param [Hash] :opts the options for the entry
218
+ # @option :opts [String] :seqno The sequence number of the entry in
219
+ # the ACL to update.
220
+ # @option :opts [String] :action The action triggered by the ACL. Valid
221
+ # values are 'permit', 'deny', or 'remark'
222
+ # @option :opts [String] :addr The IP address to permit or deny.
223
+ # @option :opts [String] :prefixlen The prefixlen for the IP address.
224
+ # @option :opts [Boolean] :log Triggers an informational log message
225
+ # to the console about the matching packet.
226
+ #
227
+ # @return [Boolean] returns true if the command complete successfully
228
+ def update_entry(name, entry)
229
+ cmds = ["ip access-list standard #{name}"]
230
+ cmds << "no #{entry[:seqno]}"
231
+ cmds << build_entry(entry)
232
+ cmds << 'exit'
233
+ configure(cmds)
234
+ end
235
+
236
+ ##
237
+ # add_entry will add an entry to the specified ACL with the
238
+ # passed in parameters.
239
+ #
240
+ # @eos_version 4.13.7M
241
+ #
242
+ # @param [String] :name The ACL name to add an entry to on the node.
243
+ # @param [Hash] :opts the options for the entry
244
+ # @option :opts [String] :action The action triggered by the ACL. Valid
245
+ # values are 'permit', 'deny', or 'remark'
246
+ # @option :opts [String] :addr The IP address to permit or deny.
247
+ # @option :opts [String] :prefixlen The prefixlen for the IP address.
248
+ # @option :opts [Boolean] :log Triggers an informational log message
249
+ # to the console about the matching packet.
250
+ #
251
+ # @return [Boolean] returns true if the command complete successfully
252
+ def add_entry(name, entry)
253
+ cmds = ["ip access-list standard #{name}"]
254
+ cmds << build_entry(entry)
255
+ cmds << 'exit'
256
+ configure(cmds)
257
+ end
258
+
259
+ ##
260
+ # remove_entry will remove the entry specified by the seqno for
261
+ # the ACL specified by name.
262
+ #
263
+ # @eos_version 4.13.7M
264
+ #
265
+ # @param [String] :name The ACL name to update on the node.
266
+ # @param [String] :seqno The sequence number of the entry in
267
+ # the ACL to remove.
268
+ #
269
+ # @return [Boolean] returns true if the command complete successfully
270
+ def remove_entry(name, seqno)
271
+ cmds = ["ip access-list standard #{name}", "no #{seqno}", 'exit']
272
+ configure(cmds)
273
+ end
274
+ end
275
+ end
276
+ end
@@ -31,12 +31,15 @@
31
31
  #
32
32
  require 'rbeapi/api'
33
33
 
34
+ ##
35
+ # Rbeapi toplevel namespace
34
36
  module Rbeapi
35
-
37
+ ##
38
+ # Rbeapi::Api
36
39
  module Api
37
-
40
+ ##
41
+ # The Dns class manages DNS settings on an EOS node.
38
42
  class Dns < Entity
39
-
40
43
  ##
41
44
  # Returns the DNS resource
42
45
  #
@@ -173,7 +176,7 @@ module Rbeapi
173
176
 
174
177
  case default
175
178
  when true
176
- cmds = 'default ip domain-list'
179
+ cmds = 'default ip domain-list'
177
180
  when false
178
181
  cmds = []
179
182
  parse_domain_list[:domain_list].each do |name|