vm_shepherd 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vm_shepherd/aws_manager.rb +89 -40
- data/lib/vm_shepherd/openstack_manager.rb +3 -0
- data/lib/vm_shepherd/shepherd.rb +63 -22
- data/lib/vm_shepherd/vcloud_manager.rb +3 -0
- data/lib/vm_shepherd/version.rb +1 -1
- data/lib/vm_shepherd/vsphere_manager.rb +19 -10
- data/spec/fixtures/shepherd/aws.yml +16 -17
- data/spec/fixtures/shepherd/openstack.yml +36 -35
- data/spec/fixtures/shepherd/vcloud.yml +40 -39
- data/spec/fixtures/shepherd/vsphere.yml +56 -55
- data/spec/vm_shepherd/aws_manager_spec.rb +160 -53
- data/spec/vm_shepherd/shepherd_spec.rb +149 -98
- data/spec/vm_shepherd/vsphere_manager_spec.rb +31 -0
- metadata +2 -2
@@ -4,11 +4,28 @@ require 'recursive_open_struct'
|
|
4
4
|
module VmShepherd
|
5
5
|
RSpec.describe Shepherd do
|
6
6
|
subject(:manager) { Shepherd.new(settings: settings) }
|
7
|
-
let(:first_config) { settings.
|
8
|
-
let(:last_config) { settings.
|
7
|
+
let(:first_config) { settings.vm_shepherd.vm_configs.first }
|
8
|
+
let(:last_config) { settings.vm_shepherd.vm_configs.last }
|
9
9
|
let(:settings) do
|
10
10
|
RecursiveOpenStruct.new(YAML.load_file(File.join(SPEC_ROOT, 'fixtures', 'shepherd', settings_fixture_name)), recurse_over_arrays: true)
|
11
11
|
end
|
12
|
+
let(:env_config) do
|
13
|
+
{
|
14
|
+
stack_name: 'aws-stack-name',
|
15
|
+
aws_access_key: 'aws-access-key',
|
16
|
+
aws_secret_key: 'aws-secret-key',
|
17
|
+
json_file: 'cloudformation.json',
|
18
|
+
parameters: {
|
19
|
+
'key_pair_name' => 'key_pair_name'
|
20
|
+
},
|
21
|
+
outputs: {
|
22
|
+
ssh_key_name: 'ssh-key-name',
|
23
|
+
security_group: 'security-group-id',
|
24
|
+
public_subnet_id: 'public-subnet-id',
|
25
|
+
private_subnet_id: 'private-subnet-id'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
12
29
|
|
13
30
|
describe '#deploy' do
|
14
31
|
context 'with vcloud settings' do
|
@@ -85,10 +102,10 @@ module VmShepherd
|
|
85
102
|
it 'uses VsphereManager to launch a vm' do
|
86
103
|
expect(VsphereManager).to receive(:new).with(
|
87
104
|
first_config.vcenter_creds.ip,
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
105
|
+
first_config.vcenter_creds.username,
|
106
|
+
first_config.vcenter_creds.password,
|
107
|
+
first_config.vsphere.datacenter,
|
108
|
+
).and_return(first_ova_manager)
|
92
109
|
|
93
110
|
|
94
111
|
expect(VsphereManager).to receive(:new).with(
|
@@ -144,41 +161,16 @@ module VmShepherd
|
|
144
161
|
|
145
162
|
context 'with AWS settings' do
|
146
163
|
let(:settings_fixture_name) { 'aws.yml' }
|
147
|
-
let(:
|
148
|
-
let(:last_ams_manager) { instance_double(AwsManager) }
|
164
|
+
let(:aws_manager) { instance_double(AwsManager) }
|
149
165
|
let(:first_ami_file_path) { 'PATH_TO_AMI_FILE' }
|
150
166
|
let(:last_ami_file_path) { 'PATH_TO_AMI_FILE-2' }
|
151
|
-
let(:first_aws_options)
|
152
|
-
|
153
|
-
aws_access_key: 'aws-access-key',
|
154
|
-
aws_secret_key: 'aws-secret-key',
|
155
|
-
ssh_key_name: 'ssh-key-name',
|
156
|
-
security_group_id: 'security-group-id',
|
157
|
-
public_subnet_id: 'public-subnet-id',
|
158
|
-
private_subnet_id: 'private-subnet-id',
|
159
|
-
elastic_ip_id: 'elastic-ip-id',
|
160
|
-
vm_name: 'vm-name'
|
161
|
-
}
|
162
|
-
end
|
163
|
-
let(:last_aws_options) do
|
164
|
-
{
|
165
|
-
aws_access_key: 'aws-access-key-2',
|
166
|
-
aws_secret_key: 'aws-secret-key-2',
|
167
|
-
ssh_key_name: 'ssh-key-name-2',
|
168
|
-
security_group_id: 'security-group-id-2',
|
169
|
-
public_subnet_id: 'public-subnet-id-2',
|
170
|
-
private_subnet_id: 'private-subnet-id-2',
|
171
|
-
elastic_ip_id: 'elastic-ip-id-2',
|
172
|
-
vm_name: 'vm-name-2'
|
173
|
-
}
|
174
|
-
end
|
167
|
+
let(:first_aws_options) { {vm_name: 'vm-name'} }
|
168
|
+
let(:last_aws_options) { {vm_name: 'vm-name-2'} }
|
175
169
|
|
176
170
|
it 'uses AwsManager to launch a VM' do
|
177
|
-
expect(AwsManager).to receive(:new).with(
|
178
|
-
expect(
|
179
|
-
|
180
|
-
expect(AwsManager).to receive(:new).with(last_aws_options).and_return(last_ams_manager)
|
181
|
-
expect(last_ams_manager).to receive(:deploy).with(last_ami_file_path)
|
171
|
+
expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
|
172
|
+
expect(aws_manager).to receive(:deploy).with(ami_file_path: first_ami_file_path, vm_config: first_aws_options)
|
173
|
+
expect(aws_manager).to receive(:deploy).with(ami_file_path: last_ami_file_path, vm_config: last_aws_options)
|
182
174
|
|
183
175
|
manager.deploy(paths: [first_ami_file_path, last_ami_file_path])
|
184
176
|
end
|
@@ -336,39 +328,14 @@ module VmShepherd
|
|
336
328
|
|
337
329
|
context 'when IAAS is AWS' do
|
338
330
|
let(:settings_fixture_name) { 'aws.yml' }
|
339
|
-
let(:
|
340
|
-
let(:first_ami_options)
|
341
|
-
|
342
|
-
aws_access_key: 'aws-access-key',
|
343
|
-
aws_secret_key: 'aws-secret-key',
|
344
|
-
ssh_key_name: 'ssh-key-name',
|
345
|
-
security_group_id: 'security-group-id',
|
346
|
-
public_subnet_id: 'public-subnet-id',
|
347
|
-
private_subnet_id: 'private-subnet-id',
|
348
|
-
elastic_ip_id: 'elastic-ip-id',
|
349
|
-
vm_name: 'vm-name'
|
350
|
-
}
|
351
|
-
end
|
352
|
-
let(:last_ams_manager) { instance_double(AwsManager) }
|
353
|
-
let(:last_ami_options) do
|
354
|
-
{
|
355
|
-
aws_access_key: 'aws-access-key-2',
|
356
|
-
aws_secret_key: 'aws-secret-key-2',
|
357
|
-
ssh_key_name: 'ssh-key-name-2',
|
358
|
-
security_group_id: 'security-group-id-2',
|
359
|
-
public_subnet_id: 'public-subnet-id-2',
|
360
|
-
private_subnet_id: 'private-subnet-id-2',
|
361
|
-
elastic_ip_id: 'elastic-ip-id-2',
|
362
|
-
vm_name: 'vm-name-2'
|
363
|
-
}
|
364
|
-
end
|
331
|
+
let(:aws_manager) { instance_double(AwsManager) }
|
332
|
+
let(:first_ami_options) { {vm_name: 'vm-name'} }
|
333
|
+
let(:last_ami_options) { {vm_name: 'vm-name-2'} }
|
365
334
|
|
366
335
|
it 'uses AwsManager to destroy a VM' do
|
367
|
-
expect(AwsManager).to receive(:new).with(
|
368
|
-
expect(
|
369
|
-
|
370
|
-
expect(AwsManager).to receive(:new).with(last_ami_options).and_return(last_ams_manager)
|
371
|
-
expect(last_ams_manager).to receive(:destroy)
|
336
|
+
expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
|
337
|
+
expect(aws_manager).to receive(:destroy).with(first_ami_options)
|
338
|
+
expect(aws_manager).to receive(:destroy).with(last_ami_options)
|
372
339
|
|
373
340
|
manager.destroy
|
374
341
|
end
|
@@ -530,38 +497,11 @@ module VmShepherd
|
|
530
497
|
|
531
498
|
context 'when IAAS is AWS' do
|
532
499
|
let(:settings_fixture_name) { 'aws.yml' }
|
533
|
-
let(:
|
534
|
-
let(:first_ami_options) do
|
535
|
-
{
|
536
|
-
aws_access_key: 'aws-access-key',
|
537
|
-
aws_secret_key: 'aws-secret-key',
|
538
|
-
ssh_key_name: 'ssh-key-name',
|
539
|
-
security_group_id: 'security-group-id',
|
540
|
-
public_subnet_id: 'public-subnet-id',
|
541
|
-
private_subnet_id: 'private-subnet-id',
|
542
|
-
elastic_ip_id: 'elastic-ip-id',
|
543
|
-
vm_name: 'vm-name'
|
544
|
-
}
|
545
|
-
end
|
546
|
-
let(:last_ams_manager) { instance_double(AwsManager) }
|
547
|
-
let(:last_ami_options) do
|
548
|
-
{
|
549
|
-
aws_access_key: 'aws-access-key-2',
|
550
|
-
aws_secret_key: 'aws-secret-key-2',
|
551
|
-
ssh_key_name: 'ssh-key-name-2',
|
552
|
-
security_group_id: 'security-group-id-2',
|
553
|
-
public_subnet_id: 'public-subnet-id-2',
|
554
|
-
private_subnet_id: 'private-subnet-id-2',
|
555
|
-
elastic_ip_id: 'elastic-ip-id-2',
|
556
|
-
vm_name: 'vm-name-2'
|
557
|
-
}
|
558
|
-
end
|
500
|
+
let(:aws_manager) { instance_double(AwsManager) }
|
559
501
|
|
560
502
|
it 'uses AwsManager to destroy a VM' do
|
561
|
-
expect(AwsManager).to receive(:new).with(
|
562
|
-
expect(
|
563
|
-
expect(AwsManager).to receive(:new).with(last_ami_options).and_return(last_ams_manager)
|
564
|
-
expect(last_ams_manager).to receive(:clean_environment)
|
503
|
+
expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
|
504
|
+
expect(aws_manager).to receive(:clean_environment)
|
565
505
|
manager.clean_environment
|
566
506
|
end
|
567
507
|
end
|
@@ -605,5 +545,116 @@ module VmShepherd
|
|
605
545
|
end
|
606
546
|
end
|
607
547
|
end
|
548
|
+
|
549
|
+
describe '#prepare_environment' do
|
550
|
+
context 'when IAAS is AWS' do
|
551
|
+
let(:settings_fixture_name) { 'aws.yml' }
|
552
|
+
let(:ams_manager) { instance_double(AwsManager) }
|
553
|
+
|
554
|
+
it 'uses AwsManager to create an environment' do
|
555
|
+
expect(AwsManager).to receive(:new).with(env_config).and_return(ams_manager)
|
556
|
+
expect(ams_manager).to receive(:prepare_environment).with('cloudformation.json')
|
557
|
+
manager.prepare_environment
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
context 'when IAAS is vcloud' do
|
562
|
+
let(:settings_fixture_name) { 'vcloud.yml' }
|
563
|
+
let(:first_vcloud_manager) { instance_double(VcloudManager) }
|
564
|
+
let(:last_vcloud_manager) { instance_double(VcloudManager) }
|
565
|
+
|
566
|
+
it 'uses VcloudManager to destroy a vm' do
|
567
|
+
expect(VcloudManager).to receive(:new).with(
|
568
|
+
{
|
569
|
+
url: first_config.creds.url,
|
570
|
+
organization: first_config.creds.organization,
|
571
|
+
user: first_config.creds.user,
|
572
|
+
password: first_config.creds.password,
|
573
|
+
},
|
574
|
+
first_config.vdc.name,
|
575
|
+
instance_of(Logger)
|
576
|
+
).and_return(first_vcloud_manager)
|
577
|
+
|
578
|
+
expect(first_vcloud_manager).to receive(:prepare_environment)
|
579
|
+
|
580
|
+
expect(VcloudManager).to receive(:new).with(
|
581
|
+
{
|
582
|
+
url: last_config.creds.url,
|
583
|
+
organization: last_config.creds.organization,
|
584
|
+
user: last_config.creds.user,
|
585
|
+
password: last_config.creds.password,
|
586
|
+
},
|
587
|
+
last_config.vdc.name,
|
588
|
+
instance_of(Logger)
|
589
|
+
).and_return(last_vcloud_manager)
|
590
|
+
|
591
|
+
expect(last_vcloud_manager).to receive(:prepare_environment)
|
592
|
+
manager.prepare_environment
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
context 'when IAAS is vsphere' do
|
597
|
+
let(:settings_fixture_name) { 'vsphere.yml' }
|
598
|
+
let(:first_ova_manager) { instance_double(VsphereManager) }
|
599
|
+
let(:last_ova_manager) { instance_double(VsphereManager) }
|
600
|
+
|
601
|
+
it 'uses VsphereManager to destroy a vm' do
|
602
|
+
expect(VsphereManager).to receive(:new).with(
|
603
|
+
first_config.vcenter_creds.ip,
|
604
|
+
first_config.vcenter_creds.username,
|
605
|
+
first_config.vcenter_creds.password,
|
606
|
+
first_config.vsphere.datacenter,
|
607
|
+
).and_return(first_ova_manager)
|
608
|
+
expect(first_ova_manager).to receive(:prepare_environment)
|
609
|
+
expect(VsphereManager).to receive(:new).with(
|
610
|
+
last_config.vcenter_creds.ip,
|
611
|
+
last_config.vcenter_creds.username,
|
612
|
+
last_config.vcenter_creds.password,
|
613
|
+
last_config.vsphere.datacenter,
|
614
|
+
).and_return(last_ova_manager)
|
615
|
+
expect(last_ova_manager).to receive(:prepare_environment)
|
616
|
+
|
617
|
+
manager.prepare_environment
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
context 'when IAAS is Openstack' do
|
622
|
+
let(:settings_fixture_name) { 'openstack.yml' }
|
623
|
+
let(:first_openstack_manager) { instance_double(OpenstackManager) }
|
624
|
+
let(:first_openstack_options) do
|
625
|
+
{
|
626
|
+
auth_url: 'http://example.com/version/tokens',
|
627
|
+
username: 'username',
|
628
|
+
api_key: 'api-key',
|
629
|
+
tenant: 'tenant',
|
630
|
+
}
|
631
|
+
end
|
632
|
+
let(:last_openstack_manager) { instance_double(OpenstackManager) }
|
633
|
+
let(:last_openstack_options) do
|
634
|
+
{
|
635
|
+
auth_url: 'http://example.com/version/tokens-2',
|
636
|
+
username: 'username-2',
|
637
|
+
api_key: 'api-key-2',
|
638
|
+
tenant: 'tenant-2',
|
639
|
+
}
|
640
|
+
end
|
641
|
+
|
642
|
+
it 'uses OpenstackManager to destroy a VM' do
|
643
|
+
expect(OpenstackManager).to receive(:new).with(first_openstack_options).and_return(first_openstack_manager)
|
644
|
+
expect(first_openstack_manager).to receive(:prepare_environment)
|
645
|
+
expect(OpenstackManager).to receive(:new).with(last_openstack_options).and_return(last_openstack_manager)
|
646
|
+
expect(last_openstack_manager).to receive(:prepare_environment)
|
647
|
+
manager.prepare_environment
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
context 'when IAAS is unknown' do
|
652
|
+
let(:settings_fixture_name) { 'unknown.yml' }
|
653
|
+
|
654
|
+
it 'raises an exception' do
|
655
|
+
expect { manager.prepare_environment }.to raise_error(Shepherd::InvalidIaas)
|
656
|
+
end
|
657
|
+
end
|
658
|
+
end
|
608
659
|
end
|
609
660
|
end
|
@@ -21,6 +21,37 @@ module VmShepherd
|
|
21
21
|
expect { vsphere_manager }.not_to raise_error
|
22
22
|
end
|
23
23
|
|
24
|
+
describe 'clean_environment' do
|
25
|
+
let(:connection) { instance_double(RbVmomi::VIM, serviceContent: service_content, searchIndex: search_index)}
|
26
|
+
let(:service_content) { instance_double(RbVmomi::VIM::ServiceContent, searchIndex: search_index)}
|
27
|
+
let(:search_index) { instance_double(RbVmomi::VIM::SearchIndex) }
|
28
|
+
let(:folder) {instance_double(RbVmomi::VIM::Folder) }
|
29
|
+
let(:datacenter) { instance_double(RbVmomi::VIM::Datacenter, name: datacenter_name) }
|
30
|
+
let(:filemanager) { instance_double(RbVmomi::VIM::FileManager) }
|
31
|
+
let(:delete_datastore_file_task) { instance_double(RbVmomi::VIM::Task) }
|
32
|
+
|
33
|
+
before do
|
34
|
+
allow(vsphere_manager).to receive(:connection).and_return(connection)
|
35
|
+
allow(folder).to receive(:traverse).and_return(folder)
|
36
|
+
allow(connection).to receive(:searchIndex).and_return(search_index)
|
37
|
+
allow(search_index).to receive(:FindByInventoryPath).with({inventoryPath: datacenter_name}).and_return(datacenter)
|
38
|
+
allow(datacenter).to receive(:tap).and_return(datacenter)
|
39
|
+
allow(datacenter).to receive(:vmFolder).and_return(folder)
|
40
|
+
allow(folder).to receive(:traverse).with('FAKE_DATACENTER_FOLDERS').and_return(folder)
|
41
|
+
allow(service_content).to receive(:fileManager).and_return(filemanager)
|
42
|
+
# stubbed private methods:
|
43
|
+
allow(subject).to receive(:find_vms).and_return(vms)
|
44
|
+
allow(subject).to receive(:power_off_vm)
|
45
|
+
allow(subject).to receive(:delete_folder_and_vms)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should delete folders and vms' do
|
49
|
+
expect(filemanager).to receive(:DeleteDatastoreFile_Task).and_return(delete_datastore_file_task)
|
50
|
+
expect(delete_datastore_file_task).to receive(:wait_for_completion)
|
51
|
+
vsphere_manager.clean_environment(datacenter_folders_to_clean: ['FAKE_DATACENTER_FOLDERS'], datastores: ['FAKE_DATASTORES'], datastore_folders_to_clean: ['FAKE_DATASTORE_FOLDERS'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
24
55
|
describe 'destroy' do
|
25
56
|
let(:search_index) { instance_double(RbVmomi::VIM::SearchIndex) }
|
26
57
|
let(:service_content) { instance_double(RbVmomi::VIM::ServiceContent, searchIndex: search_index)}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vm_shepherd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ops Manager Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-v1
|