New module - vmware_guest_powerstate
Fix adds a new module 'vmware_guest_powerstate' to manage power states of virtual machine. Fixes: #30371 Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
6a7676d738
commit
02b5c7a8a3
7 changed files with 384 additions and 107 deletions
|
@ -34,6 +34,7 @@ except ImportError:
|
||||||
from ansible.module_utils._text import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url
|
||||||
from ansible.module_utils.six import integer_types, iteritems, string_types
|
from ansible.module_utils.six import integer_types, iteritems, string_types
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
|
||||||
|
|
||||||
class TaskError(Exception):
|
class TaskError(Exception):
|
||||||
|
@ -652,3 +653,109 @@ def find_host_by_cluster_datacenter(module, content, datacenter_name, cluster_na
|
||||||
return host, cluster
|
return host, cluster
|
||||||
|
|
||||||
return None, cluster
|
return None, cluster
|
||||||
|
|
||||||
|
|
||||||
|
def set_vm_power_state(content, vm, state, force):
|
||||||
|
"""
|
||||||
|
Set the power status for a VM determined by the current and
|
||||||
|
requested states. force is forceful
|
||||||
|
"""
|
||||||
|
facts = gather_vm_facts(content, vm)
|
||||||
|
expected_state = state.replace('_', '').lower()
|
||||||
|
current_state = facts['hw_power_status'].lower()
|
||||||
|
result = dict(
|
||||||
|
changed=False,
|
||||||
|
failed=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Need Force
|
||||||
|
if not force and current_state not in ['poweredon', 'poweredoff']:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = "Virtual Machine is in %s power state. Force is required!" % current_state
|
||||||
|
return result
|
||||||
|
|
||||||
|
# State is not already true
|
||||||
|
if current_state != expected_state:
|
||||||
|
task = None
|
||||||
|
try:
|
||||||
|
if expected_state == 'poweredoff':
|
||||||
|
task = vm.PowerOff()
|
||||||
|
|
||||||
|
elif expected_state == 'poweredon':
|
||||||
|
task = vm.PowerOn()
|
||||||
|
|
||||||
|
elif expected_state == 'restarted':
|
||||||
|
if current_state in ('poweredon', 'poweringon', 'resetting', 'poweredoff'):
|
||||||
|
task = vm.Reset()
|
||||||
|
else:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = "Cannot restart virtual machine in the current state %s" % current_state
|
||||||
|
|
||||||
|
elif expected_state == 'suspended':
|
||||||
|
if current_state in ('poweredon', 'poweringon'):
|
||||||
|
task = vm.Suspend()
|
||||||
|
else:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = 'Cannot suspend virtual machine in the current state %s' % current_state
|
||||||
|
|
||||||
|
elif expected_state in ['shutdownguest', 'rebootguest']:
|
||||||
|
if current_state == 'poweredon':
|
||||||
|
if vm.guest.toolsRunningStatus == 'guestToolsRunning':
|
||||||
|
if expected_state == 'shutdownguest':
|
||||||
|
task = vm.ShutdownGuest()
|
||||||
|
else:
|
||||||
|
task = vm.RebootGuest()
|
||||||
|
# Set result['changed'] immediately because
|
||||||
|
# shutdown and reboot return None.
|
||||||
|
result['changed'] = True
|
||||||
|
else:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = "VMware tools should be installed for guest shutdown/reboot"
|
||||||
|
else:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = "Virtual machine %s must be in poweredon state for guest shutdown/reboot" % vm.name
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = to_text(e)
|
||||||
|
|
||||||
|
if task:
|
||||||
|
wait_for_task(task)
|
||||||
|
if task.info.state == 'error':
|
||||||
|
result['failed'] = True
|
||||||
|
result['msg'] = task.info.error.msg
|
||||||
|
else:
|
||||||
|
result['changed'] = True
|
||||||
|
|
||||||
|
# need to get new metadata if changed
|
||||||
|
if result['changed']:
|
||||||
|
result['instance'] = gather_vm_facts(content, vm)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class PyVmomi(object):
|
||||||
|
def __init__(self, module):
|
||||||
|
if not HAS_PYVMOMI:
|
||||||
|
module.fail_json(msg='PyVmomi Python module required. Install using "pip install PyVmomi"')
|
||||||
|
|
||||||
|
self.module = module
|
||||||
|
self.params = module.params
|
||||||
|
self.si = None
|
||||||
|
self.current_vm_obj = None
|
||||||
|
self.content = connect_to_api(self.module)
|
||||||
|
|
||||||
|
def get_vm(self):
|
||||||
|
vm = None
|
||||||
|
match_first = (self.params['name_match'] == 'first')
|
||||||
|
|
||||||
|
if self.params['uuid']:
|
||||||
|
vm = find_vm_by_id(self.content, vm_id=self.params['uuid'], vm_id_type="uuid")
|
||||||
|
elif self.params['folder'] and self.params['name']:
|
||||||
|
vm = find_vm_by_id(self.content, vm_id=self.params['name'], vm_id_type="inventory_path",
|
||||||
|
folder=self.params['folder'], match_first=match_first)
|
||||||
|
|
||||||
|
if vm:
|
||||||
|
self.current_vm_obj = vm
|
||||||
|
|
||||||
|
return vm
|
||||||
|
|
|
@ -314,9 +314,9 @@ except ImportError:
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils._text import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.module_utils.vmware import (connect_to_api, find_obj, gather_vm_facts, get_all_objs,
|
from ansible.module_utils.vmware import (find_obj, gather_vm_facts, get_all_objs,
|
||||||
compile_folder_path_for_object, serialize_spec, find_vm_by_id,
|
compile_folder_path_for_object, serialize_spec,
|
||||||
vmware_argument_spec)
|
vmware_argument_spec, set_vm_power_state, PyVmomi)
|
||||||
|
|
||||||
|
|
||||||
class PyVmomiDeviceHelper(object):
|
class PyVmomiDeviceHelper(object):
|
||||||
|
@ -496,112 +496,15 @@ class PyVmomiCache(object):
|
||||||
return datacenter
|
return datacenter
|
||||||
|
|
||||||
|
|
||||||
class PyVmomiHelper(object):
|
class PyVmomiHelper(PyVmomi):
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
if not HAS_PYVMOMI:
|
super(PyVmomiHelper, self).__init__(module)
|
||||||
module.fail_json(msg='pyvmomi module required')
|
|
||||||
|
|
||||||
self.module = module
|
|
||||||
self.device_helper = PyVmomiDeviceHelper(self.module)
|
self.device_helper = PyVmomiDeviceHelper(self.module)
|
||||||
self.params = module.params
|
|
||||||
self.si = None
|
|
||||||
self.content = connect_to_api(self.module)
|
|
||||||
self.configspec = None
|
self.configspec = None
|
||||||
self.change_detected = False
|
self.change_detected = False
|
||||||
self.customspec = None
|
self.customspec = None
|
||||||
self.current_vm_obj = None
|
|
||||||
self.cache = PyVmomiCache(self.content, dc_name=self.params['datacenter'])
|
self.cache = PyVmomiCache(self.content, dc_name=self.params['datacenter'])
|
||||||
|
|
||||||
def getvm(self, name=None, uuid=None, folder=None):
|
|
||||||
vm = None
|
|
||||||
match_first = False
|
|
||||||
if uuid:
|
|
||||||
vm = find_vm_by_id(self.content, vm_id=uuid, vm_id_type="uuid")
|
|
||||||
elif folder and name:
|
|
||||||
if self.params['name_match'] == 'first':
|
|
||||||
match_first = True
|
|
||||||
vm = find_vm_by_id(self.content, vm_id=name, vm_id_type="inventory_path", folder=folder, match_first=match_first)
|
|
||||||
if vm:
|
|
||||||
self.current_vm_obj = vm
|
|
||||||
|
|
||||||
return vm
|
|
||||||
|
|
||||||
def set_powerstate(self, vm, state, force):
|
|
||||||
"""
|
|
||||||
Set the power status for a VM determined by the current and
|
|
||||||
requested states. force is forceful
|
|
||||||
"""
|
|
||||||
facts = self.gather_facts(vm)
|
|
||||||
expected_state = state.replace('_', '').lower()
|
|
||||||
current_state = facts['hw_power_status'].lower()
|
|
||||||
result = dict(
|
|
||||||
changed=False,
|
|
||||||
failed=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Need Force
|
|
||||||
if not force and current_state not in ['poweredon', 'poweredoff']:
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = "VM is in %s power state. Force is required!" % current_state
|
|
||||||
return result
|
|
||||||
|
|
||||||
# State is not already true
|
|
||||||
if current_state != expected_state:
|
|
||||||
task = None
|
|
||||||
try:
|
|
||||||
if expected_state == 'poweredoff':
|
|
||||||
task = vm.PowerOff()
|
|
||||||
|
|
||||||
elif expected_state == 'poweredon':
|
|
||||||
task = vm.PowerOn()
|
|
||||||
|
|
||||||
elif expected_state == 'restarted':
|
|
||||||
if current_state in ('poweredon', 'poweringon', 'resetting', 'poweredoff'):
|
|
||||||
task = vm.Reset()
|
|
||||||
else:
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = "Cannot restart VM in the current state %s" % current_state
|
|
||||||
|
|
||||||
elif expected_state == 'suspended':
|
|
||||||
if current_state in ('poweredon', 'poweringon'):
|
|
||||||
task = vm.Suspend()
|
|
||||||
else:
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = 'Cannot suspend VM in the current state %s' % current_state
|
|
||||||
|
|
||||||
elif expected_state in ['shutdownguest', 'rebootguest']:
|
|
||||||
if current_state == 'poweredon' and vm.guest.toolsRunningStatus == 'guestToolsRunning':
|
|
||||||
if expected_state == 'shutdownguest':
|
|
||||||
task = vm.ShutdownGuest()
|
|
||||||
else:
|
|
||||||
task = vm.RebootGuest()
|
|
||||||
# Set result['changed'] immediately because
|
|
||||||
# shutdown and reboot return None.
|
|
||||||
result['changed'] = True
|
|
||||||
else:
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = "VM %s must be in poweredon state & tools should be installed for guest shutdown/reboot" % vm.name
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = to_text(e)
|
|
||||||
|
|
||||||
if task:
|
|
||||||
self.wait_for_task(task)
|
|
||||||
if task.info.state == 'error':
|
|
||||||
result['failed'] = True
|
|
||||||
result['msg'] = str(task.info.error.msg)
|
|
||||||
else:
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
# need to get new metadata if changed
|
|
||||||
if result['changed']:
|
|
||||||
newvm = self.getvm(uuid=vm.config.uuid)
|
|
||||||
facts = self.gather_facts(newvm)
|
|
||||||
result['instance'] = facts
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def gather_facts(self, vm):
|
def gather_facts(self, vm):
|
||||||
return gather_vm_facts(self.content, vm)
|
return gather_vm_facts(self.content, vm)
|
||||||
|
|
||||||
|
@ -1336,7 +1239,7 @@ class PyVmomiHelper(object):
|
||||||
self.customize_customvalues(vm_obj=vm)
|
self.customize_customvalues(vm_obj=vm)
|
||||||
|
|
||||||
if self.params['wait_for_ip_address'] or self.params['state'] in ['poweredon', 'restarted']:
|
if self.params['wait_for_ip_address'] or self.params['state'] in ['poweredon', 'restarted']:
|
||||||
self.set_powerstate(vm, 'poweredon', force=False)
|
set_vm_power_state(self.content, vm, 'poweredon', force=False)
|
||||||
|
|
||||||
if self.params['wait_for_ip_address']:
|
if self.params['wait_for_ip_address']:
|
||||||
self.wait_for_vm_ip(vm)
|
self.wait_for_vm_ip(vm)
|
||||||
|
@ -1422,7 +1325,7 @@ class PyVmomiHelper(object):
|
||||||
facts = {}
|
facts = {}
|
||||||
thispoll = 0
|
thispoll = 0
|
||||||
while not ips and thispoll <= poll:
|
while not ips and thispoll <= poll:
|
||||||
newvm = self.getvm(uuid=vm.config.uuid)
|
newvm = self.get_vm()
|
||||||
facts = self.gather_facts(newvm)
|
facts = self.gather_facts(newvm)
|
||||||
if facts['ipv4'] or facts['ipv6']:
|
if facts['ipv4'] or facts['ipv6']:
|
||||||
ips = True
|
ips = True
|
||||||
|
@ -1477,7 +1380,7 @@ def main():
|
||||||
pyv = PyVmomiHelper(module)
|
pyv = PyVmomiHelper(module)
|
||||||
|
|
||||||
# Check if the VM exists before continuing
|
# Check if the VM exists before continuing
|
||||||
vm = pyv.getvm(name=module.params['name'], folder=module.params['folder'], uuid=module.params['uuid'])
|
vm = pyv.get_vm()
|
||||||
|
|
||||||
# VM already exists
|
# VM already exists
|
||||||
if vm:
|
if vm:
|
||||||
|
@ -1485,13 +1388,13 @@ def main():
|
||||||
# destroy it
|
# destroy it
|
||||||
if module.params['force']:
|
if module.params['force']:
|
||||||
# has to be poweredoff first
|
# has to be poweredoff first
|
||||||
pyv.set_powerstate(vm, 'poweredoff', module.params['force'])
|
set_vm_power_state(pyv.content, vm, 'poweredoff', module.params['force'])
|
||||||
result = pyv.remove_vm(vm)
|
result = pyv.remove_vm(vm)
|
||||||
elif module.params['state'] == 'present':
|
elif module.params['state'] == 'present':
|
||||||
result = pyv.reconfigure_vm()
|
result = pyv.reconfigure_vm()
|
||||||
elif module.params['state'] in ['poweredon', 'poweredoff', 'restarted', 'suspended', 'shutdownguest', 'rebootguest']:
|
elif module.params['state'] in ['poweredon', 'poweredoff', 'restarted', 'suspended', 'shutdownguest', 'rebootguest']:
|
||||||
# set powerstate
|
# set powerstate
|
||||||
tmp_result = pyv.set_powerstate(vm, module.params['state'], module.params['force'])
|
tmp_result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force'])
|
||||||
if tmp_result['changed']:
|
if tmp_result['changed']:
|
||||||
result["changed"] = True
|
result["changed"] = True
|
||||||
if not tmp_result["failed"]:
|
if not tmp_result["failed"]:
|
||||||
|
|
124
lib/ansible/modules/cloud/vmware/vmware_guest_powerstate.py
Normal file
124
lib/ansible/modules/cloud/vmware/vmware_guest_powerstate.py
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright: (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'}
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: vmware_guest_powerstate
|
||||||
|
short_description: Manages power states of virtual machines in vCenter
|
||||||
|
description:
|
||||||
|
- Power on / Power off / Restart a virtual machine.
|
||||||
|
version_added: '2.5'
|
||||||
|
author:
|
||||||
|
- Abhijeet Kasurde (@akasurde) <akasurde@redhat.com>
|
||||||
|
requirements:
|
||||||
|
- python >= 2.6
|
||||||
|
- PyVmomi
|
||||||
|
options:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- Set the state of the virtual machine.
|
||||||
|
choices: [ powered-off, powered-on, reboot-guest, restarted, shutdown-guest, suspended ]
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the virtual machine to work with.
|
||||||
|
- Virtual machine names in vCenter are not necessarily unique, which may be problematic, see C(name_match).
|
||||||
|
name_match:
|
||||||
|
description:
|
||||||
|
- If multiple virtual machines 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 or relative path to find an existing guest or create the new guest.
|
||||||
|
- The folder should include the datacenter. ESX's datacenter is ha-datacenter
|
||||||
|
- 'Examples:'
|
||||||
|
- ' folder: /ha-datacenter/vm'
|
||||||
|
- ' folder: ha-datacenter/vm'
|
||||||
|
- ' folder: /datacenter1/vm'
|
||||||
|
- ' folder: datacenter1/vm'
|
||||||
|
- ' folder: /datacenter1/vm/folder1'
|
||||||
|
- ' folder: datacenter1/vm/folder1'
|
||||||
|
- ' folder: /folder1/datacenter1/vm'
|
||||||
|
- ' folder: folder1/datacenter1/vm'
|
||||||
|
- ' folder: /folder1/datacenter1/vm/folder2'
|
||||||
|
- ' folder: vm/folder2'
|
||||||
|
- ' folder: folder2'
|
||||||
|
default: /vm
|
||||||
|
extends_documentation_fragment: vmware.documentation
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
- name: Set the state of a virtual machine to poweroff
|
||||||
|
vmware_guest_powerstate:
|
||||||
|
hostname: 192.0.2.44
|
||||||
|
username: administrator@vsphere.local
|
||||||
|
password: vmware
|
||||||
|
validate_certs: no
|
||||||
|
folder: /testvms
|
||||||
|
name: testvm_2
|
||||||
|
state: powered-off
|
||||||
|
delegate_to: localhost
|
||||||
|
register: deploy
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r''' # '''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.vmware import PyVmomi, set_vm_power_state, vmware_argument_spec
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
argument_spec = vmware_argument_spec()
|
||||||
|
argument_spec.update(
|
||||||
|
state=dict(type='str', default='present',
|
||||||
|
choices=['powered-off', 'powered-on', 'reboot-guest', 'restarted', 'shutdown-guest', 'suspended']),
|
||||||
|
name=dict(type='str'),
|
||||||
|
name_match=dict(type='str', choices=['first', 'last'], default='first'),
|
||||||
|
uuid=dict(type='str'),
|
||||||
|
folder=dict(type='str', default='/vm'),
|
||||||
|
force=dict(type='bool', default=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
|
supports_check_mode=False,
|
||||||
|
mutually_exclusive=[
|
||||||
|
['name', 'uuid'],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
result = dict(changed=False,)
|
||||||
|
|
||||||
|
pyv = PyVmomi(module)
|
||||||
|
|
||||||
|
# Check if the VM exists before continuing
|
||||||
|
vm = pyv.get_vm()
|
||||||
|
|
||||||
|
if vm:
|
||||||
|
# VM already exists, so set power state
|
||||||
|
result = set_vm_power_state(pyv.content, vm, module.params['state'], module.params['force'])
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="Unable to set power state for non-existing virtual machine : '%s'" % (module.params.get('uuid') or module.params.get('name')))
|
||||||
|
|
||||||
|
if result.get('failed') is True:
|
||||||
|
module.fail_json(**result)
|
||||||
|
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
4
test/integration/targets/vmware_guest_powerstate/aliases
Normal file
4
test/integration/targets/vmware_guest_powerstate/aliases
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
posix/ci/cloud/group1/vcenter
|
||||||
|
cloud/vcenter
|
||||||
|
skip/python3
|
||||||
|
destructive
|
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# Copyright: (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
#
|
||||||
|
- name: make sure pyvmomi is installed
|
||||||
|
pip:
|
||||||
|
name: pyvmomi
|
||||||
|
state: latest
|
||||||
|
when: "{{ ansible_user_id == 'root' }}"
|
||||||
|
|
||||||
|
- name: store the vcenter container ip
|
||||||
|
set_fact:
|
||||||
|
vcsim: "{{ lookup('env', 'vcenter_host') }}"
|
||||||
|
- debug: var=vcsim
|
||||||
|
|
||||||
|
- include: poweroff_d1_c1_f0.yml
|
||||||
|
- include: poweroff_d1_c1_f1.yml
|
|
@ -0,0 +1,55 @@
|
||||||
|
#
|
||||||
|
# Copyright: (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
#
|
||||||
|
#- name: make sure pyvmomi is installed
|
||||||
|
# pip:
|
||||||
|
# name: pyvmomi
|
||||||
|
# state: latest
|
||||||
|
|
||||||
|
- name: Wait for Flask controller to come up online
|
||||||
|
wait_for:
|
||||||
|
host: "{{ vcsim }}"
|
||||||
|
port: 5000
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: kill vcsim
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/killall' }}"
|
||||||
|
- name: start vcsim with no folders
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/spawn?datacenter=1&cluster=1&folder=0' }}"
|
||||||
|
register: vcsim_instance
|
||||||
|
|
||||||
|
- name: Wait for Flask controller to come up online
|
||||||
|
wait_for:
|
||||||
|
host: "{{ vcsim }}"
|
||||||
|
port: 443
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: get a list of VMS from vcsim
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/govc_find?filter=VM' }}"
|
||||||
|
register: vmlist
|
||||||
|
|
||||||
|
- debug: var=vcsim_instance
|
||||||
|
- debug: var=vmlist
|
||||||
|
|
||||||
|
- name: set state to poweroff on all VMs
|
||||||
|
vmware_guest_powerstate:
|
||||||
|
validate_certs: False
|
||||||
|
hostname: "{{ vcsim }}"
|
||||||
|
username: "{{ vcsim_instance['json']['username'] }}"
|
||||||
|
password: "{{ vcsim_instance['json']['password'] }}"
|
||||||
|
name: "{{ item|basename }}"
|
||||||
|
state: powered-off
|
||||||
|
folder: "{{ item|dirname }}"
|
||||||
|
with_items: "{{ vmlist['json'] }}"
|
||||||
|
register: poweroff_d1_c1_f0
|
||||||
|
|
||||||
|
- debug: var=poweroff_d1_c1_f0
|
||||||
|
|
||||||
|
- name: make sure no changes were made
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "poweroff_d1_c1_f0.results|map(attribute='changed')|unique|list == [False]"
|
|
@ -0,0 +1,67 @@
|
||||||
|
#
|
||||||
|
# Copyright: (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
#
|
||||||
|
#- name: make sure pyvmomi is installed
|
||||||
|
# pip:
|
||||||
|
# name: pyvmomi
|
||||||
|
# state: latest
|
||||||
|
|
||||||
|
- name: Wait for Flask controller to come up online
|
||||||
|
wait_for:
|
||||||
|
host: "{{ vcsim }}"
|
||||||
|
port: 5000
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: store the vcenter container ip
|
||||||
|
set_fact:
|
||||||
|
vcsim: "{{ lookup('env', 'vcenter_host') }}"
|
||||||
|
- debug: var=vcsim
|
||||||
|
|
||||||
|
- name: kill vcsim
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/killall' }}"
|
||||||
|
|
||||||
|
- name: start vcsim with folders
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/spawn?datacenter=1&cluster=1&folder=1' }}"
|
||||||
|
register: vcsim_instance
|
||||||
|
|
||||||
|
- name: Wait for Flask controller to come up online
|
||||||
|
wait_for:
|
||||||
|
host: "{{ vcsim }}"
|
||||||
|
port: 443
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: get a list of VMS from vcsim
|
||||||
|
uri:
|
||||||
|
url: "{{ 'http://' + vcsim + ':5000/govc_find?filter=VM' }}"
|
||||||
|
register: vmlist
|
||||||
|
|
||||||
|
- debug: var=vcsim_instance
|
||||||
|
- debug: var=vmlist
|
||||||
|
|
||||||
|
# https://github.com/ansible/ansible/issues/25011
|
||||||
|
# Sending "-folders 1" to vcsim nests the datacenter under
|
||||||
|
# the folder so that the path prefix is no longer /vm
|
||||||
|
#
|
||||||
|
# /F0/DC0/vm/F0/DC0_H0_VM0
|
||||||
|
|
||||||
|
- name: set state to poweredoff on all VMs
|
||||||
|
vmware_guest_powerstate:
|
||||||
|
validate_certs: False
|
||||||
|
hostname: "{{ vcsim }}"
|
||||||
|
username: "{{ vcsim_instance['json']['username'] }}"
|
||||||
|
password: "{{ vcsim_instance['json']['password'] }}"
|
||||||
|
name: "{{ item|basename }}"
|
||||||
|
state: powered-off
|
||||||
|
folder: "{{ item|dirname }}"
|
||||||
|
with_items: "{{ vmlist['json'] }}"
|
||||||
|
register: poweroff_d1_c1_f1
|
||||||
|
|
||||||
|
- debug: var=poweroff_d1_c1_f1
|
||||||
|
|
||||||
|
- name: make sure no changes were made
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "poweroff_d1_c1_f1.results|map(attribute='changed')|unique|list == [False]"
|
Loading…
Reference in a new issue