vm_shepherd 3.3.2 → 3.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25a49a93d04e9d20815c0e49f6d1a59b0dcfec95
4
- data.tar.gz: 0884c51e7c2c8fee2a9211fb401eac3c07786bb7
3
+ metadata.gz: c20a4fbcccc9a014091dfb3b562f1a7a229250a4
4
+ data.tar.gz: 1474fc28386000077c69a829b3520d489c82186e
5
5
  SHA512:
6
- metadata.gz: 3771e8eae943ca778bde5c58ad09a751a0f5d1d53e893f0bea4d4f397851b1067aa77b36eb598eef374799e5f1b720f2d9d66f89af562e52cd9deb0253978e14
7
- data.tar.gz: 5f43ab61a483e64fda40436bd49945803522a1d24e39aca8b33465f993fd27f18a77aef8d0384c83b249b0c9e29258085b2b0075c7be78b743c1b85490970a45
6
+ metadata.gz: 5d89cffd243b8fb4530b56dff8e6e8b77e46035ac429aa2ece3b271e1d7df5150647d1337481a7edd903ba8e33c9a277fbfcb7007821d7b6d44dd15a7b218bb7
7
+ data.tar.gz: 0d5c833739ff2b3217739060375d09abe51b0f7199d7e1ea5c90ca10c0c20b6d573150f9ac376e88bc514615a5623d3599f4f4b49ad2b1d36f17db72a0d9ee31
@@ -9,8 +9,8 @@ module VmShepherd
9
9
  end
10
10
 
11
11
  def initialize(settings:)
12
- @iaas_type = settings.dig('iaas_type')
13
- @configs = settings.dig('vm_shepherd', 'vm_configs') || []
12
+ @iaas_type = settings.dig('iaas_type')
13
+ @configs = settings.dig('vm_shepherd', 'vm_configs') || []
14
14
  @env_config = settings.dig('vm_shepherd', 'env_config')
15
15
  end
16
16
 
@@ -26,10 +26,10 @@ module VmShepherd
26
26
  when VmShepherd::VCLOUD_IAAS_TYPE then
27
27
  VmShepherd::VcloudManager.new(
28
28
  {
29
- url: vm_shepherd_config.dig('creds', 'url'),
29
+ url: vm_shepherd_config.dig('creds', 'url'),
30
30
  organization: vm_shepherd_config.dig('creds', 'organization'),
31
- user: vm_shepherd_config.dig('creds', 'user'),
32
- password: vm_shepherd_config.dig('creds', 'password'),
31
+ user: vm_shepherd_config.dig('creds', 'user'),
32
+ password: vm_shepherd_config.dig('creds', 'password'),
33
33
  },
34
34
  vm_shepherd_config.dig('vdc', 'name'),
35
35
  stdout_logger
@@ -46,22 +46,13 @@ module VmShepherd
46
46
  stdout_logger,
47
47
  ).deploy(
48
48
  path,
49
+ vsphere_vm_options(vm_shepherd_config),
49
50
  {
50
- ip: vm_shepherd_config.dig('vm', 'ip'),
51
- gateway: vm_shepherd_config.dig('vm', 'gateway'),
52
- netmask: vm_shepherd_config.dig('vm', 'netmask'),
53
- dns: vm_shepherd_config.dig('vm', 'dns'),
54
- ntp_servers: vm_shepherd_config.dig('vm', 'ntp_servers'),
55
- cpus: vm_shepherd_config.dig('vm', 'cpus'),
56
- ram_mb: vm_shepherd_config.dig('vm', 'ram_mb'),
57
- vm_password: (vm_shepherd_config.dig('vm', 'vm_password') || 'tempest'),
58
- },
59
- {
60
- cluster: vm_shepherd_config.dig('vsphere', 'cluster'),
51
+ cluster: vm_shepherd_config.dig('vsphere', 'cluster'),
61
52
  resource_pool: vm_shepherd_config.dig('vsphere', 'resource_pool'),
62
- datastore: vm_shepherd_config.dig('vsphere', 'datastore'),
63
- network: vm_shepherd_config.dig('vsphere', 'network'),
64
- folder: vm_shepherd_config.dig('vsphere', 'folder'),
53
+ datastore: vm_shepherd_config.dig('vsphere', 'datastore'),
54
+ network: vm_shepherd_config.dig('vsphere', 'network'),
55
+ folder: vm_shepherd_config.dig('vsphere', 'folder'),
65
56
  }
66
57
  )
67
58
  when VmShepherd::AWS_IAAS_TYPE then
@@ -81,10 +72,10 @@ module VmShepherd
81
72
  @configs.each do |vm_shepherd_config|
82
73
  VmShepherd::VcloudManager.new(
83
74
  {
84
- url: vm_shepherd_config.dig('creds', 'url'),
75
+ url: vm_shepherd_config.dig('creds', 'url'),
85
76
  organization: vm_shepherd_config.dig('creds', 'organization'),
86
- user: vm_shepherd_config.dig('creds', 'user'),
87
- password: vm_shepherd_config.dig('creds', 'password'),
77
+ user: vm_shepherd_config.dig('creds', 'user'),
78
+ password: vm_shepherd_config.dig('creds', 'password'),
88
79
  },
89
80
  vm_shepherd_config.dig('vdc', 'name'),
90
81
  stdout_logger
@@ -118,10 +109,10 @@ module VmShepherd
118
109
  when VmShepherd::VCLOUD_IAAS_TYPE then
119
110
  VmShepherd::VcloudManager.new(
120
111
  {
121
- url: vm_shepherd_config.dig('creds', 'url'),
112
+ url: vm_shepherd_config.dig('creds', 'url'),
122
113
  organization: vm_shepherd_config.dig('creds', 'organization'),
123
- user: vm_shepherd_config.dig('creds', 'user'),
124
- password: vm_shepherd_config.dig('creds', 'password'),
114
+ user: vm_shepherd_config.dig('creds', 'user'),
115
+ password: vm_shepherd_config.dig('creds', 'password'),
125
116
  },
126
117
  vm_shepherd_config.dig('vdc', 'name'),
127
118
  stdout_logger
@@ -151,10 +142,10 @@ module VmShepherd
151
142
  @configs.each do |vm_shepherd_config|
152
143
  VmShepherd::VcloudManager.new(
153
144
  {
154
- url: vm_shepherd_config.dig('creds', 'url'),
145
+ url: vm_shepherd_config.dig('creds', 'url'),
155
146
  organization: vm_shepherd_config.dig('creds', 'organization'),
156
- user: vm_shepherd_config.dig('creds', 'user'),
157
- password: vm_shepherd_config.dig('creds', 'password'),
147
+ user: vm_shepherd_config.dig('creds', 'user'),
148
+ password: vm_shepherd_config.dig('creds', 'password'),
158
149
  },
159
150
  vm_shepherd_config.dig('vdc', 'name'),
160
151
  stdout_logger,
@@ -170,8 +161,8 @@ module VmShepherd
170
161
  stdout_logger,
171
162
  ).clean_environment(
172
163
  datacenter_folders_to_clean: vm_shepherd_config.dig('cleanup', 'datacenter_folders_to_clean'),
173
- datastores: vm_shepherd_config.dig('cleanup', 'datastores'),
174
- datastore_folders_to_clean: vm_shepherd_config.dig('cleanup', 'datastore_folders_to_clean'),
164
+ datastores: vm_shepherd_config.dig('cleanup', 'datastores'),
165
+ datastore_folders_to_clean: vm_shepherd_config.dig('cleanup', 'datastore_folders_to_clean'),
175
166
  )
176
167
  end
177
168
  when VmShepherd::AWS_IAAS_TYPE then
@@ -185,19 +176,34 @@ module VmShepherd
185
176
 
186
177
  private
187
178
 
188
-
189
179
  def stdout_logger
190
180
  Logger.new(STDOUT)
191
181
  end
192
182
 
183
+ def vsphere_vm_options(input_config)
184
+ {
185
+ ip: input_config.dig('vm', 'ip'),
186
+ gateway: input_config.dig('vm', 'gateway'),
187
+ netmask: input_config.dig('vm', 'netmask'),
188
+ dns: input_config.dig('vm', 'dns'),
189
+ ntp_servers: input_config.dig('vm', 'ntp_servers'),
190
+ cpus: input_config.dig('vm', 'cpus'),
191
+ ram_mb: input_config.dig('vm', 'ram_mb'),
192
+ vm_password: (input_config.dig('vm', 'vm_password') || 'tempest'),
193
+ }.tap do |result|
194
+ hostname = input_config.dig('vm', 'custom_hostname')
195
+ result[:custom_hostname] = hostname unless hostname.nil?
196
+ end
197
+ end
198
+
193
199
  def vcloud_deploy_options(vm_shepherd_config)
194
200
  VmShepherd::Vcloud::VappConfig.new(
195
- name: vm_shepherd_config.dig('vapp', 'ops_manager_name'),
196
- ip: vm_shepherd_config.dig('vapp', 'ip'),
201
+ name: vm_shepherd_config.dig('vapp', 'ops_manager_name'),
202
+ ip: vm_shepherd_config.dig('vapp', 'ip'),
197
203
  gateway: vm_shepherd_config.dig('vapp', 'gateway'),
198
204
  netmask: vm_shepherd_config.dig('vapp', 'netmask'),
199
- dns: vm_shepherd_config.dig('vapp', 'dns'),
200
- ntp: vm_shepherd_config.dig('vapp', 'ntp'),
205
+ dns: vm_shepherd_config.dig('vapp', 'dns'),
206
+ ntp: vm_shepherd_config.dig('vapp', 'ntp'),
201
207
  catalog: vm_shepherd_config.dig('vdc', 'catalog'),
202
208
  network: vm_shepherd_config.dig('vdc', 'network'),
203
209
  )
@@ -229,20 +235,20 @@ module VmShepherd
229
235
  OpenstackManager.new(
230
236
  auth_url: vm_shepherd_config.dig('creds', 'auth_url'),
231
237
  username: vm_shepherd_config.dig('creds', 'username'),
232
- api_key: vm_shepherd_config.dig('creds', 'api_key'),
233
- tenant: vm_shepherd_config.dig('creds', 'tenant'),
238
+ api_key: vm_shepherd_config.dig('creds', 'api_key'),
239
+ tenant: vm_shepherd_config.dig('creds', 'tenant'),
234
240
  )
235
241
  end
236
242
 
237
243
  def openstack_vm_options(vm_shepherd_config)
238
244
  {
239
- name: vm_shepherd_config.dig('vm', 'name'),
240
- flavor_name: vm_shepherd_config.dig('vm', 'flavor_name'),
241
- network_name: vm_shepherd_config.dig('vm', 'network_name'),
242
- key_name: vm_shepherd_config.dig('vm', 'key_name'),
245
+ name: vm_shepherd_config.dig('vm', 'name'),
246
+ flavor_name: vm_shepherd_config.dig('vm', 'flavor_name'),
247
+ network_name: vm_shepherd_config.dig('vm', 'network_name'),
248
+ key_name: vm_shepherd_config.dig('vm', 'key_name'),
243
249
  security_group_names: vm_shepherd_config.dig('vm', 'security_group_names'),
244
- public_ip: vm_shepherd_config.dig('vm', 'public_ip'),
245
- private_ip: vm_shepherd_config.dig('vm', 'private_ip'),
250
+ public_ip: vm_shepherd_config.dig('vm', 'public_ip'),
251
+ private_ip: vm_shepherd_config.dig('vm', 'private_ip'),
246
252
  }
247
253
  end
248
254
 
@@ -1,3 +1,3 @@
1
1
  module VmShepherd
2
- VERSION = '3.3.2'.freeze
2
+ VERSION = '3.4.0'.freeze
3
3
  end
@@ -112,7 +112,7 @@ module VmShepherd
112
112
  end
113
113
 
114
114
  def boot_vm(ovf_file_path, vm_config, vsphere_config)
115
- datacenter.vmFolder.traverse(vsphere_config[:folder], RbVmomi::VIM::Folder, true)
115
+ ensure_folder_exists(vsphere_config[:folder])
116
116
  template = deploy_ovf_template(ovf_file_path, vsphere_config)
117
117
  vm = create_vm_from_template(template, vm_config, vsphere_config)
118
118
 
@@ -120,6 +120,10 @@ module VmShepherd
120
120
  power_on_vm(vm)
121
121
  end
122
122
 
123
+ def ensure_folder_exists(folder_name)
124
+ datacenter.vmFolder.traverse(folder_name, RbVmomi::VIM::Folder, true)
125
+ end
126
+
123
127
  def delete_folder_and_vms(folder_name)
124
128
  3.times do |attempt|
125
129
  break unless (folder = datacenter.vmFolder.traverse(folder_name))
@@ -167,7 +171,17 @@ module VmShepherd
167
171
  def deploy_ovf_template(ovf_file_path, vsphere_config)
168
172
  template_name = [TEMPLATE_PREFIX, Time.new.strftime('%F-%H-%M'), cluster(vsphere_config).name].join('-')
169
173
  logger.info("BEGIN deploy_ovf ovf_file=#{ovf_file_path} template_name=#{template_name}")
174
+
170
175
  connection.serviceContent.ovfManager.deployOVF(
176
+ ovf_template_options(ovf_file_path, template_name, vsphere_config)
177
+ ).tap do |ovf_template|
178
+ ovf_template.add_delta_disk_layer_on_all_disks
179
+ ovf_template.MarkAsTemplate
180
+ end
181
+ end
182
+
183
+ def ovf_template_options(ovf_file_path, template_name, vsphere_config)
184
+ {
171
185
  uri: ovf_file_path,
172
186
  vmName: template_name,
173
187
  vmFolder: target_folder(vsphere_config),
@@ -176,10 +190,7 @@ module VmShepherd
176
190
  datastore: datastore(vsphere_config),
177
191
  networkMappings: create_network_mappings(ovf_file_path, vsphere_config),
178
192
  propertyMappings: {},
179
- ).tap do |ovf_template|
180
- ovf_template.add_delta_disk_layer_on_all_disks
181
- ovf_template.MarkAsTemplate
182
- end
193
+ }
183
194
  end
184
195
 
185
196
  def find_deploy_host(vsphere_config)
@@ -203,7 +214,7 @@ module VmShepherd
203
214
  end
204
215
 
205
216
  def create_vm_from_template(template, vm_config, vsphere_config)
206
- logger.info("BEGIN clone_vm_task tempalte=#{template.name}")
217
+ logger.info("BEGIN clone_vm_task template=#{template.name}")
207
218
  template.CloneVM_Task(
208
219
  folder: target_folder(vsphere_config),
209
220
  name: "#{template.name}-vm",
@@ -218,17 +229,17 @@ module VmShepherd
218
229
  config: {numCPUs: vm_config[:cpus] || 2, memoryMB: vm_config[:ram_mb] || 4096},
219
230
  }
220
231
  ).wait_for_completion.tap {
221
- logger.info("END clone_vm_task tempalte=#{template.name}")
232
+ logger.info("END clone_vm_task template=#{template.name}")
222
233
  }
223
234
  end
224
235
 
225
236
  def reconfigure_vm(vm, vm_config)
226
237
  virtual_machine_config_spec = create_virtual_machine_config_spec(vm_config)
227
- logger.info("BEGIN reconfigure_vm_task virtual_machine_cofig_spec=#{virtual_machine_config_spec.inspect}")
238
+ logger.info("BEGIN reconfigure_vm_task virtual_machine_config_spec=#{virtual_machine_config_spec.inspect}")
228
239
  vm.ReconfigVM_Task(
229
240
  spec: virtual_machine_config_spec
230
241
  ).wait_for_completion.tap {
231
- logger.info("END reconfigure_vm_task virtual_machine_cofig_spec=#{virtual_machine_config_spec.inspect}")
242
+ logger.info("END reconfigure_vm_task virtual_machine_config_spec=#{virtual_machine_config_spec.inspect}")
232
243
  }
233
244
  end
234
245
 
@@ -255,6 +266,7 @@ module VmShepherd
255
266
  'gateway' => vm_config[:gateway],
256
267
  'DNS' => vm_config[:dns],
257
268
  'ntp_servers' => vm_config[:ntp_servers],
269
+ 'custom_hostname' => vm_config[:custom_hostname],
258
270
  }
259
271
 
260
272
  vapp_property_specs = []
@@ -21,6 +21,7 @@ vm_shepherd:
21
21
  cpus: OVA_CPUS
22
22
  ram_mb: OVA_RAM_MB
23
23
  vm_password: not-tempest
24
+ custom_hostname: not-default-hostname
24
25
  cleanup:
25
26
  datacenter: VSPHERE_OTHER_DATACENTER
26
27
  datastores:
@@ -151,6 +151,7 @@ module VmShepherd
151
151
  cpus: first_config.dig('vm', 'cpus'),
152
152
  ram_mb: first_config.dig('vm', 'ram_mb'),
153
153
  vm_password: first_config.dig('vm', 'vm_password'),
154
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
154
155
  },
155
156
  {
156
157
  cluster: first_config.dig('vsphere', 'cluster'),
@@ -10,7 +10,30 @@ module VmShepherd
10
10
  let(:vm2) { instance_double(RbVmomi::VIM::VirtualMachine, name: 'vm_name2', resourcePool: instance_double(RbVmomi::VIM::ResourcePool, name: 'second_resource_pool')) }
11
11
  let(:vm3) { instance_double(RbVmomi::VIM::VirtualMachine, name: 'vm_name3', resourcePool: instance_double(RbVmomi::VIM::ResourcePool, name: 'second_resource_pool')) }
12
12
  let(:vms) { [vm1, vm2, vm3] }
13
+ let(:task) { instance_double(RbVmomi::VIM::Task) }
13
14
  let(:fake_logger) { instance_double(Logger).as_null_object }
15
+ let(:datacenter) do
16
+ instance_double(RbVmomi::VIM::Datacenter,
17
+ name: datacenter_name,
18
+ vmFolder: folder,
19
+ find_compute_resource: cluster,
20
+ find_datastore: datastore
21
+ )
22
+ end
23
+ let(:datastore) { double(name: datastore_name) }
24
+ let(:datastore_name) { 'datastore-name' }
25
+ let(:cluster) { instance_double(RbVmomi::VIM::ComputeResource, name: 'cluster-name', host: [host], resourcePool: double)}
26
+ let(:folder) { instance_double(RbVmomi::VIM::Folder, traverse: instance_double(RbVmomi::VIM::Folder)) }
27
+ let(:connection) { instance_double(RbVmomi::VIM, serviceContent: service_content, searchIndex: search_index) }
28
+ let(:service_content) do
29
+ instance_double(RbVmomi::VIM::ServiceContent,
30
+ searchIndex: search_index,
31
+ ovfManager: ovf_manager,
32
+ propertyCollector: instance_double(RbVmomi::VIM::PropertyCollector, collectMultiple: {}),
33
+ )
34
+ end
35
+ let(:search_index) { instance_double(RbVmomi::VIM::SearchIndex) }
36
+ let(:ovf_manager) { instance_double(RbVmomi::VIM::OvfManager) }
14
37
 
15
38
  subject(:vsphere_manager) { VsphereManager.new(host, username, password, datacenter_name, fake_logger) }
16
39
 
@@ -18,12 +41,69 @@ module VmShepherd
18
41
  expect { vsphere_manager }.not_to raise_error
19
42
  end
20
43
 
44
+ describe 'deploy' do
45
+ let(:tar_path) { 'example-tar' }
46
+ let(:ova_path) { 'example-ova' }
47
+ let(:folder_name) { 'example-folder' }
48
+ let(:ovf_template) { instance_double(RbVmomi::VIM::VirtualMachine, name: 'vm_name', add_delta_disk_layer_on_all_disks: nil, MarkAsTemplate: nil) }
49
+ let(:vsphere_config) { { folder: folder_name, datastore: datastore_name } }
50
+ let(:vm_config) { {ip: '10.0.0.1'} }
51
+
52
+ before do
53
+ allow(vsphere_manager).to receive(:system).with("nc -z -w 1 #{vm_config[:ip]} 443").and_return(false)
54
+ allow(vsphere_manager).to receive(:system).with(/tar xfv/).and_return(true)
55
+ allow(Dir).to receive(:[]).and_return(['foo.ovf'])
56
+ allow(vsphere_manager).to receive(:datacenter).and_return(datacenter)
57
+ allow(vsphere_manager).to receive(:connection).and_return(connection)
58
+ allow(ovf_manager).to receive(:deployOVF).and_return(ovf_template)
59
+ allow(vsphere_manager).to receive(:ovf_template_options).and_return({})
60
+ end
61
+
62
+ context 'When custom hostname is not set' do
63
+
64
+ it 'verifies the value of custom hostname is nil' do
65
+ expect(vsphere_manager).to receive(:create_vm_from_template).and_return(vm1)
66
+ allow(subject).to receive(:power_on_vm)
67
+ allow(task).to receive(:wait_for_completion)
68
+
69
+ expect(vm1).to receive(:ReconfigVM_Task) do |options|
70
+ custom_hostname_property = options[:spec].vAppConfig.property.find do |prop|
71
+ prop.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:label] == 'custom_hostname'
72
+ end
73
+ expect(custom_hostname_property).to_not be_nil
74
+ custom_hostname_value = custom_hostname_property.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:value]
75
+ expect(custom_hostname_value).to be_nil
76
+ task
77
+ end
78
+
79
+ subject.deploy(ova_path, vm_config, vsphere_config)
80
+ end
81
+ end
82
+
83
+ context 'When custom hostname is set' do
84
+ let(:vm_config) { {ip: '10.0.0.1', custom_hostname: 'meow' } }
85
+ it 'sets the custom hostname' do
86
+ expect(vsphere_manager).to receive(:create_vm_from_template).and_return(vm1)
87
+ allow(subject).to receive(:power_on_vm)
88
+ allow(task).to receive(:wait_for_completion)
89
+
90
+ expect(vm1).to receive(:ReconfigVM_Task) do |options|
91
+ custom_hostname_property = options[:spec].vAppConfig.property.find do |prop|
92
+ prop.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:label] == 'custom_hostname'
93
+ end
94
+ expect(custom_hostname_property).to_not be_nil
95
+ custom_hostname_value = custom_hostname_property.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:value]
96
+ expect(custom_hostname_value).to eq('meow')
97
+ task
98
+ end
99
+
100
+ subject.deploy(ova_path, vm_config, vsphere_config)
101
+ end
102
+ end
103
+ end
104
+
21
105
  describe 'clean_environment' do
22
- let(:connection) { instance_double(RbVmomi::VIM, serviceContent: service_content, searchIndex: search_index) }
23
- let(:service_content) { instance_double(RbVmomi::VIM::ServiceContent, searchIndex: search_index) }
24
- let(:search_index) { instance_double(RbVmomi::VIM::SearchIndex) }
25
- let(:folder) { instance_double(RbVmomi::VIM::Folder) }
26
- let(:datacenter) { instance_double(RbVmomi::VIM::Datacenter, name: datacenter_name) }
106
+
27
107
  let(:filemanager) { instance_double(RbVmomi::VIM::FileManager) }
28
108
  let(:delete_datastore_file_task) { instance_double(RbVmomi::VIM::Task) }
29
109
 
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: 3.3.2
4
+ version: 3.4.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: 2016-11-09 00:00:00.000000000 Z
11
+ date: 2016-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-v1
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
206
  version: '0'
207
207
  requirements: []
208
208
  rubyforge_project:
209
- rubygems_version: 2.6.6
209
+ rubygems_version: 2.4.5.1
210
210
  signing_key:
211
211
  specification_version: 4
212
212
  summary: A tool for booting and tearing down Ops Manager VMs on various Infrastructures.