Adding filename and destroy options to vmware_guest_disk (#63740)

Adding filename and destroy options to vmware_guest_disk
This commit is contained in:
Jiri Tyr 2019-12-10 15:30:15 +00:00 committed by Gonéri Le Bouder
parent 02539c9a37
commit f89db2af99
2 changed files with 60 additions and 14 deletions

View file

@ -0,0 +1,5 @@
---
minor_changes:
- vmware_guest_disk - Add `destroy` option which allows to remove a disk without deleting the VMDK file.
- vmware_guest_disk - Add `filename` option which allows to create a disk from an existing VMDK.

View file

@ -104,6 +104,10 @@ options:
- ' This value is ignored, if SCSI Controller is already present or C(state) is C(absent).'
- ' Valid values are C(buslogic), C(lsilogic), C(lsilogicsas) and C(paravirtual).'
- ' C(paravirtual) is default value for this parameter.'
- ' - C(destroy) (bool): If C(state) is C(absent), make sure the disk file is deleted from the datastore (default C(yes)).'
- ' Added in version 2.10.'
- ' - C(filename) (string): Existing disk image to be used. Filename must already exist on the datastore.'
- ' Specify filename string in C([datastore_name] path/to/file.vmdk) format. Added in version 2.10.'
- ' - C(state) (string): State of disk. This is either "absent" or "present".'
- ' If C(state) is set to C(absent), disk will be removed permanently from virtual machine configuration and from VMware storage.'
- ' If C(state) is set to C(present), disk will be added if not present at given SCSI Controller and Unit Number.'
@ -148,10 +152,11 @@ EXAMPLES = '''
scsi_type: 'buslogic'
unit_number: 1
disk_mode: 'independent_nonpersistent'
- filename: "[datastore1] path/to/existing/disk.vmdk"
delegate_to: localhost
register: disk_facts
- name: Remove disks from virtual machine using name
- name: Remove disk from virtual machine using name
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
@ -166,7 +171,7 @@ EXAMPLES = '''
delegate_to: localhost
register: disk_facts
- name: Remove disks from virtual machine using moid
- name: Remove disk from virtual machine using moid
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
@ -180,6 +185,22 @@ EXAMPLES = '''
unit_number: 1
delegate_to: localhost
register: disk_facts
- name: Remove disk from virtual machine but keep the VMDK file on the datastore
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter_name }}"
validate_certs: no
name: VM_225
disk:
- state: absent
scsi_controller: 1
unit_number: 2
destroy: no
delegate_to: localhost
register: disk_facts
'''
RETURN = """
@ -251,24 +272,31 @@ class PyVmomiHelper(PyVmomi):
return scsi_ctl
@staticmethod
def create_scsi_disk(scsi_ctl_key, disk_index, disk_mode):
def create_scsi_disk(scsi_ctl_key, disk_index, disk_mode, disk_filename):
"""
Create Virtual Device Spec for virtual disk
Args:
scsi_ctl_key: Unique SCSI Controller Key
disk_index: Disk unit number at which disk needs to be attached
disk_mode: Disk mode
disk_filename: Path to the disk file on the datastore
Returns: Virtual Device Spec for virtual disk
"""
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
disk_spec.device.backing.diskMode = disk_mode
disk_spec.device.controllerKey = scsi_ctl_key
disk_spec.device.unitNumber = disk_index
if disk_filename is not None:
disk_spec.device.backing.fileName = disk_filename
else:
disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create
return disk_spec
def reconfigure_vm(self, config_spec, device_type):
@ -347,16 +375,21 @@ class PyVmomiHelper(PyVmomi):
scsi_controller = disk['scsi_controller'] + 1000 # VMware auto assign 1000 + SCSI Controller
if disk['disk_unit_number'] not in current_scsi_info[scsi_controller]['disks'] and disk['state'] == 'present':
# Add new disk
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'])
disk_spec.device.capacityInKB = disk['size']
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'], disk['filename'])
if disk['filename'] is None:
disk_spec.device.capacityInKB = disk['size']
if disk['disk_type'] == 'thin':
disk_spec.device.backing.thinProvisioned = True
elif disk['disk_type'] == 'eagerzeroedthick':
disk_spec.device.backing.eagerlyScrub = True
disk_spec.device.backing.fileName = "[%s] %s/%s_%s_%s.vmdk" % (disk['datastore'].name,
vm_name, vm_name,
str(scsi_controller),
str(disk['disk_unit_number']))
if disk['filename'] is None:
disk_spec.device.backing.fileName = "[%s] %s/%s_%s_%s.vmdk" % (
disk['datastore'].name,
vm_name, vm_name,
str(scsi_controller),
str(disk['disk_unit_number']))
else:
disk_spec.device.backing.fileName = disk['filename']
disk_spec.device.backing.datastore = disk['datastore']
self.config_spec.deviceChange.append(disk_spec)
disk_change = True
@ -386,7 +419,8 @@ class PyVmomiHelper(PyVmomi):
# Disk already exists, deleting
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy
if disk['destroy'] is True:
disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy
disk_spec.device = current_scsi_info[scsi_controller]['disks'][disk['disk_unit_number']]
self.config_spec.deviceChange.append(disk_spec)
disk_change = True
@ -420,6 +454,8 @@ class PyVmomiHelper(PyVmomi):
# Initialize default value for disk
current_disk = dict(disk_index=disk_index,
state='present',
destroy=True,
filename=None,
datastore=None,
autoselect_datastore=True,
disk_unit_number=0,
@ -434,7 +470,9 @@ class PyVmomiHelper(PyVmomi):
else:
current_disk['state'] = disk['state']
if current_disk['state'] == 'present':
if current_disk['state'] == 'absent':
current_disk['destroy'] = disk['destroy']
elif current_disk['state'] == 'present':
# Select datastore or datastore cluster
if 'datastore' in disk:
if 'autoselect_datastore' in disk:
@ -469,11 +507,14 @@ class PyVmomiHelper(PyVmomi):
datastore_freespace = ds.summary.freeSpace
current_disk['datastore'] = datastore
if 'datastore' not in disk and 'autoselect_datastore' not in disk:
if 'datastore' not in disk and 'autoselect_datastore' not in disk and 'filename' not in disk:
self.module.fail_json(msg="Either 'datastore' or 'autoselect_datastore' is"
" required parameter while creating disk for "
"disk index [%s]." % disk_index)
if 'filename' in disk:
current_disk['filename'] = disk['filename']
if [x for x in disk.keys() if x.startswith('size_') or x == 'size']:
# size, size_tb, size_gb, size_mb, size_kb
disk_size_parse_failed = False
@ -529,7 +570,7 @@ class PyVmomiHelper(PyVmomi):
disk_index,
"', '".join(disk_units.keys())))
else:
elif current_disk['filename'] is None:
# No size found but disk, fail
self.module.fail_json(msg="No size, size_kb, size_mb, size_gb or size_tb"
" attribute found into disk index [%s] configuration." % disk_index)