squall 1.0.2 → 1.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 (170) hide show
  1. data/.gitignore +3 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +1 -1
  4. data/.rvmrc +41 -1
  5. data/.travis.yml +13 -3
  6. data/README.md +122 -27
  7. data/Rakefile +5 -34
  8. data/lib/squall/data_store_zone.rb +58 -0
  9. data/lib/squall/firewall_rule.rb +66 -0
  10. data/lib/squall/hypervisor.rb +63 -11
  11. data/lib/squall/hypervisor_zone.rb +135 -0
  12. data/lib/squall/ip_address.rb +50 -3
  13. data/lib/squall/ip_address_join.rb +46 -0
  14. data/lib/squall/network.rb +21 -4
  15. data/lib/squall/network_zone.rb +73 -0
  16. data/lib/squall/payment.rb +59 -0
  17. data/lib/squall/role.rb +28 -11
  18. data/lib/squall/statistic.rb +3 -3
  19. data/lib/squall/{base.rb → support/base.rb} +8 -4
  20. data/lib/squall/{config.rb → support/config.rb} +4 -0
  21. data/lib/squall/{exception.rb → support/exception.rb} +0 -0
  22. data/lib/squall/{params.rb → support/params.rb} +0 -0
  23. data/lib/squall/support/version.rb +3 -0
  24. data/lib/squall/support/yaml.rb +5 -0
  25. data/lib/squall/template.rb +4 -0
  26. data/lib/squall/transaction.rb +4 -0
  27. data/lib/squall/user.rb +126 -30
  28. data/lib/squall/user_group.rb +56 -0
  29. data/lib/squall/virtual_machine.rb +176 -52
  30. data/lib/squall/whitelist.rb +74 -0
  31. data/lib/squall.rb +21 -12
  32. data/spec/spec_helper.rb +21 -16
  33. data/spec/squall/data_store_zone_spec.rb +97 -0
  34. data/spec/squall/firewall_rule_spec.rb +112 -0
  35. data/spec/squall/hypervisor_spec.rb +101 -48
  36. data/spec/squall/hypervisor_zone_spec.rb +190 -0
  37. data/spec/squall/ip_address_join_spec.rb +67 -0
  38. data/spec/squall/ip_address_spec.rb +68 -6
  39. data/spec/squall/network_spec.rb +0 -1
  40. data/spec/squall/network_zone_spec.rb +147 -0
  41. data/spec/squall/payment_spec.rb +98 -0
  42. data/spec/squall/role_spec.rb +31 -46
  43. data/spec/squall/statistic_spec.rb +7 -9
  44. data/spec/squall/{base_spec.rb → support/base_spec.rb} +5 -7
  45. data/spec/squall/{config_spec.rb → support/config_spec.rb} +0 -0
  46. data/spec/{params_spec.rb → squall/support/params_spec.rb} +0 -0
  47. data/spec/squall/template_spec.rb +0 -1
  48. data/spec/squall/transaction_spec.rb +0 -1
  49. data/spec/squall/user_group_spec.rb +74 -0
  50. data/spec/squall/user_spec.rb +142 -59
  51. data/spec/squall/virtual_machine_spec.rb +179 -67
  52. data/spec/squall/whitelist_spec.rb +113 -0
  53. data/spec/squall_spec.rb +4 -8
  54. data/spec/vcr_cassettes/data_store_zone/create.yml +40 -0
  55. data/spec/vcr_cassettes/data_store_zone/delete.yml +77 -0
  56. data/spec/vcr_cassettes/data_store_zone/edit.yml +77 -0
  57. data/spec/vcr_cassettes/data_store_zone/list.yml +40 -0
  58. data/spec/vcr_cassettes/data_store_zone/show.yml +77 -0
  59. data/spec/vcr_cassettes/firewall_rule/create.yml +75 -0
  60. data/spec/vcr_cassettes/firewall_rule/delete.yml +75 -0
  61. data/spec/vcr_cassettes/firewall_rule/edit.yml +75 -0
  62. data/spec/vcr_cassettes/firewall_rule/list.yml +40 -0
  63. data/spec/vcr_cassettes/hypervisor/add_data_store_join.yml +40 -0
  64. data/spec/vcr_cassettes/hypervisor/add_network_join.yml +40 -0
  65. data/spec/vcr_cassettes/hypervisor/create.yml +7 -44
  66. data/spec/vcr_cassettes/hypervisor/data_store_joins.yml +40 -0
  67. data/spec/vcr_cassettes/hypervisor/delete.yml +11 -11
  68. data/spec/vcr_cassettes/hypervisor/edit.yml +7 -46
  69. data/spec/vcr_cassettes/hypervisor/list.yml +7 -7
  70. data/spec/vcr_cassettes/hypervisor/network_joins.yml +40 -0
  71. data/spec/vcr_cassettes/hypervisor/reboot.yml +13 -13
  72. data/spec/vcr_cassettes/hypervisor/remove_data_store_join.yml +40 -0
  73. data/spec/vcr_cassettes/hypervisor/remove_network_join.yml +40 -0
  74. data/spec/vcr_cassettes/hypervisor/show.yml +13 -13
  75. data/spec/vcr_cassettes/hypervisor_zones/add_data_store_join.yml +40 -0
  76. data/spec/vcr_cassettes/hypervisor_zones/add_network_join.yml +40 -0
  77. data/spec/vcr_cassettes/hypervisor_zones/create.yml +40 -0
  78. data/spec/vcr_cassettes/hypervisor_zones/data_store_joins.yml +40 -0
  79. data/spec/vcr_cassettes/hypervisor_zones/delete.yml +77 -0
  80. data/spec/vcr_cassettes/hypervisor_zones/edit.yml +77 -0
  81. data/spec/vcr_cassettes/hypervisor_zones/hypervisors.yml +40 -0
  82. data/spec/vcr_cassettes/hypervisor_zones/list.yml +40 -0
  83. data/spec/vcr_cassettes/hypervisor_zones/network_joins.yml +40 -0
  84. data/spec/vcr_cassettes/hypervisor_zones/remove_data_store_join.yml +40 -0
  85. data/spec/vcr_cassettes/hypervisor_zones/remove_network_join.yml +40 -0
  86. data/spec/vcr_cassettes/hypervisor_zones/show.yml +77 -0
  87. data/spec/vcr_cassettes/ipaddress/create.yml +40 -0
  88. data/spec/vcr_cassettes/ipaddress/delete.yml +40 -0
  89. data/spec/vcr_cassettes/ipaddress/edit.yml +40 -0
  90. data/spec/vcr_cassettes/ipaddress/list.yml +17 -17
  91. data/spec/vcr_cassettes/ipaddress_join/assign.yml +77 -0
  92. data/spec/vcr_cassettes/ipaddress_join/delete.yml +77 -0
  93. data/spec/vcr_cassettes/ipaddress_join/list.yml +77 -0
  94. data/spec/vcr_cassettes/network/create.yml +15 -15
  95. data/spec/vcr_cassettes/network/delete.yml +6 -6
  96. data/spec/vcr_cassettes/network/edit.yml +18 -18
  97. data/spec/vcr_cassettes/network/list.yml +3 -3
  98. data/spec/vcr_cassettes/network_zones/attach.yml +114 -0
  99. data/spec/vcr_cassettes/network_zones/create.yml +40 -0
  100. data/spec/vcr_cassettes/network_zones/delete.yml +77 -0
  101. data/spec/vcr_cassettes/network_zones/detach.yml +114 -0
  102. data/spec/vcr_cassettes/network_zones/edit.yml +77 -0
  103. data/spec/vcr_cassettes/network_zones/list.yml +40 -0
  104. data/spec/vcr_cassettes/network_zones/show.yml +77 -0
  105. data/spec/vcr_cassettes/payment/create.yml +78 -0
  106. data/spec/vcr_cassettes/payment/delete.yml +77 -0
  107. data/spec/vcr_cassettes/payment/edit.yml +77 -0
  108. data/spec/vcr_cassettes/payment/list.yml +41 -0
  109. data/spec/vcr_cassettes/role/create.yml +7 -44
  110. data/spec/vcr_cassettes/role/delete.yml +6 -6
  111. data/spec/vcr_cassettes/role/edit.yml +13 -75
  112. data/spec/vcr_cassettes/role/list.yml +7 -7
  113. data/spec/vcr_cassettes/role/permissions.yml +7 -7
  114. data/spec/vcr_cassettes/role/show.yml +13 -13
  115. data/spec/vcr_cassettes/statistic/usage_statistics.yml +7 -7
  116. data/spec/vcr_cassettes/template/list.yml +3 -3
  117. data/spec/vcr_cassettes/template/make_public.yml +6 -6
  118. data/spec/vcr_cassettes/transaction/list.yml +3 -3
  119. data/spec/vcr_cassettes/transaction/show.yml +6 -6
  120. data/spec/vcr_cassettes/user/activate.yml +7 -7
  121. data/spec/vcr_cassettes/user/create.yml +7 -83
  122. data/spec/vcr_cassettes/user/data_store_zones.yml +79 -0
  123. data/spec/vcr_cassettes/user/delete.yml +11 -11
  124. data/spec/vcr_cassettes/user/edit.yml +40 -0
  125. data/spec/vcr_cassettes/user/edit_role.yml +9 -9
  126. data/spec/vcr_cassettes/user/generate_api_key.yml +7 -7
  127. data/spec/vcr_cassettes/user/hypervisors.yml +77 -0
  128. data/spec/vcr_cassettes/user/limits.yml +77 -0
  129. data/spec/vcr_cassettes/user/list.yml +8 -8
  130. data/spec/vcr_cassettes/user/monthly_bills.yml +40 -0
  131. data/spec/vcr_cassettes/user/network_zones.yml +79 -0
  132. data/spec/vcr_cassettes/user/show.yml +29 -29
  133. data/spec/vcr_cassettes/user/stats.yml +6 -6
  134. data/spec/vcr_cassettes/user/suspend.yml +7 -7
  135. data/spec/vcr_cassettes/user/virtual_machines.yml +18 -20
  136. data/spec/vcr_cassettes/user_group/create.yml +40 -0
  137. data/spec/vcr_cassettes/user_group/delete.yml +77 -0
  138. data/spec/vcr_cassettes/user_group/edit.yml +77 -0
  139. data/spec/vcr_cassettes/user_group/list.yml +40 -0
  140. data/spec/vcr_cassettes/virtual_machine/build.yml +7 -7
  141. data/spec/vcr_cassettes/virtual_machine/change_owner.yml +8 -8
  142. data/spec/vcr_cassettes/virtual_machine/change_password.yml +13 -13
  143. data/spec/vcr_cassettes/virtual_machine/console.yml +63 -0
  144. data/spec/vcr_cassettes/virtual_machine/create.yml +9 -11
  145. data/spec/vcr_cassettes/virtual_machine/delete.yml +11 -11
  146. data/spec/vcr_cassettes/virtual_machine/edit.yml +16 -18
  147. data/spec/vcr_cassettes/virtual_machine/list.yml +3 -3
  148. data/spec/vcr_cassettes/virtual_machine/migrate.yml +22 -24
  149. data/spec/vcr_cassettes/virtual_machine/reboot.yml +22 -22
  150. data/spec/vcr_cassettes/virtual_machine/resize.yml +13 -13
  151. data/spec/vcr_cassettes/virtual_machine/segregate.yml +114 -0
  152. data/spec/vcr_cassettes/virtual_machine/set_ssh_keys.yml +77 -0
  153. data/spec/vcr_cassettes/virtual_machine/set_vip.yml +77 -0
  154. data/spec/vcr_cassettes/virtual_machine/show.yml +6 -6
  155. data/spec/vcr_cassettes/virtual_machine/shutdown.yml +6 -6
  156. data/spec/vcr_cassettes/virtual_machine/startup.yml +6 -6
  157. data/spec/vcr_cassettes/virtual_machine/stats.yml +63 -0
  158. data/spec/vcr_cassettes/virtual_machine/stop.yml +22 -22
  159. data/spec/vcr_cassettes/virtual_machine/suspend.yml +13 -13
  160. data/spec/vcr_cassettes/virtual_machine/unlock.yml +13 -13
  161. data/spec/vcr_cassettes/virtual_machine/unsuspend.yml +6 -6
  162. data/spec/vcr_cassettes/whitelist/create.yml +77 -0
  163. data/spec/vcr_cassettes/whitelist/delete.yml +77 -0
  164. data/spec/vcr_cassettes/whitelist/edit.yml +77 -0
  165. data/spec/vcr_cassettes/whitelist/list.yml +40 -0
  166. data/spec/vcr_cassettes/whitelist/show.yml +77 -0
  167. data/squall.gemspec +3 -2
  168. metadata +247 -131
  169. data/Gemfile.lock +0 -100
  170. data/lib/squall/version.rb +0 -3
@@ -2,10 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe Squall::VirtualMachine do
4
4
  before(:each) do
5
- default_config
6
5
  @virtual_machine = Squall::VirtualMachine.new
7
- @valid = {:label => 'testmachine', :hypervisor_id => 5, :hostname => 'testmachine', :memory => 512, :cpus => 1,
8
- :cpu_shares => 10, :primary_disk_size => 10}
6
+ @valid = {:label => 'testmachine', :hostname => 'testmachine', :memory => 512, :cpus => 1,
7
+ :cpu_shares => 10, :primary_disk_size => 10, :template_id => 1}
9
8
  @keys = ["monthly_bandwidth_used", "cpus", "label", "created_at", "operating_system_distro",
10
9
  "cpu_shares", "operating_system", "template_id", "allowed_swap", "local_remote_access_port",
11
10
  "memory", "updated_at", "allow_resize_without_reboot", "recovery_mode", "hypervisor_id", "id",
@@ -52,54 +51,48 @@ describe Squall::VirtualMachine do
52
51
  requires_attr(:label) { @virtual_machine.create }
53
52
  end
54
53
 
55
- it "requires hypervisor_id" do
56
- requires_attr(:hypervisor_id) { @virtual_machine.create(:label => @valid[:label]) }
57
- end
58
-
59
54
  it "requires hostname" do
60
55
  requires_attr(:hostname) {
61
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id])
56
+ @virtual_machine.create(:label => @valid[:label])
62
57
  }
63
58
  end
64
59
 
65
60
  it "requires memory" do
66
61
  requires_attr(:memory) {
67
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id], :hostname => @valid[:hostname])
62
+ @virtual_machine.create(:label => @valid[:label], :hostname => @valid[:hostname])
68
63
  }
69
64
  end
70
65
 
71
66
  it "requires cpus" do
72
67
  requires_attr(:cpus) {
73
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id], :hostname => @valid[:hostname],
68
+ @virtual_machine.create(:label => @valid[:label], :hostname => @valid[:hostname],
74
69
  :memory => @valid[:memory])
75
70
  }
76
71
  end
77
72
 
78
73
  it "requires cpu_shares" do
79
74
  requires_attr(:cpu_shares) {
80
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id], :hostname => @valid[:hostname],
75
+ @virtual_machine.create(:label => @valid[:label], :hostname => @valid[:hostname],
81
76
  :memory => @valid[:memory], :cpus => @valid[:cpu_shares])
82
77
  }
83
78
  end
84
79
 
85
80
  it "requires primary_disk_size" do
86
81
  requires_attr(:primary_disk_size) {
87
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id],
88
- :hostname => @valid[:hostname], :memory => @valid[:memory], :cpus => @valid[:cpu_shares],
82
+ @virtual_machine.create(:label => @valid[:label], :hostname => @valid[:hostname],
83
+ :memory => @valid[:memory], :cpus => @valid[:cpu_shares],
89
84
  :cpu_shares => @valid[:cpu_shares])
90
85
  }
91
86
  end
92
87
 
93
88
  it "raises error on unknown params" do
94
89
  expect {
95
- @virtual_machine.create(:label => @valid[:label], :hypervisor_id => @valid[:hypervisor_id], :hostname => @valid[:hostname],
96
- :memory => @valid[:memory], :cpus => @valid[:cpus], :cpu_shares => @valid[:cpu_shares], :what => 'what')
97
- }.to raise_error(ArgumentError, 'Missing required params: primary_disk_size')
90
+ @virtual_machine.create(@valid.merge(:what => 'what'))
91
+ }.to raise_error(ArgumentError, 'Unknown params: what')
98
92
  end
99
93
 
100
94
  it "allows all optional params" do
101
- optional = [:cpu_shares,
102
- :swap_disk_size,
95
+ optional = [:swap_disk_size,
103
96
  :primary_network_id,
104
97
  :required_automatic_backup,
105
98
  :rate_limit,
@@ -108,20 +101,22 @@ describe Squall::VirtualMachine do
108
101
  :admin_note,
109
102
  :note,
110
103
  :allowed_hot_migrate,
111
- :template_id,
104
+ :hypervisor_id,
112
105
  :initial_root_password
113
106
  ]
114
107
 
115
108
  @virtual_machine.should_receive(:request).exactly(optional.size).times.and_return Hash.new('virtual_machine' => [])
116
- optional.each do |k,v|
117
- @virtual_machine.create(@valid.merge(k.to_sym => v))
109
+ optional.each do |param|
110
+ @virtual_machine.create(@valid.merge(param => "test"))
118
111
  end
119
112
  end
120
113
 
121
114
  it "creates a virtual_machine" do
122
- virtual_machine = @virtual_machine.create(@valid)
123
- @valid.each do |k,v|
124
- virtual_machine[k].should == @valid[k.to_s]
115
+ pending "broken in OnApp (triggering the Network Interfaces error): see README (and update when fixed)" do
116
+ virtual_machine = @virtual_machine.create(@valid)
117
+ @valid.each do |k,v|
118
+ virtual_machine[k].should == @valid[k.to_s]
119
+ end
125
120
  end
126
121
  end
127
122
  end
@@ -140,20 +135,19 @@ describe Squall::VirtualMachine do
140
135
  end
141
136
 
142
137
  it "raises error on unknown params" do
143
- expect { @virtual_machine.build(1, :asdf => 1) }.to raise_error(ArgumentError, 'Unknown params: asdf')
138
+ expect { @virtual_machine.build(1, :template_id => 1, :asdf => 1) }.to raise_error(ArgumentError, 'Unknown params: asdf')
144
139
  @virtual_machine.success.should be_false
145
140
  end
146
141
 
147
142
  it "returns not found for invalid virtual_machines" do
148
- expect { @virtual_machine.build(404) }.to raise_error(Squall::NotFound)
143
+ expect { @virtual_machine.build(404, :template_id => 1) }.to raise_error(Squall::NotFound)
149
144
  @virtual_machine.success.should be_false
150
145
  end
151
146
 
152
147
  it "builds the VM" do
153
- build = @virtual_machine.build(72)
148
+ build = @virtual_machine.build(72, :template_id => 1)
154
149
 
155
150
  @virtual_machine.success.should be_true
156
- build['label'].should == 'Testingagain'
157
151
  end
158
152
  end
159
153
 
@@ -226,9 +220,11 @@ describe Squall::VirtualMachine do
226
220
  @virtual_machine.success.should be_false
227
221
  end
228
222
 
229
- it "returns error on unknown user" do
230
- expect { @virtual_machine.change_owner(1, 404) }.to raise_error(Squall::ServerError)
231
- @virtual_machine.success.should be_false
223
+ pending "this should raise a 422 on OnApp's side, but it's currently raising a 500 which causes HTTParty to explode, see README (and update when fixed)" do
224
+ it "returns error on unknown user" do
225
+ expect { @virtual_machine.change_owner(1, 2) }.to raise_error(Squall::ServerError)
226
+ @virtual_machine.success.should be_false
227
+ end
232
228
  end
233
229
 
234
230
  it "changes the user" do
@@ -261,6 +257,24 @@ describe Squall::VirtualMachine do
261
257
  @virtual_machine.success.should be_true
262
258
  end
263
259
  end
260
+
261
+ describe "#set_ssh_keys" do
262
+ use_vcr_cassette "virtual_machine/set_ssh_keys"
263
+ it "requires an id" do
264
+ expect { @virtual_machine.set_ssh_keys }.to raise_error(ArgumentError)
265
+ @virtual_machine.success.should be_false
266
+ end
267
+
268
+ it "404s on not found" do
269
+ expect { @virtual_machine.set_ssh_keys(404) }.to raise_error(Squall::NotFound)
270
+ @virtual_machine.success.should be_false
271
+ end
272
+
273
+ it "sets the SSH keys" do
274
+ result = @virtual_machine.set_ssh_keys(1)
275
+ @virtual_machine.success.should be_true
276
+ end
277
+ end
264
278
 
265
279
  describe "#migrate" do
266
280
  use_vcr_cassette "virtual_machine/migrate"
@@ -275,7 +289,7 @@ describe Squall::VirtualMachine do
275
289
  end
276
290
 
277
291
  it "accepts cold_migrate_on_rollback" do
278
- hash = [:post, "/virtual_machines/1/migrate.json", {:query => {:destination => 1, :cold_migrate_on_rollback => 1} }]
292
+ hash = [:post, "/virtual_machines/1/migrate.json", {:query => {:virtual_machine => {:destination => 1, :cold_migrate_on_rollback => 1}} }]
279
293
  @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
280
294
  @virtual_machine.migrate 1, :destination => 1, :cold_migrate_on_rollback => 1
281
295
  end
@@ -285,18 +299,40 @@ describe Squall::VirtualMachine do
285
299
  @virtual_machine.success.should be_false
286
300
  end
287
301
 
288
- it "returns error on unknown destination" do
289
- pending "Broken in OnApp" do
290
- expect { @virtual_machine.migrate(1, :destination => 404) }.to raise_error(Squall::ServerError)
302
+ it "404s on unknown destination" do
303
+ expect { @virtual_machine.migrate(1, :destination => 404) }.to raise_error(Squall::NotFound)
291
304
  @virtual_machine.success.should be_false
292
- end
293
305
  end
294
306
 
295
- it "changes the destination" do
307
+ it "changes the hypervisor" do
296
308
  pending "Broken in OnApp" do
297
309
  result = @virtual_machine.migrate(1, :destination => 2)
298
310
  @virtual_machine.success.should be_true
299
- result['hypervisor_id'].should == 2
311
+ result['virtual_machine']['hypervisor_id'].should == 2
312
+ end
313
+ end
314
+ end
315
+
316
+ describe "#set_vip" do
317
+ use_vcr_cassette "virtual_machine/set_vip"
318
+ it "requires an id" do
319
+ expect { @virtual_machine.set_vip }.to raise_error(ArgumentError)
320
+ end
321
+
322
+ it "returns not found for invalid virtual_machines" do
323
+ expect { @virtual_machine.set_vip(404) }.to raise_error(Squall::NotFound)
324
+ end
325
+
326
+ it "deletes a virtual_machine" do
327
+ @virtual_machine.set_vip(1)
328
+ @virtual_machine.success.should be_true
329
+ end
330
+
331
+ it "sets the vip status to false if currently true" do
332
+ pending "No way to actually test this without being able to interact with server state" do
333
+ result = @virtual_machine.set_vip(1)
334
+ result['virtual_machine']['vip'].should be_false
335
+ flunk("currently untestable, so make sure it doesn't pass by accident")
300
336
  end
301
337
  end
302
338
  end
@@ -312,7 +348,7 @@ describe Squall::VirtualMachine do
312
348
  end
313
349
 
314
350
  it "deletes a virtual_machine" do
315
- virtual_machine = @virtual_machine.delete(2)
351
+ virtual_machine = @virtual_machine.delete(1)
316
352
  @virtual_machine.success.should be_true
317
353
  end
318
354
  end
@@ -326,24 +362,41 @@ describe Squall::VirtualMachine do
326
362
  it "returns not found for invalid virtual_machines" do
327
363
  expect { @virtual_machine.resize(404, :memory => 1) }.to raise_error(Squall::NotFound)
328
364
  end
329
-
330
- it "requires memory" do
331
- @virtual_machine.stub(:request)
332
- requires_attr(:memory) { @virtual_machine.resize(1) }
365
+
366
+ it "accepts memory" do
367
+ hash = [:post, "/virtual_machines/1/resize.json", @virtual_machine.default_params(:memory => 1)]
368
+ @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
369
+ @virtual_machine.resize 1, :memory => 1
333
370
  end
334
-
335
- it "accepts allow_migration" do
336
- hash = [:post, "/virtual_machines/1/resize.json", @virtual_machine.default_params(:memory => 1, :allow_migration => 1)]
371
+
372
+ it "accepts cpus" do
373
+ hash = [:post, "/virtual_machines/1/resize.json", @virtual_machine.default_params(:cpus => 1)]
374
+ @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
375
+ @virtual_machine.resize 1, :cpus => 1
376
+ end
377
+
378
+ it "accepts cpu_shares" do
379
+ hash = [:post, "/virtual_machines/1/resize.json", @virtual_machine.default_params(:cpu_shares => 1)]
380
+ @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
381
+ @virtual_machine.resize 1, :cpu_shares => 1
382
+ end
383
+
384
+ it "accepts allow_cold_resize" do
385
+ hash = [:post, "/virtual_machines/1/resize.json", @virtual_machine.default_params(:allow_cold_resize => 1)]
337
386
  @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
338
- @virtual_machine.resize 1, :memory => 1, :allow_migration => 1
387
+ @virtual_machine.resize 1, :allow_cold_resize => 1
339
388
  end
340
389
 
341
390
  it "resizes a virtual_machine" do
342
- virtual_machine = @virtual_machine.resize(2, :memory => 1000)
391
+ virtual_machine = @virtual_machine.resize(1, :memory => 1000)
343
392
  @virtual_machine.success.should be_true
344
393
 
345
394
  virtual_machine['memory'].should == 1000
346
395
  end
396
+
397
+ it "requires at least one option" do
398
+ expect { @virtual_machine.resize(1) }.to raise_error(ArgumentError)
399
+ end
347
400
  end
348
401
 
349
402
  describe "#suspend" do
@@ -362,22 +415,6 @@ describe Squall::VirtualMachine do
362
415
  end
363
416
  end
364
417
 
365
- describe "#unsuspend" do
366
- use_vcr_cassette "virtual_machine/unsuspend"
367
- it "requires an id" do
368
- expect { @virtual_machine.unsuspend }.to raise_error(ArgumentError)
369
- end
370
-
371
- it "returns not found for invalid virtual_machines" do
372
- expect { @virtual_machine.unsuspend(404) }.to raise_error(Squall::NotFound)
373
- end
374
-
375
- it "unsuspends a virtual_machine" do
376
- virtual_machine = @virtual_machine.unsuspend(1)
377
- virtual_machine['suspended'].should be_false
378
- end
379
- end
380
-
381
418
  describe "#unlock" do
382
419
  use_vcr_cassette "virtual_machine/unlock"
383
420
  it "requires an id" do
@@ -427,7 +464,6 @@ describe Squall::VirtualMachine do
427
464
  it "will shutdown a virtual_machine" do
428
465
  virtual_machine = @virtual_machine.shutdown(1)
429
466
  @virtual_machine.success.should be_true
430
- virtual_machine['id'].should == 1
431
467
  end
432
468
  end
433
469
 
@@ -446,7 +482,6 @@ describe Squall::VirtualMachine do
446
482
  it "will stop a virtual_machine" do
447
483
  virtual_machine = @virtual_machine.stop(1)
448
484
  @virtual_machine.success.should be_true
449
- virtual_machine['id'].should == 1
450
485
  end
451
486
  end
452
487
 
@@ -465,7 +500,84 @@ describe Squall::VirtualMachine do
465
500
  it "will reboot a virtual_machine" do
466
501
  virtual_machine = @virtual_machine.reboot(1)
467
502
  @virtual_machine.success.should be_true
468
- virtual_machine['id'].should == 1
503
+ end
504
+
505
+ it "reboots in recovery" do
506
+ hash = [:post, "/virtual_machines/1/reboot.json", {:query => {:mode => :recovery}}]
507
+ @virtual_machine.should_receive(:request).with(*hash).once.and_return({'virtual_machine'=>{}})
508
+ @virtual_machine.reboot 1, true
509
+ end
510
+ end
511
+
512
+ describe "#segregate" do
513
+ use_vcr_cassette "virtual_machine/segregate"
514
+ it "requires an id" do
515
+ expect { @virtual_machine.segregate }.to raise_error(ArgumentError)
516
+ @virtual_machine.success.should be_false
517
+ end
518
+
519
+ it "requires a target_vm_id" do
520
+ expect { @virtual_machine.segregate 1 }.to raise_error(ArgumentError)
521
+ @virtual_machine.success.should be_false
522
+ end
523
+
524
+ it "404s on not found" do
525
+ expect { @virtual_machine.segregate(404, 1) }.to raise_error(Squall::NotFound)
526
+ @virtual_machine.success.should be_false
527
+ end
528
+
529
+ it "returns 404 on unknown target vm id" do
530
+ expect { @virtual_machine.segregate(1, 404) }.to raise_error(Squall::NotFound)
531
+ @virtual_machine.success.should be_false
532
+ end
533
+
534
+ it "changes the user" do
535
+ result = @virtual_machine.segregate(1, 2)
536
+ @virtual_machine.success.should be_true
537
+ end
538
+ end
539
+
540
+ describe "#console" do
541
+ use_vcr_cassette "virtual_machine/console"
542
+ it "requires an id" do
543
+ expect { @virtual_machine.console }.to raise_error(ArgumentError)
544
+ @virtual_machine.success.should be_false
545
+ end
546
+
547
+ it "returns not found for invalid virtual_machines" do
548
+ pending "broken on OnApp (returning 500)" do
549
+ expect { @virtual_machine.console(404) }.to raise_error(Squall::NotFound)
550
+ @virtual_machine.success.should be_false
551
+ end
552
+ end
553
+
554
+ it "will reboot a virtual_machine" do
555
+ pending "broken on OnApp (returning 500)" do
556
+ virtual_machine = @virtual_machine.console(1)
557
+ @virtual_machine.success.should be_true
558
+ end
559
+ end
560
+ end
561
+
562
+ describe "#stats" do
563
+ use_vcr_cassette "virtual_machine/stats"
564
+ it "requires an id" do
565
+ expect { @virtual_machine.stats }.to raise_error(ArgumentError)
566
+ @virtual_machine.success.should be_false
567
+ end
568
+
569
+ it "returns not found for invalid virtual_machines" do
570
+ pending "broken on OnApp (returning 500)" do
571
+ expect { @virtual_machine.stats(404) }.to raise_error(Squall::NotFound)
572
+ @virtual_machine.success.should be_false
573
+ end
574
+ end
575
+
576
+ it "will stop a virtual_machine" do
577
+ pending "broken on OnApp (returning 500)" do
578
+ virtual_machine = @virtual_machine.stats(1)
579
+ @virtual_machine.success.should be_true
580
+ end
469
581
  end
470
582
  end
471
583
  end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squall::Whitelist do
4
+ before(:each) do
5
+ @whitelist = Squall::Whitelist.new
6
+ @valid = {:ip => "192.168.1.1"}
7
+ end
8
+
9
+ describe "#list" do
10
+ use_vcr_cassette "whitelist/list"
11
+
12
+ it "requires user id" do
13
+ expect { @whitelist.list }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ it "returns a user's whitelists" do
17
+ whitelists = @whitelist.list(1)
18
+ whitelists.should be_an(Array)
19
+ end
20
+
21
+ it "contains the whitelists data" do
22
+ whitelists = @whitelist.list(1)
23
+ whitelists.all? {|w| w.is_a?(Hash) }.should be_true
24
+ end
25
+ end
26
+
27
+ describe "#show" do
28
+ use_vcr_cassette "whitelist/show"
29
+ it "requires an id" do
30
+ expect { @whitelist.show(1) }.to raise_error(ArgumentError)
31
+ end
32
+
33
+ it "returns not found for invalid whitelists" do
34
+ expect { @whitelist.show(1, 404) }.to raise_error(Squall::NotFound)
35
+ end
36
+
37
+ it "returns a whitelist" do
38
+ whitelist = @whitelist.show(1, 2)
39
+ whitelist.should be_a(Hash)
40
+ end
41
+ end
42
+
43
+ describe "#create" do
44
+ use_vcr_cassette "whitelist/create"
45
+ it "requires amount" do
46
+ invalid = @valid.reject{|k,v| k == :ip }
47
+ requires_attr(:ip) { @whitelist.create(1, invalid) }
48
+ end
49
+
50
+ it "allows all optional params" do
51
+ optional = [:description]
52
+ @whitelist.should_receive(:request).exactly(optional.size).times.and_return Hash.new("whitelist" => {})
53
+ optional.each do |param|
54
+ @whitelist.create(1, @valid.merge(param => "test"))
55
+ end
56
+ end
57
+
58
+ it "raises error on unknown params" do
59
+ expect { @whitelist.create(1, @valid.merge(:what => 'what')) }.to raise_error(ArgumentError, 'Unknown params: what')
60
+ end
61
+
62
+ it "raises an error for an invalid user id" do
63
+ expect { @whitelist.create(404, @valid) }.to raise_error(Squall::NotFound)
64
+ end
65
+
66
+ it "creates a whitelist for a user" do
67
+ @whitelist.create(1, @valid)
68
+ @whitelist.success.should be_true
69
+ end
70
+ end
71
+
72
+ describe "#edit" do
73
+ use_vcr_cassette "whitelist/edit"
74
+
75
+ it "allows select params" do
76
+ optional = [:ip, :description]
77
+ @whitelist.should_receive(:request).exactly(optional.size).times.and_return Hash.new()
78
+ optional.each do |param|
79
+ @whitelist.edit(1, 1, param => "test")
80
+ end
81
+ end
82
+
83
+ it "raises error on unknown params" do
84
+ expect { @whitelist.edit(1, 1, :what => 'what') }.to raise_error(ArgumentError, 'Unknown params: what')
85
+ end
86
+
87
+ it "edits a whitelist" do
88
+ @whitelist.edit(1, 1, :description => "This is actually a different computer.")
89
+ @whitelist.success.should be_true
90
+ end
91
+
92
+ it "raises an error for an invalid whitelist id" do
93
+ expect { @whitelist.edit(1, 404, @valid) }.to raise_error(Squall::NotFound)
94
+ end
95
+ end
96
+
97
+ describe "#delete" do
98
+ use_vcr_cassette "whitelist/delete"
99
+ it "requires an id" do
100
+ expect { @whitelist.delete }.to raise_error(ArgumentError)
101
+ end
102
+
103
+ it "deletes a whitelist" do
104
+ @whitelist.delete(1, 1)
105
+ @whitelist.success.should be_true
106
+ end
107
+
108
+ it "returns NotFound for missing user" do
109
+ expect { @whitelist.delete(1, 404) }.to raise_error(Squall::NotFound)
110
+ end
111
+ end
112
+
113
+ end
data/spec/squall_spec.rb CHANGED
@@ -14,12 +14,14 @@ describe Squall do
14
14
  end
15
15
 
16
16
  it "returns the config after yield" do
17
+ Squall.reset_config
17
18
  Squall.config { |c| c }.should == {}
18
19
  Squall.config.should == {}
19
20
  end
20
21
 
21
22
 
22
23
  it "returns the config without a block" do
24
+ Squall.reset_config
23
25
  Squall.config.should == {}
24
26
  end
25
27
 
@@ -32,7 +34,6 @@ describe Squall do
32
34
 
33
35
  describe "#reset" do
34
36
  it "resets the configuration to defaults" do
35
- default_config
36
37
  Squall.config.should_not be_empty
37
38
  Squall.reset_config
38
39
  Squall.config.should be_empty
@@ -41,15 +42,10 @@ describe Squall do
41
42
 
42
43
  describe "#config_file" do
43
44
  it "defaults to ~/.squall" do
44
- file = File.join(ENV['HOME'], '.squall.yml')
45
- config = {'username' => 'test', 'password' => 'pass', 'base_uri' => 'http://example.com'}
46
-
45
+ File.should_receive(:join).with(ENV['HOME'], '.squall.yml').and_return("/path/to/file")
47
46
  File.stub(:exists?).and_return(true)
48
- YAML.should_receive(:load_file).with(file).and_return(config)
49
-
50
- Squall.configuration_file.should be_nil
47
+ YAML.stub(:load_file).and_return({})
51
48
  Squall.config_file
52
- Squall.configuration_file.should == file
53
49
  end
54
50
 
55
51
  it "returns an error if the file doesn't exist" do
@@ -0,0 +1,40 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: http://<USER>:<PASS>@<URL>:80/data_store_zones.json?pack[label]=My%20zone
6
+ body:
7
+ headers:
8
+ content-type:
9
+ - application/json
10
+ authorization:
11
+ - Basic <REDACTED>
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 201
15
+ message: Created
16
+ headers:
17
+ x-ua-compatible:
18
+ - IE=Edge,chrome=1
19
+ location:
20
+ - http://<URL>/data_store_zones/30
21
+ x-powered-by:
22
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.1
23
+ content-type:
24
+ - application/json; charset=utf-8
25
+ x-runtime:
26
+ - "0.044737"
27
+ server:
28
+ - Apache/2.2.3 (CentOS)
29
+ date:
30
+ - Tue, 14 Feb 2012 14:59:58 GMT
31
+ set-cookie:
32
+ - <REDACTED>
33
+ status:
34
+ - "201"
35
+ cache-control:
36
+ - no-cache
37
+ transfer-encoding:
38
+ - chunked
39
+ body: "{\"data_store_group\":{\"label\":\"My zone\",\"created_at\":\"2012-02-14T14:59:58Z\",\"updated_at\":\"2012-02-14T14:59:58Z\",\"id\":30}}"
40
+ http_version: "1.1"
@@ -0,0 +1,77 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :delete
5
+ uri: http://<USER>:<PASS>@<URL>:80/data_store_zones/1.json
6
+ body:
7
+ headers:
8
+ content-type:
9
+ - application/json
10
+ authorization:
11
+ - Basic <REDACTED>
12
+ response: !ruby/struct:VCR::Response
13
+ status: !ruby/struct:VCR::ResponseStatus
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ x-ua-compatible:
18
+ - IE=Edge,chrome=1
19
+ x-powered-by:
20
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.1
21
+ etag:
22
+ - "\"99914b932bd37a50b983c5e7c90ae93b\""
23
+ content-type:
24
+ - application/json; charset=utf-8
25
+ date:
26
+ - Tue, 14 Feb 2012 15:05:56 GMT
27
+ server:
28
+ - Apache/2.2.3 (CentOS)
29
+ x-runtime:
30
+ - "0.036527"
31
+ set-cookie:
32
+ - <REDACTED>
33
+ cache-control:
34
+ - max-age=0, private, must-revalidate
35
+ status:
36
+ - "200"
37
+ transfer-encoding:
38
+ - chunked
39
+ body: "{}"
40
+ http_version: "1.1"
41
+ - !ruby/struct:VCR::HTTPInteraction
42
+ request: !ruby/struct:VCR::Request
43
+ method: :delete
44
+ uri: http://<USER>:<PASS>@<URL>:80/data_store_zones/404.json
45
+ body:
46
+ headers:
47
+ content-type:
48
+ - application/json
49
+ authorization:
50
+ - Basic <REDACTED>
51
+ response: !ruby/struct:VCR::Response
52
+ status: !ruby/struct:VCR::ResponseStatus
53
+ code: 404
54
+ message: Not Found
55
+ headers:
56
+ x-ua-compatible:
57
+ - IE=Edge,chrome=1
58
+ x-powered-by:
59
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.1
60
+ content-type:
61
+ - application/json; charset=utf-8
62
+ x-runtime:
63
+ - "0.037065"
64
+ server:
65
+ - Apache/2.2.3 (CentOS)
66
+ date:
67
+ - Tue, 14 Feb 2012 15:05:56 GMT
68
+ set-cookie:
69
+ - <REDACTED>
70
+ status:
71
+ - "404"
72
+ cache-control:
73
+ - no-cache
74
+ transfer-encoding:
75
+ - chunked
76
+ body: "{\"errors\":[\"Resource not found\"]}"
77
+ http_version: "1.1"