vm_shepherd 3.5.0 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a056d918fa69521babd0636b90a36bbc4e75a9bc
4
- data.tar.gz: 23ec4f0d83d118542fc213139604efaaa5b52fd2
2
+ SHA256:
3
+ metadata.gz: f0c4eae538ba72ae93a1bc16e07b93153be92fb3730b0c1ee995c75aaa7bbec6
4
+ data.tar.gz: c46d2af2473fb238bfb1bec5e85f8ec13d19f9a0e32f5d7c88db23bd0ad3ac25
5
5
  SHA512:
6
- metadata.gz: ce2cf10d6f705dd3633ec9d3c537c97131568ca6d91f5692a3c887d2f42fb44ffbd28ed854814f0d953a842f4424fcad651410c0b0b436a7b8af26dba7ab3a0d
7
- data.tar.gz: be9a971752b45af0359c8bd41825ef85f545ba97a1f69b29119a96816e4821de46ee7e43aeca36705127d99551860c932da318aa5b6c89df0a81fb33b9e586f3
6
+ metadata.gz: c24318537ae944dc68ccd6c214baa05c1906ba78011ae2391a4a1e8b115c5fddc20813f1556a0634a95436dfcf6b73679570bccb35386ac77936e576cc76628e
7
+ data.tar.gz: 8db0afde7bfa78be5acaf6d0736cd0a4d0fb75cce46054777873125a5ead9f6c4a479834bbeb69ab765cba7ca4bc9189708ec9b4ae6119148e231189bc04dcbc
@@ -3,4 +3,4 @@ AllCops:
3
3
  - Gemfile
4
4
  - Rakefile
5
5
  - vm_shepherd.gemspec
6
- TargetRubyVersion: 2.2
6
+ TargetRubyVersion: 2.6
@@ -1 +1 @@
1
- 2.2.4
1
+ 2.6.3
@@ -167,7 +167,7 @@ module VmShepherd
167
167
  key_name: vm_config.fetch('key_name'),
168
168
  security_group_ids: [env_config.fetch('outputs').fetch('security_group')],
169
169
  subnet: env_config.fetch('outputs').fetch('public_subnet_id'),
170
- instance_type: OPS_MANAGER_INSTANCE_TYPE
170
+ instance_type: vm_config.dig('instance_type') || OPS_MANAGER_INSTANCE_TYPE
171
171
  }
172
172
 
173
173
  if (instance_profile = env_config.fetch('outputs').fetch('instance_profile', nil))
@@ -38,7 +38,7 @@ module VmShepherd
38
38
  path,
39
39
  vcloud_deploy_options(vm_shepherd_config),
40
40
  )
41
- when VmShepherd::VSPHERE_IAAS_TYPE then
41
+ when VmShepherd::VSPHERE_IAAS_TYPE then
42
42
  VmShepherd::VsphereManager.new(
43
43
  vm_shepherd_config.dig('vcenter_creds', 'ip'),
44
44
  vm_shepherd_config.dig('vcenter_creds', 'username'),
@@ -164,6 +164,8 @@ module VmShepherd
164
164
  datacenter_folders_to_clean: vm_shepherd_config.dig('cleanup', 'datacenter_folders_to_clean'),
165
165
  datastores: vm_shepherd_config.dig('cleanup', 'datastores'),
166
166
  datastore_folders_to_clean: vm_shepherd_config.dig('cleanup', 'datastore_folders_to_clean'),
167
+ cluster_name: vm_shepherd_config.dig('vsphere', 'cluster'),
168
+ resource_pool_name: vm_shepherd_config.dig('vsphere', 'resource_pool'),
167
169
  )
168
170
  end
169
171
  when VmShepherd::AWS_IAAS_TYPE then
@@ -182,20 +184,31 @@ module VmShepherd
182
184
  end
183
185
 
184
186
  def vsphere_vm_options(input_config)
185
- {
187
+ vsphere_vm_options = {
186
188
  ip: input_config.dig('vm', 'ip'),
187
189
  gateway: input_config.dig('vm', 'gateway'),
188
190
  netmask: input_config.dig('vm', 'netmask'),
189
191
  dns: input_config.dig('vm', 'dns'),
190
192
  ntp_servers: input_config.dig('vm', 'ntp_servers'),
191
193
  cpus: input_config.dig('vm', 'cpus'),
192
- ram_mb: input_config.dig('vm', 'ram_mb'),
193
- vm_password: (input_config.dig('vm', 'vm_password') || 'tempest'),
194
- public_ssh_key: read_assets_home(input_config.dig('vm', 'public_ssh_key')),
194
+ ram_mb: input_config.dig('vm', 'ram_mb')
195
195
  }.tap do |result|
196
196
  hostname = input_config.dig('vm', 'custom_hostname')
197
197
  result[:custom_hostname] = hostname unless hostname.nil?
198
198
  end
199
+
200
+ vsphere_vm_options.merge!(vm_password: get_vsphere_vm_password(input_config))
201
+ vsphere_vm_options.merge!(public_ssh_key: get_vsphere_vm_public_ssh_key(input_config))
202
+
203
+ vsphere_vm_options
204
+ end
205
+
206
+ def get_vsphere_vm_password(input_config)
207
+ ENV['PROVISION_WITH_PASSWORD'] == 'false' ? nil : (input_config.dig('vm', 'vm_password') || ENV['VSPHERE_VM_PASSWORD'] || 'tempest')
208
+ end
209
+
210
+ def get_vsphere_vm_public_ssh_key(input_config)
211
+ ENV['PROVISION_WITH_SSH_KEY'] == 'false' ? nil : (read_assets_home(input_config.dig('vm', 'public_ssh_key')))
199
212
  end
200
213
 
201
214
  def read_assets_home(path_or_value)
@@ -1,3 +1,3 @@
1
1
  module VmShepherd
2
- VERSION = '3.5.0'.freeze
2
+ VERSION = '3.7.1'.freeze
3
3
  end
@@ -27,12 +27,12 @@ module VmShepherd
27
27
  FileUtils.remove_entry_secure(ovf_file_path, force: true) unless ovf_file_path.nil?
28
28
  end
29
29
 
30
- def clean_environment(datacenter_folders_to_clean:, datastores:, datastore_folders_to_clean:)
30
+ def clean_environment(datacenter_folders_to_clean:, datastores:, datastore_folders_to_clean:, cluster_name: nil, resource_pool_name: nil)
31
31
  return if datacenter_folders_to_clean.nil? || datastores.nil? || datacenter_folders_to_clean.nil?
32
32
 
33
33
  datacenter_folders_to_clean.each do |folder_name|
34
34
  validate_folder_name!(folder_name)
35
- delete_folder_and_vms(folder_name)
35
+ delete_folder_and_vms(folder_name, cluster_name, resource_pool_name)
36
36
  end
37
37
 
38
38
  datastore_folders_to_clean.each do |folder_name|
@@ -105,18 +105,23 @@ module VmShepherd
105
105
  end
106
106
 
107
107
  def create_network_mappings(ovf_file_path, vsphere_config)
108
- ovf = Nokogiri::XML(File.read(ovf_file_path))
109
- ovf.remove_namespaces!
108
+ ovf = parse_ovf(ovf_file_path)
110
109
  networks = ovf.xpath('//NetworkSection/Network').map { |x| x['name'] }
111
110
  Hash[networks.map { |ovf_network| [ovf_network, network(vsphere_config)] }]
112
111
  end
113
112
 
113
+ def parse_ovf(ovf_file_path)
114
+ ovf = Nokogiri::XML(File.read(ovf_file_path))
115
+ ovf.remove_namespaces!
116
+ ovf
117
+ end
118
+
114
119
  def boot_vm(ovf_file_path, vm_config, vsphere_config)
115
120
  ensure_folder_exists(vsphere_config[:folder])
116
121
  template = deploy_ovf_template(ovf_file_path, vsphere_config)
117
122
  vm = create_vm_from_template(template, vm_config, vsphere_config)
118
123
 
119
- reconfigure_vm(vm, vm_config)
124
+ reconfigure_vm(vm, vm_config, ovf_file_path)
120
125
  power_on_vm(vm)
121
126
  end
122
127
 
@@ -124,12 +129,13 @@ module VmShepherd
124
129
  datacenter.vmFolder.traverse(folder_name, RbVmomi::VIM::Folder, true)
125
130
  end
126
131
 
127
- def delete_folder_and_vms(folder_name)
132
+ def delete_folder_and_vms(folder_name, cluster_name = nil, resource_pool_name = nil)
128
133
  3.times do |attempt|
129
134
  break unless (folder = datacenter.vmFolder.traverse(folder_name))
130
135
 
131
136
  find_vms(folder).each do |vm|
132
137
  power_off_vm(vm)
138
+ convert_template_to_vm(vm, cluster_name, resource_pool_name)
133
139
  end
134
140
 
135
141
  begin
@@ -155,6 +161,7 @@ module VmShepherd
155
161
 
156
162
  def power_off_vm(vm)
157
163
  2.times do
164
+ # This will implicitly skip over VM templates, which always are in the "poweredOff" state
158
165
  break if vm.runtime.powerState == 'poweredOff'
159
166
 
160
167
  begin
@@ -168,6 +175,14 @@ module VmShepherd
168
175
  end
169
176
  end
170
177
 
178
+ def convert_template_to_vm(vm, cluster_name, resource_pool_name)
179
+ return unless vm.config.template
180
+
181
+ cluster = datacenter.find_compute_resource(cluster_name)
182
+ pool = cluster.resourcePool.resourcePool.find { |rp| rp.name == resource_pool_name }
183
+ vm.MarkAsVirtualMachine(pool: pool)
184
+ end
185
+
171
186
  def deploy_ovf_template(ovf_file_path, vsphere_config)
172
187
  template_name = [TEMPLATE_PREFIX, Time.new.strftime('%F-%H-%M'), cluster(vsphere_config).name].join('-')
173
188
  logger.info("BEGIN deploy_ovf ovf_file=#{ovf_file_path} template_name=#{template_name}")
@@ -233,8 +248,8 @@ module VmShepherd
233
248
  }
234
249
  end
235
250
 
236
- def reconfigure_vm(vm, vm_config)
237
- virtual_machine_config_spec = create_virtual_machine_config_spec(vm_config)
251
+ def reconfigure_vm(vm, vm_config, ovf_file_path)
252
+ virtual_machine_config_spec = create_virtual_machine_config_spec(vm_config, ovf_file_path)
238
253
  logger.info("BEGIN reconfigure_vm_task virtual_machine_config_spec=#{virtual_machine_config_spec.inspect}")
239
254
  vm.ReconfigVM_Task(
240
255
  spec: virtual_machine_config_spec
@@ -243,12 +258,12 @@ module VmShepherd
243
258
  }
244
259
  end
245
260
 
246
- def create_virtual_machine_config_spec(vm_config)
261
+ def create_virtual_machine_config_spec(vm_config, ovf_file_path)
247
262
  logger.info('BEGIN VmConfigSpec creation')
248
263
  vm_config_spec =
249
264
  RbVmomi::VIM::VmConfigSpec.new.tap do |vcs|
250
265
  vcs.ovfEnvironmentTransport = ['com.vmware.guestInfo']
251
- vcs.property = create_vapp_property_specs(vm_config)
266
+ vcs.property = create_vapp_property_specs(vm_config, ovf_file_path)
252
267
  end
253
268
  logger.info("END VmConfigSpec creation: #{vm_config_spec.inspect}")
254
269
 
@@ -259,57 +274,36 @@ module VmShepherd
259
274
  end
260
275
  end
261
276
 
262
- def create_vapp_property_specs(vm_config)
263
- ip_configuration = {
264
- 'ip0' => vm_config[:ip],
265
- 'netmask0' => vm_config[:netmask],
266
- 'gateway' => vm_config[:gateway],
267
- 'DNS' => vm_config[:dns],
277
+ def create_vapp_property_specs(vm_config, ovf_file_path)
278
+ property_value_map = {
279
+ 'ip0' => vm_config[:ip],
280
+ 'netmask0' => vm_config[:netmask],
281
+ 'gateway' => vm_config[:gateway],
282
+ 'DNS' => vm_config[:dns],
268
283
  'ntp_servers' => vm_config[:ntp_servers],
284
+ 'admin_password' => vm_config[:vm_password],
285
+ 'public_ssh_key' => vm_config[:public_ssh_key],
286
+ 'custom_hostname' => vm_config[:custom_hostname],
269
287
  }
270
288
 
271
289
  vapp_property_specs = []
272
290
 
273
- logger.info("BEGIN VAppPropertySpec creation configuration=#{ip_configuration.inspect}")
274
- # IP Configuration key order must match OVF template property order
275
- ip_configuration.each_with_index do |(key, value), i|
291
+ logger.info("BEGIN VAppPropertySpec creation configuration=#{property_value_map.inspect}")
292
+
293
+ # VAppPropertySpec order must match OVF template property order
294
+ ovf = parse_ovf(ovf_file_path)
295
+ ovf.xpath('//ProductSection/Property').each_with_index do |property, index|
296
+ label = property.attribute('key').value
276
297
  vapp_property_specs << RbVmomi::VIM::VAppPropertySpec.new.tap do |spec|
277
298
  spec.operation = 'edit'
278
299
  spec.info = RbVmomi::VIM::VAppPropertyInfo.new.tap do |p|
279
- p.key = i
280
- p.label = key
281
- p.value = value
300
+ p.key = index
301
+ p.label = label
302
+ p.value = property_value_map[label]
282
303
  end
283
304
  end
284
305
  end
285
306
 
286
- vapp_property_specs << RbVmomi::VIM::VAppPropertySpec.new.tap do |spec|
287
- spec.operation = 'edit'
288
- spec.info = RbVmomi::VIM::VAppPropertyInfo.new.tap do |p|
289
- p.key = 5 # this needs to be 5th to match the ovf template property order.
290
- p.label = 'admin_password'
291
- p.value = vm_config[:vm_password]
292
- end
293
- end
294
-
295
- vapp_property_specs << RbVmomi::VIM::VAppPropertySpec.new.tap do |spec|
296
- spec.operation = 'edit'
297
- spec.info = RbVmomi::VIM::VAppPropertyInfo.new.tap do |p|
298
- p.key = 6 # ditto. see above. it makes me sad, too.
299
- p.label = 'public_ssh_key'
300
- p.value = vm_config[:public_ssh_key]
301
- end
302
- end
303
-
304
- vapp_property_specs << RbVmomi::VIM::VAppPropertySpec.new.tap do |spec|
305
- spec.operation = 'edit'
306
- spec.info = RbVmomi::VIM::VAppPropertyInfo.new.tap do |p|
307
- p.key = 7 # ditto. see above. it makes me sad, too.
308
- p.label = 'custom_hostname'
309
- p.value = vm_config[:custom_hostname]
310
- end
311
- end unless vm_config[:custom_hostname].nil?
312
-
313
307
  logger.info("END VAppPropertySpec creation vapp_property_specs=#{vapp_property_specs.inspect}")
314
308
  vapp_property_specs
315
309
  end
@@ -0,0 +1,136 @@
1
+ <?xml version="1.0"?>
2
+ <Envelope ovf:version="1.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xml:lang="en-US" xmlns="http://schemas.dmtf.org/ovf/envelope/1"
5
+ xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
6
+ xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
7
+ xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
8
+ xmlns:vmw="http://www.vmware.com/schema/ovf">
9
+
10
+ <References>
11
+ <File ovf:href="pivotal-ops-manager-disk1.vmdk" ovf:size="4243996160" ovf:id="file1"/>
12
+ </References>
13
+
14
+ <DiskSection>
15
+ <Info>List of the virtual disks used in the package</Info>
16
+ <Disk ovf:capacity="171798603879"
17
+ ovf:diskId="vmdisk1"
18
+ ovf:fileRef="file1"
19
+ ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"/>
20
+ </DiskSection>
21
+
22
+ <NetworkSection>
23
+ <Info>Logical networks used in the package</Info>
24
+ <Network ovf:name="Network 1">
25
+ <Description>Logical network used by this appliance.</Description>
26
+ </Network>
27
+ </NetworkSection>
28
+
29
+ <vmw:IpAssignmentSection ovf:required="false" vmw:protocols="IPv4" vmw:schemes="">
30
+ <Info>Supported IP assignment schemes</Info>
31
+ </vmw:IpAssignmentSection>
32
+
33
+ <VirtualSystem ovf:id="FAKE_FILENAME">
34
+ <Info>A virtual machine</Info>
35
+
36
+ <ProductSection>
37
+ <Info/>
38
+ <Product>Ops Manager</Product>
39
+ <Vendor>Pivotal</Vendor>
40
+ <Version>2.3-build.203</Version>
41
+ <Property ovf:key="ip0" ovf:userConfigurable="true" ovf:type="string">
42
+ <Label>IP Address</Label>
43
+ <Description>The IP address for the Ops Manager. Leave blank if DHCP is desired.</Description>
44
+ </Property>
45
+ <Property ovf:key="netmask0" ovf:userConfigurable="true" ovf:type="string">
46
+ <Label>Netmask</Label>
47
+ <Description>The netmask for the Ops Manager's network. Leave blank if DHCP is desired.</Description>
48
+ </Property>
49
+ <Property ovf:key="gateway" ovf:userConfigurable="true" ovf:type="string">
50
+ <Label>Default Gateway</Label>
51
+ <Description>The default gateway address for the Ops Manager's network. Leave blank if DHCP is desired.</Description>
52
+ </Property>
53
+ <Property ovf:key="DNS" ovf:userConfigurable="true" ovf:type="string">
54
+ <Label>DNS</Label>
55
+ <Description>The domain name servers for the Ops Manager (comma separated). Leave blank if DHCP is desired.</Description>
56
+ </Property>
57
+ <Property ovf:key="ntp_servers" ovf:userConfigurable="true" ovf:type="string">
58
+ <Label>NTP Servers</Label>
59
+ <Description>Comma-delimited list of NTP servers</Description>
60
+ </Property>
61
+ <Property ovf:key="admin_password" ovf:userConfigurable="true" ovf:type="password">
62
+ <Label>Admin Password</Label>
63
+ <Description>This password is used to SSH into the Ops Manager. The username is 'ubuntu'. One or both of Admin Password and SSH Key is required.</Description>
64
+ </Property>
65
+ <Property ovf:key="public_ssh_key" ovf:userConfigurable="true" ovf:type="string">
66
+ <Label>Public SSH Key</Label>
67
+ <Description>The Public SSH Key is used to allow SSHing into the Ops Manager with your private ssh key. The username is 'ubuntu'. One or both of Admin Password and SSH Key is required.</Description>
68
+ </Property>
69
+ <Property ovf:key="custom_hostname" ovf:userConfigurable="true" ovf:type="string">
70
+ <Label>Custom Hostname</Label>
71
+ <Description>This will be set as the hostname on the VM. Default: 'pivotal-ops-manager'.</Description>
72
+ </Property>
73
+ </ProductSection>
74
+
75
+ <AnnotationSection>
76
+ <Info/>
77
+ <Annotation>Ops Manager for Pivotal Cloud Foundry
78
+ installs and manages PCF products and services.</Annotation>
79
+ </AnnotationSection>
80
+
81
+ <VirtualHardwareSection ovf:required="false" ovf:transport="com.vmware.guestInfo">
82
+ <Info>Virtual hardware requirements for a virtual machine</Info>
83
+ <System>
84
+ <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
85
+ <vssd:InstanceID>0</vssd:InstanceID>
86
+ <vssd:VirtualSystemIdentifier>FAKE_FILENAME</vssd:VirtualSystemIdentifier>
87
+ <vssd:VirtualSystemType>vmx-09</vssd:VirtualSystemType>
88
+ </System>
89
+ <Item>
90
+ <rasd:Caption>1 virtual CPU</rasd:Caption>
91
+ <rasd:Description>Number of virtual CPUs</rasd:Description>
92
+ <rasd:ElementName>1 virtual CPU</rasd:ElementName>
93
+ <rasd:InstanceID>1</rasd:InstanceID>
94
+ <rasd:ResourceType>3</rasd:ResourceType>
95
+ <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
96
+ </Item>
97
+ <Item>
98
+ <rasd:AllocationUnits>MegaBytes</rasd:AllocationUnits>
99
+ <rasd:Caption>8192 MB of memory</rasd:Caption>
100
+ <rasd:Description>Memory Size</rasd:Description>
101
+ <rasd:ElementName>8192 MB of memory</rasd:ElementName>
102
+ <rasd:InstanceID>2</rasd:InstanceID>
103
+ <rasd:ResourceType>4</rasd:ResourceType>
104
+ <rasd:VirtualQuantity>8192</rasd:VirtualQuantity>
105
+ </Item>
106
+ <Item>
107
+ <rasd:Address>0</rasd:Address>
108
+ <rasd:Caption>scsiController0</rasd:Caption>
109
+ <rasd:Description>SCSI Controller</rasd:Description>
110
+ <rasd:ElementName>scsiController0</rasd:ElementName>
111
+ <rasd:InstanceID>3</rasd:InstanceID>
112
+ <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
113
+ <rasd:ResourceType>6</rasd:ResourceType>
114
+ </Item>
115
+ <Item>
116
+ <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
117
+ <rasd:Caption>Ethernet adapter on 'Network 1'</rasd:Caption>
118
+ <rasd:Connection>Network 1</rasd:Connection>
119
+ <rasd:ElementName>Ethernet adapter on 'Network 1'</rasd:ElementName>
120
+ <rasd:InstanceID>4</rasd:InstanceID>
121
+ <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
122
+ <rasd:ResourceType>10</rasd:ResourceType>
123
+ </Item>
124
+ <Item>
125
+ <rasd:AddressOnParent>0</rasd:AddressOnParent>
126
+ <rasd:Caption>disk1</rasd:Caption>
127
+ <rasd:Description>Disk Image</rasd:Description>
128
+ <rasd:ElementName>disk1</rasd:ElementName>
129
+ <rasd:HostResource>/disk/vmdisk1</rasd:HostResource>
130
+ <rasd:InstanceID>5</rasd:InstanceID>
131
+ <rasd:Parent>3</rasd:Parent>
132
+ <rasd:ResourceType>17</rasd:ResourceType>
133
+ </Item>
134
+ </VirtualHardwareSection>
135
+ </VirtualSystem>
136
+ </Envelope>
@@ -0,0 +1,132 @@
1
+ <?xml version="1.0"?>
2
+ <Envelope ovf:version="1.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xml:lang="en-US" xmlns="http://schemas.dmtf.org/ovf/envelope/1"
5
+ xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
6
+ xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
7
+ xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
8
+ xmlns:vmw="http://www.vmware.com/schema/ovf">
9
+
10
+ <References>
11
+ <File ovf:href="pivotal-ops-manager-disk1.vmdk" ovf:size="4223308288" ovf:id="file1"/>
12
+ </References>
13
+
14
+ <DiskSection>
15
+ <Info>List of the virtual disks used in the package</Info>
16
+ <Disk ovf:capacity="171798603879"
17
+ ovf:diskId="vmdisk1"
18
+ ovf:fileRef="file1"
19
+ ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"/>
20
+ </DiskSection>
21
+
22
+ <NetworkSection>
23
+ <Info>Logical networks used in the package</Info>
24
+ <Network ovf:name="Network 1">
25
+ <Description>Logical network used by this appliance.</Description>
26
+ </Network>
27
+ </NetworkSection>
28
+
29
+ <vmw:IpAssignmentSection ovf:required="false" vmw:protocols="IPv4" vmw:schemes="">
30
+ <Info>Supported IP assignment schemes</Info>
31
+ </vmw:IpAssignmentSection>
32
+
33
+ <VirtualSystem ovf:id="FAKE_FILENAME">
34
+ <Info>A virtual machine</Info>
35
+
36
+ <ProductSection>
37
+ <Info/>
38
+ <Product>Ops Manager</Product>
39
+ <Vendor>Pivotal</Vendor>
40
+ <Version>2.2-build.365</Version>
41
+ <Property ovf:key="ip0" ovf:userConfigurable="true" ovf:type="string">
42
+ <Label>IP Address</Label>
43
+ <Description>The IP address for the Ops Manager. Leave blank if DHCP is desired.</Description>
44
+ </Property>
45
+ <Property ovf:key="netmask0" ovf:userConfigurable="true" ovf:type="string">
46
+ <Label>Netmask</Label>
47
+ <Description>The netmask for the Ops Manager's network. Leave blank if DHCP is desired.</Description>
48
+ </Property>
49
+ <Property ovf:key="gateway" ovf:userConfigurable="true" ovf:type="string">
50
+ <Label>Default Gateway</Label>
51
+ <Description>The default gateway address for the Ops Manager's network. Leave blank if DHCP is desired.</Description>
52
+ </Property>
53
+ <Property ovf:key="DNS" ovf:userConfigurable="true" ovf:type="string">
54
+ <Label>DNS</Label>
55
+ <Description>The domain name servers for the Ops Manager (comma separated). Leave blank if DHCP is desired.</Description>
56
+ </Property>
57
+ <Property ovf:key="ntp_servers" ovf:userConfigurable="true" ovf:type="string">
58
+ <Label>NTP Servers</Label>
59
+ <Description>Comma-delimited list of NTP servers</Description>
60
+ </Property>
61
+ <Property ovf:key="admin_password" ovf:required="true" ovf:userConfigurable="true" ovf:type="password">
62
+ <Label>Admin Password</Label>
63
+ <Description>This password is used to SSH into the Ops Manager. The username is 'ubuntu'.</Description>
64
+ </Property>
65
+ <Property ovf:key="custom_hostname" ovf:userConfigurable="true" ovf:type="string">
66
+ <Label>Custom Hostname</Label>
67
+ <Description>This will be set as the hostname on the VM. Default: 'pivotal-ops-manager'.</Description>
68
+ </Property>
69
+ </ProductSection>
70
+
71
+ <AnnotationSection>
72
+ <Info/>
73
+ <Annotation>Ops Manager for Pivotal Cloud Foundry
74
+ installs and manages PCF products and services.</Annotation>
75
+ </AnnotationSection>
76
+
77
+ <VirtualHardwareSection ovf:required="false" ovf:transport="com.vmware.guestInfo">
78
+ <Info>Virtual hardware requirements for a virtual machine</Info>
79
+ <System>
80
+ <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
81
+ <vssd:InstanceID>0</vssd:InstanceID>
82
+ <vssd:VirtualSystemIdentifier>FAKE_FILENAME</vssd:VirtualSystemIdentifier>
83
+ <vssd:VirtualSystemType>vmx-09</vssd:VirtualSystemType>
84
+ </System>
85
+ <Item>
86
+ <rasd:Caption>1 virtual CPU</rasd:Caption>
87
+ <rasd:Description>Number of virtual CPUs</rasd:Description>
88
+ <rasd:ElementName>1 virtual CPU</rasd:ElementName>
89
+ <rasd:InstanceID>1</rasd:InstanceID>
90
+ <rasd:ResourceType>3</rasd:ResourceType>
91
+ <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
92
+ </Item>
93
+ <Item>
94
+ <rasd:AllocationUnits>MegaBytes</rasd:AllocationUnits>
95
+ <rasd:Caption>8192 MB of memory</rasd:Caption>
96
+ <rasd:Description>Memory Size</rasd:Description>
97
+ <rasd:ElementName>8192 MB of memory</rasd:ElementName>
98
+ <rasd:InstanceID>2</rasd:InstanceID>
99
+ <rasd:ResourceType>4</rasd:ResourceType>
100
+ <rasd:VirtualQuantity>8192</rasd:VirtualQuantity>
101
+ </Item>
102
+ <Item>
103
+ <rasd:Address>0</rasd:Address>
104
+ <rasd:Caption>scsiController0</rasd:Caption>
105
+ <rasd:Description>SCSI Controller</rasd:Description>
106
+ <rasd:ElementName>scsiController0</rasd:ElementName>
107
+ <rasd:InstanceID>3</rasd:InstanceID>
108
+ <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
109
+ <rasd:ResourceType>6</rasd:ResourceType>
110
+ </Item>
111
+ <Item>
112
+ <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
113
+ <rasd:Caption>Ethernet adapter on 'Network 1'</rasd:Caption>
114
+ <rasd:Connection>Network 1</rasd:Connection>
115
+ <rasd:ElementName>Ethernet adapter on 'Network 1'</rasd:ElementName>
116
+ <rasd:InstanceID>4</rasd:InstanceID>
117
+ <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
118
+ <rasd:ResourceType>10</rasd:ResourceType>
119
+ </Item>
120
+ <Item>
121
+ <rasd:AddressOnParent>0</rasd:AddressOnParent>
122
+ <rasd:Caption>disk1</rasd:Caption>
123
+ <rasd:Description>Disk Image</rasd:Description>
124
+ <rasd:ElementName>disk1</rasd:ElementName>
125
+ <rasd:HostResource>/disk/vmdisk1</rasd:HostResource>
126
+ <rasd:InstanceID>5</rasd:InstanceID>
127
+ <rasd:Parent>3</rasd:Parent>
128
+ <rasd:ResourceType>17</rasd:ResourceType>
129
+ </Item>
130
+ </VirtualHardwareSection>
131
+ </VirtualSystem>
132
+ </Envelope>
@@ -0,0 +1,35 @@
1
+ iaas_type: vsphere
2
+ vm_shepherd:
3
+ vm_configs:
4
+ - vcenter_creds:
5
+ ip: OVA_URL
6
+ username: OVA_ORGANIZATION
7
+ password: OVA_PASSWORD
8
+ vsphere:
9
+ datacenter: VSPHERE_DATACENTER
10
+ cluster: VSPHERE_CLUSTER
11
+ network: VSPHERE_NETWORK
12
+ resource_pool: VSPHERE_RESOURCE_POOL
13
+ datastore: VSPHERE_DATASTORE
14
+ folder: VSPHERE_FOLDER
15
+ vm:
16
+ ip: OVA_IP
17
+ gateway: OVA_GATEWAY
18
+ netmask: OVA_NETMASK
19
+ dns: OVA_DNS
20
+ ntp_servers: OVA_NTP
21
+ public_ssh_key: OVA_SSH_KEY
22
+ cpus: OVA_CPUS
23
+ ram_mb: OVA_RAM_MB
24
+ vm_password: not-tempest
25
+ custom_hostname: not-default-hostname
26
+ cleanup:
27
+ datacenter: VSPHERE_OTHER_DATACENTER
28
+ datastores:
29
+ - VSPHERE_DATASTORE_ONE
30
+ - VSPHERE_DATASTORE_TWO
31
+ datacenter_folders_to_clean:
32
+ - DC_FOLDER_ONE
33
+ - DC_FOLDER_TWO
34
+ datastore_folders_to_clean:
35
+ - DS_DISK_FOLDER
@@ -320,6 +320,27 @@ module VmShepherd
320
320
  end
321
321
  end
322
322
 
323
+ context 'when the instance type is specified in the vm config' do
324
+ let(:vm_config) do
325
+ {
326
+ 'vm_name' => 'some-vm-name',
327
+ 'key_name' => 'ssh-key-name',
328
+ 'instance_type' => 't3.medium'
329
+ }
330
+ end
331
+
332
+ it 'creates an instance' do
333
+ expect(ec2).to receive_message_chain(:instances, :create).with(
334
+ image_id: ami_id,
335
+ key_name: 'ssh-key-name',
336
+ security_group_ids: ['security-group-id'],
337
+ subnet: 'public-subnet-id',
338
+ instance_type: 't3.medium').and_return(instance)
339
+
340
+ ami_manager.deploy(ami_file_path: ami_file_path, vm_config: vm_config)
341
+ end
342
+ end
343
+
323
344
  context 'when the ip address is in use' do
324
345
  it 'retries until the IP address is available' do
325
346
  expect(instances).to receive(:create).and_raise(AWS::EC2::Errors::InvalidIPAddress::InUse).once
@@ -281,6 +281,215 @@ module VmShepherd
281
281
  manager.deploy(paths: ['FIRST_FAKE_PATH', 'LAST_FAKE_PATH'])
282
282
  end
283
283
  end
284
+
285
+ context 'when provision environment variables are set' do
286
+ before do
287
+ allow(VsphereManager).to receive(:new).with(
288
+ first_config.dig('vcenter_creds', 'ip'),
289
+ first_config.dig('vcenter_creds', 'username'),
290
+ first_config.dig('vcenter_creds', 'password'),
291
+ first_config.dig('vsphere', 'datacenter'),
292
+ instance_of(Logger),
293
+ ).and_return(first_ova_manager)
294
+
295
+ allow_any_instance_of(Shepherd).to receive(:read_assets_home).and_return('A PUBLIC KEY')
296
+ end
297
+ let(:settings_fixture_name) { 'vsphere-one-vm-config.yml' }
298
+
299
+ context 'when the PROVISION_WITH_PASSWORD environment variable is set' do
300
+ context 'and it is true' do
301
+ before { stub_const('ENV', {'PROVISION_WITH_PASSWORD' => 'true'}) }
302
+
303
+ context 'when the vm_password is set' do
304
+ before { stub_const('ENV', {'PROVISION_WITH_PASSWORD' => 'true', 'VSPHERE_VM_PASSWORD' => 'a-password'}) }
305
+ it 'deploys with the set vm password' do
306
+ expect(first_ova_manager).to receive(:deploy).with(
307
+ 'FIRST_FAKE_PATH',
308
+ {
309
+ ip: first_config.dig('vm', 'ip'),
310
+ gateway: first_config.dig('vm', 'gateway'),
311
+ netmask: first_config.dig('vm', 'netmask'),
312
+ dns: first_config.dig('vm', 'dns'),
313
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
314
+ cpus: first_config.dig('vm', 'cpus'),
315
+ ram_mb: first_config.dig('vm', 'ram_mb'),
316
+ vm_password: first_config.dig('vm', 'vm_password'),
317
+ public_ssh_key: 'A PUBLIC KEY',
318
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
319
+ },
320
+ {
321
+ cluster: first_config.dig('vsphere', 'cluster'),
322
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
323
+ datastore: first_config.dig('vsphere', 'datastore'),
324
+ network: first_config.dig('vsphere', 'network'),
325
+ folder: first_config.dig('vsphere', 'folder'),
326
+ },
327
+ )
328
+
329
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
330
+ end
331
+ end
332
+
333
+ context 'when the ENV vsphere VM password is set' do
334
+ before do
335
+ stub_const('ENV', { 'PROVISION_WITH_PASSWORD' => 'true', 'VSPHERE_VM_PASSWORD' => 'a-password' })
336
+ first_config['vm']['vm_password'] = nil
337
+ end
338
+
339
+ it 'deploys with the ENV vm password' do
340
+ expect(first_ova_manager).to receive(:deploy).with(
341
+ 'FIRST_FAKE_PATH',
342
+ {
343
+ ip: first_config.dig('vm', 'ip'),
344
+ gateway: first_config.dig('vm', 'gateway'),
345
+ netmask: first_config.dig('vm', 'netmask'),
346
+ dns: first_config.dig('vm', 'dns'),
347
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
348
+ cpus: first_config.dig('vm', 'cpus'),
349
+ ram_mb: first_config.dig('vm', 'ram_mb'),
350
+ vm_password: 'a-password',
351
+ public_ssh_key: 'A PUBLIC KEY',
352
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
353
+ },
354
+ {
355
+ cluster: first_config.dig('vsphere', 'cluster'),
356
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
357
+ datastore: first_config.dig('vsphere', 'datastore'),
358
+ network: first_config.dig('vsphere', 'network'),
359
+ folder: first_config.dig('vsphere', 'folder'),
360
+ },
361
+ )
362
+
363
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
364
+ end
365
+ end
366
+
367
+ context 'and neither vm password is set' do
368
+ before do
369
+ first_config['vm']['vm_password'] = nil
370
+ end
371
+
372
+ it 'deploys with the hardcoded vm password' do
373
+ expect(first_ova_manager).to receive(:deploy).with(
374
+ 'FIRST_FAKE_PATH',
375
+ {
376
+ ip: first_config.dig('vm', 'ip'),
377
+ gateway: first_config.dig('vm', 'gateway'),
378
+ netmask: first_config.dig('vm', 'netmask'),
379
+ dns: first_config.dig('vm', 'dns'),
380
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
381
+ cpus: first_config.dig('vm', 'cpus'),
382
+ ram_mb: first_config.dig('vm', 'ram_mb'),
383
+ vm_password: 'tempest',
384
+ public_ssh_key: 'A PUBLIC KEY',
385
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
386
+ },
387
+ {
388
+ cluster: first_config.dig('vsphere', 'cluster'),
389
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
390
+ datastore: first_config.dig('vsphere', 'datastore'),
391
+ network: first_config.dig('vsphere', 'network'),
392
+ folder: first_config.dig('vsphere', 'folder'),
393
+ },
394
+ )
395
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
396
+ end
397
+ end
398
+ end
399
+
400
+ context 'and it is false' do
401
+ before { stub_const('ENV', {'PROVISION_WITH_PASSWORD' => 'false'}) }
402
+
403
+ it 'deploys with a nil vm password' do
404
+ expect(first_ova_manager).to receive(:deploy).with(
405
+ 'FIRST_FAKE_PATH',
406
+ {
407
+ ip: first_config.dig('vm', 'ip'),
408
+ gateway: first_config.dig('vm', 'gateway'),
409
+ netmask: first_config.dig('vm', 'netmask'),
410
+ dns: first_config.dig('vm', 'dns'),
411
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
412
+ cpus: first_config.dig('vm', 'cpus'),
413
+ ram_mb: first_config.dig('vm', 'ram_mb'),
414
+ vm_password: nil,
415
+ public_ssh_key: 'A PUBLIC KEY',
416
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
417
+ },
418
+ {
419
+ cluster: first_config.dig('vsphere', 'cluster'),
420
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
421
+ datastore: first_config.dig('vsphere', 'datastore'),
422
+ network: first_config.dig('vsphere', 'network'),
423
+ folder: first_config.dig('vsphere', 'folder'),
424
+ },
425
+ )
426
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
427
+ end
428
+ end
429
+ end
430
+
431
+ context 'when the PROVISION_WITH_SSH_KEY environment variable is set' do
432
+ context 'and it is true' do
433
+ before { stub_const('ENV', {'PROVISION_WITH_SSH_KEY' => 'true'}) }
434
+
435
+ it 'deploys with the set public ssh key' do
436
+ expect(first_ova_manager).to receive(:deploy).with(
437
+ 'FIRST_FAKE_PATH',
438
+ {
439
+ ip: first_config.dig('vm', 'ip'),
440
+ gateway: first_config.dig('vm', 'gateway'),
441
+ netmask: first_config.dig('vm', 'netmask'),
442
+ dns: first_config.dig('vm', 'dns'),
443
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
444
+ cpus: first_config.dig('vm', 'cpus'),
445
+ ram_mb: first_config.dig('vm', 'ram_mb'),
446
+ vm_password: first_config.dig('vm', 'vm_password'),
447
+ public_ssh_key: 'A PUBLIC KEY',
448
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
449
+ },
450
+ {
451
+ cluster: first_config.dig('vsphere', 'cluster'),
452
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
453
+ datastore: first_config.dig('vsphere', 'datastore'),
454
+ network: first_config.dig('vsphere', 'network'),
455
+ folder: first_config.dig('vsphere', 'folder'),
456
+ },
457
+ )
458
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
459
+ end
460
+ end
461
+
462
+ context 'and it is false' do
463
+ before { stub_const('ENV', {'PROVISION_WITH_SSH_KEY' => 'false'}) }
464
+
465
+ it 'deploys with a nil public ssh key' do
466
+ expect(first_ova_manager).to receive(:deploy).with(
467
+ 'FIRST_FAKE_PATH',
468
+ {
469
+ ip: first_config.dig('vm', 'ip'),
470
+ gateway: first_config.dig('vm', 'gateway'),
471
+ netmask: first_config.dig('vm', 'netmask'),
472
+ dns: first_config.dig('vm', 'dns'),
473
+ ntp_servers: first_config.dig('vm', 'ntp_servers'),
474
+ cpus: first_config.dig('vm', 'cpus'),
475
+ ram_mb: first_config.dig('vm', 'ram_mb'),
476
+ vm_password: first_config.dig('vm', 'vm_password'),
477
+ public_ssh_key: nil,
478
+ custom_hostname: first_config.dig('vm', 'custom_hostname')
479
+ },
480
+ {
481
+ cluster: first_config.dig('vsphere', 'cluster'),
482
+ resource_pool: first_config.dig('vsphere', 'resource_pool'),
483
+ datastore: first_config.dig('vsphere', 'datastore'),
484
+ network: first_config.dig('vsphere', 'network'),
485
+ folder: first_config.dig('vsphere', 'folder'),
486
+ },
487
+ )
488
+ manager.deploy(paths: ['FIRST_FAKE_PATH'])
489
+ end
490
+ end
491
+ end
492
+ end
284
493
  end
285
494
 
286
495
  context 'with AWS settings' do
@@ -616,6 +825,8 @@ module VmShepherd
616
825
  datacenter_folders_to_clean: first_config.dig('cleanup', 'datacenter_folders_to_clean'),
617
826
  datastores: first_config.dig('cleanup', 'datastores'),
618
827
  datastore_folders_to_clean: first_config.dig('cleanup', 'datastore_folders_to_clean'),
828
+ cluster_name: first_config.dig('vsphere', 'cluster'),
829
+ resource_pool_name: first_config.dig('vsphere', 'resource_pool'),
619
830
  }
620
831
  end
621
832
  let(:last_ova_manager) { instance_double(VsphereManager) }
@@ -624,6 +835,8 @@ module VmShepherd
624
835
  datacenter_folders_to_clean: last_config.dig('cleanup', 'datacenter_folders_to_clean'),
625
836
  datastores: last_config.dig('cleanup', 'datastores'),
626
837
  datastore_folders_to_clean: last_config.dig('cleanup', 'datastore_folders_to_clean'),
838
+ cluster_name: last_config.dig('vsphere', 'cluster'),
839
+ resource_pool_name: last_config.dig('vsphere', 'resource_pool'),
627
840
  }
628
841
  end
629
842
 
@@ -48,18 +48,20 @@ module VmShepherd
48
48
  let(:ovf_template) { instance_double(RbVmomi::VIM::VirtualMachine, name: 'vm_name', add_delta_disk_layer_on_all_disks: nil, MarkAsTemplate: nil) }
49
49
  let(:vsphere_config) { { folder: folder_name, datastore: datastore_name } }
50
50
  let(:vm_config) { {ip: '10.0.0.1'} }
51
+ let(:ovf_path) { 'spec/fixtures/ova_manager/default.ovf' }
51
52
 
52
53
  before do
53
54
  allow(vsphere_manager).to receive(:system).with("nc -z -w 1 #{vm_config[:ip]} 443").and_return(false)
54
55
  allow(vsphere_manager).to receive(:system).with(/tar xfv/).and_return(true)
55
- allow(Dir).to receive(:[]).and_return(['foo.ovf'])
56
+ allow(Dir).to receive(:[]).and_return([ovf_path])
57
+ allow(FileUtils).to receive(:remove_entry_secure)
56
58
  allow(vsphere_manager).to receive(:datacenter).and_return(datacenter)
57
59
  allow(vsphere_manager).to receive(:connection).and_return(connection)
58
60
  allow(ovf_manager).to receive(:deployOVF).and_return(ovf_template)
59
61
  allow(vsphere_manager).to receive(:ovf_template_options).and_return({})
60
62
  end
61
63
 
62
- context 'When custom hostname is not set' do
64
+ context 'When a property value is not set' do
63
65
  it 'verifies the value of custom hostname is nil' do
64
66
  expect(vsphere_manager).to receive(:create_vm_from_template).and_return(vm1)
65
67
  allow(subject).to receive(:power_on_vm)
@@ -69,7 +71,34 @@ module VmShepherd
69
71
  custom_hostname_property = options[:spec].vAppConfig.property.find do |prop|
70
72
  prop.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:label] == 'custom_hostname'
71
73
  end
74
+ expect(custom_hostname_property.info.value).to be_nil
75
+ task
76
+ end
77
+
78
+ subject.deploy(ova_path, vm_config, vsphere_config)
79
+ end
80
+ end
81
+
82
+ context 'When the ovf does not contain a public_ssh_key property' do
83
+ let(:ovf_path) { 'spec/fixtures/ova_manager/without_public_ssh_key.ovf' }
84
+ let(:vm_config) { {ip: '10.0.0.1', custom_hostname: 'meow' } }
85
+
86
+ it 'does not create a property spec' do
87
+ expect(vsphere_manager).to receive(:create_vm_from_template).and_return(vm1)
88
+ allow(subject).to receive(:power_on_vm)
89
+ allow(task).to receive(:wait_for_completion)
90
+
91
+ expect(vm1).to receive(:ReconfigVM_Task) do |options|
92
+ custom_hostname_property = options[:spec].vAppConfig.property.find do |prop|
93
+ prop.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:label] == 'custom_hostname'
94
+ end
95
+ expect(custom_hostname_property.info.key).to eq(6)
96
+
97
+ custom_hostname_property = options[:spec].vAppConfig.property.find do |prop|
98
+ prop.instance_variable_get(:@props)[:info].instance_variable_get(:@props)[:label] == 'public_ssh_key'
99
+ end
72
100
  expect(custom_hostname_property).to be_nil
101
+
73
102
  task
74
103
  end
75
104
 
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'ruby_vcloud_sdk', '0.7.4'
25
25
 
26
26
  spec.add_dependency 'rbvmomi', '1.11.3'
27
+ spec.add_dependency 'xmlrpc'
27
28
 
28
29
  spec.add_development_dependency 'bundler'
29
30
  spec.add_development_dependency 'rake'
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.5.0
4
+ version: 3.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ops Manager Team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-01 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-v1
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.11.3
83
+ - !ruby/object:Gem::Dependency
84
+ name: xmlrpc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bundler
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -167,12 +181,15 @@ files:
167
181
  - lib/vm_shepherd/version.rb
168
182
  - lib/vm_shepherd/vsphere_manager.rb
169
183
  - spec/backport_refinements_spec.rb
184
+ - spec/fixtures/ova_manager/default.ovf
170
185
  - spec/fixtures/ova_manager/foo.ova
186
+ - spec/fixtures/ova_manager/without_public_ssh_key.ovf
171
187
  - spec/fixtures/shepherd/aws-no-elb.yml
172
188
  - spec/fixtures/shepherd/aws.yml
173
189
  - spec/fixtures/shepherd/openstack.yml
174
190
  - spec/fixtures/shepherd/unknown.yml
175
191
  - spec/fixtures/shepherd/vcloud.yml
192
+ - spec/fixtures/shepherd/vsphere-one-vm-config.yml
176
193
  - spec/fixtures/shepherd/vsphere.yml
177
194
  - spec/spec_helper.rb
178
195
  - spec/support/patched_fog.rb
@@ -190,7 +207,7 @@ files:
190
207
  homepage: ''
191
208
  licenses: []
192
209
  metadata: {}
193
- post_install_message:
210
+ post_install_message:
194
211
  rdoc_options: []
195
212
  require_paths:
196
213
  - lib
@@ -205,19 +222,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
222
  - !ruby/object:Gem::Version
206
223
  version: '0'
207
224
  requirements: []
208
- rubyforge_project:
209
- rubygems_version: 2.4.5.1
210
- signing_key:
225
+ rubygems_version: 3.0.3
226
+ signing_key:
211
227
  specification_version: 4
212
228
  summary: A tool for booting and tearing down Ops Manager VMs on various Infrastructures.
213
229
  test_files:
214
230
  - spec/backport_refinements_spec.rb
231
+ - spec/fixtures/ova_manager/default.ovf
215
232
  - spec/fixtures/ova_manager/foo.ova
233
+ - spec/fixtures/ova_manager/without_public_ssh_key.ovf
216
234
  - spec/fixtures/shepherd/aws-no-elb.yml
217
235
  - spec/fixtures/shepherd/aws.yml
218
236
  - spec/fixtures/shepherd/openstack.yml
219
237
  - spec/fixtures/shepherd/unknown.yml
220
238
  - spec/fixtures/shepherd/vcloud.yml
239
+ - spec/fixtures/shepherd/vsphere-one-vm-config.yml
221
240
  - spec/fixtures/shepherd/vsphere.yml
222
241
  - spec/spec_helper.rb
223
242
  - spec/support/patched_fog.rb