rbeapi 0.5.1 → 1.0

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 +211 -76
  2. data/Gemfile +14 -3
  3. data/README.md +74 -38
  4. data/Rakefile +38 -17
  5. data/gems/inifile/inifile.spec.tmpl +31 -4
  6. data/gems/net_http_unix/net_http_unix.spec.tmpl +34 -8
  7. data/gems/netaddr/netaddr.spec.tmpl +31 -5
  8. data/guide/getting-started.rst +95 -64
  9. data/guide/installation.rst +27 -6
  10. data/guide/release-notes.rst +5 -1
  11. data/guide/testing.rst +5 -2
  12. data/guide/upgrading.rst +2 -0
  13. data/lib/rbeapi/api/dns.rb +8 -2
  14. data/lib/rbeapi/api/interfaces.rb +107 -21
  15. data/lib/rbeapi/api/ipinterfaces.rb +48 -0
  16. data/lib/rbeapi/api/prefixlists.rb +53 -23
  17. data/lib/rbeapi/api/routemaps.rb +11 -0
  18. data/lib/rbeapi/api/stp.rb +6 -3
  19. data/lib/rbeapi/api/switchports.rb +5 -11
  20. data/lib/rbeapi/api/system.rb +1 -1
  21. data/lib/rbeapi/api/users.rb +2 -0
  22. data/lib/rbeapi/api/varp.rb +6 -0
  23. data/lib/rbeapi/api/vlans.rb +44 -0
  24. data/lib/rbeapi/api/vrrp.rb +13 -0
  25. data/lib/rbeapi/client.rb +19 -4
  26. data/lib/rbeapi/switchconfig.rb +330 -0
  27. data/lib/rbeapi/version.rb +1 -1
  28. data/rbeapi.gemspec +2 -0
  29. data/rbeapi.spec.tmpl +30 -3
  30. data/spec/fixtures/.gitignore +1 -0
  31. data/spec/support/matchers/switch_config_sections.rb +80 -0
  32. data/spec/system/rbeapi/api/interfaces_base_spec.rb +32 -3
  33. data/spec/system/rbeapi/api/interfaces_ethernet_spec.rb +56 -8
  34. data/spec/system/rbeapi/api/interfaces_portchannel_spec.rb +33 -1
  35. data/spec/system/rbeapi/api/interfaces_vxlan_spec.rb +27 -0
  36. data/spec/system/rbeapi/api/ipinterfaces_spec.rb +34 -1
  37. data/spec/system/rbeapi/api/prefixlists_spec.rb +198 -0
  38. data/spec/system/rbeapi/api/stp_instances_spec.rb +49 -5
  39. data/spec/system/rbeapi/api/switchports_spec.rb +15 -9
  40. data/spec/system/rbeapi/api/vlans_spec.rb +46 -0
  41. data/spec/unit/rbeapi/api/interfaces/base_spec.rb +1 -1
  42. data/spec/unit/rbeapi/api/interfaces/ethernet_spec.rb +1 -1
  43. data/spec/unit/rbeapi/api/interfaces/portchannel_spec.rb +9 -2
  44. data/spec/unit/rbeapi/api/interfaces/vxlan_spec.rb +1 -1
  45. data/spec/unit/rbeapi/api/prefixlists/default_spec.rb +202 -0
  46. data/spec/unit/rbeapi/api/prefixlists/fixture_prefixlists.text +11 -0
  47. data/spec/unit/rbeapi/api/routemaps/default_spec.rb +5 -0
  48. data/spec/unit/rbeapi/api/switchports/default_spec.rb +4 -4
  49. data/spec/unit/rbeapi/api/system/default_spec.rb +5 -0
  50. data/spec/unit/rbeapi/api/system/fixture_system.text +1 -0
  51. data/spec/unit/rbeapi/api/vlans/default_spec.rb +30 -0
  52. data/spec/unit/rbeapi/api/vrrp/default_spec.rb +10 -0
  53. data/spec/unit/rbeapi/client_spec.rb +42 -0
  54. data/spec/unit/rbeapi/switchconfig2_spec.rb +119 -0
  55. data/spec/unit/rbeapi/switchconfig3_spec.rb +125 -0
  56. data/spec/unit/rbeapi/switchconfig_spec.rb +335 -0
  57. metadata +21 -7
@@ -23,7 +23,7 @@ describe Rbeapi::Api::VxlanInterface do
23
23
  let(:resource) { subject.get('Vxlan1') }
24
24
 
25
25
  let(:keys) do
26
- [:type, :shutdown, :description, :name, :source_interface,
26
+ [:type, :shutdown, :load_interval, :description, :name, :source_interface,
27
27
  :multicast_group, :udp_port, :flood_list, :vlans]
28
28
  end
29
29
 
@@ -0,0 +1,202 @@
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/api/prefixlists'
35
+
36
+ include FixtureHelpers
37
+
38
+ describe Rbeapi::Api::Prefixlists do
39
+ subject { described_class.new(node) }
40
+
41
+ let(:node) { double('node') }
42
+
43
+ def prefixlists
44
+ prefixlists = Fixtures[:prefixlists]
45
+ return prefixlists if prefixlists
46
+ fixture('prefixlists', format: :text, dir: File.dirname(__FILE__))
47
+ end
48
+
49
+ before :each do
50
+ allow(subject.node).to receive(:running_config).and_return(prefixlists)
51
+ end
52
+
53
+ describe '#get' do
54
+ let(:resource) { subject.get('test1') }
55
+
56
+ let(:prefixlist) do
57
+ [{
58
+ 'seq' => '10',
59
+ 'action' => 'permit',
60
+ 'prefix' => '1.2.3.0/24'
61
+ },
62
+ {
63
+ 'seq' => '20',
64
+ 'action' => 'permit',
65
+ 'prefix' => '2.3.4.0/24 le 30'
66
+ },
67
+ {
68
+ 'seq' => '30',
69
+ 'action' => 'permit',
70
+ 'prefix' => '3.4.5.0/24 ge 26 le 30'
71
+ }]
72
+ end
73
+
74
+ let(:keys) { ['seq', 'action', 'prefix'] }
75
+
76
+ it 'returns the prefix list for an existing name' do
77
+ expect(resource).to eq(prefixlist)
78
+ end
79
+
80
+ it 'returns an array of prefixes' do
81
+ expect(resource).to be_a_kind_of(Array)
82
+ end
83
+
84
+ it 'has three prefixes' do
85
+ expect(resource.size).to eq(3)
86
+ end
87
+
88
+ it 'has all keys' do
89
+ resource.each do |prefix|
90
+ expect(prefix.keys).to match_array(keys)
91
+ end
92
+ end
93
+
94
+ let(:nonexistent) { subject.get('nonexistent') }
95
+ it 'returns nil for a non-existing name' do
96
+ expect(nonexistent).to eq(nil)
97
+ end
98
+ end
99
+
100
+ describe '#getall' do
101
+ let(:resource) { subject.getall }
102
+
103
+ let(:plists) do
104
+ {
105
+ "test1" => [
106
+ {
107
+ "seq" => "10",
108
+ "action" => "permit",
109
+ "prefix" => "1.2.3.0/24"
110
+ },
111
+ {
112
+ "seq" => "20",
113
+ "action" => "permit",
114
+ "prefix" => "2.3.4.0/24 le 30"
115
+ },
116
+ {
117
+ "seq" => "30",
118
+ "action" => "permit",
119
+ "prefix" => "3.4.5.0/24 ge 26 le 30"
120
+ }
121
+ ],
122
+ "test2" => [
123
+ {
124
+ "seq" => "10",
125
+ "action" => "permit",
126
+ "prefix" => "10.11.0.0/16"
127
+ },
128
+ {
129
+ "seq" => "20",
130
+ "action" => "permit",
131
+ "prefix" => "10.12.0.0/16 le 24"
132
+ }
133
+ ],
134
+ "test3" => []
135
+ }
136
+ end
137
+
138
+ it 'returns all prefix lists' do
139
+ expect(resource).to eq(plists)
140
+ end
141
+
142
+ it 'returns a hash' do
143
+ expect(resource).to be_a_kind_of(Hash)
144
+ end
145
+
146
+ it 'has three prefix lists' do
147
+ expect(resource.size).to eq(3)
148
+ end
149
+ end
150
+
151
+ describe '#create' do
152
+ it 'creates a new prefix list' do
153
+ expect(node).to receive(:config).with('ip prefix-list plist1')
154
+ expect(subject.create('plist1')).to be_truthy
155
+ end
156
+
157
+ it 'creates an existing prefix list' do
158
+ expect(node).to receive(:config).with('ip prefix-list test1')
159
+ expect(subject.create('test1')).to be_truthy
160
+ end
161
+ end
162
+
163
+ describe '#add_rule' do
164
+ it 'adds rule to existing prefix list' do
165
+ expect(node).to receive(:config).with('ip prefix-list test1 seq 25 permit 9.8.7.0/24')
166
+ expect(subject.add_rule('test1', 'permit','9.8.7.0/24', '25')).to be_truthy
167
+ end
168
+
169
+ it 'adds rule to existing prefix list w/o seq' do
170
+ expect(node).to receive(:config).with('ip prefix-list test1 permit 8.7.6.0/24')
171
+ expect(subject.add_rule('test1', 'permit', '8.7.6.0/24')).to be_truthy
172
+ end
173
+
174
+ it 'adds rule to non-existing prefix list' do
175
+ expect(node).to receive(:config).with('ip prefix-list plist2 seq 10 permit 6.5.4.128/25')
176
+ expect(subject.add_rule('plist2', 'permit', '6.5.4.128/25', '10')).to be_truthy
177
+ end
178
+
179
+ it 'adds rule to non-existing prefix list w/o seq' do
180
+ expect(node).to receive(:config).with('ip prefix-list plist2 deny 5.4.3.0/25')
181
+ expect(subject.add_rule('plist2', 'deny', '5.4.3.0/25')).to be_truthy
182
+ end
183
+
184
+ it 'overwrites existing rule' do
185
+ expect(node).to receive(:config).with('ip prefix-list test1 seq 20 permit 2.3.5.0/24 le 28')
186
+ expect(subject.add_rule('test1', 'permit', '2.3.5.0/24 le 28', '20')).to be_truthy
187
+ end
188
+ end
189
+
190
+ describe '#delete' do
191
+ it 'deletes a prefix-list' do
192
+ expect(node).to receive(:config).with('no ip prefix-list test1')
193
+ expect(subject.delete('test1'))
194
+ end
195
+
196
+ it 'deletes a rule from a prefix-list' do
197
+ expect(node).to receive(:config).with('no ip prefix-list test2 seq 10')
198
+ expect(subject.delete('test2', '10'))
199
+ end
200
+ end
201
+
202
+ end
@@ -0,0 +1,11 @@
1
+ ip prefix-list test1
2
+ seq 10 permit 1.2.3.0/24
3
+ seq 20 permit 2.3.4.0/24 le 30
4
+ seq 30 permit 3.4.5.0/24 ge 26 le 30
5
+ !
6
+ ip prefix-list test2
7
+ seq 10 permit 10.11.0.0/16
8
+ seq 20 permit 10.12.0.0/16 le 24
9
+ !
10
+ ip prefix-list test3
11
+ !
@@ -244,6 +244,11 @@ describe Rbeapi::Api::Routemaps do
244
244
  expect(subject.create('test', 'deny', 20,
245
245
  default: true)).to be_truthy
246
246
  end
247
+
248
+ it 'raises an ArgumentError if opts match is not an array' do
249
+ expect { subject.create('test', 'permit', 10, match: '123') }
250
+ .to raise_error(ArgumentError)
251
+ end
247
252
  end
248
253
 
249
254
  describe '#delete' do
@@ -195,11 +195,11 @@ describe Rbeapi::Api::Switchports do
195
195
  .to raise_error(ArgumentError)
196
196
  end
197
197
 
198
- it 'sets vlan 8 and 9 to the trunk allowed vlans' do
198
+ it 'sets vlan 8-10 and 100 to the trunk allowed vlans' do
199
199
  expect(node).to receive(:config)
200
- .with(['interface Ethernet1', 'switchport trunk allowed vlan none',
201
- 'switchport trunk allowed vlan 8,9'])
202
- expect(subject.set_trunk_allowed_vlans('Ethernet1', value: [8, 9]))
200
+ .with(['interface Ethernet1', 'switchport trunk allowed vlan 8-10,100'])
201
+ expect(subject.set_trunk_allowed_vlans('Ethernet1',
202
+ value: ['8-10', '100']))
203
203
  .to be_truthy
204
204
  end
205
205
 
@@ -68,6 +68,11 @@ describe Rbeapi::Api::System do
68
68
  it 'has four entries' do
69
69
  expect(subject.get.size).to eq(4)
70
70
  end
71
+
72
+ it 'retrieves only global ip routing' do
73
+ expect(subject.get.size).to eq(4)
74
+ expect(subject.get[:iprouting]).to eq(true)
75
+ end
71
76
  end
72
77
 
73
78
  describe '#set_hostname' do
@@ -1,5 +1,6 @@
1
1
  hostname localhost
2
2
  ip routing
3
+ no ip routing vrf foo
3
4
  banner login
4
5
  Login Banner
5
6
  Second Line
@@ -132,4 +132,34 @@ describe Rbeapi::Api::Vlans do
132
132
  expect(subject.remove_trunk_group('1', 'foo')).to be_truthy
133
133
  end
134
134
  end
135
+
136
+ describe '#set_trunk_groups' do
137
+ it 'raises an ArgumentError if value is not an array' do
138
+ expect { subject.set_trunk_groups('vlan 1', value: 'foo') }
139
+ .to raise_error(ArgumentError)
140
+ end
141
+
142
+ it 'sets trunk group to foo bar bang' do
143
+ expect(node).to receive(:config)
144
+ .with(['vlan 1', 'trunk group foo',
145
+ 'trunk group bar', 'trunk group bang', 'no trunk group mlag_ctl',
146
+ 'no trunk group test'])
147
+ expect(subject.set_trunk_groups('1', value: %w(foo bar bang)))
148
+ .to be_truthy
149
+ end
150
+
151
+ it 'negate switchport trunk group' do
152
+ expect(node).to receive(:config)
153
+ .with(['vlan 1', 'no trunk group'])
154
+ expect(subject.set_trunk_groups('1', enable: false))
155
+ .to be_truthy
156
+ end
157
+
158
+ it 'default switchport trunk group' do
159
+ expect(node).to receive(:config)
160
+ .with(['vlan 1', 'default trunk group'])
161
+ expect(subject.set_trunk_groups('1', default: true))
162
+ .to be_truthy
163
+ end
164
+ end
135
165
  end
@@ -169,6 +169,16 @@ describe Rbeapi::Api::Vrrp do
169
169
  expect { subject.create('Vlan100', 9) }.to \
170
170
  raise_error ArgumentError
171
171
  end
172
+
173
+ it 'raises an ArgumentError if secondary_ip is not an array' do
174
+ expect { subject.create('Ethernet1', 9, secondary_ip: '123') }
175
+ .to raise_error(ArgumentError)
176
+ end
177
+
178
+ it 'raises an ArgumentError if track is not an array' do
179
+ expect { subject.create('Ethernet1', 9, track: '123') }
180
+ .to raise_error(ArgumentError)
181
+ end
172
182
  end
173
183
 
174
184
  describe '#delete' do
@@ -209,4 +209,46 @@ describe Rbeapi::Client do
209
209
  host: 'test2')
210
210
  end
211
211
  end
212
+
213
+ describe '#get_config' do
214
+ def startup_config
215
+ "! Command: show running-config\n! device: jere-debug-agent1 (vEOS, EOS-4.14.9.1M)\n!\n! boot system flash:/vEOS-4.14.9.1M.swi\n!\nip routing vrf MGMT\n!\nmanagement api http-commands\n no protocol https\n protocol unix-socket\n no shutdown\n vrf MGMT\n no shutdown\n!\nmanagement ssh\n vrf MGMT\n no shutdown\n!\n!\nend\n"
216
+ end
217
+
218
+ def startup_config_response
219
+ [{"output"=>startup_config}]
220
+ end
221
+
222
+ let(:node) do
223
+ subject.config.read(fixture_file('dut.conf'))
224
+ subject.connect_to('dut')
225
+ end
226
+
227
+ before(:each) do
228
+ allow(node).to receive(:run_commands) { startup_config_response }
229
+ end
230
+
231
+ it 'with no arguments returns the startup-config' do
232
+ expect(node.get_config()).to eq(startup_config.strip.split("\n"))
233
+ end
234
+
235
+ it 'with no arguments and an empty startup-config returns the startup-config' do
236
+ allow(node).to receive(:run_commands) { [{"output"=>""}] }
237
+ expect(node.get_config()).to eq([])
238
+ end
239
+
240
+ it 'with no arguments and no startup-config returns nil' do
241
+ msg = "CLI command 2 of 2 'show startup-config' failed: could not run command"
242
+ allow(node).to receive(:run_commands).and_raise(Rbeapi::Eapilib::CommandError.new(msg, 1000))
243
+ expect(node.get_config()).to be_nil
244
+ end
245
+
246
+ it 'raises invalid command error' do
247
+ msg = "CLI command 2 of 2 'show startup-configurations' failed: invalid command"
248
+ allow(node).to receive(:run_commands).and_raise(Rbeapi::Eapilib::CommandError.new(msg, 1000))
249
+ expect { node.get_config(config: 'running-configurations') }
250
+ .to raise_error Rbeapi::Eapilib::CommandError
251
+ end
252
+
253
+ end
212
254
  end
@@ -0,0 +1,119 @@
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/switchconfig'
35
+
36
+ include FixtureHelpers
37
+ include Rbeapi::SwitchConfig
38
+
39
+ describe Rbeapi::SwitchConfig::SwitchConfig do
40
+ test_config = <<-EOS
41
+ ! Test on multi-level children sections
42
+ management api http-commands
43
+ no shutdown
44
+ vrf cloud-mgmt
45
+ no shutdown
46
+ EOS
47
+ test_config_global = ['management api http-commands']
48
+ cmds = [[' no shutdown',
49
+ ' vrf cloud-mgmt'],
50
+ [' no shutdown']]
51
+
52
+ subject { described_class.new(test_config) }
53
+
54
+ # SwitchConfig class methods
55
+ describe '#initialize' do
56
+ it 'returns the processed configuration' do
57
+ sc = subject.global
58
+ # Validate the global section
59
+ expect(sc.line).to eq('')
60
+ expect(sc.parent).to eq(nil)
61
+ expect(sc.cmds).to eq(test_config_global)
62
+ expect(sc.children.length).to eq(1)
63
+
64
+ # Validate the child of global
65
+ expect(sc.children[0].line).to eq(test_config_global[0])
66
+ expect(sc.children[0].parent).to eq(sc)
67
+ expect(sc.children[0].cmds).to eq(cmds[0])
68
+ expect(sc.children[0].children.length).to eq(1)
69
+
70
+ # Validate the child of global
71
+ child = sc.children[0].children
72
+ expect(child[0].line).to eq(cmds[0][1])
73
+ expect(child[0].parent).to eq(sc.children[0])
74
+ expect(child[0].cmds).to eq(cmds[1])
75
+ expect(child[0].children.length).to eq(0)
76
+ end
77
+ end
78
+
79
+ describe '#compare' do
80
+ it 'Verify compare returns array of 2 Sections' do
81
+ expect(subject.compare(subject)).to be_instance_of(Array)
82
+ expect(subject.compare(subject)[0]).to be_instance_of(Section)
83
+ expect(subject.compare(subject)[1]).to be_instance_of(Section)
84
+ end
85
+
86
+ it 'Verify compare of same switch configs' do
87
+ expect(subject.compare(subject)[0].line).to eq('')
88
+ expect(subject.compare(subject)[0].cmds).to eq([])
89
+ expect(subject.compare(subject)[0].children).to eq([])
90
+ expect(subject.compare(subject)[1].line).to eq('')
91
+ expect(subject.compare(subject)[1].cmds).to eq([])
92
+ expect(subject.compare(subject)[1].children).to eq([])
93
+ end
94
+
95
+ it 'Verify compare of shutdown management vrf' do
96
+ new_conf = <<-EOS
97
+ management api http-commands
98
+ no shutdown
99
+ vrf cloud-mgmt
100
+ shutdown
101
+ EOS
102
+ org_new_diff = <<-EOS
103
+ management api http-commands
104
+ vrf cloud-mgmt
105
+ no shutdown
106
+ EOS
107
+ new_org_diff = <<-EOS
108
+ management api http-commands
109
+ vrf cloud-mgmt
110
+ shutdown
111
+ EOS
112
+ swc_new = Rbeapi::SwitchConfig::SwitchConfig.new(new_conf)
113
+ swc_org_new = Rbeapi::SwitchConfig::SwitchConfig.new(org_new_diff)
114
+ swc_new_org = Rbeapi::SwitchConfig::SwitchConfig.new(new_org_diff)
115
+ expect(subject.compare(swc_new)[0]).to section_equal(swc_org_new.global)
116
+ expect(subject.compare(swc_new)[1]).to section_equal(swc_new_org.global)
117
+ end
118
+ end
119
+ end