|
|
@ -104,6 +104,10 @@ options:
|
|
|
|
- ' This value is ignored, if SCSI Controller is already present or C(state) is C(absent).'
|
|
|
|
- ' 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).'
|
|
|
|
- ' Valid values are C(buslogic), C(lsilogic), C(lsilogicsas) and C(paravirtual).'
|
|
|
|
- ' C(paravirtual) is default value for this parameter.'
|
|
|
|
- ' 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".'
|
|
|
|
- ' - 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(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.'
|
|
|
|
- ' 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'
|
|
|
|
scsi_type: 'buslogic'
|
|
|
|
unit_number: 1
|
|
|
|
unit_number: 1
|
|
|
|
disk_mode: 'independent_nonpersistent'
|
|
|
|
disk_mode: 'independent_nonpersistent'
|
|
|
|
|
|
|
|
- filename: "[datastore1] path/to/existing/disk.vmdk"
|
|
|
|
delegate_to: localhost
|
|
|
|
delegate_to: localhost
|
|
|
|
register: disk_facts
|
|
|
|
register: disk_facts
|
|
|
|
|
|
|
|
|
|
|
|
- name: Remove disks from virtual machine using name
|
|
|
|
- name: Remove disk from virtual machine using name
|
|
|
|
vmware_guest_disk:
|
|
|
|
vmware_guest_disk:
|
|
|
|
hostname: "{{ vcenter_hostname }}"
|
|
|
|
hostname: "{{ vcenter_hostname }}"
|
|
|
|
username: "{{ vcenter_username }}"
|
|
|
|
username: "{{ vcenter_username }}"
|
|
|
@ -166,7 +171,7 @@ EXAMPLES = '''
|
|
|
|
delegate_to: localhost
|
|
|
|
delegate_to: localhost
|
|
|
|
register: disk_facts
|
|
|
|
register: disk_facts
|
|
|
|
|
|
|
|
|
|
|
|
- name: Remove disks from virtual machine using moid
|
|
|
|
- name: Remove disk from virtual machine using moid
|
|
|
|
vmware_guest_disk:
|
|
|
|
vmware_guest_disk:
|
|
|
|
hostname: "{{ vcenter_hostname }}"
|
|
|
|
hostname: "{{ vcenter_hostname }}"
|
|
|
|
username: "{{ vcenter_username }}"
|
|
|
|
username: "{{ vcenter_username }}"
|
|
|
@ -180,6 +185,22 @@ EXAMPLES = '''
|
|
|
|
unit_number: 1
|
|
|
|
unit_number: 1
|
|
|
|
delegate_to: localhost
|
|
|
|
delegate_to: localhost
|
|
|
|
register: disk_facts
|
|
|
|
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 = """
|
|
|
|
RETURN = """
|
|
|
@ -251,24 +272,31 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
return scsi_ctl
|
|
|
|
return scsi_ctl
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@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
|
|
|
|
Create Virtual Device Spec for virtual disk
|
|
|
|
Args:
|
|
|
|
Args:
|
|
|
|
scsi_ctl_key: Unique SCSI Controller Key
|
|
|
|
scsi_ctl_key: Unique SCSI Controller Key
|
|
|
|
disk_index: Disk unit number at which disk needs to be attached
|
|
|
|
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
|
|
|
|
Returns: Virtual Device Spec for virtual disk
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
disk_spec = vim.vm.device.VirtualDeviceSpec()
|
|
|
|
disk_spec = vim.vm.device.VirtualDeviceSpec()
|
|
|
|
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
|
|
|
|
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 = vim.vm.device.VirtualDisk()
|
|
|
|
disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
|
|
|
|
disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
|
|
|
|
disk_spec.device.backing.diskMode = disk_mode
|
|
|
|
disk_spec.device.backing.diskMode = disk_mode
|
|
|
|
disk_spec.device.controllerKey = scsi_ctl_key
|
|
|
|
disk_spec.device.controllerKey = scsi_ctl_key
|
|
|
|
disk_spec.device.unitNumber = disk_index
|
|
|
|
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
|
|
|
|
return disk_spec
|
|
|
|
|
|
|
|
|
|
|
|
def reconfigure_vm(self, config_spec, device_type):
|
|
|
|
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
|
|
|
|
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':
|
|
|
|
if disk['disk_unit_number'] not in current_scsi_info[scsi_controller]['disks'] and disk['state'] == 'present':
|
|
|
|
# Add new disk
|
|
|
|
# Add new disk
|
|
|
|
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'])
|
|
|
|
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'], disk['filename'])
|
|
|
|
disk_spec.device.capacityInKB = disk['size']
|
|
|
|
if disk['filename'] is None:
|
|
|
|
|
|
|
|
disk_spec.device.capacityInKB = disk['size']
|
|
|
|
if disk['disk_type'] == 'thin':
|
|
|
|
if disk['disk_type'] == 'thin':
|
|
|
|
disk_spec.device.backing.thinProvisioned = True
|
|
|
|
disk_spec.device.backing.thinProvisioned = True
|
|
|
|
elif disk['disk_type'] == 'eagerzeroedthick':
|
|
|
|
elif disk['disk_type'] == 'eagerzeroedthick':
|
|
|
|
disk_spec.device.backing.eagerlyScrub = True
|
|
|
|
disk_spec.device.backing.eagerlyScrub = True
|
|
|
|
disk_spec.device.backing.fileName = "[%s] %s/%s_%s_%s.vmdk" % (disk['datastore'].name,
|
|
|
|
if disk['filename'] is None:
|
|
|
|
vm_name, vm_name,
|
|
|
|
disk_spec.device.backing.fileName = "[%s] %s/%s_%s_%s.vmdk" % (
|
|
|
|
str(scsi_controller),
|
|
|
|
disk['datastore'].name,
|
|
|
|
str(disk['disk_unit_number']))
|
|
|
|
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']
|
|
|
|
disk_spec.device.backing.datastore = disk['datastore']
|
|
|
|
self.config_spec.deviceChange.append(disk_spec)
|
|
|
|
self.config_spec.deviceChange.append(disk_spec)
|
|
|
|
disk_change = True
|
|
|
|
disk_change = True
|
|
|
@ -386,7 +419,8 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
# Disk already exists, deleting
|
|
|
|
# Disk already exists, deleting
|
|
|
|
disk_spec = vim.vm.device.VirtualDeviceSpec()
|
|
|
|
disk_spec = vim.vm.device.VirtualDeviceSpec()
|
|
|
|
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
|
|
|
|
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']]
|
|
|
|
disk_spec.device = current_scsi_info[scsi_controller]['disks'][disk['disk_unit_number']]
|
|
|
|
self.config_spec.deviceChange.append(disk_spec)
|
|
|
|
self.config_spec.deviceChange.append(disk_spec)
|
|
|
|
disk_change = True
|
|
|
|
disk_change = True
|
|
|
@ -420,6 +454,8 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
# Initialize default value for disk
|
|
|
|
# Initialize default value for disk
|
|
|
|
current_disk = dict(disk_index=disk_index,
|
|
|
|
current_disk = dict(disk_index=disk_index,
|
|
|
|
state='present',
|
|
|
|
state='present',
|
|
|
|
|
|
|
|
destroy=True,
|
|
|
|
|
|
|
|
filename=None,
|
|
|
|
datastore=None,
|
|
|
|
datastore=None,
|
|
|
|
autoselect_datastore=True,
|
|
|
|
autoselect_datastore=True,
|
|
|
|
disk_unit_number=0,
|
|
|
|
disk_unit_number=0,
|
|
|
@ -434,7 +470,9 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
current_disk['state'] = disk['state']
|
|
|
|
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
|
|
|
|
# Select datastore or datastore cluster
|
|
|
|
if 'datastore' in disk:
|
|
|
|
if 'datastore' in disk:
|
|
|
|
if 'autoselect_datastore' in disk:
|
|
|
|
if 'autoselect_datastore' in disk:
|
|
|
@ -469,11 +507,14 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
datastore_freespace = ds.summary.freeSpace
|
|
|
|
datastore_freespace = ds.summary.freeSpace
|
|
|
|
current_disk['datastore'] = datastore
|
|
|
|
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"
|
|
|
|
self.module.fail_json(msg="Either 'datastore' or 'autoselect_datastore' is"
|
|
|
|
" required parameter while creating disk for "
|
|
|
|
" required parameter while creating disk for "
|
|
|
|
"disk index [%s]." % disk_index)
|
|
|
|
"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']:
|
|
|
|
if [x for x in disk.keys() if x.startswith('size_') or x == 'size']:
|
|
|
|
# size, size_tb, size_gb, size_mb, size_kb
|
|
|
|
# size, size_tb, size_gb, size_mb, size_kb
|
|
|
|
disk_size_parse_failed = False
|
|
|
|
disk_size_parse_failed = False
|
|
|
@ -529,7 +570,7 @@ class PyVmomiHelper(PyVmomi):
|
|
|
|
disk_index,
|
|
|
|
disk_index,
|
|
|
|
"', '".join(disk_units.keys())))
|
|
|
|
"', '".join(disk_units.keys())))
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
elif current_disk['filename'] is None:
|
|
|
|
# No size found but disk, fail
|
|
|
|
# No size found but disk, fail
|
|
|
|
self.module.fail_json(msg="No size, size_kb, size_mb, size_gb or size_tb"
|
|
|
|
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)
|
|
|
|
" attribute found into disk index [%s] configuration." % disk_index)
|
|
|
|