vagrant-cosmic 0.1.0

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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +8 -0
  4. data/Docker/.dockerignore +2 -0
  5. data/Docker/Dockerfile +48 -0
  6. data/Docker/Dockerfile.chefdk_0_17 +49 -0
  7. data/Docker/Dockerfile.latest_dependencies +49 -0
  8. data/Docker/README.md +95 -0
  9. data/Docker/vac.ps1 +29 -0
  10. data/Docker/vac.sh +30 -0
  11. data/Gemfile +21 -0
  12. data/Gemfile.lock +187 -0
  13. data/LICENSE +8 -0
  14. data/README.md +409 -0
  15. data/Rakefile +106 -0
  16. data/build_rpm.sh +7 -0
  17. data/functional-tests/basic/Vagrantfile.basic_networking +34 -0
  18. data/functional-tests/basic/basic_spec.rb +15 -0
  19. data/functional-tests/networking/Vagrantfile.advanced_networking +106 -0
  20. data/functional-tests/networking/networking_spec.rb +14 -0
  21. data/functional-tests/rsync/Vagrantfile.advanced_networking +40 -0
  22. data/functional-tests/rsync/rsync_spec.rb +9 -0
  23. data/functional-tests/vmlifecycle/Vagrantfile.advanced_networking +64 -0
  24. data/functional-tests/vmlifecycle/vmlifecycle_spec.rb +25 -0
  25. data/lib/vagrant-cosmic/action/connect_cosmic.rb +47 -0
  26. data/lib/vagrant-cosmic/action/is_created.rb +18 -0
  27. data/lib/vagrant-cosmic/action/is_stopped.rb +18 -0
  28. data/lib/vagrant-cosmic/action/message_already_created.rb +16 -0
  29. data/lib/vagrant-cosmic/action/message_not_created.rb +16 -0
  30. data/lib/vagrant-cosmic/action/message_will_not_destroy.rb +16 -0
  31. data/lib/vagrant-cosmic/action/read_rdp_info.rb +42 -0
  32. data/lib/vagrant-cosmic/action/read_ssh_info.rb +70 -0
  33. data/lib/vagrant-cosmic/action/read_state.rb +38 -0
  34. data/lib/vagrant-cosmic/action/read_transport_info.rb +59 -0
  35. data/lib/vagrant-cosmic/action/read_winrm_info.rb +69 -0
  36. data/lib/vagrant-cosmic/action/run_instance.rb +819 -0
  37. data/lib/vagrant-cosmic/action/start_instance.rb +81 -0
  38. data/lib/vagrant-cosmic/action/stop_instance.rb +28 -0
  39. data/lib/vagrant-cosmic/action/terminate_instance.rb +208 -0
  40. data/lib/vagrant-cosmic/action/timed_provision.rb +21 -0
  41. data/lib/vagrant-cosmic/action/wait_for_state.rb +41 -0
  42. data/lib/vagrant-cosmic/action/warn_networks.rb +19 -0
  43. data/lib/vagrant-cosmic/action.rb +210 -0
  44. data/lib/vagrant-cosmic/capabilities/rdp.rb +12 -0
  45. data/lib/vagrant-cosmic/capabilities/winrm.rb +12 -0
  46. data/lib/vagrant-cosmic/config.rb +422 -0
  47. data/lib/vagrant-cosmic/errors.rb +27 -0
  48. data/lib/vagrant-cosmic/exceptions/exceptions.rb +15 -0
  49. data/lib/vagrant-cosmic/model/cosmic_resource.rb +51 -0
  50. data/lib/vagrant-cosmic/plugin.rb +82 -0
  51. data/lib/vagrant-cosmic/provider.rb +58 -0
  52. data/lib/vagrant-cosmic/service/cosmic_resource_service.rb +76 -0
  53. data/lib/vagrant-cosmic/util/timer.rb +17 -0
  54. data/lib/vagrant-cosmic/version.rb +5 -0
  55. data/lib/vagrant-cosmic.rb +17 -0
  56. data/locales/en.yml +131 -0
  57. data/spec/spec_helper.rb +53 -0
  58. data/spec/vagrant-cosmic/action/read_ssh_info_spec.rb +80 -0
  59. data/spec/vagrant-cosmic/action/retrieve_public_ip_port_spec.rb +94 -0
  60. data/spec/vagrant-cosmic/action/run_instance_spec.rb +573 -0
  61. data/spec/vagrant-cosmic/action/terminate_instance_spec.rb +207 -0
  62. data/spec/vagrant-cosmic/config_spec.rb +340 -0
  63. data/spec/vagrant-cosmic/model/cosmic_resource_spec.rb +95 -0
  64. data/spec/vagrant-cosmic/service/cosmic_resource_service_spec.rb +43 -0
  65. data/spec/vagrant-cosmic/support/be_a_resource.rb +6 -0
  66. data/vagrant-cosmic.gemspec +59 -0
  67. data/vagrant-cosmic.spec +42 -0
  68. metadata +218 -0
@@ -0,0 +1,207 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-cosmic/action/terminate_instance'
3
+ require 'vagrant-cosmic/config'
4
+
5
+ require 'vagrant'
6
+ require 'fog/cosmic'
7
+
8
+ describe VagrantPlugins::Cosmic::Action::TerminateInstance do
9
+ let(:action) { VagrantPlugins::Cosmic::Action::TerminateInstance.new(app, env) }
10
+
11
+ let(:destroy_server_response) { { id: JOB_ID } }
12
+
13
+ let(:cs_job) { double('Fog::Cosmic::Compute::Job') }
14
+
15
+ let(:fake_job_result) do
16
+ {
17
+ 'queryasyncjobresultresponse' => {
18
+ 'jobstatus' => 1,
19
+ 'jobresult' => {
20
+ 'portforwardingrule' => {
21
+ 'id' => PORT_FORWARDING_RULE_ID
22
+ },
23
+ 'networkacl' => {
24
+ 'id' => ACL_ID
25
+ },
26
+ 'virtualmachine' => {
27
+ 'password' => GENERATED_PASSWORD
28
+ }
29
+ }
30
+ }
31
+ }
32
+ end
33
+
34
+ describe '#terminate_instance in advanced zone' do
35
+ subject { action.call(env) }
36
+ let(:app) { double('Vagrant::Action::Warden') }
37
+
38
+ let(:provider_config) do
39
+ config = VagrantPlugins::Cosmic::Config.new
40
+
41
+ config.finalize!
42
+ config.get_domain_config(:cosmic)
43
+ end
44
+
45
+ let(:machine) { double('Vagrant::Machine') }
46
+ let(:data_dir) { double('Pathname') }
47
+ let(:a_path) { double('Pathname') }
48
+ let(:file) { double('File') }
49
+
50
+ let(:cosmic_compute) { double('Fog::Cosmic::Compute') }
51
+ let(:servers) { double('Fog::Cosmic::Compute::Servers') }
52
+ let(:server) { double('Fog::Cosmic::Compute::Server') }
53
+ let(:ui) { double('Vagrant::UI::Prefixed') }
54
+ let(:root_path) { double('Pathname') }
55
+ let(:env) do
56
+ {
57
+ root_path: root_path,
58
+ ui: ui,
59
+ machine: machine,
60
+ cosmic_compute: cosmic_compute
61
+ }
62
+ end
63
+
64
+ before(:each) do
65
+ allow(app).to receive(:call).and_return(true)
66
+
67
+ allow(ui).to receive(:info)
68
+ expect(ui).not_to receive(:warn)
69
+ allow(ui).to receive(:detail)
70
+
71
+ allow(machine).to receive(:provider_config).and_return(provider_config)
72
+ allow(machine).to receive(:data_dir).and_return(data_dir)
73
+
74
+ allow(data_dir).to receive(:join).and_return(a_path)
75
+ allow(a_path).to receive(:file?).and_return(false)
76
+
77
+ expect(cosmic_compute).to receive(:servers).and_return(servers)
78
+ expect(servers).to receive(:get).with(SERVER_ID).and_return(server)
79
+ expect(server).to receive(:destroy).with('expunge' => false).and_return(cs_job)
80
+ expect(cs_job).to receive(:id).and_return(JOB_ID)
81
+
82
+ allow(cosmic_compute).to receive(:query_async_job_result).with(jobid: JOB_ID).and_return(fake_job_result)
83
+ allow(machine).to receive(:id).and_return(SERVER_ID)
84
+ expect(machine).to receive(:id=).with(nil)
85
+ end
86
+
87
+ context 'destroys a simple VM' do
88
+ it 'destroys a vm' do
89
+ should eq true
90
+ end
91
+
92
+ context 'with firewall rules removal' do
93
+ let(:firewall_path) { double('Pathname') }
94
+ let(:file_content) { double }
95
+ let(:firewall_rule) { 'UUID of Firewall rule' }
96
+ let(:network_acl) { 'UUID of ACL' }
97
+
98
+ before(:each) do
99
+ expect(data_dir).to receive(:join).with('firewall').and_return(firewall_path)
100
+ expect(firewall_path).to receive(:file?).and_return(true)
101
+ # A VM will never belong to both a VPC and regular router, but allowed for this test
102
+ allow(File).to receive(:read).and_return("#{network_acl},networkacl\n" + "#{firewall_rule},firewallrule\n")
103
+
104
+ expect(cosmic_compute).to receive(:request)
105
+ .with(command: 'deleteNetworkACL', id: network_acl)
106
+ .and_return('deletenetworkaclresponse' => { 'jobid' => JOB_ID })
107
+
108
+ expect(cosmic_compute).to receive(:request)
109
+ .with(command: 'deleteFirewallRule', id: 'UUID of Firewall rule')
110
+ .and_return('deletefirewallruleresponse' => { 'jobid' => JOB_ID })
111
+
112
+ expect(firewall_path).to receive(:delete).and_return(true)
113
+ end
114
+
115
+ it 'destroys a vm' do
116
+ should eq true
117
+ end
118
+ end
119
+
120
+ context 'with port forwarding removal' do
121
+ let(:port_forwarding_path) { double('Pathname') }
122
+
123
+ before(:each) do
124
+ expect(data_dir).to receive(:join).with('port_forwarding').and_return(port_forwarding_path)
125
+ expect(port_forwarding_path).to receive(:file?).and_return(true)
126
+ allow(File).to receive(:read)
127
+ .and_return("#{PORT_FORWARDING_RULE_ID}\n#{PORT_FORWARDING_RULE_ID}_2\n#{PORT_FORWARDING_RULE_ID}_3")
128
+
129
+ [PORT_FORWARDING_RULE_ID, "#{PORT_FORWARDING_RULE_ID}_2", "#{PORT_FORWARDING_RULE_ID}_3"]
130
+ .each do |port_forwarding_rule_id|
131
+
132
+ expect(cosmic_compute).to receive(:delete_port_forwarding_rule)
133
+ .with(id: port_forwarding_rule_id)
134
+ .and_return('deleteportforwardingruleresponse' => { 'jobid' => JOB_ID })
135
+ end
136
+ expect(port_forwarding_path).to receive(:delete).and_return(true)
137
+ end
138
+
139
+ it 'destroys a vm' do
140
+ should eq true
141
+ end
142
+ end
143
+
144
+ context 'with volume removal' do
145
+ let(:volumes_path) { double('Pathname') }
146
+
147
+ before(:each) do
148
+ expect(data_dir).to receive(:join).with('volumes').and_return(volumes_path)
149
+ expect(volumes_path).to receive(:file?).and_return(true)
150
+ allow(File).to receive(:read)
151
+ .and_return("#{VOLUME_ID}\n#{VOLUME_ID}_2\n#{VOLUME_ID}_3")
152
+
153
+ [VOLUME_ID, "#{VOLUME_ID}_2", "#{VOLUME_ID}_3"]
154
+ .each do |volume_id|
155
+
156
+ expect(cosmic_compute).to receive(:detach_volume)
157
+ .with(id: volume_id)
158
+ .and_return('detachvolumeresponse' => { 'jobid' => JOB_ID })
159
+ expect(cosmic_compute).to receive(:delete_volume)
160
+ .with(id: volume_id)
161
+ .and_return('deletevolumeresponse' => { 'success' => 'true' })
162
+ end
163
+ expect(volumes_path).to receive(:delete).and_return(true)
164
+ end
165
+
166
+ it 'destroys a vm' do
167
+ should eq true
168
+ end
169
+ end
170
+
171
+ context 'with credentials file removal' do
172
+ let(:credentials_path) { double('Pathname') }
173
+
174
+ before(:each) do
175
+ expect(data_dir).to receive(:join).with('vmcredentials').and_return(credentials_path)
176
+ expect(credentials_path).to receive(:file?).and_return(true)
177
+ expect(credentials_path).to receive(:delete).and_return(true)
178
+ end
179
+
180
+ it 'destroys a vm' do
181
+ should eq true
182
+ end
183
+ end
184
+
185
+ context 'with generated SSH key removal' do
186
+ let(:ssh_key_path) { double('Pathname') }
187
+
188
+ before(:each) do
189
+ expect(data_dir).to receive(:join).with('sshkeyname').and_return(ssh_key_path)
190
+ expect(ssh_key_path).to receive(:file?).and_return(true)
191
+ allow(File).to receive(:read)
192
+ .and_return("#{SSH_GENERATED_KEY_NAME}\n")
193
+
194
+ expect(cosmic_compute).to receive(:delete_ssh_key_pair)
195
+ .with(name: SSH_GENERATED_KEY_NAME)
196
+ .and_return('deletesshkeypairresponse' => { 'success' => 'true' })
197
+
198
+ expect(ssh_key_path).to receive(:delete).and_return(true)
199
+ end
200
+
201
+ it 'destroys a vm' do
202
+ should eq true
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,340 @@
1
+ require "spec_helper"
2
+ require "vagrant-cosmic/config"
3
+
4
+ describe VagrantPlugins::Cosmic::Config do
5
+ let(:instance) { described_class.new }
6
+
7
+ # Ensure tests are not affected by Cosmic credential environment variables
8
+ before :each do
9
+ allow(ENV).to receive_messages(:[] => nil)
10
+ end
11
+
12
+ describe "defaults" do
13
+ subject do
14
+ instance.tap do |o|
15
+ o.finalize!
16
+ end
17
+ end
18
+
19
+ its("host") { should be_nil }
20
+ its("path") { should be_nil }
21
+ its("port") { should be_nil }
22
+ its("scheme") { should be_nil }
23
+ its("api_key") { should be_nil }
24
+ its("secret_key") { should be_nil }
25
+ its("instance_ready_timeout") { should == 120 }
26
+ its("domain_id") { should be_nil }
27
+ its("network_id") { should be_nil }
28
+ its("project_id") { should be_nil }
29
+ its("service_offering_id") { should be_nil }
30
+ its("disk_offering_id") { should be_nil }
31
+ its("template_id") { should be_nil }
32
+ its("zone_id") { should be_nil }
33
+ its("keypair") { should be_nil }
34
+ its("static_nat") { should == [] }
35
+ its("pf_ip_address_id") { should be_nil }
36
+ its("pf_ip_address") { should be_nil }
37
+ its("pf_public_port") { should be_nil }
38
+ its("pf_public_rdp_port") { should be_nil }
39
+ its("pf_private_rdp_port") { should == 3389 }
40
+ its("pf_public_port_randomrange") { should == {:start=>49152, :end=>65535} }
41
+ its("pf_private_port") { should be_nil }
42
+ its("pf_open_firewall") { should == true }
43
+ its("pf_trusted_networks") { should be_nil }
44
+ its("port_forwarding_rules") { should == [] }
45
+ its("firewall_rules") { should == [] }
46
+ its("display_name") { should be_nil }
47
+ its("group") { should be_nil }
48
+ its("user_data") { should be_nil }
49
+ its("ssh_key") { should be_nil }
50
+ its("ssh_user") { should be_nil }
51
+ its("vm_user") { should be_nil }
52
+ its("vm_password") { should be_nil }
53
+ its("private_ip_address") { should be_nil }
54
+ its("expunge_on_destroy") { should == false }
55
+ end
56
+
57
+ describe "getting credentials from environment" do
58
+ context "without Cosmic credential environment variables" do
59
+ subject do
60
+ instance.tap do |o|
61
+ o.finalize!
62
+ end
63
+ end
64
+
65
+ its("api_key") { should be_nil }
66
+ its("secret_key") { should be_nil }
67
+ end
68
+
69
+ context "with Cosmic credential variables" do
70
+ before :each do
71
+ allow(ENV).to receive(:[]).with("COSMIC_API_KEY").and_return("api_key")
72
+ allow(ENV).to receive(:[]).with("COSMIC_SECRET_KEY").and_return("secret_key")
73
+ end
74
+
75
+ subject do
76
+ instance.tap do |o|
77
+ o.finalize!
78
+ end
79
+ end
80
+
81
+ its("api_key") { should == "api_key" }
82
+ its("secret_key") { should == "secret_key" }
83
+ end
84
+ end
85
+
86
+ describe "overriding defaults" do
87
+ # I typically don't meta-program in tests, but this is a very
88
+ # simple boilerplate test, so I cut corners here. It just sets
89
+ # each of these attributes to "foo" in isolation, and reads the value
90
+ # and asserts the proper result comes back out.
91
+ [:api_key, :template_id, :zone_id, :instance_ready_timeout,
92
+ :service_offering_id, :disk_offering_id, :api_key,
93
+ :secret_key, :network_id, :user_data].each do |attribute|
94
+
95
+ it "should not default #{attribute} if overridden" do
96
+ instance.send("#{attribute}=".to_sym, "foo")
97
+ instance.finalize!
98
+ expect(instance.send(attribute)).to be =='foo'
99
+ end
100
+
101
+ end
102
+
103
+ it 'should not default pf_open_firewall if overridden' do
104
+ instance.pf_open_firewall = false
105
+ instance.finalize!
106
+
107
+ expect(instance.pf_open_firewall).to be false
108
+ end
109
+ end
110
+
111
+ describe "getting credentials from environment" do
112
+ context "without Cosmic credential environment variables" do
113
+ subject do
114
+ instance.tap do |o|
115
+ o.finalize!
116
+ end
117
+ end
118
+
119
+ its("api_key") { should be_nil }
120
+ its("secret_key") { should be_nil }
121
+ end
122
+
123
+ end
124
+
125
+ describe "domain config" do
126
+ let(:config_host) { "foo" }
127
+ let(:config_path) { "foo" }
128
+ let(:config_port) { "foo" }
129
+ let(:config_scheme) { "foo" }
130
+ let(:config_api_key) { "foo" }
131
+ let(:config_secret_key) { "foo" }
132
+ let(:config_instance_ready_timeout) { 11111 }
133
+ let(:config_domain_id) { "foo" }
134
+ let(:config_network_id) { "foo" }
135
+ let(:config_project_id) { "foo" }
136
+ let(:config_service_offering_id) { "foo" }
137
+ let(:config_disk_offering_id) { "foo" }
138
+ let(:config_template_id) { "foo" }
139
+ let(:config_zone_id) { "foo" }
140
+ let(:config_keypair) { "foo" }
141
+ let(:config_static_nat) { [{:foo => "bar"}, {:bar => "foo"}] }
142
+ let(:config_pf_ip_address_id) { "foo" }
143
+ let(:config_pf_ip_address) { "foo" }
144
+ let(:config_pf_public_port_randomrange) { {:start=>1, :end=>9} }
145
+ let(:config_pf_public_port) { "foo" }
146
+ let(:config_pf_public_rdp_port) { "foo" }
147
+ let(:config_pf_private_rdp_port) { "foo" }
148
+ let(:config_pf_private_port) { "foo" }
149
+ let(:config_pf_open_firewall) { false }
150
+ let(:config_pf_trusted_networks) { ["foo", "bar"] }
151
+ let(:config_port_forwarding_rules) { [{:foo => "bar"}, {:bar => "foo"}] }
152
+ let(:config_firewall_rules) { [{:foo => "bar"}, {:bar => "foo"}] }
153
+ let(:config_display_name) { "foo" }
154
+ let(:config_group) { "foo" }
155
+ let(:config_ssh_key) { "./foo.pem" }
156
+ let(:config_ssh_user) { "foo" }
157
+ let(:config_vm_user) { "foo" }
158
+ let(:config_vm_password) { "foo" }
159
+ let(:config_private_ip_address) { "foo" }
160
+ let(:config_expunge_on_destroy) { "foo" }
161
+
162
+ def set_test_values(instance)
163
+ instance.host = config_host
164
+ instance.path = config_path
165
+ instance.port = config_port
166
+ instance.scheme = config_scheme
167
+ instance.api_key = config_api_key
168
+ instance.secret_key = config_secret_key
169
+ instance.instance_ready_timeout = config_instance_ready_timeout
170
+ instance.domain_id = config_domain_id
171
+ instance.network_id = config_network_id
172
+ instance.project_id = config_project_id
173
+ instance.service_offering_id = config_service_offering_id
174
+ instance.disk_offering_id = config_disk_offering_id
175
+ instance.template_id = config_template_id
176
+ instance.zone_id = config_zone_id
177
+ instance.keypair = config_keypair
178
+ instance.static_nat = config_static_nat
179
+ instance.pf_ip_address_id = config_pf_ip_address_id
180
+ instance.pf_public_port_randomrange = config_pf_public_port_randomrange
181
+ instance.pf_ip_address = config_pf_ip_address
182
+ instance.pf_public_port = config_pf_public_port
183
+ instance.pf_public_rdp_port = config_pf_public_rdp_port
184
+ instance.pf_private_rdp_port = config_pf_private_rdp_port
185
+ instance.pf_private_port = config_pf_private_port
186
+ instance.pf_open_firewall = config_pf_open_firewall
187
+ instance.pf_trusted_networks = config_pf_trusted_networks
188
+ instance.port_forwarding_rules = config_port_forwarding_rules
189
+ instance.firewall_rules = config_firewall_rules
190
+ instance.display_name = config_display_name
191
+ instance.group = config_group
192
+ instance.ssh_key = config_ssh_key
193
+ instance.ssh_user = config_ssh_user
194
+ instance.vm_user = config_vm_user
195
+ instance.vm_password = config_vm_password
196
+ instance.private_ip_address = config_private_ip_address
197
+ instance.expunge_on_destroy = config_expunge_on_destroy
198
+ end
199
+
200
+ it "should raise an exception if not finalized" do
201
+ expect { instance.get_domain_config("default") }.
202
+ to raise_error(RuntimeError)
203
+ end
204
+
205
+ context "with no specific config set" do
206
+ subject do
207
+ # Set the values on the top-level object
208
+ set_test_values(instance)
209
+
210
+ # Finalize so we can get the domain config
211
+ instance.finalize!
212
+
213
+ # Get a lower level domain
214
+ instance.get_domain_config("default")
215
+ end
216
+
217
+ its("host") { should == config_host }
218
+ its("path") { should == config_path }
219
+ its("port") { should == config_port }
220
+ its("scheme") { should == config_scheme }
221
+ its("api_key") { should == config_api_key }
222
+ its("secret_key") { should == config_secret_key }
223
+ its("instance_ready_timeout") { should == config_instance_ready_timeout }
224
+ its("domain_id") { should == config_domain_id }
225
+ its("network_id") { should == config_network_id }
226
+ its("project_id") { should == config_project_id }
227
+ its("service_offering_id") { should == config_service_offering_id }
228
+ its("disk_offering_id") { should == config_disk_offering_id }
229
+ its("template_id") { should == config_template_id }
230
+ its("zone_id") { should == config_zone_id }
231
+ its("keypair") { should == config_keypair }
232
+ its("static_nat") { should == config_static_nat }
233
+ its("pf_ip_address_id") { should == config_pf_ip_address_id }
234
+ its("pf_ip_address") { should == config_pf_ip_address }
235
+ its("pf_public_port") { should == config_pf_public_port }
236
+ its("pf_public_rdp_port") { should == config_pf_public_rdp_port }
237
+ its("pf_private_rdp_port") { should == config_pf_private_rdp_port }
238
+ its("pf_public_port_randomrange") { should == config_pf_public_port_randomrange}
239
+ its("pf_private_port") { should == config_pf_private_port }
240
+ its("pf_trusted_networks") { should == config_pf_trusted_networks}
241
+ its("pf_open_firewall") { should == config_pf_open_firewall }
242
+ its("port_forwarding_rules") { should == config_port_forwarding_rules }
243
+ its("firewall_rules") { should == config_firewall_rules }
244
+ its("display_name") { should == config_display_name }
245
+ its("group") { should == config_group }
246
+ its("ssh_key") { should == config_ssh_key }
247
+ its("ssh_user") { should == config_ssh_user }
248
+ its("vm_user") { should == config_vm_user }
249
+ its("vm_password") { should == config_vm_password }
250
+ its("private_ip_address") { should == config_private_ip_address }
251
+ its("expunge_on_destroy") { should == config_expunge_on_destroy }
252
+ end
253
+
254
+ context "with a specific config set" do
255
+ let(:domain_name) { "hashi-domain" }
256
+
257
+ subject do
258
+ # Set the values on a specific domain
259
+ instance.domain_config domain_name do |config|
260
+ set_test_values(config)
261
+ end
262
+
263
+ # Finalize so we can get the domain config
264
+ instance.finalize!
265
+
266
+ # Get the domain
267
+ instance.get_domain_config(domain_name)
268
+ end
269
+
270
+ its("host") { should == config_host }
271
+ its("path") { should == config_path }
272
+ its("port") { should == config_port }
273
+ its("scheme") { should == config_scheme }
274
+ its("api_key") { should == config_api_key }
275
+ its("secret_key") { should == config_secret_key }
276
+ its("instance_ready_timeout") { should == config_instance_ready_timeout }
277
+ its("domain_id") { should == config_domain_id }
278
+ its("network_id") { should == config_network_id }
279
+ its("project_id") { should == config_project_id }
280
+ its("service_offering_id") { should == config_service_offering_id }
281
+ its("disk_offering_id") { should == config_disk_offering_id }
282
+ its("template_id") { should == config_template_id }
283
+ its("zone_id") { should == config_zone_id }
284
+ its("keypair") { should == config_keypair }
285
+ its("static_nat") { should == config_static_nat }
286
+ its("pf_ip_address_id") { should == config_pf_ip_address_id }
287
+ its("pf_ip_address") { should == config_pf_ip_address }
288
+ its("pf_public_port") { should == config_pf_public_port }
289
+ its("pf_public_rdp_port") { should == config_pf_public_rdp_port }
290
+ its("pf_private_rdp_port") { should == config_pf_private_rdp_port }
291
+ its("pf_public_port_randomrange") { should == config_pf_public_port_randomrange}
292
+ its("pf_private_port") { should == config_pf_private_port }
293
+ its("pf_open_firewall") { should == config_pf_open_firewall }
294
+ its("pf_trusted_networks") { should == config_pf_trusted_networks}
295
+ its("port_forwarding_rules") { should == config_port_forwarding_rules }
296
+ its("firewall_rules") { should == config_firewall_rules }
297
+ its("display_name") { should == config_display_name }
298
+ its("group") { should == config_group }
299
+ its("ssh_key") { should == config_ssh_key }
300
+ its("ssh_user") { should == config_ssh_user }
301
+ its("vm_user") { should == config_vm_user }
302
+ its("vm_password") { should == config_vm_password }
303
+ its("private_ip_address") { should == config_private_ip_address }
304
+ its("expunge_on_destroy") { should == config_expunge_on_destroy }
305
+ end
306
+
307
+ describe "inheritance of parent config" do
308
+ let(:domain_name) { "hashi-domain" }
309
+
310
+ subject do
311
+ # Set the values on a specific domain
312
+ instance.domain_config domain_name do |config|
313
+ config.template_id = "child"
314
+ end
315
+
316
+ # Set some top-level values
317
+ instance.api_key = "parent"
318
+ instance.template_id = "parent"
319
+
320
+ # Finalize and get the domain
321
+ instance.finalize!
322
+ instance.get_domain_config(domain_name)
323
+ end
324
+
325
+ its("api_key") { should == "parent" }
326
+ its("template_id") { should == "child" }
327
+ end
328
+
329
+ describe "shortcut configuration" do
330
+ subject do
331
+ # Use the shortcut configuration to set some values
332
+ instance.domain_config "Domain1", :template_id => "child"
333
+ instance.finalize!
334
+ instance.get_domain_config("Domain1")
335
+ end
336
+
337
+ its("template_id") { should == "child" }
338
+ end
339
+ end
340
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-cosmic/model/cosmic_resource'
3
+
4
+ include VagrantPlugins::Cosmic::Model
5
+
6
+ describe CosmicResource do
7
+ context 'when all attribtues are defined' do
8
+ let(:resource) { CosmicResource.new('id', 'name', 'kind') }
9
+
10
+ describe '#to_s' do
11
+ it 'prints the resource with all attributes' do
12
+ expect(resource.to_s).to be_eql 'kind - id:name'
13
+ end
14
+ end
15
+
16
+ describe '#is_undefined?' do
17
+ it { expect(resource.is_undefined?).to be_eql false }
18
+ end
19
+
20
+ describe '#is_id_undefined?' do
21
+ it { expect(resource.is_id_undefined?).to be_eql false }
22
+ end
23
+
24
+ describe '#is_name_undefined?' do
25
+ it { expect(resource.is_name_undefined?).to be_eql false }
26
+ end
27
+ end
28
+
29
+ context 'when kind is not defined' do
30
+ describe '#new' do
31
+ it 'raises an error when kind is nil' do
32
+ expect { CosmicResource.new('id', 'name', nil) }.to raise_error('Resource must have a kind')
33
+ end
34
+
35
+ it 'raises an error when kind is empty' do
36
+ expect { CosmicResource.new('id', 'name', '') }.to raise_error('Resource must have a kind')
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#is_undefined?' do
42
+ it { expect(CosmicResource.new('', '', 'kind').is_undefined?).to be_eql true }
43
+ it { expect(CosmicResource.new(nil, '', 'kind').is_undefined?).to be_eql true }
44
+ it { expect(CosmicResource.new('', nil, 'kind').is_undefined?).to be_eql true }
45
+ it { expect(CosmicResource.new(nil, nil, 'kind').is_undefined?).to be_eql true }
46
+ it { expect(CosmicResource.new('id', nil, 'kind').is_undefined?).to be_eql false }
47
+ it { expect(CosmicResource.new(nil, 'name', 'kind').is_undefined?).to be_eql false }
48
+ it { expect(CosmicResource.new('id', '', 'kind').is_undefined?).to be_eql false }
49
+ it { expect(CosmicResource.new('', 'name', 'kind').is_undefined?).to be_eql false }
50
+ end
51
+
52
+ describe '#is_id_undefined?' do
53
+ it { expect(CosmicResource.new('', 'name', 'kind').is_id_undefined?).to be_eql true }
54
+ it { expect(CosmicResource.new(nil, 'name', 'kind').is_id_undefined?).to be_eql true }
55
+ it { expect(CosmicResource.new('', '', 'kind').is_id_undefined?).to be_eql true }
56
+ it { expect(CosmicResource.new(nil, '', 'kind').is_id_undefined?).to be_eql true }
57
+ it { expect(CosmicResource.new('', nil, 'kind').is_id_undefined?).to be_eql true }
58
+ it { expect(CosmicResource.new(nil, nil, 'kind').is_id_undefined?).to be_eql true }
59
+ it { expect(CosmicResource.new('id', nil, 'kind').is_id_undefined?).to be_eql false }
60
+ it { expect(CosmicResource.new('id', '', 'kind').is_id_undefined?).to be_eql false }
61
+ end
62
+
63
+ describe '#is_name_undefined?' do
64
+ it { expect(CosmicResource.new('id', '', 'kind').is_name_undefined?).to be_eql true }
65
+ it { expect(CosmicResource.new('id', nil, 'kind').is_name_undefined?).to be_eql true }
66
+ it { expect(CosmicResource.new('', '', 'kind').is_name_undefined?).to be_eql true }
67
+ it { expect(CosmicResource.new(nil, '', 'kind').is_name_undefined?).to be_eql true }
68
+ it { expect(CosmicResource.new('', nil, 'kind').is_name_undefined?).to be_eql true }
69
+ it { expect(CosmicResource.new(nil, nil, 'kind').is_name_undefined?).to be_eql true }
70
+ it { expect(CosmicResource.new(nil, 'name', 'kind').is_name_undefined?).to be_eql false }
71
+ it { expect(CosmicResource.new('', 'name', 'kind').is_name_undefined?).to be_eql false }
72
+ end
73
+
74
+ describe '#create_id_list' do
75
+ subject { CosmicResource.create_id_list(ids, kind) }
76
+
77
+ let(:kind) { 'network' }
78
+ let(:ids) { %w(id1 id2) }
79
+
80
+ its(:count) { should eq 2 }
81
+ its([0]) { should be_a_resource('id1', nil, kind) }
82
+ its([1]) { should be_a_resource('id2', nil, kind) }
83
+ end
84
+
85
+ describe '#create_name_list' do
86
+ subject { CosmicResource.create_name_list(names, kind) }
87
+
88
+ let(:kind) { 'network' }
89
+ let(:names) { %w(name1 name2) }
90
+
91
+ its(:count) { should eq 2 }
92
+ its([0]) { should be_a_resource(nil, 'name1', kind) }
93
+ its([1]) { should be_a_resource(nil, 'name2', kind) }
94
+ end
95
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-cosmic/model/cosmic_resource'
3
+ require 'vagrant-cosmic/service/cosmic_resource_service'
4
+
5
+ include VagrantPlugins::Cosmic::Model
6
+ include VagrantPlugins::Cosmic::Service
7
+
8
+ describe CosmicResourceService do
9
+ let(:cosmic_compute) { double('Fog::Cosmic::Compute') }
10
+ let(:ui) { double('Vagrant::UI') }
11
+ let(:service) { CosmicResourceService.new(cosmic_compute, ui) }
12
+
13
+ before do
14
+ response = {
15
+ 'listkindsresponse' => {
16
+ 'kind' => [{ 'id' => 'resource id', 'name' => 'resource name' }]
17
+ }
18
+ }
19
+ allow(cosmic_compute).to receive(:send).with(:list_kinds, { 'id' => 'resource id' }).and_return(response)
20
+ allow(cosmic_compute).to receive(:send).with(:list_kinds, {}).and_return(response)
21
+
22
+ allow(ui).to receive(:detail)
23
+ allow(ui).to receive(:info)
24
+ end
25
+
26
+ describe '#sync_resource' do
27
+ it 'retrives the missing name' do
28
+ resource = CosmicResource.new('resource id', nil, 'kind')
29
+ service.sync_resource(resource)
30
+
31
+ expect(resource.name).to be_eql 'resource name'
32
+ expect(resource.id).to be_eql 'resource id'
33
+ end
34
+
35
+ it 'retrives the missing id' do
36
+ resource = CosmicResource.new(nil, 'resource name', 'kind')
37
+ service.sync_resource(resource)
38
+
39
+ expect(resource.id).to be_eql 'resource id'
40
+ expect(resource.name).to be_eql 'resource name'
41
+ end
42
+ end
43
+ end