rbeapi 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/Gemfile +1 -1
  3. data/README.md +17 -12
  4. data/guide/.gitignore +2 -0
  5. data/guide/api.rst +5894 -0
  6. data/guide/conf.py +5 -5
  7. data/guide/contributing.rst +6 -0
  8. data/guide/getting-started.rst +134 -0
  9. data/guide/index.rst +3 -5
  10. data/guide/installation.rst +56 -1
  11. data/guide/license.rst +13 -2
  12. data/guide/overview.rst +2 -5
  13. data/guide/testing.rst +5 -1
  14. data/guide/upgrading.rst +10 -0
  15. data/lib/rbeapi/api.rb +37 -36
  16. data/lib/rbeapi/api/aaa.rb +90 -90
  17. data/lib/rbeapi/api/acl.rb +70 -53
  18. data/lib/rbeapi/api/bgp.rb +186 -163
  19. data/lib/rbeapi/api/dns.rb +51 -45
  20. data/lib/rbeapi/api/interfaces.rb +344 -328
  21. data/lib/rbeapi/api/ipinterfaces.rb +92 -92
  22. data/lib/rbeapi/api/logging.rb +32 -32
  23. data/lib/rbeapi/api/mlag.rb +97 -97
  24. data/lib/rbeapi/api/ntp.rb +39 -39
  25. data/lib/rbeapi/api/ospf.rb +58 -58
  26. data/lib/rbeapi/api/prefixlists.rb +22 -22
  27. data/lib/rbeapi/api/radius.rb +77 -49
  28. data/lib/rbeapi/api/routemaps.rb +110 -64
  29. data/lib/rbeapi/api/snmp.rb +104 -100
  30. data/lib/rbeapi/api/staticroutes.rb +27 -20
  31. data/lib/rbeapi/api/stp.rb +100 -84
  32. data/lib/rbeapi/api/switchports.rb +98 -77
  33. data/lib/rbeapi/api/system.rb +93 -25
  34. data/lib/rbeapi/api/tacacs.rb +54 -35
  35. data/lib/rbeapi/api/users.rb +68 -68
  36. data/lib/rbeapi/api/varp.rb +56 -47
  37. data/lib/rbeapi/api/vlans.rb +86 -86
  38. data/lib/rbeapi/api/vrrp.rb +210 -173
  39. data/lib/rbeapi/client.rb +142 -108
  40. data/lib/rbeapi/eapilib.rb +73 -62
  41. data/lib/rbeapi/utils.rb +8 -8
  42. data/lib/rbeapi/version.rb +2 -2
  43. data/spec/fixtures/test.conf +3 -3
  44. data/spec/system/rbeapi/api/system_spec.rb +46 -2
  45. data/spec/system/rbeapi/api/vlans_spec.rb +5 -2
  46. data/spec/system/rbeapi/client_spec.rb +4 -4
  47. data/spec/unit/rbeapi/api/system/default_spec.rb +40 -4
  48. data/spec/unit/rbeapi/api/system/fixture_system.text +14 -0
  49. data/spec/unit/rbeapi/api/vlans/default_spec.rb +1 -1
  50. data/spec/unit/rbeapi/api/vlans/fixture_vlans.text +2 -0
  51. data/spec/unit/rbeapi/client_spec.rb +1 -0
  52. metadata +9 -9
  53. data/guide/cookbook.rst +0 -4
  54. data/guide/developing.rst +0 -4
  55. data/guide/faq.rst +0 -4
  56. data/guide/quickstart.rst +0 -4
  57. data/guide/troubleshooting.rst +0 -1
@@ -58,8 +58,8 @@ module Rbeapi
58
58
  # The EapiError class provides one property for holding the set of
59
59
  # commands issued when the error was generated.
60
60
  #
61
- # @param [String] :message The error message to return from raising
62
- # the exception
61
+ # @param message [String] The error message to return from raising
62
+ # the exception.
63
63
  def initalize(message)
64
64
  @message = message
65
65
  @commands = nil
@@ -77,12 +77,14 @@ module Rbeapi
77
77
  ##
78
78
  # The exception contains the eAPI error code and error text.
79
79
  #
80
- # @param [String] :message The error message to return from raising
81
- # this exception
82
- # @param [Integer] :code The error code associated with the error
83
- # message to be raised
84
- # @param [Array] :commands The list of commands that were used in the
85
- # eAPI request message
80
+ # @param message [String] The error message to return from raising
81
+ # this exception.
82
+ #
83
+ # @param code [Integer] The error code associated with the error
84
+ # message to be raised.
85
+ #
86
+ # @param commands [Array] The list of commands that were used in the
87
+ # eAPI request message.
86
88
  def initialize(message, code, commands = nil)
87
89
  @error_code = code
88
90
  @error_text = message
@@ -101,12 +103,14 @@ module Rbeapi
101
103
  ##
102
104
  # The exception contains the eAPI error code and error text.
103
105
  #
104
- # @param [String] :message The error message to return from raising
105
- # this exception
106
- # @param [String] :connection_type The optional connection_type of
107
- # the instance
108
- # @param [Array] :commands The list of commands that were used in the
109
- # eAPI request message
106
+ # @param message [String] The error message to return from raising
107
+ # this exception.
108
+ #
109
+ # @param connection_type [String] The optional connection_type of
110
+ # the instance.
111
+ #
112
+ # @param commands [Array] The list of commands that were used in the
113
+ # eAPI request message.
110
114
  def initialize(message, connection_type = nil, commands = nil)
111
115
  @connection_type = connection_type
112
116
  @commands = commands
@@ -117,16 +121,18 @@ module Rbeapi
117
121
  ##
118
122
  # The EapiConnection provides a base class for building eAPI connection
119
123
  # instances with a specific transport for connecting to Arista EOS
120
- # devices. This class handles sending and receiving eAPI calls using
121
- # JSON-RPC. This class should not need to be directly instantiated.
124
+ # devices. This class handles sending and receiving eAPI calls using
125
+ # JSON-RPC. This class should not need to be directly instantiated.
122
126
  class EapiConnection
123
127
  attr_reader :error
128
+ attr_reader :open_timeout
129
+ attr_reader :read_timeout
124
130
 
125
131
  ##
126
132
  # The connection contains the transport.
127
133
  #
128
- # @param [Net::HTTP] :transport The HTTP transport to use for sending
129
- # and receive eAPI request and response messages
134
+ # @param transport [Net::HTTP] The HTTP transport to use for sending
135
+ # and receive eAPI request and response messages.
130
136
  def initialize(transport)
131
137
  @transport = transport
132
138
  @error = nil
@@ -134,13 +140,16 @@ module Rbeapi
134
140
 
135
141
  ##
136
142
  # Configures the connection authentication values (username and
137
- # password). The authentication values are used to authenticate
138
- # the eAPI connection. Using authentication is only required for
139
- # connections that use Http or Https transports
143
+ # password). The authentication values are used to authenticate
144
+ # the eAPI connection. Using authentication is only required for
145
+ # connections that use Http or Https transports.
146
+ #
147
+ # @param opts [Hash] The authentication parameters.
140
148
  #
141
- # @options :opts [String] :username The username to use to
149
+ # @option opts username [String] The username to use to
142
150
  # authenticate with eAPI. Default is 'admin'.
143
- # @options :opts [String] :password The password to use to
151
+ #
152
+ # @option opts password [String] The password to use to
144
153
  # authenticate with eAPI. Default is ''.
145
154
  def authentication(opts = {})
146
155
  @username = opts.fetch(:username, 'admin')
@@ -149,12 +158,13 @@ module Rbeapi
149
158
 
150
159
  ##
151
160
  # Configures the connection timeout values (open_timeout and
152
- # read_timeout). The timeout values are used for the eAPI
161
+ # read_timeout). The timeout values are used for the eAPI
153
162
  # connection.
154
163
  #
155
- # @option :opts [Float] :open_timeout Number of seconds to wait for the
164
+ # @option opts open_timeout [Float] Number of seconds to wait for the
156
165
  # eAPI connection to open. Default is DEFAULT_HTTP_OPEN_TIMEOUT.
157
- # @option :opts [Float] :read_timeout Number of seconds to wait for one
166
+ #
167
+ # @option opts read_timeout [Float] Number of seconds to wait for one
158
168
  # block of eAPI results to be read (via one read(2) call). Default
159
169
  # is DEFAULT_HTTP_READ_TIMEOUT.
160
170
  def timeouts(opts = {})
@@ -162,14 +172,6 @@ module Rbeapi
162
172
  @read_timeout = opts.fetch(:read_timeout, DEFAULT_HTTP_READ_TIMEOUT)
163
173
  end
164
174
 
165
- ##
166
- # Gets values for open_timeout and read_timeout
167
- #
168
- # @return [Hash] open_timeout and read_timeout
169
- def get_timeouts
170
- { open_timeout: @open_timeout, read_timeout: @read_timeout }
171
- end
172
-
173
175
  ##
174
176
  # Generates the eAPI JSON request message.
175
177
  #
@@ -187,18 +189,21 @@ module Rbeapi
187
189
  # "id": <reqid>
188
190
  # }
189
191
  #
190
- # @param [Array] :commands The ordered set of commands that should
191
- # be included in the eAPI request
192
- # @param [Hash] :opts Optional keyword arguments
193
- # @option :opts [String] :id The value to use for the eAPI request
194
- # id. If not provided,the object_id for the connection instance
195
- # will be used
196
- # @option :opts [String] :format The encoding formation to pass in
197
- # the eAPI request. Valid values are json or text. The default
198
- # value is json
192
+ # @param commands [Array] The ordered set of commands that should
193
+ # be included in the eAPI request.
194
+ #
195
+ # @param opts [Hash] Optional keyword arguments.
196
+ #
197
+ # @option opts id [String] The value to use for the eAPI request
198
+ # id. If not provided,the object_id for the connection instance
199
+ # will be used.
200
+ #
201
+ # @option opts format [String] The encoding formation to pass in
202
+ # the eAPI request. Valid values are json or text. The default
203
+ # value is json.
199
204
  #
200
205
  # @return [Hash] Returns a Ruby hash of the request message that is
201
- # suitable to be JSON encoded and sent to the destination node
206
+ # suitable to be JSON encoded and sent to the destination node.
202
207
  def request(commands, opts = {})
203
208
  id = opts.fetch(:reqid, object_id)
204
209
  format = opts.fetch(:format, 'json')
@@ -211,7 +216,7 @@ module Rbeapi
211
216
  ##
212
217
  # This method will send the request to the node over the specified
213
218
  # transport and return a response message with the contents from
214
- # the eAPI response. eAPI responds to request messages with either
219
+ # the eAPI response. eAPI responds to request messages with either
215
220
  # a success message or failure message.
216
221
  #
217
222
  # @example eAPI Response - success
@@ -248,16 +253,18 @@ module Rbeapi
248
253
  # "id": <reqid>
249
254
  # }
250
255
  #
251
- # @param [Hash] :data A hash containing the body of the request
252
- # message. This should be a valid eAPI request message.
253
- # @option :opts [Float] :open_timeout Number of seconds to wait for the
256
+ # @param data [Hash] A hash containing the body of the request
257
+ # message. This should be a valid eAPI request message.
258
+ #
259
+ # @option opts open_timeout [Float] Number of seconds to wait for the
254
260
  # eAPI connection to open.
255
- # @option :opts [Float] :read_timeout Number of seconds to wait for one
261
+ #
262
+ # @option opts read_timeout [Float] Number of seconds to wait for one
256
263
  # block of eAPI results to be read (via one read(2) call).
257
264
  #
258
- # @return [Hash] returns the response message as a Ruby hash object
265
+ # @return [Hash] Returns the response message as a Ruby hash object.
259
266
  #
260
- # @raises [CommandError] Raised if an eAPI failure response is return
267
+ # @raise [CommandError] Raised if an eAPI failure response is return
261
268
  # from the destination node.
262
269
  def send(data, opts)
263
270
  request = Net::HTTP::Post.new('/command-api')
@@ -289,24 +296,28 @@ module Rbeapi
289
296
  # Executes the commands on the destination node and returns the
290
297
  # response from the node.
291
298
  #
292
- # @param [Array] :commands The ordered list of commands to execute
299
+ # @param commands [Array] The ordered list of commands to execute
293
300
  # on the destination node.
294
- # @param [Hash] :opts Optional keyword arguments
295
- # @option :opts [String] :encoding Used to specify the encoding to be
296
- # used for the response. Valid encoding values are json or text
297
- # @option :opts [Float] :open_timeout Number of seconds to wait for the
301
+ #
302
+ # @param opts [Hash] Optional keyword arguments.
303
+ #
304
+ # @option opts encoding [String] Used to specify the encoding to be
305
+ # used for the response. Valid encoding values are json or text.
306
+ #
307
+ # @option opts open_timeout [Float] Number of seconds to wait for the
298
308
  # eAPI connection to open.
299
- # @option :opts [Float] :read_timeout Number of seconds to wait for one
309
+ #
310
+ # @option opts read_timeout [Float] Number of seconds to wait for one
300
311
  # block of eAPI results to be read (via one read(2) call).
301
312
  #
302
- # @returns [Array<Hash>] This method will return the array of responses
313
+ # @return [Array<Hash>] This method will return the array of responses
303
314
  # for each command executed on the node.
304
315
  #
305
- # @raises [CommandError] Raises a CommandError if rescued from the
306
- # send method and adds the list of commands to the exception message
316
+ # @raise [CommandError] Raises a CommandError if rescued from the
317
+ # send method and adds the list of commands to the exception message.
307
318
  #
308
- # @raises [ConnectionError] Raises a ConnectionError if rescued and
309
- # adds the list of commands to the exception message
319
+ # @raise [ConnectionError] Raises a ConnectionError if rescued and
320
+ # adds the list of commands to the exception message.
310
321
  def execute(commands, opts = {})
311
322
  @error = nil
312
323
  request = request(commands, opts)
@@ -33,19 +33,19 @@
33
33
  require 'syslog'
34
34
 
35
35
  ##
36
- # Rbeapi toplevel namespace
36
+ # Rbeapi toplevel namespace.
37
37
  module Rbeapi
38
38
  ##
39
- # Utils module
39
+ # Utils module.
40
40
  module Utils
41
41
  ##
42
42
  # Iterates through a hash structure and converts all of the keys
43
43
  # to symbols.
44
44
  #
45
- # @param [Hash] :value The hash structure to convert the keys
45
+ # @param value [Hash] The hash structure to convert the keys.
46
46
  #
47
47
  # @return [Hash] An updated hash structure with all keys converted to
48
- # symboles
48
+ # symboles.
49
49
  def self.transform_keys_to_symbols(value)
50
50
  return value unless value.is_a?(Hash)
51
51
  hash = value.each_with_object({}) do |(k, v), hsh|
@@ -56,11 +56,11 @@ module Rbeapi
56
56
  end
57
57
 
58
58
  ##
59
- # Returns a class object from a string capable of being instatiated
59
+ # Returns a class object from a string capable of being instatiated.
60
60
  #
61
- # @param [String] :name The name of the class to return a constant for
61
+ # @param name [String] The name of the class to return a constant for.
62
62
  #
63
- # @return [Object] Returns a a class object that can be instatiated
63
+ # @return [Object] Returns a a class object that can be instatiated.
64
64
  def self.class_from_string(name)
65
65
  name.split('::').inject(Object) do |mod, cls|
66
66
  mod.const_get(cls)
@@ -70,7 +70,7 @@ module Rbeapi
70
70
  ##
71
71
  # Syslogs a warning message.
72
72
  #
73
- # @param [String] :message The message to log.
73
+ # @param message [String] The message to log.
74
74
  def self.syslog_warning(message)
75
75
  Syslog.open('rbeapi', Syslog::LOG_PID) { |s| s.warning message }
76
76
  end
@@ -31,7 +31,7 @@
31
31
  #
32
32
 
33
33
  # #
34
- # Rbeapi toplevel namespace
34
+ # Rbeapi toplevel namespace.
35
35
  module Rbeapi
36
- VERSION = '0.5.0'
36
+ VERSION = '0.5.1'
37
37
  end
@@ -1,6 +1,8 @@
1
- [connection:veos01]
1
+ [DEFAULT]
2
2
  username: eapi
3
3
  password: password
4
+
5
+ [connection:veos01]
4
6
  transport: http
5
7
  host: veos01
6
8
 
@@ -14,8 +16,6 @@ host: veos03
14
16
 
15
17
  [connection:veos04]
16
18
  host: 172.16.10.1
17
- username: eapi
18
- password: password
19
19
  enablepwd: itsasecret
20
20
  port: 1234
21
21
  transport: https
@@ -13,10 +13,14 @@ describe Rbeapi::Api::System do
13
13
 
14
14
  describe '#get' do
15
15
  let(:entity) do
16
- { hostname: 'localhost', iprouting: true }
16
+ { hostname: 'localhost', iprouting: true, banner_motd: '',
17
+ banner_login: '' }
17
18
  end
18
19
 
19
- before { node.config(['hostname localhost', 'ip routing']) }
20
+ before do
21
+ node.config(['hostname localhost', 'ip routing', 'no banner motd',
22
+ 'no banner login'])
23
+ end
20
24
 
21
25
  it 'returns the snmp resource' do
22
26
  expect(subject.get).to eq(entity)
@@ -88,4 +92,44 @@ describe Rbeapi::Api::System do
88
92
  end
89
93
  end
90
94
  end
95
+
96
+ describe '#set_banner' do
97
+ before { node.config(['no banner login', 'no banner motd']) }
98
+
99
+ it 'configures the login value' do
100
+ expect(subject.get[:banner_login]).to eq('')
101
+ expect(subject.set_banner('login', value: 'foo')).to be_truthy
102
+ expect(subject.get[:banner_login]).to eq('foo')
103
+ end
104
+
105
+ it 'negates the login value' do
106
+ expect(subject.get[:banner_login]).to eq('')
107
+ expect(subject.set_banner('login', enable: false)).to be_truthy
108
+ expect(subject.get[:banner_login]).to eq('')
109
+ end
110
+
111
+ it 'defaults the login value' do
112
+ expect(subject.get[:banner_login]).to eq('')
113
+ expect(subject.set_banner('login', default: true)).to be_truthy
114
+ expect(subject.get[:banner_login]).to eq('')
115
+ end
116
+
117
+ it 'configures the motd value' do
118
+ expect(subject.get[:banner_motd]).to eq('')
119
+ expect(subject.set_banner('motd', value: 'foo')).to be_truthy
120
+ expect(subject.get[:banner_motd]).to eq('foo')
121
+ end
122
+
123
+ it 'negates the motd value' do
124
+ expect(subject.get[:banner_motd]).to eq('')
125
+ expect(subject.set_banner('motd', enable: false)).to be_truthy
126
+ expect(subject.get[:banner_motd]).to eq('')
127
+ end
128
+
129
+ it 'defaults the motd value' do
130
+ expect(subject.get[:banner_motd]).to eq('')
131
+ expect(subject.set_banner('motd', default: true)).to be_truthy
132
+ expect(subject.get[:banner_motd]).to eq('')
133
+ end
134
+ end
91
135
  end
@@ -14,10 +14,13 @@ describe Rbeapi::Api::Vlans do
14
14
  context '#get' do
15
15
  describe 'with defaults' do
16
16
  let(:entity) do
17
- { name: 'default', state: 'active', trunk_groups: [] }
17
+ { name: 'default', state: 'active', trunk_groups: %w(mlag test) }
18
18
  end
19
19
 
20
- before { node.config(['no vlan 1-4094', 'vlan 1']) }
20
+ before do
21
+ node.config(['no vlan 1-4094', 'vlan 1', 'trunk group mlag',
22
+ 'trunk group test'])
23
+ end
21
24
 
22
25
  it 'returns the vlan resource' do
23
26
  expect(subject.get('1')).to eq(entity)
@@ -348,8 +348,8 @@ describe Rbeapi::Client do
348
348
 
349
349
  describe 'test timeouts' do
350
350
  it 'loads default timeout values' do
351
- expect(node.connection.get_timeouts).to eq(open_timeout: 10,
352
- read_timeout: 10)
351
+ expect(node.connection.open_timeout).to eq(10)
352
+ expect(node.connection.read_timeout).to eq(10)
353
353
  end
354
354
 
355
355
  describe 'loads veos05' do
@@ -359,8 +359,8 @@ describe Rbeapi::Client do
359
359
  end
360
360
 
361
361
  it 'loads timeout values from conf file' do
362
- expect(node.connection.get_timeouts).to eq(open_timeout: 12,
363
- read_timeout: 12)
362
+ expect(node.connection.open_timeout).to eq(12)
363
+ expect(node.connection.read_timeout).to eq(12)
364
364
  end
365
365
  end
366
366
  end
@@ -41,7 +41,9 @@ describe Rbeapi::Api::System do
41
41
  let(:node) { double('node') }
42
42
 
43
43
  let(:test) do
44
- { hostname: 'localhost', iprouting: true }
44
+ { hostname: 'localhost', iprouting: true,
45
+ banner_motd: "MOTD Banner\nSecond Line\nEOF \n*\\v1?",
46
+ banner_login: "Login Banner\nSecond Line\n123456\n EOF" }
45
47
  end
46
48
 
47
49
  def system
@@ -56,15 +58,15 @@ describe Rbeapi::Api::System do
56
58
 
57
59
  describe '#get' do
58
60
  it 'returns the username collection' do
59
- expect(subject.get).to include(test)
61
+ expect(subject.get).to eq(test)
60
62
  end
61
63
 
62
64
  it 'returns a hash collection' do
63
65
  expect(subject.get).to be_a_kind_of(Hash)
64
66
  end
65
67
 
66
- it 'has two entries' do
67
- expect(subject.get.size).to eq(2)
68
+ it 'has four entries' do
69
+ expect(subject.get.size).to eq(4)
68
70
  end
69
71
  end
70
72
 
@@ -99,4 +101,38 @@ describe Rbeapi::Api::System do
99
101
  expect(subject.set_iprouting(enable: false)).to be_truthy
100
102
  end
101
103
  end
104
+
105
+ describe '#set_banner' do
106
+ it 'sets the login banner' do
107
+ expect(node).to receive(:config).with([{ cmd: 'banner login',
108
+ input: "login banner\n" }])
109
+ expect(subject.set_banner('login', value: 'login banner')).to be_truthy
110
+ end
111
+
112
+ it 'negates the login banner' do
113
+ expect(node).to receive(:config).with('no banner login')
114
+ expect(subject.set_banner('login', enable: false)).to be_truthy
115
+ end
116
+
117
+ it 'defaults the login banner' do
118
+ expect(node).to receive(:config).with('default banner login')
119
+ expect(subject.set_banner('login', default: true)).to be_truthy
120
+ end
121
+
122
+ it 'sets the motd banner' do
123
+ expect(node).to receive(:config).with([{ cmd: 'banner motd',
124
+ input: "motd banner\n" }])
125
+ expect(subject.set_banner('motd', value: 'motd banner')).to be_truthy
126
+ end
127
+
128
+ it 'negates the motd banner' do
129
+ expect(node).to receive(:config).with('no banner motd')
130
+ expect(subject.set_banner('motd', enable: false)).to be_truthy
131
+ end
132
+
133
+ it 'defaults the motd banner' do
134
+ expect(node).to receive(:config).with('default banner motd')
135
+ expect(subject.set_banner('motd', default: true)).to be_truthy
136
+ end
137
+ end
102
138
  end