#!/usr/bin/python # -*- coding: utf-8 -*- # # This module is also sponsored by E.T.A.I. (www.etai.fr) # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'version': '1.0'} DOCUMENTATION = ''' --- module: vmware_guest_facts short_description: Gather facts about a single VM description: - Gather facts about a single VM on a VMware ESX cluster version_added: 2.3 author: - Loic Blot (@nerzhul) notes: - Tested on vSphere 5.5 requirements: - "python >= 2.6" - PyVmomi options: name: description: - Name of the VM to work with required: True name_match: description: - If multiple VMs matching the name, use the first or last found default: 'first' choices: ['first', 'last'] uuid: description: - UUID of the instance to manage if known, this is VMware's unique identifier. - This is required if name is not supplied. folder: description: - Destination folder, absolute path to find an existing guest. - This is required if name is supplied. datacenter: description: - Destination datacenter for the deploy operation required: True extends_documentation_fragment: vmware.documentation ''' EXAMPLES = ''' # Gather facts - name: gather the VM facts vmware_guest_facts: hostname: 192.168.1.209 username: administrator@vsphere.local password: vmware validate_certs: no uuid: 421e4592-c069-924d-ce20-7e7533fab926 register: facts ''' RETURN = """ instance: descripton: metadata about the virtualmachine returned: always type: dict sample: None """ import os import time # import module snippets from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.pycompat24 import get_exception from ansible.module_utils.six import iteritems from ansible.module_utils.vmware import connect_to_api, find_vm_by_id, gather_vm_facts try: import json except ImportError: import simplejson as json HAS_PYVMOMI = False try: import pyVmomi from pyVmomi import vim HAS_PYVMOMI = True except ImportError: pass class PyVmomiHelper(object): def __init__(self, module): if not HAS_PYVMOMI: module.fail_json(msg='pyvmomi module required') self.module = module self.params = module.params self.content = connect_to_api(self.module) def getvm(self, name=None, uuid=None, folder=None): vm = None if uuid: vm = find_vm_by_id(self.content, vm_id=uuid, vm_id_type="uuid") elif folder: # Build the absolute folder path to pass into the search method if not self.params['folder'].startswith('/'): self.module.fail_json(msg="Folder %(folder)s needs to be an absolute path, starting with '/'." % self.params) searchpath = '%(datacenter)s%(folder)s' % self.params # get all objects for this path ... f_obj = self.content.searchIndex.FindByInventoryPath(searchpath) if f_obj: if isinstance(f_obj, vim.Datacenter): f_obj = f_obj.vmFolder for c_obj in f_obj.childEntity: if not isinstance(c_obj, vim.VirtualMachine): continue if c_obj.name == name: vm = c_obj if self.params['name_match'] == 'first': break return vm def gather_facts(self, vm): return gather_vm_facts(self.content, vm) def get_obj(content, vimtype, name): """ Return an object by name, if name is None the first found object is returned """ obj = None container = content.viewManager.CreateContainerView( content.rootFolder, vimtype, True) for c in container.view: if name: if c.name == name: obj = c break else: obj = c break container.Destroy() return obj def main(): module = AnsibleModule( argument_spec=dict( hostname=dict( type='str', default=os.environ.get('VMWARE_HOST') ), username=dict( type='str', default=os.environ.get('VMWARE_USER') ), password=dict( type='str', no_log=True, default=os.environ.get('VMWARE_PASSWORD') ), validate_certs=dict(required=False, type='bool', default=True), name=dict(required=True, type='str'), name_match=dict(required=False, type='str', default='first'), uuid=dict(required=False, type='str'), folder=dict(required=False, type='str', default='/vm'), datacenter=dict(required=True, type='str'), ), ) # Prepend /vm if it was missing from the folder path, also strip trailing slashes if not module.params['folder'].startswith('/vm') and module.params['folder'].startswith('/'): module.params['folder'] = '/vm%(folder)s' % module.params module.params['folder'] = module.params['folder'].rstrip('/') pyv = PyVmomiHelper(module) # Check if the VM exists before continuing vm = pyv.getvm(name=module.params['name'], folder=module.params['folder'], uuid=module.params['uuid']) # VM already exists if vm: try: module.exit_json(instance=pyv.gather_facts(vm)) except Exception: e = get_exception() module.fail_json(msg="Fact gather failed with exception %s" % e) else: module.fail_json(msg="Unable to gather facts for non-existing VM %(name)s" % module.params) if __name__ == '__main__': main()