ansible/cloud/vsphere_guest

329 lines
9.6 KiB
Text
Raw Normal View History

#!/usr/bin/python2
# -*- coding: utf-8 -*-
# TODO:
# Ability to set CPU/Memory reservations
try:
import json
except ImportError:
import simplejson as json
DOCUMENTATION = '''
---
module: vsphere_client
short_description: Creates a virtual guest on vsphere.
description:
- Communicates with vsphere, creating a new virtual guest OS based on
the specifications you specify to the module.
version_added: "1.1"
options:
vcenter_hostname:
description:
- The hostname of the vcenter server the module will connect to, to create the guest.
required: true
default: null
aliases: []
user:
description:
- username of the user to connect to vcenter as.
required: true
default: null
password:
description:
- password of the user to connect to vcenter as.
required: true
default: null
resource_pool:
description:
- The name of the resource_pool to create the VM in.
required: false
default: None
cluster:
description:
- The name of the cluster to create the VM in. By default this is derived from the host you tell the module to build the guest on.
required: false
default: None
datacenter:
description:
- The name of the datacenter to create the VM in.
required: true
default: null
datastore:
description:
- The datastore to store the VMs config files in. (Hard-disk locations are specified separately.)
required: true
default: null
esxi_hostname:
description:
- The hostname of the esxi host you want the VM to be created on.
required: true
default: null
power_on:
description:
- Whether or not to power on the VM after creation.
required: false
default: no
choices: [yes, no]
vm_name:
description:
- The name you want to call the VM.
required: true
default: null
vm_memory_mb:
description:
- How much memory in MB to give the VM.
required: false
default: 1024
vm_num_cpus:
description:
- How many vCPUs to give the VM.
required: false
default: 1
vm_scsi:
description:
- The type of scsi controller to add to the VM.
required: false
default: "paravirtual"
choices: [paravirtual, lsi, lsi_sas, bus_logic]
vm_disk:
description:
- A key, value list of disks and their sizes and which datastore to keep it in.
required: false
default: null
vm_nic:
description:
- A key, value list of nics, their types and what network to put them on.
required: false
default: null
choices: [vmxnet3, vmxnet2, vmxnet, e1000, e1000e, pcnet32]
vm_notes:
description:
- Any notes that you want to show up in the VMs Annotations field.
required: false
default: null
vm_cdrom:
description:
- A path, including datastore, to an ISO you want the CDROM device on the VM to have.
required: false
default: null
vm_extra_config:
description:
- A key, value pair of any extra values you want set or changed in the vmx file of the VM. Useful to set advanced options on the VM.
required: false
default: null
guestosid:
description:
- "A vmware guest needs to have a specific OS identifier set on it
during creation. You can find your os guestosid at the following URL:
http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.GuestOsDescriptor.GuestOsIdentifier.html"
required: true
default: null
# informational: requirements for nodes
requirements: [ pysphere ]
author: Romeo Theriault
'''
def power_state(vm, state, force):
power_status = vm.get_status()
check_status = ' '.join(state.split("_")).upper()
# Need Force
if not force and power_status in [
'SUSPENDED', 'POWERING ON',
'RESETTING', 'BLOCKED ON MSG'
]:
return "VM is in %s power state. Force is required!" % power_status
# State is already true
if power_status == check_status:
return False
else:
try:
if state == 'powered_off':
vm.power_off(sync_run=True)
elif state == 'powered_on':
vm.power_on(sync_run=True)
elif state == 'restarted':
if power_status in ('POWERED ON', 'POWERING ON', 'RESETTING'):
vm.reset(sync_run=False)
else:
return "Cannot restart VM in the current state %s" \
% power_status
return True
except Exception, e:
return e
return False
def gather_facts(vm):
"""
Gather facts for VM directly from vsphere.
"""
vm.get_properties()
facts = {
'module_hw': True,
'hw_name': vm.properties.name,
'hw_guest_full_name': vm.properties.config.guestFullName,
'hw_guest_id': vm.properties.config.guestId,
'hw_product_uuid': vm.properties.config.uuid,
'hw_processor_count': vm.properties.config.hardware.numCPU,
'hw_memtotal_mb': vm.properties.config.hardware.memoryMB,
}
ifidx = 0
for entry in vm.properties.config.hardware.device:
if not hasattr(entry, 'macAddress'):
continue
factname = 'hw_eth' + str(ifidx)
facts[factname] = {
'addresstype': entry.addressType,
'label': entry.deviceInfo.label,
'macaddress': entry.macAddress,
'macaddress_dash': entry.macAddress.replace(':', '-'),
'summary': entry.deviceInfo.summary,
}
ifidx += 1
return facts
def main():
vm = None
module = AnsibleModule(
argument_spec=dict(
vcenter_hostname=dict(required=True, type='str'),
username=dict(required=True, type='str'),
password=dict(required=True, type='str'),
state=dict(
required=False,
choices=[
'powered_on',
'powered_off',
'present',
'absent',
'restarted',
'reconfigured'
],
default='present'),
vmware_guest_facts=dict(required=False, choices=BOOLEANS),
guest=dict(required=True, type='str'),
guest_config=dict(required=False, type='dict', default={}),
force=dict(required=False, choices=BOOLEANS, default=False),
),
supports_check_mode=False,
mutually_exclusive=[['state', 'vmware_guest_facts']],
required_together=[
['state', 'force'],
['state', 'guest_config']
],
)
try:
from pysphere import VIServer, VIProperty, MORTypes
from pysphere.resources import VimService_services as VI
from pysphere.vi_task import VITask
from pysphere import VIException, VIApiException, FaultTypes
except ImportError, e:
module.fail_json(msg='pysphere module required')
vcenter_hostname = module.params['vcenter_hostname']
username = module.params['username']
password = module.params['password']
vmware_guest_facts = module.params['vmware_guest_facts']
state = module.params['state']
guest = module.params['guest']
force = module.params['force']
guest_config = module.params['guest_config']
# CONNECT TO THE SERVER
viserver = VIServer()
try:
viserver.connect(vcenter_hostname, username, password)
except VIApiException, err:
module.fail_json(msg="Cannot connect to %s: %s" %
(vcenter_hostname, err))
# Check if the VM exists before continuing
try:
vm = viserver.get_vm_by_name(guest)
# Run for facts only
if vmware_guest_facts:
try:
module.exit_json(ansible_facts=gather_facts(vm))
except Exception, e:
module.fail_json(
msg="Fact gather failed with exception %s" % e)
# Power Changes
elif state in ['powered_on', 'powered_off', 'restarted']:
state_result = power_state(vm, state, force)
# Failure
if isinstance(state_result, basestring):
module.fail_json(msg=state_result)
else:
module.exit_json(changed=state_result)
# Just check if there
elif state == 'present' and not len(guest_config):
module.exit_json(changed=False)
# Fail on reconfig without params
elif state == 'reconfigured':
if not len(guest_config):
module.fail_json(
msg="guest_config is required to reconfigure a VM")
# do it
else:
pass
# VM doesn't exist
except Exception:
# Fail for fact gather task
if vmware_guest_facts:
module.fail_json(
msg="No such VM %s. Fact gathering requires an existing vm"
% guest)
if state not in ['absent', 'present']:
module.fail_json(
msg="No such VM %s. States [powered_on, powered_off, "
"restarted, reconfigured] required an existing VM" % guest)
elif state == 'absent':
module.exit_json(changed=False, msg="vm %s not present" % guest)
# Create the VM
elif state == 'present':
pass
if vm:
# If the vm already exists, lets get some info from it, pass back the
# vm's vmware_guest_facts and then exit.
viserver.disconnect()
module.exit_json(
changed=False,
vcenter=vcenter_hostname)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()