vominator 0.0.1

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 (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +116 -0
  7. data/Rakefile +12 -0
  8. data/bin/vominate +12 -0
  9. data/circle.yml +5 -0
  10. data/lib/ec2.rb +12 -0
  11. data/lib/ec2/instances.rb +362 -0
  12. data/lib/ec2/security_groups.rb +314 -0
  13. data/lib/ec2/ssm.rb +81 -0
  14. data/lib/vominator/aws.rb +15 -0
  15. data/lib/vominator/constants.rb +53 -0
  16. data/lib/vominator/ec2.rb +308 -0
  17. data/lib/vominator/instances.rb +34 -0
  18. data/lib/vominator/route53.rb +125 -0
  19. data/lib/vominator/security_groups.rb +26 -0
  20. data/lib/vominator/ssm.rb +57 -0
  21. data/lib/vominator/version.rb +3 -0
  22. data/lib/vominator/vominator.rb +74 -0
  23. data/lib/vominator/vpc.rb +82 -0
  24. data/lib/vpc.rb +8 -0
  25. data/lib/vpc/create.rb +188 -0
  26. data/spec/lib/instances_spec.rb +2 -0
  27. data/spec/lib/vominator/aws_spec.rb +6 -0
  28. data/spec/lib/vominator/ec2_spec.rb +783 -0
  29. data/spec/lib/vominator/instances_spec.rb +96 -0
  30. data/spec/lib/vominator/route53_spec.rb +64 -0
  31. data/spec/lib/vominator/ssm_spec.rb +95 -0
  32. data/spec/lib/vominator/vominator_spec.rb +209 -0
  33. data/spec/spec_helper.rb +103 -0
  34. data/spec/support/matchers/exit_with_code.rb +24 -0
  35. data/test/puke/cloud-configs/.gitkeep +0 -0
  36. data/test/puke/cloud-configs/cloud-config-example.erb +63 -0
  37. data/test/puke/config.yaml +16 -0
  38. data/test/puke/products/sample-api/instances.yaml +37 -0
  39. data/test/puke/products/sample-api/security_groups.yaml +19 -0
  40. data/test/vominator.yaml +7 -0
  41. data/vominator.gemspec +34 -0
  42. metadata +259 -0
@@ -0,0 +1,2 @@
1
+ require 'spec_helper'
2
+
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'vominator/aws'
3
+
4
+ describe Vominator::AWS do
5
+
6
+ end
@@ -0,0 +1,783 @@
1
+ require 'spec_helper'
2
+ require 'vominator/ec2'
3
+ require 'pry'
4
+ describe Vominator::EC2 do
5
+
6
+ before(:each) do
7
+ @puke_variables = Vominator.get_puke_variables('test')
8
+ Aws.config[:stub_responses] = true
9
+ @ec2_client = Aws::EC2::Client.new
10
+ @ec2_client.stub_responses(:describe_vpcs, :next_token => nil, :vpcs => [
11
+ {
12
+ :vpc_id => 'vpc-ada2d4c8',
13
+ :cidr_block => '10.203.0.0/16'
14
+ }
15
+ ])
16
+ @ec2_client.stub_responses(:describe_subnets, :next_token => nil, :subnets => [
17
+ {
18
+ :subnet_id => 'sub-11111',
19
+ :vpc_id => 'vpc-ada2d4c8',
20
+ :cidr_block => '10.203.41.0/24',
21
+ :availability_zone => 'us-east-1c'
22
+ },
23
+ {
24
+ :subnet_id => 'sub-11112',
25
+ :vpc_id => 'vpc-ada2d4c8',
26
+ :cidr_block => '10.203.42.0/24',
27
+ :availability_zone => 'us-east-1d'
28
+ },
29
+ {
30
+ :subnet_id => 'sub-11113',
31
+ :vpc_id => 'vpc-ada2d4c8',
32
+ :cidr_block => '10.203.43.0/24',
33
+ :availability_zone => 'us-east-1e'
34
+ }
35
+ ])
36
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
37
+ {
38
+ :reservation_id => 'r-567b402e',
39
+ :owner_id => '012329383471727',
40
+ :groups => [],
41
+ :instances => [{
42
+ :instance_id => 'i-1968d168',
43
+ :vpc_id => 'vpc-ada2d4c8',
44
+ :key_name => 'ci@example.com',
45
+ :instance_type => 'm3.medium',
46
+ :private_ip_address => '10.203.41.21',
47
+ :virtualization_type => 'hvm',
48
+ :architecture => 'x86_64',
49
+ :source_dest_check => false,
50
+ :ebs_optimized => false,
51
+ :state => { :code => 16, :name => 'running'},
52
+ :tags => [{:key => 'Name', :value => 'sample-api-1.test'}],
53
+ :placement => {:availability_zone => 'us-east-1c'},
54
+ :security_groups => [{:group_name => 'test-sample-api-server', :group_id => 'sg-11111'}],
55
+ :block_device_mappings => [{:device_name => 'sdf', :ebs => {:volume_id => 'vol-11111', :status => 'in-use'}}]
56
+ }]
57
+ },
58
+ {
59
+ :reservation_id => 'r-7013f428',
60
+ :owner_id => '012329383471727',
61
+ :groups => [],
62
+ :instances => [{
63
+ :instance_id => 'i-1766874c',
64
+ :vpc_id => 'vpc-ada2d4c8',
65
+ :key_name => 'ci@example.com',
66
+ :instance_type => 'm3.medium',
67
+ :private_ip_address => '10.203.42.21',
68
+ :virtualization_type => 'hvm',
69
+ :architecture => 'x86_64',
70
+ :source_dest_check => false,
71
+ :ebs_optimized => false,
72
+ :state => { :code => 16, :name => 'running'},
73
+ :tags => [{:key => 'Name', :value => 'sample-api-2.test'}],
74
+ :placement => {:availability_zone => 'us-east-1d'}
75
+ }]
76
+ },
77
+ {
78
+ :reservation_id => 'r-b274d2f4',
79
+ :owner_id => '012329383471727',
80
+ :groups => [],
81
+ :instances => [{
82
+ :instance_id => 'i-1b68d16a',
83
+ :vpc_id => 'vpc-ada2d4c8',
84
+ :key_name => 'ci@example.com',
85
+ :instance_type => 'm3.medium',
86
+ :private_ip_address => '10.203.43.21',
87
+ :virtualization_type => 'hvm',
88
+ :architecture => 'x86_64',
89
+ :source_dest_check => false,
90
+ :ebs_optimized => false,
91
+ :state => { :code => 16, :name => 'running'},
92
+ :tags => [{:key => 'Name', :value => 'sample-api-3.test'}],
93
+ :placement => {:availability_zone => 'us-east-1e'}
94
+ }]
95
+ }
96
+ ])
97
+ @ec2_client.stub_responses(:describe_security_groups, :next_token => nil, :security_groups => [
98
+ {
99
+ :vpc_id => 'vpc-ada2d4c8',
100
+ :owner_id => '012329383471727',
101
+ :group_id => 'sg-11111',
102
+ :group_name => 'test-sample-api-load-balancer',
103
+ :description => 'test-sample-api-load-balancer',
104
+ :ip_permissions => [
105
+ {
106
+ :ip_protocol => 'tcp',
107
+ :from_port => 80,
108
+ :to_port => 80,
109
+ :ip_ranges => [
110
+ {
111
+ :cidr_ip => '0.0.0.0/0'
112
+ }
113
+ ]
114
+ }
115
+ ],
116
+ :ip_permissions_egress => [
117
+ {
118
+ :ip_protocol => 'tcp',
119
+ :from_port => 8080,
120
+ :to_port => 8080,
121
+ :user_id_group_pairs => [
122
+ {
123
+ :group_name => 'test-sample-api-server',
124
+ :group_id => 'sg-11112'
125
+ }
126
+ ]
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ :vpc_id => 'vpc-ada2d4c8',
132
+ :owner_id => '012329383471727',
133
+ :group_id => 'sg-11112',
134
+ :group_name => 'test-sample-api-server',
135
+ :description => 'test-sample-api-server',
136
+ :ip_permissions => [
137
+ {
138
+ :ip_protocol => 'tcp',
139
+ :from_port => 8080,
140
+ :to_port => 8080,
141
+ :user_id_group_pairs => [
142
+ {
143
+ :group_name => 'test-sample-api-load-balancer',
144
+ :group_id => 'sg-11111'
145
+ }
146
+ ]
147
+ }
148
+ ],
149
+ :ip_permissions_egress => [
150
+ ]
151
+ }
152
+ ])
153
+ @ec2_client.stub_responses(:describe_volumes, :next_token => nil, :volumes => [
154
+ :volume_id => 'vol-11111',
155
+ :size => 100,
156
+ :availability_zone => 'us-east-1c',
157
+ :state => 'in-use',
158
+ :attachments => [{
159
+ :volume_id => 'vol-11111',
160
+ :instance_id => 'i-1968d168',
161
+ :device => 'sdf',
162
+ :state => 'in-use'
163
+ }]
164
+ ])
165
+ @ec2 = Aws::EC2::Resource.new(client: @ec2_client)
166
+ end
167
+
168
+ describe 'get_virt_type' do
169
+ context 'when I pass a valid instance_type' do
170
+ let (:instance_type) {Vominator::EC2.get_virt_type('m3.medium')}
171
+
172
+ subject { instance_type }
173
+ # TODO: We should probably test all instance types here.
174
+ it 'returns the appropriate instance type' do
175
+ expect { instance_type }.to_not raise_error
176
+ expect(instance_type).to match('hvm')
177
+ end
178
+ end
179
+
180
+ context 'when I pass an invalid instance type' do
181
+ let (:instance_type) {Vominator::EC2.get_virt_type('invalid_instance_type')}
182
+
183
+ subject { instance_type }
184
+
185
+ it 'should raise error ArgumentError' do
186
+ expect { instance_type }.to raise_error(ArgumentError)
187
+ end
188
+ end
189
+ end
190
+
191
+ describe 'get_ephemeral_dev_count' do
192
+ context 'when I pass a valid instance_type' do
193
+ let (:ephemeral_dev_count) { Vominator::EC2.get_ephemeral_dev_count('m3.medium')}
194
+
195
+ subject { ephemeral_dev_count }
196
+
197
+ # TODO: We should probably test all instance types here.
198
+ it 'returns the appropriate number of ephemeral devices' do
199
+ expect { ephemeral_dev_count }.to_not raise_error
200
+ expect(ephemeral_dev_count).to match(1)
201
+ end
202
+ end
203
+
204
+ context 'when I pass an invalid instance type' do
205
+ let (:ephemeral_dev_count) { Vominator::EC2.get_ephemeral_dev_count('invalid_instance_type')}
206
+
207
+ subject { ephemeral_dev_count }
208
+
209
+ xit 'should do something'
210
+
211
+ end
212
+ end
213
+
214
+ describe 'get_instances' do
215
+ context 'when I pass a valid ec2 resource' do
216
+ let (:instances) { Vominator::EC2.get_instances(@ec2) }
217
+
218
+ subject { instances }
219
+
220
+ it 'should return ec2 instances' do
221
+ expect {instances}.to_not raise_error
222
+ expect(instances.count).to eq 3
223
+ expect(instances['10.203.41.21'][:instance_id]).to match 'i-1968d168'
224
+ expect(instances['10.203.41.21'][:security_groups].first).to include('test-sample-api-server')
225
+ end
226
+ end
227
+
228
+ context 'when I pass an invalid ec2 resource' do
229
+
230
+ xit 'do something' do
231
+
232
+ end
233
+
234
+ end
235
+ end
236
+
237
+ describe 'get_instance' do
238
+ context 'when I pass a valid ec2 resource and a valid instance ID' do
239
+ let (:instance) { Vominator::EC2.get_instance(@ec2, 'i-1968d168')}
240
+
241
+ subject { instance }
242
+
243
+ it 'should return an ec2 instance object' do
244
+ expect {instance}.to_not raise_error
245
+ expect(instance.id).to match 'i-1968d168'
246
+ expect(instance.private_ip_address).to match '10.203.41.21'
247
+ end
248
+ end
249
+
250
+ context 'when I pass an invalid ec2 resource or invalid instance ID.' do
251
+ xit 'do something'
252
+ end
253
+ end
254
+
255
+ describe 'get_security_group_name_ids_hash' do
256
+ context 'when I pass a valid resource and vpc_id' do
257
+ let (:security_groups) { Vominator::EC2.get_security_group_name_ids_hash(@ec2, @puke_variables['vpc_id'])}
258
+
259
+ subject { security_groups }
260
+
261
+ it 'should return all security groups for the vpc' do
262
+ expect { security_groups }.to_not raise_error
263
+ expect(security_groups.count).to eq 2
264
+ expect(security_groups['test-sample-api-load-balancer']).to eq 'sg-11111'
265
+ expect(security_groups['test-sample-api-server']).to eq 'sg-11112'
266
+ end
267
+ end
268
+
269
+ context 'when I pass an invalid resource or vpc_id' do
270
+ xit 'do something'
271
+ end
272
+ end
273
+
274
+ describe 'get_subnets' do
275
+ context 'when I pass a valid resource and vpc_id' do
276
+ let (:subnets) { Vominator::EC2.get_subnets(@ec2, @puke_variables['vpc_id'])}
277
+
278
+ subject { subnets }
279
+
280
+ it 'should return all subnets for the vpc' do
281
+ expect { subnets }.to_not raise_error
282
+ expect(subnets.count).to eq 3
283
+ expect(subnets['10.203.41.0/24'].id).to match 'sub-11111'
284
+ expect(subnets['10.203.42.0/24'].id).to match 'sub-11112'
285
+ expect(subnets['10.203.43.0/24'].id).to match 'sub-11113'
286
+ end
287
+ end
288
+
289
+ context 'when I pass an invalid resource or vpc_id' do
290
+ xit 'do something'
291
+ end
292
+ end
293
+
294
+ describe 'get_ami' do
295
+ context 'when I pass a valid puke_config, HVM instance type, and linux as the os' do
296
+ let (:ami) { Vominator::EC2.get_ami(@puke_variables, 'm3.medium', 'linux')}
297
+
298
+ subject {ami}
299
+
300
+ it 'should return a linux ami for an HVM Instance.' do
301
+ expect { ami }.to_not raise_error
302
+ expect(ami).to match('ami-260d074e')
303
+ end
304
+ end
305
+
306
+ context 'when I pass a valid puke_config, paravirtual instance type, and linux as the os' do
307
+ let (:ami) { Vominator::EC2.get_ami(@puke_variables, 't1.micro', 'linux')}
308
+
309
+ subject {ami}
310
+
311
+ it 'should return a linux ami for an Paravirtual Instance.' do
312
+ expect { ami }.to_not raise_error
313
+ expect(ami).to match('ami-280d0740')
314
+ end
315
+ end
316
+
317
+ context 'when I pass a valid puke_config, HVM instance type, and windows as the os' do
318
+ let (:ami) { Vominator::EC2.get_ami(@puke_variables, 'm3.medium', 'windows')}
319
+
320
+ subject {ami}
321
+
322
+ it 'should return a linux ami for an HVM Instance.' do
323
+ expect { ami }.to_not raise_error
324
+ expect(ami).to match('ami-9231e2fa')
325
+ end
326
+ end
327
+
328
+ context 'when I pass a valid puke_config, paravirtual instance type, and windows as the os' do
329
+ let (:ami) { Vominator::EC2.get_ami(@puke_variables, 't1.micro', 'windows')}
330
+
331
+ subject {ami}
332
+
333
+ it 'should return a linux ami for an Paravirtual Instance.' do
334
+ expect { ami }.to_not raise_error
335
+ expect(ami).to match('ami-78bce2lm')
336
+ end
337
+ end
338
+
339
+ context 'when I pass an invalid puke_config, instance_type or os' do
340
+ xit 'do something'
341
+ end
342
+ end
343
+
344
+ describe 'create_subnet' do
345
+ context 'when I pass a valid resource, subnet, az, and vpc_id' do
346
+ let (:subnet) { Vominator::EC2.create_subnet(@ec2, '10.203.21.0/24', 'us-east-1a', @puke_variables['vpc_id'])}
347
+
348
+ subject { subnet }
349
+
350
+ xit 'should return a subnet object' do
351
+ expect { subnet }.to_not raise_error
352
+ # TODO: How do we verify that this actually worked?
353
+ end
354
+ end
355
+
356
+ context 'when I pass an invalid resource, subnet, az, or vpc_id' do
357
+ xit 'do something'
358
+ end
359
+ end
360
+
361
+ describe 'get_termination_protection' do
362
+ context 'when I pass a valid client, instance_id and the instance is protected from termination' do
363
+ let (:termination_protection) { Vominator::EC2.get_termination_protection(@ec2_client, 'i-1968d168')}
364
+
365
+ subject { termination_protection }
366
+
367
+ it 'should be protected from termination' do
368
+ @ec2_client.stub_responses(:describe_instance_attribute, :instance_id => 'i-1968d168', :disable_api_termination => { :value => true })
369
+ expect { termination_protection}.to_not raise_error
370
+ expect(termination_protection).to be true
371
+ end
372
+ end
373
+
374
+ context 'when I pass a valid client, instance_id, and the instance is not protected from termination' do
375
+ let (:termination_protection) { Vominator::EC2.get_termination_protection(@ec2_client, 'i-1766874c')}
376
+
377
+ subject { termination_protection }
378
+
379
+ it 'should not be protected from termination' do
380
+ @ec2_client.stub_responses(:describe_instance_attribute, :instance_id => 'i-1766874c', :disable_api_termination => { :value => false })
381
+ expect { termination_protection}.to_not raise_error
382
+ expect(termination_protection).to be false
383
+ end
384
+ end
385
+
386
+ context 'when I pass an invalid client, or instance_id' do
387
+ xit 'do something'
388
+ end
389
+ end
390
+
391
+ describe 'set_termination_protection' do
392
+ context 'When I pass a valid client, instance_id and set the instance protection to true' do
393
+ let (:termination_protection) { Vominator::EC2.set_termination_protection(@ec2_client, 'i-1968d168', true)}
394
+
395
+ subject { termination_protection }
396
+
397
+ it 'should be enabled' do
398
+ @ec2_client.stub_responses(:describe_instance_attribute, :instance_id => 'i-1968d168', :disable_api_termination => { :value => true })
399
+ expect { termination_protection }.to_not raise_error
400
+ expect(termination_protection).to be true
401
+ end
402
+ end
403
+
404
+ context 'When I pass a valid client, instance_id and set the instance protection to false' do
405
+ let (:termination_protection) { Vominator::EC2.set_termination_protection(@ec2_client, 'i-1968d168', false)}
406
+
407
+ subject { termination_protection }
408
+
409
+ it 'should not be enabled' do
410
+ @ec2_client.stub_responses(:describe_instance_attribute, :instance_id => 'i-1968d168', :disable_api_termination => { :value => false })
411
+ expect { termination_protection }.to_not raise_error
412
+ expect(termination_protection).to be false
413
+ end
414
+ end
415
+
416
+ context 'when I pass an invalid client, instance_id or state' do
417
+ xit 'do something'
418
+ end
419
+ end
420
+ describe 'get_instance_state' do
421
+ context 'when I pass a valid resource and instance_id' do
422
+ let (:instance_state) { Vominator::EC2.get_instance_state(@ec2, 'i-1968d168') }
423
+
424
+ subject { instance_state }
425
+
426
+ it 'should return running when the instance is running' do
427
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
428
+ {
429
+ :reservation_id => 'r-567b402e',
430
+ :instances => [{
431
+ :instance_id => 'i-1968d168',
432
+ :instance_type => 'm3.large',
433
+ :state => { :code => 64, :name => 'running'},
434
+ }]
435
+ }])
436
+
437
+ expect { instance_state }.to_not raise_error
438
+ expect(instance_state).to match 'running'
439
+ end
440
+
441
+ it 'should return stopped when the instance is stopped' do
442
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
443
+ {
444
+ :reservation_id => 'r-567b402e',
445
+ :instances => [{
446
+ :instance_id => 'i-1968d168',
447
+ :instance_type => 'm3.large',
448
+ :state => { :code => 64, :name => 'stopped'},
449
+ }]
450
+ }])
451
+
452
+ expect { instance_state }.to_not raise_error
453
+ expect(instance_state).to match 'stopped'
454
+ end
455
+ end
456
+ end
457
+
458
+ describe 'set_instance_type' do
459
+ context 'when I pass a valid resource, instance_id, and instance_type' do
460
+ let (:instance_type) { Vominator::EC2.set_instance_type(@ec2, 'i-1968d168', 'm3.large', 'sample-api-1.test.example.com')}
461
+
462
+ subject { instance_type }
463
+
464
+ it 'should resize the instance' do
465
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
466
+ {
467
+ :reservation_id => 'r-567b402e',
468
+ :instances => [{
469
+ :instance_id => 'i-1968d168',
470
+ :instance_type => 'm3.large',
471
+ :state => { :code => 64, :name => 'stopped'},
472
+ }]
473
+ }])
474
+ expect { instance_type }.to_not raise_error
475
+ expect(instance_type).to match 'm3.large'
476
+ end
477
+ end
478
+
479
+ context 'when I pass an invalid resource, instance_id, or instance_type' do
480
+ xit 'do something'
481
+ end
482
+ end
483
+
484
+ describe 'assign_public_ip' do
485
+ context 'when I pass a valid resource and instance_id' do
486
+ let (:public_ip) { Vominator::EC2.assign_public_ip(@ec2_client, 'i-1968d168' )}
487
+
488
+ subject { public_ip }
489
+
490
+ it 'should assign the instance an public ip' do
491
+ @ec2_client.stub_responses(:allocate_address, :public_ip => '84.84.84.84')
492
+ expect { public_ip }.to_not raise_error
493
+ expect(public_ip).to match '84.84.84.84'
494
+ end
495
+ end
496
+
497
+ context 'when i pass an invalid resource and instance_id' do
498
+ xit 'do something'
499
+ end
500
+ end
501
+
502
+ describe 'remove_public_ip' do
503
+ context 'when I pass a valid resource and instance_id' do
504
+ let (:removed_public_ip) { Vominator::EC2.remove_public_ip(@ec2_client, 'i-1968d168' )}
505
+
506
+ subject { removed_public_ip }
507
+
508
+ it 'should remove the instance an public ip' do
509
+ @ec2_client.stub_responses(:describe_addresses, :addresses => [{:instance_id => 'i-1968d168', :public_ip => '84.84.84.84'}])
510
+ expect { removed_public_ip }.to_not raise_error
511
+ expect(removed_public_ip).to be true
512
+ end
513
+ end
514
+
515
+ context 'when i pass an invalid resource and instance_id' do
516
+ xit 'do something'
517
+ end
518
+ end
519
+
520
+ describe 'set_source_dest_check' do
521
+ context 'when I pass a valid resource, instance_id and enable source destination checking' do
522
+ let (:source_dest_check) { Vominator::EC2.set_source_dest_check(@ec2, 'i-1968d168', true )}
523
+
524
+ subject { source_dest_check }
525
+
526
+ it 'should remove the instance an public ip' do
527
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
528
+ {
529
+ :reservation_id => 'r-567b402e',
530
+ :instances => [{
531
+ :instance_id => 'i-1968d168',
532
+ :instance_type => 'm3.large',
533
+ :source_dest_check => true
534
+ }]
535
+ }])
536
+
537
+ expect { source_dest_check }.to_not raise_error
538
+ expect(source_dest_check).to be true
539
+ end
540
+ end
541
+
542
+ context 'when I pass a valid resource, instance_id and disabling source destination checking' do
543
+ let (:source_dest_check) { Vominator::EC2.set_source_dest_check(@ec2, 'i-1968d168', false )}
544
+
545
+ subject { source_dest_check }
546
+
547
+ it 'should remove the instance an public ip' do
548
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
549
+ {
550
+ :reservation_id => 'r-567b402e',
551
+ :instances => [{
552
+ :instance_id => 'i-1968d168',
553
+ :instance_type => 'm3.large',
554
+ :source_dest_check => false
555
+ }]
556
+ }])
557
+ expect { source_dest_check }.to_not raise_error
558
+ expect(source_dest_check).to be false
559
+ end
560
+ end
561
+
562
+ context 'when i pass an invalid resource, instance_id, or state' do
563
+ xit 'do something'
564
+ end
565
+ end
566
+
567
+ describe 'set_ebs_optimized' do
568
+ context 'when I pass a valid resource, instance_id and enable EBS optimization' do
569
+ let (:ebs_optimized) { Vominator::EC2.set_ebs_optimized(@ec2, 'i-1968d168', true, 'sample-api-1.example.com' )}
570
+
571
+ subject { ebs_optimized }
572
+
573
+ it 'should remove the instance an public ip' do
574
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
575
+ {
576
+ :reservation_id => 'r-567b402e',
577
+ :instances => [{
578
+ :instance_id => 'i-1968d168',
579
+ :instance_type => 'm3.large',
580
+ :ebs_optimized => true,
581
+ :state => { :code => 64, :name => 'stopped'}
582
+ }]
583
+ }])
584
+ expect { ebs_optimized }.to_not raise_error
585
+ expect(ebs_optimized).to be true
586
+ end
587
+ end
588
+
589
+ context 'when I pass a valid resource, instance_id and disabling EBS optimization' do
590
+ let (:ebs_optimized) { Vominator::EC2.set_ebs_optimized(@ec2, 'i-1968d168', false, 'sample-api-1.example.com' )}
591
+
592
+ subject { ebs_optimized }
593
+
594
+ it 'should remove the instance an public ip' do
595
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
596
+ {
597
+ :reservation_id => 'r-567b402e',
598
+ :instances => [{
599
+ :instance_id => 'i-1968d168',
600
+ :instance_type => 'm3.large',
601
+ :ebs_optimized => false,
602
+ :state => { :code => 64, :name => 'stopped'}
603
+ }]
604
+ }])
605
+ expect { ebs_optimized }.to_not raise_error
606
+ expect(ebs_optimized).to be false
607
+ end
608
+ end
609
+
610
+ context 'when i pass an invalid resource, instance_id, or state' do
611
+ xit 'do something'
612
+ end
613
+ end
614
+
615
+ describe 'set_security_groups' do
616
+ context 'when I pass a valid resource, instance_id, security_groups, and vpc_security_groups' do
617
+ vpc_security_groups = Hash.new
618
+ vpc_security_groups['test-sample-api-server'] = 'sg-11111'
619
+ let (:security_groups) { Vominator::EC2.set_security_groups(@ec2, 'i-1968d168', ['test-security-group'], vpc_security_groups)}
620
+
621
+ subject { security_groups }
622
+
623
+ it 'should append test-security-group to the instances list of security groups' do
624
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
625
+ {
626
+ :reservation_id => 'r-567b402e',
627
+ :instances => [{
628
+ :instance_id => 'i-1968d168',
629
+ :security_groups => [{ :group_name => 'test-sample-api-server', :group_id => 'sg-11111'}, { :group_name => 'test-security-group', :group_id => 'sg-11113'}]
630
+ }]
631
+ }])
632
+ expect { security_groups }.to_not raise_error
633
+ expect(security_groups.count).to eq 2
634
+ expect(security_groups).to include 'test-sample-api-server'
635
+ expect(security_groups).to include 'test-security-group'
636
+ end
637
+ end
638
+
639
+ context 'when I pass a valid resource, instance_id, security_groups, vpc_security_groups, and set append to false' do
640
+ vpc_security_groups = Hash.new
641
+ vpc_security_groups['test-sample-api-server'] = 'sg-11111'
642
+ let (:security_groups) { Vominator::EC2.set_security_groups(@ec2, 'i-1968d168', ['test-security-group'], vpc_security_groups, false)}
643
+
644
+ subject { security_groups }
645
+
646
+ it 'should append test-security-group to the instances list of security groups' do
647
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
648
+ {
649
+ :reservation_id => 'r-567b402e',
650
+ :instances => [{
651
+ :instance_id => 'i-1968d168',
652
+ :security_groups => [{ :group_name => 'test-security-group', :group_id => 'sg-11113'}]
653
+ }]
654
+ }])
655
+ expect { security_groups }.to_not raise_error
656
+ expect(security_groups.count).to eq 1
657
+ expect(security_groups).to include 'test-security-group'
658
+ end
659
+ end
660
+ end
661
+
662
+ describe 'get_ebs_volume' do
663
+ context 'when I pass a valid resource and ebs_volume_id' do
664
+ let (:volume) { Vominator::EC2.get_ebs_volume(@ec2, 'vol-11111') }
665
+
666
+ subject { volume }
667
+
668
+ it 'should return a valid aws ec2 volume object' do
669
+ expect { volume }.to_not raise_error
670
+ expect(volume.id).to eq 'vol-11111'
671
+ end
672
+ end
673
+
674
+ context 'when I pass an invalid resource or ebs_volume_id' do
675
+ xit 'do something'
676
+ end
677
+
678
+ end
679
+
680
+ describe 'get_instance_ebs_volumes' do
681
+ context 'when I pass a valid resource and instance id' do
682
+ let (:volumes) { Vominator::EC2.get_instance_ebs_volumes(@ec2, 'i-1968d168') }
683
+
684
+ subject { volumes }
685
+
686
+ it 'should return a list of device names for attached ebs volumes' do
687
+ expect { volumes }.to_not raise_error
688
+ expect(volumes.count).to eq 1
689
+ expect(volumes.first).to match 'sdf'
690
+ end
691
+ end
692
+
693
+ context 'when I pass an invalid resource or instance id' do
694
+ xit 'do something'
695
+ end
696
+ end
697
+
698
+ describe 'add_ebs_volume' do
699
+ context 'when I pass a valid resource, instance_id, volume_type, volume_size, and mount_point)' do
700
+ let (:volume) { Vominator::EC2.add_ebs_volume(@ec2, 'i-1968d168', 'magnetic', 100, 'sdf')}
701
+
702
+ subject { volume }
703
+
704
+ it 'should return a valid volume object' do
705
+ @ec2_client.stub_responses(:describe_volumes,
706
+ {:volumes => [{:volume_id => 'vol-11111', :size => 100, :availability_zone => 'us-east-1c', :state => 'available'}]},
707
+ {:volumes => [{:volume_id => 'vol-11111', :size => 100, :availability_zone => 'us-east-1c', :state => 'in-use'}]}
708
+ )
709
+ @ec2_client.stub_responses(:create_volume, :volume_id => 'vol-11111', :size => 100, :availability_zone => 'us-east-1c', :state => 'in-use', :attachments => [{:device => 'sdf', :volume_id => 'vol-11111', :state => 'in-use'}])
710
+ expect { volume }.to_not raise_error
711
+ expect(volume.attachments.first.device).to match 'sdf'
712
+ end
713
+ end
714
+ end
715
+
716
+ describe 'get_ephemeral_devices' do
717
+ context 'when I pass a valid instance type' do
718
+ let (:devices) { Vominator::EC2.get_ephemeral_devices('m3.medium') }
719
+
720
+ subject { devices }
721
+
722
+ it 'should return a hash consisting of mount points and ephemeral device ids' do
723
+ expect {devices}.to_not raise_error
724
+ expect(devices.count).to eq 1
725
+ expect(devices['/dev/sdb']).to match 'ephemeral0'
726
+ end
727
+ end
728
+
729
+ context 'when I pass an invalid instance type' do
730
+ xit 'do something'
731
+ end
732
+ end
733
+
734
+ describe 'create_instance' do
735
+ context 'when I pass a valid resource, hostname, environment, ami, subnet id, instance type, keypair name, private ip, az and security groups' do
736
+ let (:instance) { Vominator::EC2.create_instance(@ec2, 'sample-api-1','test','ami-111111','sub-11111','m3.medium','test@example.com','10.203.41.21','us-east-1c',['sg-11111'],'',false,nil)}
737
+
738
+ subject { instance }
739
+
740
+ it 'should create an instance' do
741
+ @ec2_client.stub_responses(:run_instances, :next_token => nil, :instances => [
742
+ {
743
+ :instance_id => 'i-1968d168',
744
+ :state => { :code => 64, :name => 'running'}
745
+ }])
746
+
747
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
748
+ {
749
+ :reservation_id => 'r-567b402e',
750
+ :instances => [{
751
+ :instance_id => 'i-1968d168',
752
+ :state => { :code => 64, :name => 'running'}
753
+ }]
754
+ }])
755
+
756
+ expect { instance }.to_not raise_error
757
+ expect(instance.id).to match 'i-1968d168'
758
+ end
759
+ end
760
+ end
761
+
762
+ describe 'terminate_instance' do
763
+ context 'when I pass a valid resource and instance id' do
764
+ let (:instance) { Vominator::EC2.terminate_instance(@ec2, 'i-1968d168')}
765
+
766
+ subject { instance }
767
+
768
+ it 'should terminate the instance' do
769
+ @ec2_client.stub_responses(:describe_instances, :next_token => nil, :reservations => [
770
+ {
771
+ :reservation_id => 'r-567b402e',
772
+ :instances => [{
773
+ :instance_id => 'i-1968d168',
774
+ :state => { :code => 64, :name => 'terminated'}
775
+ }]
776
+ }])
777
+
778
+ expect { instance }.to_not raise_error
779
+ expect(instance).to be true
780
+ end
781
+ end
782
+ end
783
+ end