tenks/ansible/action_plugins/tenks_schedule.py
2018-08-21 16:57:39 +00:00

70 lines
2.7 KiB
Python

# Avoid shadowing of system copy module by copy action plugin.
from __future__ import absolute_import
from copy import deepcopy
import operator
from ansible.errors import AnsibleActionFail
from ansible.module_utils._text import to_text
from ansible.plugins.action import ActionBase
from six import iteritems
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
"""
Schedule specifications of VMs by flavour onto hypervisors.
:param hypervisor_vars: A dict of hostvars for each hypervisor, keyed
by hypervisor hostname.
:param specs: A dict mapping flavour names to the number of VMs
required of that flavour.
:param flavours: A dict mapping flavour names to a dict of properties
of that flavour.
:param vm_name_prefix: A string with with to prefix all sequential VM
names.
:returns: A dict containing lists of VM details, keyed by the
hostname of the hypervisor to which they are scheduled.
:raises: AnsibleError if insufficient hypervisors exist to host the
requested VMs.
"""
result = super(ActionModule, self).run(tmp, task_vars)
del tmp # tmp no longer has any effect
self._validate_vars(task_vars)
vms = []
idx = 0
for flav, cnt in iteritems(task_vars['specs']):
for _ in xrange(cnt):
vm = deepcopy(task_vars['flavours'][flav])
# Sequentially number the VM names.
vm['name'] = "%s%d" % (task_vars['vm_name_prefix'], idx)
vms.append(vm)
idx += 1
# TODO(w-miller): currently we just arbitrarily schedule all VMs to the
# first hypervisor. Improve this algorithm to make it more
# sophisticated.
result['result'] = {task_vars['hypervisor_vars'].keys()[0]: vms}
return result
def _validate_vars(self, task_vars):
if task_vars is None:
task_vars = {}
REQUIRED_TASK_VARS = {'hypervisor_vars', 'specs', 'flavours'}
OPTIONAL_TASK_VARS = {('vm_name_prefix', 'vm')}
for var in REQUIRED_TASK_VARS:
if var not in task_vars:
e = "The parameter '%s' must be specified." % var
raise AnsibleActionFail(to_text(e))
for var in OPTIONAL_TASK_VARS:
if var[0] not in task_vars:
task_vars[var[0]] = var[1]
if not task_vars['hypervisor_vars']:
e = ("There are no hosts in the 'hypervisors' group to which we "
"can schedule.")
raise AnsibleActionFail(to_text(e))