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.
- checksums.yaml +7 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +25 -2
- data/Gemfile +13 -7
- data/Rakefile +8 -7
- data/lib/rbeapi/api/alias.rb +160 -0
- data/lib/rbeapi/api/bgp.rb +9 -9
- data/lib/rbeapi/api/dns.rb +3 -1
- data/lib/rbeapi/api/interfaces.rb +194 -32
- data/lib/rbeapi/api/ipinterfaces.rb +5 -3
- data/lib/rbeapi/api/managementdefaults.rb +119 -0
- data/lib/rbeapi/api/mlag.rb +6 -6
- data/lib/rbeapi/api/ntp.rb +1 -1
- data/lib/rbeapi/api/ospf.rb +171 -12
- data/lib/rbeapi/api/prefixlists.rb +19 -9
- data/lib/rbeapi/api/radius.rb +5 -5
- data/lib/rbeapi/api/routemaps.rb +12 -12
- data/lib/rbeapi/api/snmp.rb +6 -4
- data/lib/rbeapi/api/stp.rb +24 -24
- data/lib/rbeapi/api/switchports.rb +15 -9
- data/lib/rbeapi/api/tacacs.rb +1 -1
- data/lib/rbeapi/api/users.rb +4 -4
- data/lib/rbeapi/api/varp.rb +7 -3
- data/lib/rbeapi/api/vlans.rb +2 -2
- data/lib/rbeapi/api/vrrp.rb +61 -61
- data/lib/rbeapi/client.rb +9 -6
- data/lib/rbeapi/eapilib.rb +3 -3
- data/lib/rbeapi/netdev/snmp.rb +8 -6
- data/lib/rbeapi/switchconfig.rb +9 -10
- data/lib/rbeapi/version.rb +1 -1
- data/spec/support/fixtures.rb +4 -4
- data/spec/support/matchers/switch_config_sections.rb +2 -2
- data/spec/system/rbeapi/api/acl_spec.rb +2 -4
- data/spec/system/rbeapi/api/alias_spec.rb +168 -0
- data/spec/system/rbeapi/api/bgp_spec.rb +1 -2
- data/spec/system/rbeapi/api/interfaces_base_spec.rb +7 -8
- data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +36 -3
- data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +35 -3
- data/spec/system/rbeapi/api/interfaces_vlan_spec.rb +90 -0
- data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +3 -4
- data/spec/system/rbeapi/api/managementdefaults_spec.rb +31 -0
- data/spec/system/rbeapi/api/ospf_interfaces_spec.rb +36 -11
- data/spec/system/rbeapi/api/ospf_spec.rb +240 -17
- data/spec/system/rbeapi/api/prefixlists_spec.rb +105 -89
- data/spec/system/rbeapi/api/routemaps_spec.rb +15 -10
- data/spec/system/rbeapi/api/users_spec.rb +4 -5
- data/spec/system/rbeapi/api/vrrp_spec.rb +2 -5
- data/spec/system/rbeapi/client_spec.rb +1 -2
- data/spec/unit/rbeapi/api/acl/default_spec.rb +1 -2
- data/spec/unit/rbeapi/api/alias/default_spec.rb +119 -0
- data/spec/unit/rbeapi/api/alias/fixture_alias.text +3 -0
- data/spec/unit/rbeapi/api/bgp/bgp_neighbors_spec.rb +1 -2
- data/spec/unit/rbeapi/api/bgp/bgp_spec.rb +1 -2
- data/spec/unit/rbeapi/api/interfaces/base_spec.rb +1 -1
- data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +35 -1
- data/spec/unit/rbeapi/api/interfaces/fixture_interfaces.text +68 -0
- data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +41 -4
- data/spec/unit/rbeapi/api/interfaces/vlan_spec.rb +72 -0
- data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +2 -2
- data/spec/unit/rbeapi/api/managementdefaults/default_spec.rb +50 -0
- data/spec/unit/rbeapi/api/managementdefaults/fixture_managementdefaults.yaml +1 -0
- data/spec/unit/rbeapi/api/prefixlists/default_spec.rb +98 -80
- data/spec/unit/rbeapi/api/prefixlists/fixture_prefixlists.text +9 -4
- data/spec/unit/rbeapi/api/users/default_spec.rb +2 -4
- data/spec/unit/rbeapi/api/vrrp/default_spec.rb +2 -5
- data/spec/unit/rbeapi/client_spec.rb +21 -14
- data/spec/unit/rbeapi/switchconfig_spec.rb +10 -3
- metadata +49 -59
data/lib/rbeapi/client.rb
CHANGED
@@ -42,12 +42,13 @@ module Rbeapi
|
|
42
42
|
# Rbeapi::Client
|
43
43
|
module Client
|
44
44
|
class << self
|
45
|
-
DEFAULT_TRANSPORT = 'https'
|
45
|
+
DEFAULT_TRANSPORT = 'https'.freeze
|
46
46
|
|
47
47
|
TRANSPORTS = { 'http' => 'Rbeapi::Eapilib::HttpEapiConnection',
|
48
48
|
'https' => 'Rbeapi::Eapilib::HttpsEapiConnection',
|
49
49
|
'http_local' => 'Rbeapi::Eapilib::HttpLocalEapiConenction',
|
50
50
|
'socket' => 'Rbeapi::Eapilib::SocketEapiConnection' }
|
51
|
+
.freeze
|
51
52
|
|
52
53
|
##
|
53
54
|
# Returns the currently loaded config object. This function will
|
@@ -165,7 +166,7 @@ module Rbeapi
|
|
165
166
|
# The Config class holds the loaded configuration file data. It is a
|
166
167
|
# subclass of IniFile.
|
167
168
|
class Config < IniFile
|
168
|
-
CONFIG_SEARCH_PATH = ['/mnt/flash/eapi.conf']
|
169
|
+
CONFIG_SEARCH_PATH = ['/mnt/flash/eapi.conf'].freeze
|
169
170
|
|
170
171
|
##
|
171
172
|
# The Config class will automatically search for a filename to load
|
@@ -226,10 +227,10 @@ module Rbeapi
|
|
226
227
|
|
227
228
|
# For each section, if the host parameter is omitted then the
|
228
229
|
# connection name is used.
|
229
|
-
has_default =
|
230
|
+
has_default = has_section?('DEFAULT')
|
230
231
|
sections.each do |name|
|
231
232
|
next unless name.start_with?('connection:')
|
232
|
-
conn = self[
|
233
|
+
conn = self[name.to_s]
|
233
234
|
conn['host'] = name.split(':')[1] unless conn['host']
|
234
235
|
|
235
236
|
# Merge in the default values into the connections
|
@@ -517,13 +518,15 @@ module Rbeapi
|
|
517
518
|
begin
|
518
519
|
result = run_commands("show #{config} #{params}", encoding: encoding)
|
519
520
|
rescue Rbeapi::Eapilib::CommandError => error
|
520
|
-
|
521
|
+
# rubocop:disable Style/GuardClause
|
522
|
+
if error.to_s =~ /'show (running|startup)-config'/
|
521
523
|
return nil
|
522
524
|
else
|
523
525
|
raise error
|
524
526
|
end
|
527
|
+
# rubocop:enable Style/GuardClause
|
525
528
|
end
|
526
|
-
if encoding == 'json'
|
529
|
+
if encoding == 'json' # rubocop:disable Style/GuardClause
|
527
530
|
return result.first
|
528
531
|
else
|
529
532
|
return result.first['output'].strip.split("\n") unless as_string
|
data/lib/rbeapi/eapilib.rb
CHANGED
@@ -46,8 +46,8 @@ module Rbeapi
|
|
46
46
|
DEFAULT_HTTP_LOCAL_PORT = 8080
|
47
47
|
DEFAULT_HTTP_OPEN_TIMEOUT = 10
|
48
48
|
DEFAULT_HTTP_READ_TIMEOUT = 10
|
49
|
-
DEFAULT_HTTP_PATH = '/command-api'
|
50
|
-
DEFAULT_UNIX_SOCKET = '/var/run/command-api.sock'
|
49
|
+
DEFAULT_HTTP_PATH = '/command-api'.freeze
|
50
|
+
DEFAULT_UNIX_SOCKET = '/var/run/command-api.sock'.freeze
|
51
51
|
|
52
52
|
##
|
53
53
|
# Base error class for generating exceptions. The EapiError class
|
@@ -283,7 +283,7 @@ module Rbeapi
|
|
283
283
|
if decoded.include?('error')
|
284
284
|
code = decoded['error']['code']
|
285
285
|
msg = decoded['error']['message']
|
286
|
-
|
286
|
+
raise CommandError.new(msg, code)
|
287
287
|
end
|
288
288
|
rescue Timeout::Error
|
289
289
|
raise ConnectionError, 'unable to connect to eAPI'
|
data/lib/rbeapi/netdev/snmp.rb
CHANGED
@@ -104,7 +104,7 @@ module Rbeapi
|
|
104
104
|
resource_hash[:security] = sec_match[1] if sec_match
|
105
105
|
ver_match = /^(v\d)/.match(auth) # first 2 characters
|
106
106
|
resource_hash[:version] = ver_match[1] if ver_match
|
107
|
-
resource_hash[:type] = /trap
|
107
|
+
resource_hash[:type] = type =~ /trap/ ? :traps : :informs
|
108
108
|
resource_hash[:username] = username
|
109
109
|
resource_hash
|
110
110
|
end
|
@@ -243,7 +243,7 @@ module Rbeapi
|
|
243
243
|
user_s.scan(/^(\w+).*?: (.*)/).each_with_object({}) do |(h, v), m|
|
244
244
|
key = SNMP_USER_PARAM[h.downcase.intern] || h.downcase.intern
|
245
245
|
m[key] = case key
|
246
|
-
when :privacy then /AES
|
246
|
+
when :privacy then v =~ /AES/ ? :aes128 : :des
|
247
247
|
when :version then v.sub('v2c', 'v2').intern
|
248
248
|
when :auth then v.downcase.intern
|
249
249
|
when :roles then v.sub(/ \(.*?\)/, '')
|
@@ -262,7 +262,7 @@ module Rbeapi
|
|
262
262
|
authentication: :auth,
|
263
263
|
privacy: :privacy,
|
264
264
|
group: :roles
|
265
|
-
}
|
265
|
+
}.freeze
|
266
266
|
|
267
267
|
##
|
268
268
|
# snmp_user_set creates or updates an SNMP user account on the target
|
@@ -290,13 +290,15 @@ module Rbeapi
|
|
290
290
|
# hash which is idempotent.
|
291
291
|
def snmp_user_set(opts = {})
|
292
292
|
group = [*opts[:roles]].first
|
293
|
-
|
293
|
+
raise ArgumentError, 'at least one role is required' unless group
|
294
294
|
version = opts[:version].to_s.sub('v2', 'v2c')
|
295
295
|
cmd = user_cmd = "snmp-server user #{opts[:name]} #{group} #{version}"
|
296
296
|
if opts[:password] && version == 'v3'
|
297
297
|
privacy = opts[:privacy].to_s.scan(/aes|des/).first
|
298
|
-
|
299
|
-
|
298
|
+
unless privacy
|
299
|
+
raise ArgumentError,
|
300
|
+
'privacy is required when managing passwords'
|
301
|
+
end
|
300
302
|
cmd += " auth #{opts[:auth] || 'sha'} #{opts[:password]} "\
|
301
303
|
"priv #{privacy} #{opts[:password]}"
|
302
304
|
end
|
data/lib/rbeapi/switchconfig.rb
CHANGED
@@ -127,7 +127,7 @@ module Rbeapi
|
|
127
127
|
# @return [Section] The Section object contains the portion of self
|
128
128
|
# that is not in section2.
|
129
129
|
def compare_r(section2)
|
130
|
-
|
130
|
+
raise '@line must equal section2.line' if @line != section2.line
|
131
131
|
|
132
132
|
# XXX Need to have a list of exceptions of mode commands that
|
133
133
|
# support default. If all the commands have been removed from
|
@@ -180,9 +180,7 @@ module Rbeapi
|
|
180
180
|
# in section2. The second Section object returned is the portion of
|
181
181
|
# section2 that is not in self.
|
182
182
|
def compare(section2)
|
183
|
-
if @line != section2.line
|
184
|
-
fail 'XXX What if @line does not equal section2.line'
|
185
|
-
end
|
183
|
+
raise '@line does not equal section2.line' if @line != section2.line
|
186
184
|
|
187
185
|
results = []
|
188
186
|
# Compare self with section2
|
@@ -234,16 +232,17 @@ module Rbeapi
|
|
234
232
|
config.each_line do |line|
|
235
233
|
skip = true if @multiline_cmds.any? { |cmd| line =~ /#{cmd}/ }
|
236
234
|
if skip
|
237
|
-
if line =~ /^\s*EOF$/
|
235
|
+
if line =~ /^\s*EOF$/ # rubocop:disable Style/GuardClause
|
238
236
|
skip = false
|
239
237
|
else
|
240
238
|
next
|
241
239
|
end
|
242
240
|
end
|
243
241
|
ind = line[/\A */].size
|
244
|
-
if ind % @indent
|
245
|
-
|
246
|
-
|
242
|
+
if (ind % @indent).nonzero? # rubocop:disable Style/Next
|
243
|
+
raise ArgumentError, 'SwitchConfig indentation must be multiple '\
|
244
|
+
"of #{@indent} improper indent #{ind}: "\
|
245
|
+
"#{line}"
|
247
246
|
end
|
248
247
|
end
|
249
248
|
true
|
@@ -277,7 +276,7 @@ module Rbeapi
|
|
277
276
|
end
|
278
277
|
if combine
|
279
278
|
longline << line
|
280
|
-
if line =~ /^\s*EOF$/
|
279
|
+
if line =~ /^\s*EOF$/ # rubocop:disable Style/GuardClause
|
281
280
|
line = longline.join
|
282
281
|
combine = false
|
283
282
|
else
|
@@ -287,7 +286,7 @@ module Rbeapi
|
|
287
286
|
|
288
287
|
# Ignore comment lines and the end statement if there
|
289
288
|
# XXX Fix parsing end
|
290
|
-
next if line.start_with?('!'
|
289
|
+
next if line.start_with?('!', 'end')
|
291
290
|
line.chomp!
|
292
291
|
next if line.empty?
|
293
292
|
indent_level = line[/\A */].size / @indent
|
data/lib/rbeapi/version.rb
CHANGED
data/spec/support/fixtures.rb
CHANGED
@@ -37,7 +37,7 @@ class Fixtures
|
|
37
37
|
def self.save(key, obj, opts = {})
|
38
38
|
dir = opts[:dir] || File.expand_path('../../fixtures', __FILE__)
|
39
39
|
file = Pathname.new(File.join(dir, "fixture_#{key}.yaml"))
|
40
|
-
|
40
|
+
raise ArgumentError, "Error, file #{file} exists" if file.exist?
|
41
41
|
File.open(file, 'w+') { |f| f.puts YAML.dump(obj) }
|
42
42
|
end
|
43
43
|
end
|
@@ -75,9 +75,9 @@ module FixtureHelpers
|
|
75
75
|
text = Pathname.new(File.join(dir, "fixture_#{key}.text"))
|
76
76
|
|
77
77
|
data = if yaml.exist?; then YAML.load(File.read(yaml))
|
78
|
-
elsif json.exist?; then JSON.
|
78
|
+
elsif json.exist?; then JSON.parse(File.read(json))
|
79
79
|
elsif text.exist?; then File.read(text)
|
80
|
-
else
|
80
|
+
else raise "could not load YAML, JSON or TEXT fixture #{key} "\
|
81
81
|
"tried:\n #{yaml}\n #{json} #{text}"
|
82
82
|
end
|
83
83
|
|
@@ -88,7 +88,7 @@ module FixtureHelpers
|
|
88
88
|
when :json then JSON.pretty_generate(data)
|
89
89
|
when :yaml then YAML.dump(data)
|
90
90
|
when :text then data
|
91
|
-
else
|
91
|
+
else raise ArgumentError, "unknown format #{opts[:format].inspect}"
|
92
92
|
end
|
93
93
|
end
|
94
94
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
@@ -61,12 +61,12 @@ end
|
|
61
61
|
|
62
62
|
RSpec::Matchers.define :section_equal do |expected|
|
63
63
|
if expected.class != Rbeapi::SwitchConfig::Section
|
64
|
-
|
64
|
+
raise 'expected is not a Rbeapi::SwitchConfig::Section class'
|
65
65
|
end
|
66
66
|
|
67
67
|
match do |actual|
|
68
68
|
if actual.class != Rbeapi::SwitchConfig::Section
|
69
|
-
|
69
|
+
raise 'actual is not a Rbeapi::SwitchConfig::Section class'
|
70
70
|
end
|
71
71
|
|
72
72
|
section_compare(actual, expected)
|
@@ -34,14 +34,12 @@ describe Rbeapi::Api::Acl do
|
|
34
34
|
'40' => { seqno: '40', action: 'permit', srcaddr: '5.6.7.0',
|
35
35
|
srcprefixlen: '24', log: nil },
|
36
36
|
'50' => { seqno: '50', action: 'permit', srcaddr: '9.10.11.0',
|
37
|
-
srcprefixlen: '255.255.255.0', log: 'log' }
|
38
|
-
}
|
37
|
+
srcprefixlen: '255.255.255.0', log: 'log' } }
|
39
38
|
end
|
40
39
|
|
41
40
|
let(:test2_entries) do
|
42
41
|
{ '10' => { seqno: '10', action: 'deny', srcaddr: '16.0.0.0',
|
43
|
-
srcprefixlen: '8', log: nil }
|
44
|
-
}
|
42
|
+
srcprefixlen: '8', log: nil } }
|
45
43
|
end
|
46
44
|
|
47
45
|
describe '#get' do
|
@@ -0,0 +1,168 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2016, 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 'spec_helper'
|
33
|
+
|
34
|
+
require 'rbeapi/client'
|
35
|
+
require 'rbeapi/api/alias'
|
36
|
+
|
37
|
+
describe Rbeapi::Api::Alias do
|
38
|
+
subject { described_class.new(node) }
|
39
|
+
|
40
|
+
let(:node) do
|
41
|
+
Rbeapi::Client.config.read(fixture_file('dut.conf'))
|
42
|
+
Rbeapi::Client.connect_to('dut')
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:command) do
|
46
|
+
'my command'
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:test) do
|
50
|
+
{ name: 'test1',
|
51
|
+
command: 'my command' }
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:test_multi) do
|
55
|
+
{ name: 'desc',
|
56
|
+
command: "1 conf\n 2 int %1\n 3 descr %2\n 4 end" }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#getall' do
|
60
|
+
let(:resource) { subject.getall }
|
61
|
+
|
62
|
+
let(:test1_entries) do
|
63
|
+
{ 'test1' => { name: 'test1', command: 'my command' },
|
64
|
+
'test2' => { name: 'test2', command: 'my command 2' },
|
65
|
+
'test3' => { name: 'test3', command: 'my command 3' },
|
66
|
+
'desc' => { name: 'desc',
|
67
|
+
command: "1 conf\n 2 int %1\n 3 descr %2\n 4 end" } }
|
68
|
+
end
|
69
|
+
|
70
|
+
before do
|
71
|
+
node.config(['no alias test1',
|
72
|
+
'no alias test2',
|
73
|
+
'no alias test3.domain',
|
74
|
+
'no alias desc',
|
75
|
+
'alias test1 my command',
|
76
|
+
'alias test2 my command 2',
|
77
|
+
'alias test3 my command 3',
|
78
|
+
'alias desc',
|
79
|
+
'1 conf',
|
80
|
+
'2 int %1',
|
81
|
+
'3 descr %2',
|
82
|
+
'4 end',
|
83
|
+
'end'])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns the alias collection' do
|
87
|
+
expect(subject.getall).to include(test1_entries)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns a hash collection' do
|
91
|
+
expect(subject.getall).to be_a_kind_of(Hash)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#get' do
|
96
|
+
before do
|
97
|
+
node.config(['no alias test1',
|
98
|
+
'no alias test2',
|
99
|
+
'no alias test3.domain',
|
100
|
+
'no alias desc',
|
101
|
+
'alias test1 my command',
|
102
|
+
'alias test2 my command 2',
|
103
|
+
'alias test3 my command 3',
|
104
|
+
'alias desc',
|
105
|
+
'1 conf',
|
106
|
+
'2 int %1',
|
107
|
+
'3 descr %2',
|
108
|
+
'4 end',
|
109
|
+
'end'])
|
110
|
+
end
|
111
|
+
it 'returns the alias name and body' do
|
112
|
+
expect(subject.get('test1')).to eq(test)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'returns the alias name and body for multiline entry' do
|
116
|
+
expect(subject.get('desc')).to eq(test_multi)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'returns a hash' do
|
120
|
+
expect(subject.get('test1')).to be_a_kind_of(Hash)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'has 2 entries' do
|
124
|
+
expect(subject.get('test1').size).to eq(2)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#create' do
|
129
|
+
before do
|
130
|
+
node.config(['no alias test1'])
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'create a new alias name' do
|
134
|
+
expect(subject.get('test1')).to eq(nil)
|
135
|
+
expect(subject.create('test1', command: 'my command')).to be_truthy
|
136
|
+
expect(subject.get('test1')[:command]).to eq('my command')
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'raises ArgumentError for create without required args ' do
|
140
|
+
expect { subject.create('test1') }.to \
|
141
|
+
raise_error ArgumentError
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#delete' do
|
146
|
+
before do
|
147
|
+
node.config(['alias test12 a command'])
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'delete an alias resource' do
|
151
|
+
expect(subject.get('test12')[:name]).to eq('test12')
|
152
|
+
expect(subject.delete('test12')).to be_truthy
|
153
|
+
expect(subject.get('test12')).to eq(nil)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#set_command' do
|
158
|
+
before do
|
159
|
+
node.config(['no alias test13'])
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'change the command alias' do
|
163
|
+
expect(subject.create('test13', command: 'my command')).to be_truthy
|
164
|
+
expect(subject.create('test13', command: 'my command 2')).to be_truthy
|
165
|
+
expect(subject.get('test13')[:command]).to eq('my command 2')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -20,8 +20,8 @@ describe Rbeapi::Api::Interfaces do
|
|
20
20
|
describe '#get' do
|
21
21
|
context 'with interface Loopback' do
|
22
22
|
let(:entity) do
|
23
|
-
{ name: 'Loopback0', type: 'generic', description: '',
|
24
|
-
load_interval: '' }
|
23
|
+
{ name: 'Loopback0', type: 'generic', description: '',
|
24
|
+
encapsulation: '', shutdown: false, load_interval: '' }
|
25
25
|
end
|
26
26
|
|
27
27
|
before { node.config(['no interface Loopback0', 'interface Loopback0']) }
|
@@ -34,9 +34,9 @@ describe Rbeapi::Api::Interfaces do
|
|
34
34
|
context 'with interface Port-Channel' do
|
35
35
|
let(:entity) do
|
36
36
|
{ name: 'Port-Channel1', type: 'portchannel', description: '',
|
37
|
-
shutdown: false, load_interval: '', members: [],
|
38
|
-
minimum_links: '0',
|
39
|
-
|
37
|
+
encapsulation: '', shutdown: false, load_interval: '', members: [],
|
38
|
+
lacp_mode: 'on', minimum_links: '0', lacp_fallback: 'disabled',
|
39
|
+
lacp_timeout: '90' }
|
40
40
|
end
|
41
41
|
|
42
42
|
before do
|
@@ -51,10 +51,9 @@ describe Rbeapi::Api::Interfaces do
|
|
51
51
|
|
52
52
|
context 'with interface Vxlan' do
|
53
53
|
let(:entity) do
|
54
|
-
{ name: 'Vxlan1', type: 'vxlan', description: '',
|
54
|
+
{ name: 'Vxlan1', type: 'vxlan', description: '', encapsulation: '',
|
55
55
|
shutdown: false, load_interval: '', source_interface: '',
|
56
|
-
multicast_group: '',
|
57
|
-
udp_port: 4789, flood_list: [], vlans: {} }
|
56
|
+
multicast_group: '', udp_port: 4789, flood_list: [], vlans: {} }
|
58
57
|
end
|
59
58
|
|
60
59
|
before do
|