rbeapi 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|