vagrant-skytap 0.2.10 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/lib/vagrant-skytap/action/check_created.rb +43 -0
  4. data/lib/vagrant-skytap/action/check_running.rb +43 -0
  5. data/lib/vagrant-skytap/action/get_host_vm.rb +52 -0
  6. data/lib/vagrant-skytap/action/prepare_nfs_settings.rb +22 -5
  7. data/lib/vagrant-skytap/action.rb +11 -18
  8. data/lib/vagrant-skytap/api/connectable.rb +50 -0
  9. data/lib/vagrant-skytap/api/environment.rb +10 -5
  10. data/lib/vagrant-skytap/api/interface.rb +9 -0
  11. data/lib/vagrant-skytap/api/network.rb +60 -1
  12. data/lib/vagrant-skytap/api/public_ip.rb +7 -75
  13. data/lib/vagrant-skytap/api/publish_set.rb +4 -0
  14. data/lib/vagrant-skytap/api/published_service.rb +7 -71
  15. data/lib/vagrant-skytap/api/resource.rb +25 -3
  16. data/lib/vagrant-skytap/api/tunnel.rb +69 -0
  17. data/lib/vagrant-skytap/api/vm.rb +10 -2
  18. data/lib/vagrant-skytap/api/vpn.rb +2 -106
  19. data/lib/vagrant-skytap/cap/host_metadata.rb +45 -0
  20. data/lib/vagrant-skytap/connection/public_ip_choice.rb +94 -0
  21. data/lib/vagrant-skytap/connection/published_service_choice.rb +100 -0
  22. data/lib/vagrant-skytap/connection/tunnel_choice.rb +118 -0
  23. data/lib/vagrant-skytap/connection/vpn_choice.rb +132 -0
  24. data/lib/vagrant-skytap/connection.rb +123 -0
  25. data/lib/vagrant-skytap/errors.rb +4 -0
  26. data/lib/vagrant-skytap/plugin.rb +5 -0
  27. data/lib/vagrant-skytap/setup_helper.rb +34 -8
  28. data/lib/vagrant-skytap/version.rb +1 -1
  29. data/locales/en.yml +46 -0
  30. data/spec/unit/actions/prepare_nfs_settings_spec.rb +63 -16
  31. data/spec/unit/cap/host_metadata_spec.rb +43 -0
  32. data/spec/unit/connections/public_ip_choice_spec.rb +57 -0
  33. data/spec/unit/connections/published_service_choice_spec.rb +79 -0
  34. data/spec/unit/connections/tunnel_choice_spec.rb +124 -0
  35. data/spec/unit/connections/vpn_choice_spec.rb +109 -0
  36. data/spec/unit/interface_spec.rb +53 -0
  37. data/spec/unit/network_spec.rb +123 -0
  38. data/spec/unit/setup_helper_spec.rb +59 -19
  39. data/spec/unit/support/api_responses/tunnel1.json +7 -0
  40. data/spec/unit/support/api_responses/vm1.json +12 -1
  41. data/spec/unit/support/shared/rest_api_context.rb +1 -0
  42. data/spec/unit/tunnel_spec.rb +62 -0
  43. data/spec/unit/vm_spec.rb +53 -60
  44. metadata +22 -2
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path("../../base", __FILE__)
24
+ require "vagrant-skytap/cap/host_metadata"
25
+
26
+ describe VagrantPlugins::Skytap::Cap::HostMetadata do
27
+ let(:machine) { double("machine") }
28
+
29
+ before do
30
+ stub_request(:get, %r{http://gw/skytap}).to_return(body: '', status: 404)
31
+ end
32
+
33
+ describe "host_metadata" do
34
+ it "returns nil if the metadata is not found" do
35
+ expect(described_class.host_metadata(machine)).to be nil
36
+ end
37
+
38
+ it "returns the metadata if found" do
39
+ stub_request(:get, %r{http://gw/skytap}).to_return(body: '{"id": 1}', status: 200)
40
+ expect(described_class.host_metadata(machine)).to eq({"id" => 1})
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path("../../base", __FILE__)
24
+ require 'vagrant-skytap/connection/public_ip_choice'
25
+
26
+ describe VagrantPlugins::Skytap::Connection::PublicIpChoice do
27
+ include_context "skytap"
28
+
29
+ let(:env) { {} }
30
+ let(:ip_address) { '10.5.0.1' }
31
+ let(:port) { 22 }
32
+ let(:host_port_tuple) { [ip_address, port] }
33
+ let(:ip) { double(:ip, address: ip_address, :attached? => false) }
34
+ let(:interface) { double(:interface, id: 1, attach_public_ip: nil) }
35
+
36
+ let(:instance) { described_class.new(env, ip, interface) }
37
+
38
+ describe "choose" do
39
+ subject { instance.choose }
40
+
41
+ context "when not attached" do
42
+ before do
43
+ expect(interface).to receive(:attach_public_ip)
44
+ end
45
+ it { should == host_port_tuple }
46
+ end
47
+
48
+ context "when attached" do
49
+ before do
50
+ allow(ip).to receive(:attached?).and_return(true)
51
+ expect(interface).to_not receive(:attach_public_ip)
52
+ end
53
+ it { should == host_port_tuple }
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,79 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path("../../base", __FILE__)
24
+ require 'vagrant-skytap/connection/published_service_choice'
25
+
26
+ describe VagrantPlugins::Skytap::Connection::PublishedServiceChoice do
27
+ include_context "skytap"
28
+
29
+ let(:env) { {} }
30
+ let(:ip_address) { '10.5.0.1' }
31
+ let(:port) { 12345 }
32
+ let(:internal_port) { 22 }
33
+ let(:host_port_tuple) { [ip_address, port] }
34
+ let(:interface) { double(:interface, create_published_service: published_service) }
35
+ let(:published_service) { double(:published_service, external_ip: ip_address, external_port: port, internal_port: internal_port) }
36
+ let(:service) { published_service }
37
+
38
+ let(:instance) { described_class.new(env, interface, service) }
39
+
40
+ describe "choose" do
41
+ subject { instance.choose }
42
+
43
+ context "when service does not exist" do
44
+ let(:service) { nil }
45
+ before do
46
+ expect(interface).to receive(:create_published_service)
47
+ end
48
+ it { should == host_port_tuple }
49
+ end
50
+
51
+ context "when service exists" do
52
+ before do
53
+ expect(interface).to_not receive(:create_published_service)
54
+ end
55
+ it { should == host_port_tuple }
56
+ end
57
+ end
58
+
59
+ describe "valid?" do
60
+ subject { instance.valid? }
61
+
62
+ context "when service does not exist" do
63
+ let(:service) { nil }
64
+ it { should be true }
65
+ end
66
+
67
+ context "when service exists" do
68
+ context "with default port" do
69
+ it { should be true }
70
+ end
71
+
72
+ context "with non-standard port" do
73
+ let(:internal_port) { 9999 }
74
+ it { should be false }
75
+ end
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path("../../base", __FILE__)
24
+ require 'vagrant-skytap/connection/tunnel_choice'
25
+
26
+ describe VagrantPlugins::Skytap::Connection::TunnelChoice, tc: true do
27
+ include_context "skytap"
28
+
29
+ let(:env) { {} }
30
+ let(:nat_address) { '11.0.0.1' }
31
+ let(:port) { 22 }
32
+ let(:host_port_tuple) { [nat_address, port] }
33
+ let(:network) { double(:network) }
34
+ let(:networks) { [guest_network] }
35
+ let(:environment) { double(:environment, id: 1, networks: networks) }
36
+
37
+ let(:host_network) do
38
+ double(:host_network, id: 1, environment: environment, :connected_to_network? => connected,
39
+ :tunnelable? => tunnelable, :nat_enabled? => host_nat_enabled)
40
+ end
41
+ let(:guest_network) { double(:guest_network, id: 2, :nat_enabled? => guest_nat_enabled, connect_to_network: nil) }
42
+ let(:connected) { false }
43
+ let(:tunnelable) { false }
44
+ let(:host_nat_enabled) { false }
45
+ let(:guest_nat_enabled) { false }
46
+
47
+ let(:host_subnet) { double(:host_subnet) }
48
+ let(:guest_subnet) { double(:guest_subnet, :overlaps? => overlaps) }
49
+ let(:overlaps) { true }
50
+
51
+ let(:tunnel) { double(:tunnel, source_network: guest_network, target_network: host_network, :busy? => false) }
52
+ let(:tunnels) { [tunnel] }
53
+ let(:interface) { double(:interface, id: 1, network: guest_network, nat_address_for_network: nat_address) }
54
+ let(:interfaces) { [interface] }
55
+ let(:vm) { double(:vm, id: 1, interfaces: interfaces, get_interface_by_id: interface) }
56
+
57
+ let(:instance) { described_class.new(env, host_network, interface) }
58
+
59
+ before do
60
+ allow(interface).to receive(:vm).and_return(vm)
61
+ allow(vm).to receive(:reload).and_return(vm)
62
+ allow(environment).to receive(:reload).and_return(environment)
63
+ allow(host_network).to receive(:subnet).and_return(host_subnet) if host_network
64
+ allow(guest_network).to receive(:subnet).and_return(guest_subnet) if guest_network
65
+ end
66
+
67
+ describe "valid?" do
68
+ subject {instance.valid?}
69
+
70
+ context "when the guest is not connected to a network" do
71
+ let(:guest_network) {nil}
72
+ it {should be false}
73
+ end
74
+
75
+ context "when the host network is not tunnelable" do
76
+ it {should be false}
77
+ end
78
+
79
+ context "when the host network is not NAT enabled" do
80
+ it {should be false}
81
+ end
82
+
83
+ context "when the host network is tunnelable and NAT enabled" do
84
+ let(:tunnelable) { true }
85
+ let(:host_nat_enabled) { true }
86
+
87
+ context "when the guest network is not NAT enabled" do
88
+ context "when the host and guest subnets overlap" do
89
+ it {should be false}
90
+ end
91
+
92
+ context "when the host and guest subnets do not overlap" do
93
+ let(:overlaps) { false }
94
+ it {should be true}
95
+ end
96
+ end
97
+
98
+ context "when the guest network is NAT enabled" do
99
+ let(:guest_nat_enabled) { true }
100
+ it {should be true}
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "choose" do
106
+ subject { instance.choose }
107
+
108
+ context "when not connected" do
109
+ before do
110
+ expect(guest_network).to receive(:connect_to_network)
111
+ end
112
+ it { should == host_port_tuple }
113
+ end
114
+
115
+ context "when connected" do
116
+ let(:connected) { true }
117
+ before do
118
+ expect(guest_network).to_not receive(:connect_to_network)
119
+ end
120
+ it { should == host_port_tuple }
121
+ end
122
+ end
123
+ end
124
+
@@ -0,0 +1,109 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path("../../base", __FILE__)
24
+ require 'vagrant-skytap/connection/vpn_choice'
25
+
26
+ describe VagrantPlugins::Skytap::Connection::VpnChoice do
27
+ include_context "skytap"
28
+
29
+ let(:env) { {} }
30
+ let(:nat_address) { '11.0.0.1' }
31
+ let(:port) { 22 }
32
+ let(:host_port_tuple) { [nat_address, port] }
33
+ let(:environment) { double(:environment, id: 1) }
34
+ let(:vpn) { double(:vpn, id: 1, name: "My VPN", :nat_enabled? => true, :subsumes? => true) }
35
+ let(:network) { double(:network, id: 1, environment: environment) }
36
+ let(:interface) { double(:interface, id: 1, network: network, attachment_for: vpn_attachment, address_for: nat_address) }
37
+ let(:interfaces) { [interface] }
38
+ let(:vm) { double(:vm, id: 1, interfaces: interfaces, get_interface_by_id: interface) }
39
+
40
+ let(:disconnected_vpn_attachment) { double(:disconnected_vpn_attachment, :connected? => false, :connect! => connected_vpn_attachment) }
41
+ let(:connected_vpn_attachment) { double(:connected_vpn_attachment, :connected? => true) }
42
+ let(:vpn_attachment) { disconnected_vpn_attachment }
43
+
44
+ let(:instance) { described_class.new(env, vpn, vm) }
45
+
46
+ before do
47
+ allow(vm).to receive(:reload).and_return(vm)
48
+ end
49
+
50
+ describe "select_interface" do
51
+ # Pass in a separate vpn to avoid errors when creating the instance
52
+ let(:vpn2) { double(:vpn2, :nat_enabled? => nat_enabled, :subsumes? => subsumes) }
53
+ subject { instance.select_interface(vm, vpn2) }
54
+ let(:nat_enabled) { true }
55
+ let(:subsumes) { true }
56
+
57
+ context "when vpn is nat_enabled" do
58
+ it { should eq interface }
59
+ end
60
+
61
+ context "when vpn is not nat_enabled" do
62
+ let(:nat_enabled) { false }
63
+
64
+ context "when vpn subsumes the network" do
65
+ it { should eq interface }
66
+ end
67
+
68
+ context "when vpn does not subsume the network" do
69
+ let(:subsumes) { false }
70
+ it { should be nil }
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "choose" do
76
+ subject { instance.choose }
77
+ before :each do
78
+ allow(API::VpnAttachment).to receive(:create).and_return(disconnected_vpn_attachment)
79
+ end
80
+
81
+ context "when not attached" do
82
+ let(:vpn_attachment) { nil }
83
+ before do
84
+ expect(API::VpnAttachment).to receive(:create)
85
+ expect(disconnected_vpn_attachment).to receive(:connect!)
86
+ end
87
+ it { should == host_port_tuple }
88
+ end
89
+
90
+ context "when attached and disconnected" do
91
+ let(:vpn_attachment) {disconnected_vpn_attachment}
92
+ before do
93
+ expect(API::VpnAttachment).to_not receive(:create)
94
+ expect(vpn_attachment).to receive(:connect!)
95
+ end
96
+ it { should == host_port_tuple }
97
+ end
98
+
99
+ context "when attached and connected" do
100
+ let(:vpn_attachment) {connected_vpn_attachment}
101
+ before do
102
+ expect(API::VpnAttachment).to_not receive(:create)
103
+ expect(vpn_attachment).to_not receive(:connect!)
104
+ end
105
+ it { should == host_port_tuple }
106
+ end
107
+ end
108
+ end
109
+
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require_relative 'base'
24
+
25
+ describe VagrantPlugins::Skytap::API::Interface do
26
+ include_context "rest_api"
27
+
28
+ let(:json_path) { File.join(File.expand_path('..', __FILE__), 'support', 'api_responses') }
29
+ let(:vm1_attrs) { read_json(json_path, 'vm1.json') }
30
+ let(:interface_attrs) { vm1_attrs['interfaces'].first }
31
+
32
+ let(:env) { {} }
33
+ let(:network) { double(:network, id: "2") }
34
+ let(:vm) { nil }
35
+
36
+ let(:attrs) { interface_attrs }
37
+ let(:instance) { described_class.new(attrs, vm, env) }
38
+
39
+ describe "nat_address_for_network" do
40
+ subject { instance.nat_address_for_network(network) }
41
+
42
+ context "when subject has a nat address from the network" do
43
+ it { should eq "10.0.4.1" }
44
+ end
45
+
46
+ context "when subject has a nat address from a different network" do
47
+ before do
48
+ allow(network).to receive(:id).and_return("3")
49
+ end
50
+ it { should be nil }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,123 @@
1
+ # Copyright (c) 2014-2016 Skytap, Inc.
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ require_relative 'base'
24
+
25
+ describe VagrantPlugins::Skytap::API::Network do
26
+ include_context "rest_api"
27
+
28
+ let(:json_path) { File.join(File.expand_path('..', __FILE__), 'support', 'api_responses') }
29
+ let(:network1_attrs) { read_json(json_path, 'network1.json') }
30
+ let(:network2_attrs) { network1_attrs.merge("id" => "2") }
31
+ let(:network3_attrs) { network1_attrs.merge("id" => "3") }
32
+ let(:nat_subnet) { "11.0.0.0/24" }
33
+ let(:tunnelable) { true }
34
+
35
+ let(:tunnel1_attrs) { read_json(json_path, 'tunnel1.json').merge("source_network" => network1_attrs, "target_network" => network2_attrs) }
36
+ let(:tunnel2_attrs) { tunnel1_attrs.merge("target_network" => network3_attrs) }
37
+ let(:tunnels_attrs) { [tunnel1_attrs] }
38
+
39
+ let(:env) { { ui: ui } }
40
+ let(:attrs) { network1_attrs.merge("tunnels" => tunnels_attrs) }
41
+ let(:instance) { described_class.new(attrs, nil, env) }
42
+
43
+ describe "nat_enabled?" do
44
+ subject {instance.nat_enabled?}
45
+ let(:attrs) {network1_attrs.merge("nat_subnet" => nat_subnet)}
46
+
47
+ context "when nat subnet is set" do
48
+ it {should be true}
49
+ end
50
+
51
+ context "when nat subnet is unset" do
52
+ let(:nat_subnet) {nil}
53
+ it {should be false}
54
+ end
55
+ end
56
+
57
+ describe "tunnelable?" do
58
+ subject {instance.tunnelable?}
59
+ let(:attrs) {network1_attrs.merge("tunnelable" => tunnelable)}
60
+
61
+ context "when tunnelable" do
62
+ it {should be true}
63
+ end
64
+
65
+ context "when not tunnelable" do
66
+ let(:tunnelable) {false}
67
+ it {should be false}
68
+ end
69
+ end
70
+
71
+ describe "tunnels" do
72
+ subject {instance.tunnels}
73
+
74
+ context "when no tunnels exist" do
75
+ let(:tunnels_attrs) { [] }
76
+ it {should eq []}
77
+ end
78
+
79
+ context "when a tunnel exists" do
80
+ its("count") {should eq 1}
81
+ its("first") {should be_a(API::Tunnel)}
82
+ end
83
+ end
84
+
85
+ describe "connected_to_network?" do
86
+ subject {instance.connected_to_network?(network2)}
87
+
88
+ before do
89
+ allow(instance).to receive(:tunnels).and_return(tunnels)
90
+ end
91
+
92
+ let(:network2) { double(:network2, id: 2) }
93
+ let(:network3) { double(:network3, id: 3) }
94
+ let(:tunnel_to_2) { double(:tunnel_to_2, source_network: instance, target_network: network2) }
95
+ let(:tunnel_to_3) { double(:tunnel_to_3, source_network: instance, target_network: network3) }
96
+
97
+ context "when not connected to anything" do
98
+ let(:tunnels) { [] }
99
+ it {should eq false}
100
+ end
101
+
102
+ context "when connected to the specified network" do
103
+ let(:tunnels) { [tunnel_to_2] }
104
+ it {should eq true}
105
+ end
106
+
107
+ context "when connected to a different network" do
108
+ let(:tunnels) { [tunnel_to_3] }
109
+ it {should eq false}
110
+ end
111
+
112
+ context "when connected to both networks" do
113
+ let(:tunnels) { [tunnel_to_2, tunnel_to_3] }
114
+ it {should eq true}
115
+ end
116
+
117
+ context "when the endpoints are reversed" do
118
+ let(:tunnel_to_2_reversed) { double(:tunnel_to_2_reversed, source_network: network2, target_network: instance) }
119
+ let(:tunnels) { [tunnel_to_2_reversed] }
120
+ it {should eq true}
121
+ end
122
+ end
123
+ end