Remove incidental vmware tests (#72420)

* Add explicit tests for ansible.module_utils.common.network.is_mac

* Test missing ANSIBLE_CONFIG

* Add explicit inventory script tests

* Add explicit tests for _consume_options

* Adjust perms, remove extra file

* ci_complete ci_coverage

* remove incidental_inventory_vmware_vm_inventory

* ci_complete ci_coverage

* Remove incidental_script_inventory_vmware_inventory

* ci_complete ci_coverage

* Remove incidental_vmware_guest

* ci_complete ci_coverage

* Remove incidental_vmware_host_hyperthreading and incidental_vmware_prepare_tests

* ci_complete ci_coverage

* newline and comment about what the test is doing

* ci_complete ci_coverage

(cherry picked from commit ccc63abc8e)
pull/72548/head
Matt Martz 4 years ago committed by Rick Elrod
parent 5b5870886b
commit e555358c32

@ -136,7 +136,6 @@ matrix:
- env: T=i/aws/3.6/1
- env: T=i/azure/2.7/1
- env: T=i/azure/3.6/1
- env: T=i/vcenter//1
- env: T=i/tower//1
- env: T=i/cloud//1

@ -0,0 +1,4 @@
- assert:
that:
- '"00:00:00:a1:2b:cc" is is_mac'
- '"foo" is not is_mac'

@ -0,0 +1,14 @@
# Copyright: (c) 2020, Matt Martz <matt@sivel.net>
# 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
from ansible.module_utils.common.network import is_mac
class TestModule(object):
def tests(self):
return {
'is_mac': is_mac,
}

@ -13,3 +13,5 @@ ANSIBLE_TIMEOUT='lola' ansible -m ping testhost -i ../../inventory "$@" 2>&1|gre
ANSIBLE_REMOTE_TMP="$HOME/.ansible/directory_with_no_space" ansible -m ping testhost -i ../../inventory "$@"
ANSIBLE_REMOTE_TMP="$HOME/.ansible/directory with space" ansible -m ping testhost -i ../../inventory "$@"
ANSIBLE_CONFIG=nonexistent.cfg ansible-config dump --only-changed -v | grep 'No config file found; using defaults'

@ -1,3 +0,0 @@
shippable/vcenter/incidental
cloud/vcenter
destructive

@ -1,8 +0,0 @@
[defaults]
inventory = test-config.vmware.yaml
[inventory]
enable_plugins = vmware_vm_inventory
cache = True
cache_plugin = jsonfile
cache_connection = inventory_cache

@ -1,83 +0,0 @@
#!/usr/bin/env bash
[[ -n "$DEBUG" || -n "$ANSIBLE_DEBUG" ]] && set -x
set -euo pipefail
# Required to differentiate between Python 2 and 3 environ
PYTHON=${ANSIBLE_TEST_PYTHON_INTERPRETER:-python}
export ANSIBLE_CONFIG=ansible.cfg
export VMWARE_SERVER="${VCENTER_HOSTNAME}"
export VMWARE_USERNAME="${VCENTER_USERNAME}"
export VMWARE_PASSWORD="${VCENTER_PASSWORD}"
port=5000
VMWARE_CONFIG=test-config.vmware.yaml
inventory_cache="$(pwd)/inventory_cache"
cat > "$VMWARE_CONFIG" <<VMWARE_YAML
plugin: vmware_vm_inventory
strict: False
validate_certs: False
with_tags: False
VMWARE_YAML
cleanup() {
echo "Cleanup"
if [ -f "${VMWARE_CONFIG}" ]; then
rm -f "${VMWARE_CONFIG}"
fi
if [ -d "${inventory_cache}" ]; then
echo "Removing ${inventory_cache}"
rm -rf "${inventory_cache}"
fi
echo "Done"
exit 0
}
trap cleanup INT TERM EXIT
echo "DEBUG: Using ${VCENTER_HOSTNAME} with username ${VCENTER_USERNAME} and password ${VCENTER_PASSWORD}"
echo "Kill all previous instances"
curl "http://${VCENTER_HOSTNAME}:${port}/killall" > /dev/null 2>&1
echo "Start new VCSIM server"
curl "http://${VCENTER_HOSTNAME}:${port}/spawn?datacenter=1&cluster=1&folder=0" > /dev/null 2>&1
echo "Debugging new instances"
curl "http://${VCENTER_HOSTNAME}:${port}/govc_find"
# Get inventory
ansible-inventory -i ${VMWARE_CONFIG} --list
echo "Check if cache is working for inventory plugin"
if [ ! -n "$(find "${inventory_cache}" -maxdepth 1 -name 'vmware_vm_inventory_*' -print -quit)" ]; then
echo "Cache directory not found. Please debug"
exit 1
fi
echo "Cache is working"
# Get inventory using YAML
ansible-inventory -i ${VMWARE_CONFIG} --list --yaml
# Install TOML for --toml
${PYTHON} -m pip freeze | grep toml > /dev/null 2>&1
TOML_TEST_RESULT=$?
if [ $TOML_TEST_RESULT -ne 0 ]; then
echo "Installing TOML package"
${PYTHON} -m pip install toml
else
echo "TOML package already exists, skipping installation"
fi
# Get inventory using TOML
ansible-inventory -i ${VMWARE_CONFIG} --list --toml
TOML_INVENTORY_LIST_RESULT=$?
if [ $TOML_INVENTORY_LIST_RESULT -ne 0 ]; then
echo "Inventory plugin failed to list inventory host using --toml, please debug"
exit 1
fi
# Test playbook with given inventory
ansible-playbook -i ${VMWARE_CONFIG} test_vmware_vm_inventory.yml --connection=local "$@"

@ -1,24 +0,0 @@
# Test code for the vmware guest dynamic plugin module
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: Test VMware Guest Dynamic Inventroy Plugin
hosts: localhost
tasks:
- name: store the vcenter container ip
set_fact:
vcsim: "{{ lookup('env', 'VCENTER_HOSTNAME') }}"
- name: Check that there are 'all' and 'otherGuest' groups present in inventory
assert:
that: "'{{ item }}' in {{ groups.keys() | list }}"
with_items:
- all
- otherGuest
- name: Check if Hostname and other details are populated in hostvars
assert:
that:
- hostvars[item].name is defined
with_items: "{{ groups['all'] }}"

@ -1,3 +0,0 @@
shippable/vcenter/incidental
cloud/vcenter
destructive

@ -1,58 +0,0 @@
#!/usr/bin/env bash
[[ -n "$DEBUG" || -n "$ANSIBLE_DEBUG" ]] && set -x
set -euo pipefail
contrib_dir=$(pwd)
echo "DEBUG: using ${contrib_dir}"
export ANSIBLE_CONFIG=ansible.cfg
export VMWARE_SERVER="${VCENTER_HOSTNAME}"
export VMWARE_USERNAME="${VCENTER_USERNAME}"
export VMWARE_PASSWORD="${VCENTER_PASSWORD}"
VMWARE_CONFIG=${contrib_dir}/vmware_inventory.ini
trap cleanup INT TERM EXIT
# Remove default inventory config file
if [ -f "${VMWARE_CONFIG}" ];
then
echo "DEBUG: Creating backup of ${VMWARE_CONFIG}"
cp "${VMWARE_CONFIG}" "${VMWARE_CONFIG}.bk"
fi
cat > "${VMWARE_CONFIG}" <<VMWARE_INI
[vmware]
server=${VMWARE_SERVER}
username=${VMWARE_USERNAME}
password=${VMWARE_PASSWORD}
validate_certs=False
VMWARE_INI
function cleanup {
# Revert back to previous one
if [ -f "${VMWARE_CONFIG}.bk" ]; then
echo "DEBUG: Cleanup ${VMWARE_CONFIG}"
mv "${VMWARE_CONFIG}.bk" "${VMWARE_CONFIG}"
fi
}
echo "DEBUG: Using ${VCENTER_HOSTNAME} with username ${VCENTER_USERNAME} and password ${VCENTER_PASSWORD}"
echo "Kill all previous instances"
curl "http://${VCENTER_HOSTNAME}:5000/killall" > /dev/null 2>&1
echo "Start new VCSIM server"
curl "http://${VCENTER_HOSTNAME}:5000/spawn?datacenter=1&cluster=1&folder=0" > /dev/null 2>&1
echo "Debugging new instances"
curl "http://${VCENTER_HOSTNAME}:5000/govc_find"
# Get inventory
ansible-playbook -i ./vmware_inventory.sh "./test_vmware_inventory.yml" --connection=local "$@"
echo "DEBUG: Done"

@ -1,18 +0,0 @@
# Test code for the vmware guest contrib inventory
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: Test VMware guest contrib inventroy script
hosts: localhost
tasks:
- name: store the vcenter container ip
set_fact:
vcsim: "{{ lookup('env', 'VCENTER_HOSTNAME') }}"
- name: Check that groups present in inventory
assert:
that:
- "'{{item}}' in groups"
with_items:
- all

@ -1,127 +0,0 @@
# Ansible VMware external inventory script settings
[vmware]
# The resolvable hostname or ip address of the vsphere
server=vcenter
# The port for the vsphere API
#port=443
# The username with access to the vsphere API. This setting
# may also be defined via the VMWARE_USERNAME environment variable.
username=administrator@vsphere.local
# The password for the vsphere API. This setting
# may also be defined via the VMWARE_PASSWORD environment variable.
password=vmware
# Verify the server's SSL certificate
#validate_certs = True
# Specify the number of seconds to use the inventory cache before it is
# considered stale. If not defined, defaults to 0 seconds.
#cache_max_age = 3600
# Specify the directory used for storing the inventory cache. If not defined,
# caching will be disabled.
#cache_path = ~/.cache/ansible
# Max object level refers to the level of recursion the script will delve into
# the objects returned from pyvomi to find serializable facts. The default
# level of 0 is sufficient for most tasks and will be the most performant.
# Beware that the recursion can exceed python's limit (causing traceback),
# cause sluggish script performance and return huge blobs of facts.
# If you do not know what you are doing, leave this set to 1.
#max_object_level=1
# Lower the keynames for facts to make addressing them easier.
#lower_var_keys=True
# Don't retrieve and process some VMware attribute keys
# Default values permit to sanitize inventory meta and to improve a little bit
# performance by removing non-common group attributes.
#skip_keys = declaredalarmstate,disabledmethod,dynamicproperty,dynamictype,environmentbrowser,managedby,parent,childtype,resourceconfig
# Host alias for objects in the inventory. VMware allows duplicate VM names
# so they can not be considered unique. Use this setting to alter the alias
# returned for the hosts. Any atributes for the guest can be used to build
# this alias. The default combines the config name and the config uuid and
# expects that the ansible_host will be set by the host_pattern.
#alias_pattern={{ config.name + '_' + config.uuid }}
# Host pattern is the value set for ansible_host and ansible_ssh_host, which
# needs to be a hostname or ipaddress the ansible controlhost can reach.
#host_pattern={{ guest.ipaddress }}
# Host filters are a comma separated list of jinja patterns to remove
# non-matching hosts from the final result.
# EXAMPLES:
# host_filters={{ config.guestid == 'rhel7_64Guest' }}
# host_filters={{ config.cpuhotremoveenabled != False }},{{ runtime.maxmemoryusage >= 512 }}
# host_filters={{ config.cpuhotremoveenabled != False }},{{ runtime.maxmemoryusage >= 512 }}
# host_filters={{ runtime.powerstate == "poweredOn" }}
# host_filters={{ guest.gueststate == "notRunning" }}
# The default value is powerstate of virtual machine equal to "poweredOn". (Changed in version 2.5)
# Runtime state does not require to have vmware tools installed as compared to "guest.gueststate"
#host_filters={{ runtime.powerstate == "poweredOn" }}
# Groupby patterns enable the user to create groups via any possible jinja
# expression. The resulting value will the groupname and the host will be added
# to that group. Be careful to not make expressions that simply return True/False
# because those values will become the literal group name. The patterns can be
# comma delimited to create as many groups as necessary
#groupby_patterns={{ guest.guestid }},{{ 'templates' if config.template else 'guests'}}
# Group by custom fields will use VMware custom fields to generate hostgroups
# based on {{ custom_field_group_prefix }} + field_name + _ + field_value
# Set groupby_custom_field to True will enable this feature
# If custom field value is comma separated, multiple groups are created.
# Warning: This required max_object_level to be set to 2 or greater.
#groupby_custom_field = False
# You can customize prefix used by custom field hostgroups generation here.
# vmware_tag_ prefix is the default and consistent with ec2_tag_
#custom_field_group_prefix = vmware_tag_
# You can blacklist custom fields so that they are not included in the
# groupby_custom_field option. This is useful when you have custom fields that
# have values that are unique to individual hosts. Timestamps for example.
# The groupby_custom_field_excludes option should be a comma separated list of custom
# field keys to be blacklisted.
#groupby_custom_field_excludes=<custom_field_1>,<custom_field_2>,<custom_field_3>
# The script attempts to recurse into virtualmachine objects and serialize
# all available data. The serialization is comprehensive but slow. If the
# vcenter environment is large and the desired properties are known, create
# a 'properties' section in this config and make an arbitrary list of
# key=value settings where the value is a path to a specific property. If
# If this feature is enabled, be sure to fetch every property that is used
# in the jinja expressions defined above. For performance tuning, reduce
# the number of properties to the smallest amount possible and limit the
# use of properties that are not direct attributes of vim.VirtualMachine
#[properties]
#prop01=name
#prop02=config.cpuHotAddEnabled
#prop03=config.cpuHotRemoveEnabled
#prop04=config.instanceUuid
#prop05=config.hardware.numCPU
#prop06=config.template
#prop07=config.name
#prop08=guest.hostName
#prop09=guest.ipAddress
#prop10=guest.guestId
#prop11=guest.guestState
#prop12=runtime.maxMemoryUsage
# In order to populate `customValue` (virtual machine's custom attributes) inside hostvars,
# uncomment following property. Please see - https://github.com/ansible/ansible/issues/41395
#prop13=customValue

@ -1,793 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C): 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Requirements
# - pyvmomi >= 6.0.0.2016.4
# TODO:
# * more jq examples
# * optional folder hierarchy
"""
$ jq '._meta.hostvars[].config' data.json | head
{
"alternateguestname": "",
"instanceuuid": "5035a5cd-b8e8-d717-e133-2d383eb0d675",
"memoryhotaddenabled": false,
"guestfullname": "Red Hat Enterprise Linux 7 (64-bit)",
"changeversion": "2016-05-16T18:43:14.977925Z",
"uuid": "4235fc97-5ddb-7a17-193b-9a3ac97dc7b4",
"cpuhotremoveenabled": false,
"vpmcenabled": false,
"firmware": "bios",
"""
from __future__ import print_function
import atexit
import datetime
import itertools
import json
import os
import re
import ssl
import sys
import uuid
from time import time
from jinja2 import Environment
from ansible.module_utils.six import integer_types, PY3
from ansible.module_utils.six.moves import configparser
try:
import argparse
except ImportError:
sys.exit('Error: This inventory script required "argparse" python module. Please install it or upgrade to python-2.7')
try:
from pyVmomi import vim, vmodl
from pyVim.connect import SmartConnect, Disconnect
except ImportError:
sys.exit("ERROR: This inventory script required 'pyVmomi' Python module, it was not able to load it")
def regex_match(s, pattern):
'''Custom filter for regex matching'''
reg = re.compile(pattern)
if reg.match(s):
return True
else:
return False
def select_chain_match(inlist, key, pattern):
'''Get a key from a list of dicts, squash values to a single list, then filter'''
outlist = [x[key] for x in inlist]
outlist = list(itertools.chain(*outlist))
outlist = [x for x in outlist if regex_match(x, pattern)]
return outlist
class VMwareMissingHostException(Exception):
pass
class VMWareInventory(object):
__name__ = 'VMWareInventory'
guest_props = False
instances = []
debug = False
load_dumpfile = None
write_dumpfile = None
maxlevel = 1
lowerkeys = True
config = None
cache_max_age = None
cache_path_cache = None
cache_path_index = None
cache_dir = None
server = None
port = None
username = None
password = None
validate_certs = True
host_filters = []
skip_keys = []
groupby_patterns = []
groupby_custom_field_excludes = []
safe_types = [bool, str, float, None] + list(integer_types)
iter_types = [dict, list]
bad_types = ['Array', 'disabledMethod', 'declaredAlarmState']
vimTableMaxDepth = {
"vim.HostSystem": 2,
"vim.VirtualMachine": 2,
}
custom_fields = {}
# use jinja environments to allow for custom filters
env = Environment()
env.filters['regex_match'] = regex_match
env.filters['select_chain_match'] = select_chain_match
# translation table for attributes to fetch for known vim types
vimTable = {
vim.Datastore: ['_moId', 'name'],
vim.ResourcePool: ['_moId', 'name'],
vim.HostSystem: ['_moId', 'name'],
}
@staticmethod
def _empty_inventory():
return {"_meta": {"hostvars": {}}}
def __init__(self, load=True):
self.inventory = VMWareInventory._empty_inventory()
if load:
# Read settings and parse CLI arguments
self.parse_cli_args()
self.read_settings()
# Check the cache
cache_valid = self.is_cache_valid()
# Handle Cache
if self.args.refresh_cache or not cache_valid:
self.do_api_calls_update_cache()
else:
self.debugl('loading inventory from cache')
self.inventory = self.get_inventory_from_cache()
def debugl(self, text):
if self.args.debug:
try:
text = str(text)
except UnicodeEncodeError:
text = text.encode('utf-8')
print('%s %s' % (datetime.datetime.now(), text))
def show(self):
# Data to print
self.debugl('dumping results')
data_to_print = None
if self.args.host:
data_to_print = self.get_host_info(self.args.host)
elif self.args.list:
# Display list of instances for inventory
data_to_print = self.inventory
return json.dumps(data_to_print, indent=2)
def is_cache_valid(self):
''' Determines if the cache files have expired, or if it is still valid '''
valid = False
if os.path.isfile(self.cache_path_cache):
mod_time = os.path.getmtime(self.cache_path_cache)
current_time = time()
if (mod_time + self.cache_max_age) > current_time:
valid = True
return valid
def do_api_calls_update_cache(self):
''' Get instances and cache the data '''
self.inventory = self.instances_to_inventory(self.get_instances())
self.write_to_cache(self.inventory)
def write_to_cache(self, data):
''' Dump inventory to json file '''
with open(self.cache_path_cache, 'w') as f:
f.write(json.dumps(data, indent=2))
def get_inventory_from_cache(self):
''' Read in jsonified inventory '''
jdata = None
with open(self.cache_path_cache, 'r') as f:
jdata = f.read()
return json.loads(jdata)
def read_settings(self):
''' Reads the settings from the vmware_inventory.ini file '''
scriptbasename = __file__
scriptbasename = os.path.basename(scriptbasename)
scriptbasename = scriptbasename.replace('.py', '')
defaults = {'vmware': {
'server': '',
'port': 443,
'username': '',
'password': '',
'validate_certs': True,
'ini_path': os.path.join(os.path.dirname(__file__), '%s.ini' % scriptbasename),
'cache_name': 'ansible-vmware',
'cache_path': '~/.ansible/tmp',
'cache_max_age': 3600,
'max_object_level': 1,
'skip_keys': 'declaredalarmstate,'
'disabledmethod,'
'dynamicproperty,'
'dynamictype,'
'environmentbrowser,'
'managedby,'
'parent,'
'childtype,'
'resourceconfig',
'alias_pattern': '{{ config.name + "_" + config.uuid }}',
'host_pattern': '{{ guest.ipaddress }}',
'host_filters': '{{ runtime.powerstate == "poweredOn" }}',
'groupby_patterns': '{{ guest.guestid }},{{ "templates" if config.template else "guests"}}',
'lower_var_keys': True,
'custom_field_group_prefix': 'vmware_tag_',
'groupby_custom_field_excludes': '',
'groupby_custom_field': False}
}
if PY3:
config = configparser.ConfigParser()
else:
config = configparser.SafeConfigParser()
# where is the config?
vmware_ini_path = os.environ.get('VMWARE_INI_PATH', defaults['vmware']['ini_path'])
vmware_ini_path = os.path.expanduser(os.path.expandvars(vmware_ini_path))
config.read(vmware_ini_path)
if 'vmware' not in config.sections():
config.add_section('vmware')
# apply defaults
for k, v in defaults['vmware'].items():
if not config.has_option('vmware', k):
config.set('vmware', k, str(v))
# where is the cache?
self.cache_dir = os.path.expanduser(config.get('vmware', 'cache_path'))
if self.cache_dir and not os.path.exists(self.cache_dir):
os.makedirs(self.cache_dir)
# set the cache filename and max age
cache_name = config.get('vmware', 'cache_name')
self.cache_path_cache = self.cache_dir + "/%s.cache" % cache_name
self.debugl('cache path is %s' % self.cache_path_cache)
self.cache_max_age = int(config.getint('vmware', 'cache_max_age'))
# mark the connection info
self.server = os.environ.get('VMWARE_SERVER', config.get('vmware', 'server'))
self.debugl('server is %s' % self.server)
self.port = int(os.environ.get('VMWARE_PORT', config.get('vmware', 'port')))
self.username = os.environ.get('VMWARE_USERNAME', config.get('vmware', 'username'))
self.debugl('username is %s' % self.username)
self.password = os.environ.get('VMWARE_PASSWORD', config.get('vmware', 'password', raw=True))
self.validate_certs = os.environ.get('VMWARE_VALIDATE_CERTS', config.get('vmware', 'validate_certs'))
if self.validate_certs in ['no', 'false', 'False', False]:
self.validate_certs = False
self.debugl('cert validation is %s' % self.validate_certs)
# behavior control
self.maxlevel = int(config.get('vmware', 'max_object_level'))
self.debugl('max object level is %s' % self.maxlevel)
self.lowerkeys = config.get('vmware', 'lower_var_keys')
if type(self.lowerkeys) != bool:
if str(self.lowerkeys).lower() in ['yes', 'true', '1']:
self.lowerkeys = True
else:
self.lowerkeys = False
self.debugl('lower keys is %s' % self.lowerkeys)
self.skip_keys = list(config.get('vmware', 'skip_keys').split(','))
self.debugl('skip keys is %s' % self.skip_keys)
temp_host_filters = list(config.get('vmware', 'host_filters').split('}},'))
for host_filter in temp_host_filters:
host_filter = host_filter.rstrip()
if host_filter != "":
if not host_filter.endswith("}}"):
host_filter += "}}"
self.host_filters.append(host_filter)
self.debugl('host filters are %s' % self.host_filters)
temp_groupby_patterns = list(config.get('vmware', 'groupby_patterns').split('}},'))
for groupby_pattern in temp_groupby_patterns:
groupby_pattern = groupby_pattern.rstrip()
if groupby_pattern != "":
if not groupby_pattern.endswith("}}"):
groupby_pattern += "}}"
self.groupby_patterns.append(groupby_pattern)
self.debugl('groupby patterns are %s' % self.groupby_patterns)
temp_groupby_custom_field_excludes = config.get('vmware', 'groupby_custom_field_excludes')
self.groupby_custom_field_excludes = [x.strip('"') for x in [y.strip("'") for y in temp_groupby_custom_field_excludes.split(",")]]
self.debugl('groupby exclude strings are %s' % self.groupby_custom_field_excludes)
# Special feature to disable the brute force serialization of the
# virtual machine objects. The key name for these properties does not
# matter because the values are just items for a larger list.
if config.has_section('properties'):
self.guest_props = []
for prop in config.items('properties'):
self.guest_props.append(prop[1])
# save the config
self.config = config
def parse_cli_args(self):
''' Command line argument processing '''
parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on PyVmomi')
parser.add_argument('--debug', action='store_true', default=False,
help='show debug info')
parser.add_argument('--list', action='store_true', default=True,
help='List instances (default: True)')
parser.add_argument('--host', action='store',
help='Get all the variables about a specific instance')
parser.add_argument('--refresh-cache', action='store_true', default=False,
help='Force refresh of cache by making API requests to VSphere (default: False - use cache files)')
parser.add_argument('--max-instances', default=None, type=int,
help='maximum number of instances to retrieve')
self.args = parser.parse_args()
def get_instances(self):
''' Get a list of vm instances with pyvmomi '''
kwargs = {'host': self.server,
'user': self.username,
'pwd': self.password,
'port': int(self.port)}
if self.validate_certs and hasattr(ssl, 'SSLContext'):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
kwargs['sslContext'] = context
elif self.validate_certs and not hasattr(ssl, 'SSLContext'):
sys.exit('pyVim does not support changing verification mode with python < 2.7.9. Either update '
'python or use validate_certs=false.')
elif not self.validate_certs and hasattr(ssl, 'SSLContext'):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_NONE
context.check_hostname = False
kwargs['sslContext'] = context
elif not self.validate_certs and not hasattr(ssl, 'SSLContext'):
# Python 2.7.9 < or RHEL/CentOS 7.4 <
pass
return self._get_instances(kwargs)
def _get_instances(self, inkwargs):
''' Make API calls '''
instances = []
si = None
try:
si = SmartConnect(**inkwargs)
except ssl.SSLError as connection_error:
if '[SSL: CERTIFICATE_VERIFY_FAILED]' in str(connection_error) and self.validate_certs:
sys.exit("Unable to connect to ESXi server due to %s, "
"please specify validate_certs=False and try again" % connection_error)
except Exception as exc:
self.debugl("Unable to connect to ESXi server due to %s" % exc)
sys.exit("Unable to connect to ESXi server due to %s" % exc)
self.debugl('retrieving all instances')
if not si:
sys.exit("Could not connect to the specified host using specified "
"username and password")
atexit.register(Disconnect, si)
content = si.RetrieveContent()
# Create a search container for virtualmachines
self.debugl('creating containerview for virtualmachines')
container = content.rootFolder
viewType = [vim.VirtualMachine]
recursive = True
containerView = content.viewManager.CreateContainerView(container, viewType, recursive)
children = containerView.view
for child in children:
# If requested, limit the total number of instances
if self.args.max_instances:
if len(instances) >= self.args.max_instances:
break
instances.append(child)
self.debugl("%s total instances in container view" % len(instances))
if self.args.host:
instances = [x for x in instances if x.name == self.args.host]
instance_tuples = []
for instance in instances:
if self.guest_props:
ifacts = self.facts_from_proplist(instance)
else:
ifacts = self.facts_from_vobj(instance)
instance_tuples.append((instance, ifacts))
self.debugl('facts collected for all instances')
try:
cfm = content.customFieldsManager
if cfm is not None and cfm.field:
for f in cfm.field:
if not f.managedObjectType or f.managedObjectType == vim.VirtualMachine:
self.custom_fields[f.key] = f.name
self.debugl('%d custom fields collected' % len(self.custom_fields))
except vmodl.RuntimeFault as exc:
self.debugl("Unable to gather custom fields due to %s" % exc.msg)
except IndexError as exc:
self.debugl("Unable to gather custom fields due to %s" % exc)
return instance_tuples
def instances_to_inventory(self, instances):
''' Convert a list of vm objects into a json compliant inventory '''
self.debugl('re-indexing instances based on ini settings')
inventory = VMWareInventory._empty_inventory()
inventory['all'] = {}
inventory['all']['hosts'] = []
for idx, instance in enumerate(instances):
# make a unique id for this object to avoid vmware's
# numerous uuid's which aren't all unique.
thisid = str(uuid.uuid4())
idata = instance[1]
# Put it in the inventory
inventory['all']['hosts'].append(thisid)
inventory['_meta']['hostvars'][thisid] = idata.copy()
inventory['_meta']['hostvars'][thisid]['ansible_uuid'] = thisid
# Make a map of the uuid to the alias the user wants
name_mapping = self.create_template_mapping(
inventory,
self.config.get('vmware', 'alias_pattern')
)
# Make a map of the uuid to the ssh hostname the user wants
host_mapping = self.create_template_mapping(
inventory,
self.config.get('vmware', 'host_pattern')
)
# Reset the inventory keys
for k, v in name_mapping.items():
if not host_mapping or k not in host_mapping:
continue
# set ansible_host (2.x)
try:
inventory['_meta']['hostvars'][k]['ansible_host'] = host_mapping[k]
# 1.9.x backwards compliance
inventory['_meta']['hostvars'][k]['ansible_ssh_host'] = host_mapping[k]
except Exception:
continue
if k == v:
continue
# add new key
inventory['all']['hosts'].append(v)
inventory['_meta']['hostvars'][v] = inventory['_meta']['hostvars'][k]
# cleanup old key
inventory['all']['hosts'].remove(k)
inventory['_meta']['hostvars'].pop(k, None)
self.debugl('pre-filtered hosts:')
for i in inventory['all']['hosts']:
self.debugl(' * %s' % i)
# Apply host filters
for hf in self.host_filters:
if not hf:
continue
self.debugl('filter: %s' % hf)
filter_map = self.create_template_mapping(inventory, hf, dtype='boolean')
for k, v in filter_map.items():
if not v:
# delete this host
inventory['all']['hosts'].remove(k)
inventory['_meta']['hostvars'].pop(k, None)
self.debugl('post-filter hosts:')
for i in inventory['all']['hosts']:
self.debugl(' * %s' % i)
# Create groups
for gbp in self.groupby_patterns:
groupby_map = self.create_template_mapping(inventory, gbp)
for k, v in groupby_map.items():
if v not in inventory:
inventory[v] = {}
inventory[v]['hosts'] = []
if k not in inventory[v]['hosts']:
inventory[v]['hosts'].append(k)
if self.config.get('vmware', 'groupby_custom_field'):
for k, v in inventory['_meta']['hostvars'].items():
if 'customvalue' in v:
for tv in v['customvalue']:
newkey = None
field_name = self.custom_fields[tv['key']] if tv['key'] in self.custom_fields else tv['key']
if field_name in self.groupby_custom_field_excludes:
continue
values = []
keylist = map(lambda x: x.strip(), tv['value'].split(','))
for kl in keylist:
try:
newkey = "%s%s_%s" % (self.config.get('vmware', 'custom_field_group_prefix'), str(field_name), kl)
newkey = newkey.strip()
except Exception as e:
self.debugl(e)
values.append(newkey)
for tag in values:
if not tag:
continue
if tag not in inventory:
inventory[tag] = {}
inventory[tag]['hosts'] = []
if k not in inventory[tag]['hosts']:
inventory[tag]['hosts'].append(k)
return inventory
def create_template_mapping(self, inventory, pattern, dtype='string'):
''' Return a hash of uuid to templated string from pattern '''
mapping = {}
for k, v in inventory['_meta']['hostvars'].items():
t = self.env.from_string(pattern)
newkey = None
try:
newkey = t.render(v)
newkey = newkey.strip()
except Exception as e:
self.debugl(e)
if not newkey:
continue
elif dtype == 'integer':
newkey = int(newkey)
elif dtype == 'boolean':
if newkey.lower() == 'false':
newkey = False
elif newkey.lower() == 'true':
newkey = True
elif dtype == 'string':
pass
mapping[k] = newkey
return mapping
def facts_from_proplist(self, vm):
'''Get specific properties instead of serializing everything'''
rdata = {}
for prop in self.guest_props:
self.debugl('getting %s property for %s' % (prop, vm.name))
key = prop
if self.lowerkeys:
key = key.lower()
if '.' not in prop:
# props without periods are direct attributes of the parent
vm_property = getattr(vm, prop)
if isinstance(vm_property, vim.CustomFieldsManager.Value.Array):
temp_vm_property = []
for vm_prop in vm_property:
temp_vm_property.append({'key': vm_prop.key,
'value': vm_prop.value})
rdata[key] = temp_vm_property
else:
rdata[key] = vm_property
else:
# props with periods are subkeys of parent attributes
parts = prop.split('.')
total = len(parts) - 1
# pointer to the current object
val = None
# pointer to the current result key
lastref = rdata
for idx, x in enumerate(parts):
if isinstance(val, dict):
if x in val:
val = val.get(x)
elif x.lower() in val:
val = val.get(x.lower())
else:
# if the val wasn't set yet, get it from the parent
if not val:
try:
val = getattr(vm, x)
except AttributeError as e:
self.debugl(e)
else:
# in a subkey, get the subprop from the previous attrib
try:
val = getattr(val, x)
except AttributeError as e:
self.debugl(e)
# make sure it serializes
val = self._process_object_types(val)
# lowercase keys if requested
if self.lowerkeys:
x = x.lower()
# change the pointer or set the final value
if idx != total:
if x not in lastref:
lastref[x] = {}
lastref = lastref[x]
else:
lastref[x] = val
if self.args.debug:
self.debugl("For %s" % vm.name)
for key in list(rdata.keys()):
if isinstance(rdata[key], dict):
for ikey in list(rdata[key].keys()):
self.debugl("Property '%s.%s' has value '%s'" % (key, ikey, rdata[key][ikey]))
else:
self.debugl("Property '%s' has value '%s'" % (key, rdata[key]))
return rdata
def facts_from_vobj(self, vobj, level=0):
''' Traverse a VM object and return a json compliant data structure '''
# pyvmomi objects are not yet serializable, but may be one day ...
# https://github.com/vmware/pyvmomi/issues/21
# WARNING:
# Accessing an object attribute will trigger a SOAP call to the remote.
# Increasing the attributes collected or the depth of recursion greatly
# increases runtime duration and potentially memory+network utilization.
if level == 0:
try:
self.debugl("get facts for %s" % vobj.name)
except Exception as e:
self.debugl(e)
rdata = {}
methods = dir(vobj)
methods = [str(x) for x in methods if not x.startswith('_')]
methods = [x for x in methods if x not in self.bad_types]
methods = [x for x in methods if not x.lower() in self.skip_keys]
methods = sorted(methods)
for method in methods:
# Attempt to get the method, skip on fail
try:
methodToCall = getattr(vobj, method)
except Exception as e:
continue
# Skip callable methods
if callable(methodToCall):
continue
if self.lowerkeys:
method = method.lower()
rdata[method] = self._process_object_types(
methodToCall,
thisvm=vobj,
inkey=method,
)
return rdata
def _process_object_types(self, vobj, thisvm=None, inkey='', level=0):
''' Serialize an object '''
rdata = {}
if type(vobj).__name__ in self.vimTableMaxDepth and level >= self.vimTableMaxDepth[type(vobj).__name__]:
return rdata
if vobj is None:
rdata = None
elif type(vobj) in self.vimTable:
rdata = {}
for key in self.vimTable[type(vobj)]:
try:
rdata[key] = getattr(vobj, key)
except Exception as e:
self.debugl(e)
elif issubclass(type(vobj), str) or isinstance(vobj, str):
if vobj.isalnum():
rdata = vobj
else:
rdata = vobj.encode('utf-8').decode('utf-8')
elif issubclass(type(vobj), bool) or isinstance(vobj, bool):
rdata = vobj
elif issubclass(type(vobj), integer_types) or isinstance(vobj, integer_types):
rdata = vobj
elif issubclass(type(vobj), float) or isinstance(vobj, float):
rdata = vobj
elif issubclass(type(vobj), list) or issubclass(type(vobj), tuple):
rdata = []
try:
vobj = sorted(vobj)
except Exception:
pass
for idv, vii in enumerate(vobj):
if level + 1 <= self.maxlevel:
vid = self._process_object_types(
vii,
thisvm=thisvm,
inkey=inkey + '[' + str(idv) + ']',
level=(level + 1)
)
if vid:
rdata.append(vid)
elif issubclass(type(vobj), dict):
pass
elif issubclass(type(vobj), object):
methods = dir(vobj)
methods = [str(x) for x in methods if not x.startswith('_')]
methods = [x for x in methods if x not in self.bad_types]
methods = [x for x in methods if not inkey + '.' + x.lower() in self.skip_keys]
methods = sorted(methods)
for method in methods:
# Attempt to get the method, skip on fail
try:
methodToCall = getattr(vobj, method)
except Exception as e:
continue
if callable(methodToCall):
continue
if self.lowerkeys:
method = method.lower()
if level + 1 <= self.maxlevel:
try:
rdata[method] = self._process_object_types(
methodToCall,
thisvm=thisvm,
inkey=inkey + '.' + method,
level=(level + 1)
)
except vim.fault.NoPermission:
self.debugl("Skipping method %s (NoPermission)" % method)
else:
pass
return rdata
def get_host_info(self, host):
''' Return hostvars for a single host '''
if host in self.inventory['_meta']['hostvars']:
return self.inventory['_meta']['hostvars'][host]
elif self.args.host and self.inventory['_meta']['hostvars']:
match = None
for k, v in self.inventory['_meta']['hostvars'].items():
if self.inventory['_meta']['hostvars'][k]['name'] == self.args.host:
match = k
break
if match:
return self.inventory['_meta']['hostvars'][match]
else:
raise VMwareMissingHostException('%s not found' % host)
else:
raise VMwareMissingHostException('%s not found' % host)
if __name__ == "__main__":
# Run the script
print(VMWareInventory().show())

@ -1,3 +0,0 @@
#!/usr/bin/env bash
python.py "./vmware_inventory.py" "$@"

@ -1,3 +0,0 @@
shippable/vcenter/incidental
cloud/vcenter
needs/target/incidental_vmware_prepare_tests

@ -1,33 +0,0 @@
vmware_guest_test_playbooks:
- boot_firmware_d1_c1_f0.yml
- boot_firmware_d1_c1_f0.yml
- cdrom_d1_c1_f0.yml
- check_mode.yml
- clone_customize_guest_test.yml
- clone_d1_c1_f0.yml
- clone_resize_disks.yml
- clone_with_convert.yml
- create_d1_c1_f0.yml
- create_guest_invalid_d1_c1_f0.yml
- create_nw_d1_c1_f0.yml
- create_rp_d1_c1_f0.yml
- delete_vm.yml
- disk_mode_d1_c1_f0.yml
- disk_size_d1_c1_f0.yml
- disk_type_d1_c1_f0.yml
- linked_clone_d1_c1_f0.yml
- mac_address_d1_c1_f0.yml
- max_connections.yml
- mem_reservation.yml
- network_negative_test.yml
- network_with_device.yml
# Currently, VCSIM doesn't support DVPG (as portkeys are not available) so commenting this test
# - network_with_dvpg.yml
# - network_with_portgroup.yml
- non_existent_vm_ops.yml
- poweroff_d1_c1_f0.yml
- poweroff_d1_c1_f1.yml
# - template_d1_c1_f0.yml
- vapp_d1_c1_f0.yml
- reconfig_vm_to_latest_version.yml
- remove_vm_from_inventory.yml

@ -1,117 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new VMs with boot_firmware as 'bios'
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
boot_firmware: "bios"
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: "{{ f0 }}"
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_d1_c1_f0 is changed
# VCSIM does not recognizes existing VMs boot firmware
- when: vcsim is not defined
block:
- name: create new VMs again with boot_firmware as 'bios'
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
boot_firmware: "bios"
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: "{{ f0 }}"
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- clone_d1_c1_f0 is changed
- name: create new VMs with boot_firmware as 'efi'
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm3
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
boot_firmware: "efi"
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: "{{ f0 }}"
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_d1_c1_f0 is changed
# VCSIM does not recognizes existing VMs boot firmware
- when: vcsim is not defined
block:
- name: create new VMs again with boot_firmware as 'efi'
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm3
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
boot_firmware: "efi"
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: "{{ f0 }}"
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- not (clone_d1_c1_f0 is changed)

@ -1,269 +0,0 @@
- name: Create VM with CDROM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: vm
name: test_vm1
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] centos.iso"
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was created
assert:
that:
- "cdrom_vm.changed == true"
- name: Update CDROM to iso for the new VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "vm"
name: test_vm1
datastore: "{{ rw_datastore }}"
datacenter: "{{ dc1 }}"
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
state: present
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was changed
assert:
that:
- "cdrom_vm.changed == true"
- name: Update CDROM to client for the new VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: vm
name: test_vm1
datacenter: "{{ dc1 }}"
cdrom:
type: client
state: present
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was changed
assert:
that:
- "cdrom_vm.changed == true"
- name: clone vm
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
template: test_vm1
datacenter: "{{ dc1 }}"
state: poweredoff
folder: vm
convert: thin
- name: Update CDROM to none for the new VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: vm
name: test_vm2
datacenter: "{{ dc1 }}"
cdrom:
type: none
state: present
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was changed
assert:
that:
- "cdrom_vm.changed == true"
- name: Create VM with multiple disks and a CDROM - GitHub issue 38679
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ f0 }}"
name: test_vm3
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was created
assert:
that:
- "cdrom_vm.changed == true"
- name: Create VM with multiple CDROMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: vm
name: test_vm1
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
cdrom:
- controller_type: ide
controller_number: 0
unit_number: 0
type: iso
iso_path: "[{{ ro_datastore }}] centos.iso"
- controller_type: ide
controller_number: 0
unit_number: 1
type: client
- controller_number: 1
unit_number: 0
type: none
- controller_number: 1
unit_number: 1
type: client
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was created
assert:
that:
- "cdrom_vm.changed == true"
- name: Remove the last 2 CDROMs and update the first 2 for the new VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: vm
name: test_vm1
datacenter: "{{ dc1 }}"
cdrom:
- controller_type: ide
controller_number: 0
unit_number: 0
type: client
- controller_type: ide
controller_number: 0
unit_number: 1
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
- controller_type: ide
controller_number: 1
unit_number: 0
state: absent
- controller_type: ide
controller_number: 1
unit_number: 1
state: absent
state: present
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was changed
assert:
that:
- "cdrom_vm.changed == true"
# VCSIM fails with invalidspec exception but real vCenter PASS testcase
# Commenting this testcase till the time
- when: vcsim is not defined
block:
- name: Again create VM with multiple disks and a CDROM - GitHub issue 38679
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ f0 }}"
name: test_vm3
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] base.iso"
register: cdrom_vm
- debug: var=cdrom_vm
- name: assert the VM was created
assert:
that:
- cdrom_vm is changed

@ -1,60 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Perform all operation in check mode
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: "{{ item }}"
with_items:
- absent
- present
- poweredoff
- poweredon
- restarted
- suspended
- shutdownguest
- rebootguest
register: check_mode_state
check_mode: yes
- debug:
var: check_mode_state
- name: assert that changes were made
assert:
that:
- "check_mode_state.results|map(attribute='changed')|unique|list == [true]"
- "check_mode_state.results|map(attribute='vm_name')|unique|list == [ virtual_machines[0].name ]"
- name: Perform all operation on non-existent VM in check mode
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: non_existent_vm
datacenter: "{{ dc1 }}"
state: "{{ item }}"
with_items:
- present
- poweredoff
- poweredon
- restarted
- suspended
register: check_mode_state
check_mode: yes
- debug:
var: check_mode_state
- name: assert that changes were made
assert:
that:
- "check_mode_state.results|map(attribute='changed')|unique|list == [true]"
- "check_mode_state.results|map(attribute='desired_operation')|unique|list == ['deploy_vm']"

@ -1,47 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Pavan Bidkar <pbidkar@vmware.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: clone vm from template and customize GOS
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
template: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: poweredoff
folder: "{{ virtual_machines[0].folder }}"
convert: thin
register: clone_customize
- debug:
var: clone_customize
- name: assert that changes were made
assert:
that:
- clone_customize is changed
- name: clone vm from template and customize GOS again
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
template: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: poweredoff
folder: "{{ virtual_machines[0].folder }}"
convert: thin
register: clone_customize_again
- debug:
var: clone_customize_again
- name: assert that changes were not made
assert:
that:
- not (clone_customize_again is changed)

@ -1,101 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2017, James Tanner <tanner.jc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new linked clone without specifying snapshot_src
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
template: "{{ virtual_machines[0].name }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
linked_clone: True
register: linked_clone_d1_c1_f0
ignore_errors: True
- debug:
var: linked_clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- not (linked_clone_d1_c1_f0 is changed)
- name: create new linked clone without specifying linked_clone
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
template: "{{ virtual_machines[0].name }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
snapshot_src: "snap_shot1"
register: linked_clone_d1_c1_f0
ignore_errors: True
- debug:
var: linked_clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- not (linked_clone_d1_c1_f0 is changed)
# TODO: VCSIM: snapshot is not supported in current vcsim
#
#- name: create new linked clone with linked_clone and snapshot_src
# vmware_guest:
# validate_certs: False
# hostname: "{{ vcenter_hostname }}"
# username: "{{ vcenter_username }}"
# password: "{{ vcenter_password }}"
# name: "{{ 'new_vm_' + item|basename }}"
# template: "{{ item|basename }}"
# guest_id: centos64Guest
# datacenter: "{{ (item|basename).split('_')[0] }}"
# folder: "{{ item|dirname }}"
# snapshot_src: "snap_shot1"
# linked_clone: True
# with_items: "{{ vmlist['json'] }}"
# register: linked_clone_d1_c1_f0
# ignore_errors: True
#- debug: var=linked_clone_d1_c1_f0
#- name: assert that changes were made
# assert:
# that:
# - "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [true]"
# TODO: VCSIM: snapshot is not supported in current vcsim
#
#- name: create new linked clone with linked_clone and snapshot_src again
# vmware_guest:
# validate_certs: False
# hostname: "{{ vcenter_hostname }}"
# username: "{{ vcenter_username }}"
# password: "{{ vcenter_password }}"
# name: "{{ 'new_vm_' + item|basename }}"
# template: "{{ item|basename }}"
# guest_id: centos64Guest
# datacenter: "{{ (item|basename).split('_')[0] }}"
# folder: "{{ item|dirname }}"
# snapshot_src: "snap_shot1"
# linked_clone: True
# with_items: "{{ vmlist['json'] }}"
# register: linked_clone_d1_c1_f0
# ignore_errors: True
#- debug: var=linked_clone_d1_c1_f0
#- name: assert that changes were not made
# assert:
# that:
# - "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [false]"

@ -1,77 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Noe Gonzalez <noe.a.gonzalez@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- when: vcsim is not defined
block:
- name: create new VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: clone_resize_disks_original
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
folder: "{{ f0 }}"
hardware:
num_cpus: 1
memory_mb: 128
guest_id: centos7_64Guest
disk:
- size_gb: 1
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
- name: convert to VM template
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: clone_resize_disks_original
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
folder: "{{ f0 }}"
is_template: True
- name: clone template and modify disks
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: clone_resize_disks_clone
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
folder: "{{ f0 }}"
disk:
- size_gb: 2
type: thin
datastore: "{{ rw_datastore }}"
- size_gb: 3
type: thin
datastore: "{{ rw_datastore }}"
template: clone_resize_disks_original
state: poweredoff
register: l_clone_template_modify_disks
- assert:
that:
- l_clone_template_modify_disks.changed | bool
- name: delete VM clone & original template
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ item }}"
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
folder: "{{ f0 }}"
state: absent
with_items:
- clone_resize_disks_original
- clone_resize_disks_clone

@ -1,66 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Christophe FERREIRA <christophe.ferreira@cnaf.fr>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: clone vm from template and convert to thin
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
template: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: poweredoff
folder: "{{ virtual_machines[0].folder }}"
convert: thin
register: clone_thin
- debug: var=clone_thin
- name: assert that changes were made
assert:
that:
- clone_thin is changed
- name: clone vm from template and convert to thick
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
template: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: poweredoff
folder: "{{ virtual_machines[0].folder }}"
convert: thick
register: clone_thick
- debug: var=clone_thick
- name: assert that changes were made
assert:
that:
- clone_thick is changed
- name: clone vm from template and convert to eagerzeroedthick
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm3
template: "{{ virtual_machines[0].name }}"
datacenter: "{{ dc1 }}"
state: poweredoff
folder: "{{ virtual_machines[0].folder }}"
convert: eagerzeroedthick
register: clone_eagerzeroedthick
- debug: var=clone_eagerzeroedthick
- name: assert that changes were made
assert:
that:
- clone_eagerzeroedthick is changed

@ -1,164 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2017, James Tanner <tanner.jc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
num_cpu_cores_per_socket: 1
memory_mb: 128
hotadd_memory: true
hotadd_cpu: false
# vcsim does not support these settings, so commenting
# till the time.
# memory_reservation: 128
# memory_reservation_lock: False
# nested_virt: True
# hotremove_cpu: True
# mem_limit: 8096
# mem_reservation: 4096
# cpu_limit: 8096
# cpu_reservation: 4096
max_connections: 10
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: '{{ f0 }}'
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_d1_c1_f0 is changed
- name: create the VM again
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
num_cpu_cores_per_socket: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: '{{ f0 }}'
register: clone_d1_c1_f0_recreate
- debug: var=clone_d1_c1_f0_recreate
- name: assert that no changes were made after re-creating
assert:
that:
- not (clone_d1_c1_f0_recreate is changed)
- name: modify the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 2
memory_mb: 128
state: present
folder: '{{ f0 }}'
register: clone_d1_c1_f0_modify
- debug: var=clone_d1_c1_f0_modify
- name: assert that changes were made with modification
assert:
that:
- clone_d1_c1_f0_modify is changed
- name: re-modify the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 2
memory_mb: 128
state: present
folder: '{{ f0 }}'
register: clone_d1_c1_f0_remodify
- debug: var=clone_d1_c1_f0_remodify
- name: assert that no changes were made when re-modified
assert:
that:
- not (clone_d1_c1_f0_remodify is changed)
- name: delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
state: absent
folder: '{{ f0 }}'
register: clone_d1_c1_f0_delete
- debug: var=clone_d1_c1_f0_delete
- name: assert that changes were made with deletion
assert:
that:
- clone_d1_c1_f0_delete is changed
- name: re-delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
state: absent
folder: '{{ f0 }}'
register: clone_d1_c1_f0_redelete
- debug: var=clone_d1_c1_f0_redelete
- name: assert that no changes were made with redeletion
assert:
that:
- not (clone_d1_c1_f0_redelete is changed)

@ -1,32 +0,0 @@
# Test code for the vmware_guest module.
# 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)
- when: vcsim is not defined
block:
- name: create new virtual machine with invalid guest id
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: invalid_vm
guest_id: "invalid_guest_id"
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
folder: "{{ f0 }}"
register: invalid_guest_0001_d1_c1_f0
ignore_errors: yes
- debug: var=invalid_guest_0001_d1_c1_f0
- name: assert that changes were made
assert:
that:
- "not (invalid_guest_0001_d1_c1_f0 is changed)"
- "'configSpec.guestId' in invalid_guest_0001_d1_c1_f0['msg']"

@ -1,38 +0,0 @@
# Test code for the vmware_guest module.
# 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: create new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: 'VM Network'
device_type: vmxnet3
ip: 192.168.10.1
netmask: 255.255.255.0
wake_on_lan: True
start_connected: True
allow_guest_control: True
state: poweredoff
folder: F0
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_d1_c1_f0 is changed

@ -1,205 +0,0 @@
# Create one with the defaults
- name: create new VM with default resource pool
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: F0
register: clone_rp_d1_c1_f0
- debug: var=clone_rp_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_rp_d1_c1_f0 is changed
- name: delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
state: absent
folder: F0
register: clone_rp_d1_c1_f0_delete
- debug: var=clone_rp_d1_c1_f0_delete
- name: assert that changes were made with deletion
assert:
that:
- clone_rp_d1_c1_f0_delete is changed
# now create with just a cluster
- name: create new VM with default resource pool in cluster
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: F0
register: clone_rpc_d1_c1_f0
- debug: var=clone_rpc_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_rpc_d1_c1_f0 is changed
- name: delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
state: absent
folder: F0
register: clone_rpc_d1_c1_f0_delete
- debug: var=clone_rpc_d1_c1_f0_delete
- name: assert that changes were made with deletion
assert:
that:
- clone_rpc_d1_c1_f0_delete is changed
# now create with a specific resource pool
- name: create new VM with specific resource pool in cluster
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: DC0_C0_RP1
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: F0
register: clone_rpcp_d1_c1_f0
- debug: var=clone_rpcp_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_rpcp_d1_c1_f0 is changed
- name: delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
state: absent
folder: F0
register: clone_rpcp_d1_c1_f0_delete
- debug: var=clone_rpcp_d1_c1_f0_delete
- name: assert that changes were made with deletion
assert:
that:
- clone_rpcp_d1_c1_f0_delete is changed
# now create with a specific host
- name: create new VM with specific host
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
esxi_hostname: '{{ esxi1 }}'
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: F0
register: clone_rph_d1_c1_f0
- debug: var=clone_rph_d1_c1_f0
- name: assert that changes were made
assert:
that:
- clone_rph_d1_c1_f0 is changed
- name: delete the new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
#template: "{{ item|basename }}"
#guest_id: centos64Guest
datacenter: "{{ dc1 }}"
state: absent
folder: F0
register: clone_rph_d1_c1_f0_delete
- debug: var=clone_rph_d1_c1_f0_delete
- name: assert that changes were made with deletion
assert:
that:
- clone_rph_d1_c1_f0_delete is changed

@ -1,22 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Delete VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: nothinghere
datacenter: "{{ dc1 }}"
state: absent
register: delete_vm
ignore_errors: yes
- debug: var=delete_vm
- name: assert that changes were made
assert:
that:
- "not delete_vm.changed"

@ -1,89 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new VMs with invalid disk mode
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
disk_mode: 'invalid_disk_mode'
state: poweredoff
folder: "{{ f0 }}"
register: test_vm1
ignore_errors: True
- debug: var=test_vm1
- name: assert that changes were not made
assert:
that:
- not(test_vm1 is changed)
- name: create new VMs with valid disk mode
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
disk_mode: 'independent_persistent'
state: poweredoff
folder: "{{ f0 }}"
register: test_vm1_2
- debug: var=test_vm1_2
- name: assert that changes were made
assert:
that:
- test_vm1_2 is changed
#TODO: vcsim does not support reconfiguration of disk mode, fails with types.InvalidDeviceSpec
- when: vcsim is not defined
block:
- name: create new VMs with valid disk mode again
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
disk_mode: 'independent_persistent'
state: poweredoff
folder: "{{ f0 }}"
register: test_vm1_2
- debug: var=test_vm1_2
- name: assert that changes were not made
assert:
that:
- not (test_vm1_2 is changed)

@ -1,31 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new VMs with invalid disk size
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 0gb
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: "{{ f0 }}"
register: disk_size_d1_c1_f0
ignore_errors: True
- debug: var=disk_size_d1_c1_f0
- name: assert that changes were made
assert:
that:
- not (disk_size_d1_c1_f0 is changed)

@ -1,33 +0,0 @@
# Test code for the vmware_guest module.
# 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: create new VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: poweredoff
folder: F0
register: disk_type_d1_c1_f0
- debug: var=disk_type_d1_c1_f0
- name: assert that changes were made
assert:
that:
- disk_type_d1_c1_f0 is changed

@ -1,100 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create new linked clone without specifying snapshot_src
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ 'new_vm_' + item.name }}"
template: "{{ item.name }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
linked_clone: True
with_items: "{{ virtual_machines }}"
register: linked_clone_d1_c1_f0
ignore_errors: True
- debug: var=linked_clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [false]"
- name: create new linked clone without specifying linked_clone
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ 'new_vm_' + item.name }}"
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
snapshot_src: "snap_shot1"
with_items: "{{ virtual_machines }}"
register: linked_clone_d1_c1_f0
ignore_errors: True
- debug: var=linked_clone_d1_c1_f0
- name: assert that changes were not made
assert:
that:
- "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [false]"
# TODO: VCSIM: snapshot is not supported in current vcsim
#
#- name: create new linked clone with linked_clone and snapshot_src
# vmware_guest:
# validate_certs: False
# hostname: "{{ vcsim }}"
# username: "{{ vcsim_instance['json']['username'] }}"
# password: "{{ vcsim_instance['json']['password'] }}"
# name: "{{ 'new_vm_' + item|basename }}"
# template: "{{ item|basename }}"
# guest_id: centos64Guest
# datacenter: "{{ (item|basename).split('_')[0] }}"
# folder: "{{ item|dirname }}"
# snapshot_src: "snap_shot1"
# linked_clone: True
# with_items: "{{ vmlist['json'] }}"
# register: linked_clone_d1_c1_f0
# ignore_errors: True
#- debug: var=linked_clone_d1_c1_f0
#- name: assert that changes were made
# assert:
# that:
# - "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [true]"
# TODO: VCSIM: snapshot is not supported in current vcsim
#
#- name: create new linked clone with linked_clone and snapshot_src again
# vmware_guest:
# validate_certs: False
# hostname: "{{ vcsim }}"
# username: "{{ vcsim_instance['json']['username'] }}"
# password: "{{ vcsim_instance['json']['password'] }}"
# name: "{{ 'new_vm_' + item|basename }}"
# template: "{{ item|basename }}"
# guest_id: centos64Guest
# datacenter: "{{ (item|basename).split('_')[0] }}"
# folder: "{{ item|dirname }}"
# snapshot_src: "snap_shot1"
# linked_clone: True
# with_items: "{{ vmlist['json'] }}"
# register: linked_clone_d1_c1_f0
# ignore_errors: True
#- debug: var=linked_clone_d1_c1_f0
#- name: assert that changes were not made
# assert:
# that:
# - "linked_clone_d1_c1_f0.results|map(attribute='changed')|unique|list == [false]"

@ -1,37 +0,0 @@
# Test code for the vmware_guest module.
# 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: create new VMs with manual MAC address
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: VM Network
ip: 192.168.10.12
netmask: 255.255.255.0
gateway: 192.168.10.254
mac: aa:bb:cc:dd:aa:42
state: poweredoff
folder: vm
register: clone_d1_c1_f0
- debug: var=clone_d1_c1_f0
- name: assert that changes were made
assert:
that:
- "clone_d1_c1_f0['instance']['hw_eth0']['addresstype'] == 'manual'"
- "clone_d1_c1_f0['instance']['hw_eth0']['macaddress'] == 'aa:bb:cc:dd:aa:42'"

@ -1,19 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2017, James Tanner <tanner.jc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- import_role:
name: incidental_vmware_prepare_tests
vars:
setup_attach_host: true
setup_datacenter: true
setup_datastore: true
setup_dvswitch: true
setup_resource_pool: true
setup_virtualmachines: true
setup_dvs_portgroup: true
- include_tasks: run_test_playbook.yml
with_items: '{{ vmware_guest_test_playbooks }}'
loop_control:
loop_var: test_playbook

@ -1,45 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- when: vcsim is not defined
block:
- &add_mk_conn
name: Create new VM with max_connections as 4
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
max_connections: 4
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
folder: "{{ f0 }}"
register: mk_conn_result_0001
- debug: var=mk_conn_result_0001
- name: Assert that changes were made
assert:
that:
- mk_conn_result_0001 is changed
- <<: *add_mk_conn
name: Again create new VMs again with max_connections as 4
register: mk_conn_result_0002
- debug: var=mk_conn_result_0002
- name: Assert that changes were not made
assert:
that:
- not (mk_conn_result_0002 is changed)

@ -1,125 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- when: vcsim is not defined
block:
- &add_mem_reserve
name: Create new VMs with mem_reservation as 0
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
mem_reservation: 0
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
folder: "{{ virtual_machines[0].folder }}"
register: mem_reserve_result_0001
- debug: var=mem_reserve_result_0001
- name: Assert that changes were made
assert:
that:
- mem_reserve_result_0001 is changed
- <<: *add_mem_reserve
name: Again create new VMs with mem_reservation as 0
register: mem_reserve_result_0002
- debug: var=mem_reserve_result_0002
- name: Assert that changes were not made
assert:
that:
- not (mem_reserve_result_0002 is changed)
- &add_memory_reserve
name: Create new VM with memory_reservation as 0
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
memory_reservation: 0
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
folder: "{{ virtual_machines[0].folder }}"
register: memory_reserve_result_0003
- debug: var=memory_reserve_result_0003
- name: Assert that changes were made
assert:
that:
- memory_reserve_result_0003 is changed
- <<: *add_memory_reserve
name: Again create new VMs with memory_reservation as 0
register: memory_reserve_result_0004
- debug: var=memory_reserve_result_0004
- name: Assert that changes were not made
assert:
that:
- not (memory_reserve_result_0004 is changed)
- &no_memory_reserve
name: Create new VMs without memory_reservation or mem_reservation
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm3
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
hardware:
num_cpus: 1
memory_mb: 128
memory_reservation: 0
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
folder: "{{ virtual_machines[0].folder }}"
register: no_memory_reserve_result_0005
- debug: var=no_memory_reserve_result_0005
- name: Assert that changes were made
assert:
that:
- no_memory_reserve_result_0005 is changed
- <<: *no_memory_reserve
name: Again create new VMs without memory_reservation or mem_reservation
register: no_memory_reserve_result_0006
- debug: var=no_memory_reserve_result_0006
- name: Assert that changes were not made
assert:
that:
- not (no_memory_reserve_result_0006 is changed)

@ -1,339 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- debug: var=f0
- name: create new VMs with non-existent network
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "Non existent VM"
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: non_existent_network
ignore_errors: yes
- debug: var=non_existent_network
- name: assert that no changes were not made
assert:
that:
- not (non_existent_network is changed)
- "'does not exist' in non_existent_network.msg"
- name: create new VMs with network and with only IP
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
type: static
ip: 10.10.10.10
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: no_netmask
ignore_errors: yes
- debug: var=no_netmask
- name: assert that no changes were not made
assert:
that:
- "not no_netmask.changed"
- "\"'netmask' is required if 'ip' is specified under VM network list.\" in no_netmask.msg"
- name: create new VMs with network and with only netmask
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
type: static
netmask: 255.255.255.0
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: no_ip
ignore_errors: yes
- debug: var=no_ip
- name: assert that changes were not made
assert:
that:
- "not no_ip.changed"
- "\"'ip' is required if 'netmask' is specified under VM network list.\" in no_ip.msg"
- name: create new VMs with network and without network name
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- ip: 10.10.10.10
netmask: 255.255.255
type: static
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: no_network_name
ignore_errors: yes
- debug: var=no_network_name
- name: assert that no changes were not made
assert:
that:
- "not no_network_name.changed"
- "\"Please specify at least a network name or a VLAN name under VM network list.\" in no_network_name.msg"
- name: create new VMs with network and without network name
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- vlan: non_existing_vlan
ip: 10.10.10.10
netmask: 255.255.255
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: no_network
ignore_errors: yes
- debug: var=no_network
- name: assert that changes were not made
assert:
that:
- "not no_network.changed"
- "\"VLAN 'non_existing_vlan' does not exist.\" in no_network.msg"
- name: create new VMs with invalid device type
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
ip: 10.10.10.10
netmask: 255.255.255
device_type: abc
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: invalid_device_type
ignore_errors: yes
- debug: var=invalid_device_type
- name: assert that changes were not made
assert:
that:
- "not invalid_device_type.changed"
- "\"Device type specified 'abc' is not valid.\" in invalid_device_type.msg"
- name: create new VMs with invalid device MAC address
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
ip: 10.10.10.10
netmask: 255.255.255
device_type: e1000
mac: abcdef
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: invalid_mac
ignore_errors: yes
- debug: var=invalid_mac
- name: assert that changes were not made
assert:
that:
- "not invalid_mac.changed"
- "\"Device MAC address 'abcdef' is invalid.\" in invalid_mac.msg"
- name: create new VMs with invalid network type
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
ip: 10.10.10.10
netmask: 255.255.255
device_type: e1000
mac: 01:23:45:67:89:ab
type: aaaaa
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: invalid_network_type
ignore_errors: yes
- debug: var=invalid_network_type
- name: assert that changes were not made
assert:
that:
- "not invalid_network_type.changed"
- "\"Network type 'aaaaa' is not a valid parameter.\" in invalid_network_type.msg"
- name: create new VMs with IP, netmask and network type as "DHCP"
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: new_vm
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
ip: 10.10.10.10
netmask: 255.255.255
device_type: e1000
mac: 01:23:45:67:89:ab
type: dhcp
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: invalid_dhcp_network_type
ignore_errors: yes
- debug: var=invalid_dhcp_network_type
- name: assert that changes were not made
assert:
that:
- "not invalid_dhcp_network_type.changed"
- "\"Static IP information provided for network\" in invalid_dhcp_network_type.msg"
- name: create new VMs with no network type which set network type as "DHCP"
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: "VM Network"
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: no_network_type
ignore_errors: yes
- debug: var=no_network_type
- name: assert that changes were made
assert:
that:
- "no_network_type.changed"

@ -1,60 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Testcase to check #38605
- name: Deploy VM first VM
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm1
disk:
- size: 10mb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: 'VM Network'
device_type: "vmxnet3"
register: vm_result
- debug: var=vm_result
- assert:
that:
- "vm_result.changed"
- name: Deploy VM again
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm1
disk:
- size: 10mb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: 'VM Network'
device_type: "vmxnet3"
register: vm_result_again
- debug: var=vm_result_again
- assert:
that:
- not (vm_result_again is changed)

@ -1,152 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Clone from existing VM with DVPG
- when: vcsim is not defined
block:
- name: Deploy VM from template
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
template: "{{ virtual_machines[0].name }}"
name: test_vm1
disk:
- size: 1gb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: '{{ dvpg1 }}'
register: no_vm_result
- debug: var=no_vm_result
- assert:
that:
- no_vm_result is changed
# New clone with DVPG
- name: Deploy new VM with DVPG
vmware_guest:
esxi_hostname: "{{ esxi_hosts[0] }}"
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm2
disk:
- size: 1gb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: '{{ dvpg1 }}'
dvswitch_name: "{{ dvswitch1 }}"
register: no_vm_result
- debug: var=no_vm_result
- assert:
that:
- no_vm_result is changed
- name: Deploy same VM again
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm2
disk:
- size: 1gb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: '{{ dvpg1 }}'
register: no_vm_result
- debug: var=no_vm_result
- assert:
that:
- not (no_vm_result is changed)
- name: Deploy new VM with DVPG with slash in name
vmware_guest:
esxi_hostname: "{{ esxi_hosts[0] }}"
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm3
disk:
- size: 1gb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: '{{ dvpg_with_slash }}'
dvswitch_name: "{{ dvswitch1 }}"
register: no_vm_result
- debug: var=no_vm_result
- assert:
that:
- no_vm_result is changed
- name: Deploy same VM again
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
state: poweredon
folder: "{{ f0 }}"
name: test_vm3
disk:
- size: 1gb
datastore: "{{ rw_datastore }}"
guest_id: rhel7_64guest
hardware:
memory_mb: 128
num_cpus: 1
networks:
- name: '{{ dvpg_with_slash }}'
register: no_vm_result
- debug: var=no_vm_result
- assert:
that:
- not (no_vm_result is changed)
always:
- when: vcsim is not defined
name: Remove VM to free the portgroup
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: '{{ item }}'
force: yes
state: absent
with_items:
- test_vm1
- test_vm2
- test_vm3

@ -1,47 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>, Tim Steinbach <tim@nequissimus.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Add portgroup
vmware_dvs_portgroup:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
portgroup_name: "portgroup_network"
switch_name: "{{ dvswitch1 }}"
vlan_id: "1"
num_ports: 2
portgroup_type: earlyBinding
state: present
register: dvsportgroup
- debug: var=dvsportgroup
- name: create new VMs with portgroup
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
disk:
- size: 3mb
type: thin
datastore: "{{ rw_datastore }}"
networks:
- name: portgroup_network
switch_name: "{{ dvswitch1 }}"
hardware:
num_cpus: 1
memory_mb: 128
state: poweredoff
folder: "{{ f0 }}"
register: vm_with_portgroup
ignore_errors: no
- debug: var=vm_with_portgroup
- assert:
that:
- vm_with_portgroup is changed

@ -1,23 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Perform operation on non-existent VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "non_existent_vm"
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
state: poweredoff
register: non_existent_vm_ops
ignore_errors: yes
- debug: var=non_existent_vm_ops
- name: assert that changes were not made
assert:
that:
- not (non_existent_vm_ops is changed)
- "'msg' in non_existent_vm_ops"
- "'Unable to find the datastore with given parameters.' in non_existent_vm_ops.msg"

@ -1,27 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2017, James Tanner <tanner.jc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: create a VM with the poweroff status
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ item.name }}"
state: poweredoff
with_items: "{{ virtual_machines }}"
register: poweroff_d1_c1_f0
- debug:
var: poweroff_d1_c1_f0
- name: make sure changes were made
assert:
that:
- poweroff_d1_c1_f0.results[0].instance.hw_power_status == "poweredOff"
- name: make sure no changes were made (the VMs are already off)
assert:
that:
- poweroff_d1_c1_f0.results[0].changed|bool == false

@ -1,22 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2017, James Tanner <tanner.jc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# 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:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ item.name }}"
state: poweredoff
folder: "{{ item.folder }}"
with_items: "{{ virtual_machines }}"
register: poweroff_d1_c1_f1
- debug: var=poweroff_d1_c1_f1

@ -1,73 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Pavan Bidkar <pbidkar@vmware.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Skipping out idepotency test untill issue fixed in reconfigure_vm() become_method
- name: Create VM with hardware version 12
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos7_64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
datastore: '{{ rw_datastore }}'
hardware:
num_cpus: 4
memory_mb: 1028
version: 12
state: present
register: create_vm_with_version_12
- name: assert that changes were made
assert:
that:
- create_vm_with_version_12 is changed
- name: Deploy New VM with latest hardware version
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm2
guest_id: centos7_64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
datastore: '{{ rw_datastore }}'
hardware:
num_cpus: 4
memory_mb: 1028
version: latest
state: present
register: deploy_vm_to_latest
- name: assert that changes were made
assert:
that:
- deploy_vm_to_latest is changed
- name: Upgrade VM to latest version
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos7_64Guest
datacenter: "{{ dc1 }}"
folder: "{{ f0 }}"
datastore: '{{ rw_datastore }}'
hardware:
num_cpus: 4
memory_mb: 1028
version: latest
state: present
register: upgrade_vm
- name: assert that changes were made
assert:
that:
- upgrade_vm is changed

@ -1,61 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2019, Pavan Bidkar <pbidkar@vmware.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: Create VM to unregister
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
guest_id: centos64Guest
datacenter: "{{ dc1 }}"
folder: F0
hardware:
num_cpus: 1
num_cpu_cores_per_socket: 1
memory_mb: 128
disk:
- size: 1gb
type: thin
datastore: "{{ rw_datastore }}"
state: present
register: create_vm_for_test
- name: assert that changes were made
assert:
that:
- create_vm_for_test is changed
- name: Remove VM from Inventory
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
delete_from_inventory: True
state: absent
register: remove_vm_from_inventory
- name: assert that changes were made
assert:
that:
- remove_vm_from_inventory is changed
- name: Remove VM again from Inventory
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: test_vm1
delete_from_inventory: True
state: absent
register: remove_again_vm_from_inventory
- name: assert that changes were made
assert:
that:
- not (remove_again_vm_from_inventory is changed)

@ -1,17 +0,0 @@
- block:
- include_tasks: '{{ test_playbook }}'
always:
- name: Remove VM
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
# cluster: "{{ ccr1 }}"
name: '{{ item }}'
force: yes
state: absent
with_items:
- test_vm1
- test_vm2
- test_vm3

@ -1,105 +0,0 @@
- name: Create VMs with the poweredoff state
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
validate_certs: no
folder: '{{ f0 }}'
name: 'test_vm1'
state: poweredoff
guest_id: debian8_64Guest
disk:
- size_gb: 1
type: thin
datastore: '{{ rw_datastore }}'
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
networks:
- name: VM Network
- name: ensure that VM1 are not flagged as templates
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
folder: "{{ virtual_machines[1].folder }}"
name: "{{ virtual_machines[1].name }}"
state: present
is_template: False
register: no_template_initial
- debug: var=no_template_initial
- name: ensure no changes were made
assert:
that:
- not (no_template_initial is changed)
- name: convert VM1 to template
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
folder: "{{ virtual_machines[1].folder }}"
name: "{{ virtual_machines[1].name }}"
state: present
is_template: True
register: convert_to_template
- debug: var=convert_to_template
- name: ensure that changes were made
assert:
that:
- convert_to_template is changed
- name: make double sure that VM1 is template
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
folder: "{{ virtual_machines[1].folder }}"
name: "{{ virtual_machines[1].name }}"
state: present
is_template: True
register: still_templates
- debug: var=still_templates
- name: ensure that no changes were made
assert:
that:
- not (still_templates is changed)
# To avoid the follow error of vcsim: VirtualMachine:vm-67 does not implement: MarkAsVirtualMachine
- when: vcsim is not defined
block:
- name: convert template back to VMs
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
folder: "{{ virtual_machines[1].folder }}"
name: "{{ virtual_machines[1].name }}"
state: present
is_template: False
register: revert_to_vm
- debug: var=revert_to_vm
- name: ensure that changes were made
assert:
that:
- revert_to_vm is changed

@ -1,100 +0,0 @@
# Test code for the vmware_guest module.
# Copyright: (c) 2018, goshkis
# Copyright: (c) 2019, Abhijeet Kasurde <akasurde@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- &vapp_new_vm
name: Create test VM with vAPP settings
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "vm"
name: test_vm1
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: "{{ rw_datastore }}"
vapp_properties:
- id: prop_id1
category: category
label: prop_label1
type: string
value: prop_value1
- id: prop_id2
category: category
label: prop_label2
type: string
value: prop_value2
register: vapp_vm
- debug: var=vapp_vm
- name: assert the vApp propeties were created
assert:
that:
- "vapp_vm.failed == false"
- "vapp_vm.changed == true"
- when: vcsim is not defined
block:
- <<: *vapp_new_vm
name: Try to create same VM with same vAPP settings
register: vapp_vm_no_change
- debug: var=vapp_vm_no_change
- name: Assert that vApp properties were not changed
assert:
that:
- "vapp_vm_no_change.failed == false"
- "not vapp_vm_no_change.changed"
- &vapp_edit_vm
name: Edit one vApp property and removing another
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "vm"
name: test_vm1
datacenter: "{{ dc1 }}"
vapp_properties:
- id: prop_id1
operation: remove
- id: prop_id2
value: prop_value3
state: present
register: vapp_vm
- debug: var=vapp_vm
- name: assert the VM was changed
assert:
that:
- "vapp_vm.failed == false"
- "vapp_vm.changed == true"
- when: vcsim is not defined
block:
- <<: *vapp_edit_vm
name: Try to edit VM with vApp settings
register: vapp_vm_no_change_edit
- debug: var=vapp_vm_no_change_edit
- name: assert the VM was changed
assert:
that:
- "vapp_vm_no_change_edit.failed == false"
- "vapp_vm_no_change_edit.changed == false"

@ -1,93 +0,0 @@
- name: Create Windows 10 VM with VBS enabled
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ f0 }}"
name: vbs-Test
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: windows9_64Guest
hardware:
memory_mb: 128
num_cpus: 1
virt_based_security: True
version: 14
boot_firmware: efi
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: '{{ rw_datastore }}'
cdrom:
type: client
register: vbs_vm
- debug: var=vbs_vm
- name: assert the VM was created
assert:
that:
- "vbs_vm.failed == false"
- "vbs_vm.changed == true"
- name: Create Windows Server 2016 VM without VBS enabled
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ f0 }}"
name: vbs-Test2
datacenter: "{{ dc1 }}"
cluster: "{{ ccr1 }}"
resource_pool: Resources
guest_id: windows9Server64Guest
hardware:
memory_mb: 128
num_cpus: 1
version: 14
boot_firmware: efi
scsi: paravirtual
disk:
- size_mb: 128
type: thin
datastore: '{{ rw_datastore }}'
cdrom:
type: client
register: vbs_vm
- debug: var=vbs_vm
- name: assert the VM was created
assert:
that:
- "vbs_vm.failed == false"
- "vbs_vm.changed == true"
- name: Enable VBS for Windows Server 2016 VM
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ f0 }}"
name: vbs-Test2
datacenter: "{{ f0 }}"
disk:
- size_mb: 256
type: thin
datastore: '{{ rw_datastore }}'
hardware:
virt_based_security: True
state: present
register: vbs_vm
- debug: var=vbs_vm
- name: assert the VM was changed
assert:
that:
- vbs_vm is changed

@ -1,3 +0,0 @@
cloud/vcenter
shippable/vcenter/incidental
needs/target/incidental_vmware_prepare_tests

@ -1,92 +0,0 @@
# Test code for the vmware_host_hyperthreading module.
# Copyright: (c) 2018, Christian Kotte <christian.kotte@gmx.de>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Hyperthreading optimization is not available for hosts in vcsim
- import_role:
name: incidental_vmware_prepare_tests
vars:
setup_attach_host: true
- name: Enable Hyperthreading everywhere
vmware_host_hyperthreading:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
state: disabled
register: enable_hyperthreading_everywhere
ignore_errors: true
- when: enable_hyperthreading_everywhere is succeeded
block:
- name: Disable Hyperthreading for a given host
vmware_host_hyperthreading:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
esxi_hostname: '{{ esxi1 }}'
validate_certs: no
state: disabled
register: host_hyperthreading_info
- debug: var=host_hyperthreading_info
- assert:
that:
- host_hyperthreading_info is defined
- host_hyperthreading_info.changed
- name: Disable Hyperthreading for a given host in check mode
vmware_host_hyperthreading:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
esxi_hostname: '{{ esxi1 }}'
validate_certs: no
state: disabled
register: host_hyperthreading_info_check_mode
check_mode: yes
- debug: var=host_hyperthreading_info_check_mode
- assert:
that:
- host_hyperthreading_info_check_mode is defined
- name: Disable Hyperthreading for all hosts in given cluster
vmware_host_hyperthreading:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
cluster_name: "{{ ccr1 }}"
validate_certs: no
state: disabled
register: host_hyperthreading_info
- debug: var=host_hyperthreading_info
- assert:
that:
- host_hyperthreading_info is defined
- host_hyperthreading_info is changed
- name: Enable Hyperthreading for all hosts in given cluster in check mode
vmware_host_hyperthreading:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
cluster_name: "{{ ccr1 }}"
validate_certs: no
state: enabled
register: host_hyperthreading_info_check_mode
check_mode: yes
- debug: var=host_hyperthreading_info_check_mode
- assert:
that:
- host_hyperthreading_info_check_mode is defined
- host_hyperthreading_info_check_mode.changed

@ -1,29 +0,0 @@
---
- include_tasks: teardown_with_esxi.yml
when: esxi_hosts|length > 0
- include_tasks: teardown.yml
- when: setup_esxi_instance is not defined
block:
- include_tasks: setup_datacenter.yml
- include_tasks: setup_cluster.yml
- include_tasks: setup_attach_hosts.yml
when: setup_attach_host is defined
- include_tasks: setup_datastore.yml
when: setup_datastore is defined
- include_tasks: setup_virtualmachines.yml
when: setup_virtualmachines is defined
- include_tasks: setup_switch.yml
when: setup_switch is defined
- include_tasks: setup_dvswitch.yml
when: setup_dvswitch is defined
- include_tasks: setup_resource_pool.yml
when: setup_resource_pool is defined
- include_tasks: setup_category.yml
when: setup_category is defined
- include_tasks: setup_tag.yml
when: setup_tag is defined
- include_tasks: setup_content_library.yml
when: setup_content_library is defined
- include_tasks: setup_dvs_portgroup.yml
when: setup_dvs_portgroup is defined

@ -1,48 +0,0 @@
---
- name: load vars
include_vars:
file: vcsim.yml
- name: kill vcsim
uri:
url: http://{{ vcsim }}:5000/killall
- name: start vcsim (all dressed)
uri:
url: http://{{ vcsim }}:5000/spawn?cluster=1&folder=1&ds=2
register: vcsim_instance
when: setup_esxi_instance is not defined
- name: start vcsim (ESXi only)
uri:
url: http://{{ vcsim }}:5000/spawn?esx=1
register: vcsim_instance
when: setup_esxi_instance is defined
# - name: get a list of Hosts from vcsim
# uri:
# url: http://{{ vcsim }}:5000/govc_find?filter=H
# register: vcsim_host_list
# - name: get a list of Hosts from vcsim
# uri:
# url: http://{{ vcsim }}:5000/govc_find?filter=F
# register: vcsim_host_folder
# - debug: var=vcsim_host_folder
- set_fact:
vcenter_hostname: "{{ vcsim }}"
vcenter_username: "user"
vcenter_password: "pass"
- name: set state to poweroff on all VMs
vmware_guest:
name: "{{ item.name }}"
state: poweredoff
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
with_items: "{{ virtual_machines + virtual_machines_in_cluster }}"
register: poweroff_d1_c1_f0

@ -1,25 +0,0 @@
---
- name: load vmware common vars
include_vars:
file: common.yml
- when: vcsim is not defined
block:
- when: esxi1_hostname is not defined and esxi2_hostname is not defined
include_vars:
file: vcenter_only.yml
- when: esxi1_hostname is defined and esxi2_hostname is not defined
include_vars:
file: vcenter_1esxi.yml
- when: esxi1_hostname is defined and esxi2_hostname is defined
include_vars:
file: vcenter_2esxi.yml
- when: vcsim is not defined
include_tasks: init_real_lab.yml
- when: vcsim is defined
include_tasks: init_vcsim.yml

@ -1,30 +0,0 @@
- fail:
msg: "No ESXi hosts defined. esxi_hosts is empty."
when: "esxi_hosts|length == 0"
- name: Add ESXi Hosts to vCenter
vmware_host:
datacenter_name: '{{ dc1 }}'
cluster_name: '{{ ccr1 }}'
esxi_hostname: '{{ item }}'
esxi_username: '{{ esxi_user }}'
esxi_password: '{{ esxi_password }}'
state: add_or_reconnect
with_items: "{{ esxi_hosts }}"
- name: Disable the Maintenance Mode
vmware_maintenancemode:
esxi_hostname: '{{ item }}'
state: absent
with_items: "{{ esxi_hosts }}"
- name: Add Management Network VM Portgroup
vmware_portgroup:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
esxi_hostname: 'item'
switch: "vSwitch0"
portgroup: VM Network
validate_certs: no
with_items: "{{ esxi_hosts }}"

@ -1,5 +0,0 @@
- name: Create a category for cluster
vmware_category:
category_name: '{{ cluster_category }}'
category_description: '{{ cluster_category }} description'
state: present

@ -1,10 +0,0 @@
- name: Create Cluster
vmware_cluster:
datacenter_name: '{{ dc1 }}'
cluster_name: '{{ ccr1 }}'
- name: Enable DRS on Cluster
vmware_cluster_drs:
datacenter_name: '{{ dc1 }}'
cluster_name: '{{ ccr1 }}'
enable_drs: yes

@ -1,7 +0,0 @@
- name: Create Content Library
vmware_content_library_manager:
library_name: test-content-lib
library_description: 'Library created by the prepare_vmware_tests role'
library_type: local
datastore_name: '{{ rw_datastore }}'
state: present

@ -1,11 +0,0 @@
- name: Create Datacenter
vmware_datacenter:
datacenter_name: '{{ dc1 }}'
state: present
- name: Create a VM folder on given Datacenter
vcenter_folder:
datacenter: '{{ dc1 }}'
folder_name: '{{ f0 }}'
folder_type: vm
state: present

@ -1,42 +0,0 @@
---
- name: Mount NFS (ro_datastore) datastores to ESXi
vmware_host_datastore:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
datastore_name: '{{ ro_datastore }}'
datastore_type: '{{ infra.datastores[ro_datastore].type }}'
nfs_server: '{{ infra.datastores[ro_datastore].server }}'
nfs_path: '{{ infra.datastores[ro_datastore].path }}'
nfs_ro: '{{ infra.datastores[ro_datastore].ro }}'
state: present
validate_certs: no
with_items: "{{ esxi_hosts }}"
- name: Mount NFS (rw_datastore) datastores on the ESXi
vmware_host_datastore:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
datastore_name: '{{ rw_datastore }}'
datastore_type: '{{ infra.datastores[rw_datastore].type }}'
nfs_server: '{{ infra.datastores[rw_datastore].server }}'
nfs_path: '{{ infra.datastores[rw_datastore].path }}'
nfs_ro: '{{ infra.datastores[rw_datastore].ro }}'
state: present
validate_certs: no
with_items: "{{ esxi_hosts }}"
- vmware_host_scanhba:
refresh_storage: true
cluster_name: '{{ ccr1 }}'
- name: The vcenter needs a bit of time to refresh the DS list
vmware_datastore_info:
validate_certs: false
cluster: '{{ ccr1 }}'
register: setup_datastore_datatstore_info
failed_when: setup_datastore_datatstore_info.datastores|selectattr('type', 'equalto', 'NFS')|list|length != 2
until: setup_datastore_datatstore_info is succeeded
retries: 60
delay: 1

@ -1,18 +0,0 @@
---
- name: create basic DVS portgroup
vmware_dvs_portgroup:
switch_name: "{{ dvswitch1 }}"
portgroup_name: '{{ dvpg1 }}'
vlan_id: 0
num_ports: 32
portgroup_type: earlyBinding
state: present
- name: Create the DVS PG with slash in name
vmware_dvs_portgroup:
portgroup_name: '{{ dvpg_with_slash }}'
switch_name: '{{ dvswitch1 }}'
vlan_id: 0
num_ports: 120
portgroup_type: earlyBinding
state: present

@ -1,20 +0,0 @@
---
- name: Create the DVSwitch
vmware_dvswitch:
datacenter_name: '{{ dc1 }}'
switch_name: '{{ dvswitch1 }}'
switch_version: 6.0.0
mtu: 9000
uplink_quantity: 2
discovery_proto: lldp
discovery_operation: both
state: present
- name: Attach the hosts to the DVSwitch
vmware_dvs_host:
esxi_hostname: "{{ item }}"
switch_name: '{{ dvswitch1 }}'
vmnics:
- vmnic1
state: present
with_items: "{{ esxi_hosts }}"
when: setup_attach_host is defined

@ -1,15 +0,0 @@
---
- name: Add resource pool to vCenter
vmware_resource_pool:
datacenter: '{{ dc1 }}'
cluster: '{{ ccr1 }}'
resource_pool: DC0_C0_RP1
mem_shares: normal
mem_limit: -1
mem_reservation: 0
mem_expandable_reservations: yes
cpu_shares: normal
cpu_limit: -1
cpu_reservation: 0
cpu_expandable_reservations: yes
state: present

@ -1,7 +0,0 @@
---
- name: Add a VMware vSwitchs
vmware_vswitch:
esxi_hostname: '{{ item }}'
switch_name: "{{ switch1 }}"
state: present
with_items: "{{ esxi_hosts }}"

@ -1,15 +0,0 @@
- name: Get Category facts
vmware_category_info:
register: cat_info
- name: Get Category id for {{ cluster_category }}
set_fact:
cluster_category_id: "{{ cat_info.tag_category_info[0].category_id }}"
- name: Create a tag for cluster
vmware_tag:
category_id: '{{ cluster_category_id }}'
tag_name: '{{ cluster_tag }}'
tag_description: '{{ cluster_tag }} Description'
state: present
when: cluster_category_id is defined

@ -1,46 +0,0 @@
---
- name: Create VMs
vmware_guest:
datacenter: "{{ dc1 }}"
folder: '{{ item.folder }}'
name: '{{ item.name }}'
state: poweredoff
guest_id: debian8_64Guest
disk:
- size_gb: 1
type: thin
datastore: '{{ rw_datastore }}'
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
networks:
- name: VM Network
with_items: '{{ virtual_machines }}'
- name: Create VMs in cluster
vmware_guest:
datacenter: "{{ dc1 }}"
folder: '{{ item.folder }}'
cluster: '{{ item.cluster }}'
name: '{{ item.name }}'
state: poweredoff
guest_id: debian8_64Guest
disk:
- size_gb: 1
type: thin
datastore: '{{ rw_datastore }}'
hardware:
memory_mb: 128
num_cpus: 1
scsi: paravirtual
cdrom:
type: iso
iso_path: "[{{ ro_datastore }}] fedora.iso"
networks:
- name: VM Network
with_items: '{{ virtual_machines_in_cluster }}'

@ -1,24 +0,0 @@
---
- name: Delete a datastore cluster to datacenter
vmware_datastore_cluster:
datacenter_name: "{{ dc1 }}"
datastore_cluster_name: '{{ item }}'
state: absent
with_items:
- DSC1
- DSC2
ignore_errors: yes
- name: Remove the datacenter
vmware_datacenter:
datacenter_name: '{{ item }}'
state: absent
when: vcsim is not defined
with_items:
- '{{ dc1 }}'
- datacenter_0001
- name: kill vcsim
uri:
url: "http://{{ vcsim }}:5000/killall"
when: vcsim is defined

@ -1,96 +0,0 @@
---
- name: Clean up the firewall rules
vmware_host_firewall_manager:
cluster_name: '{{ ccr1 }}'
rules:
- name: vvold
enabled: False
- name: CIMHttpServer
enabled: True
allowed_hosts:
all_ip: True
- name: NFC
enabled: True
allowed_hosts:
all_ip: True
ignore_errors: yes
- name: Remove the VM prepared by prepare_vmware_tests
vmware_guest:
name: "{{ item.name }}"
force: yes
state: absent
with_items: '{{ virtual_machines + virtual_machines_in_cluster }}'
- name: Remove the test_vm* VMs
vmware_guest:
name: "{{ item }}"
force: yes
state: absent
with_items:
- test_vm1
- test_vm2
- test_vm3
- name: Remove the DVS portgroups
vmware_dvs_portgroup:
switch_name: "{{ dvswitch1 }}"
portgroup_name: '{{ item }}'
vlan_id: 0
num_ports: 32
portgroup_type: earlyBinding
state: absent
loop:
- DC0_DVPG0
- DVPG/1
ignore_errors: yes
- name: Remove the DVSwitch
vmware_dvswitch:
datacenter_name: '{{ dc1 }}'
state: absent
switch_name: '{{ item }}'
loop:
- '{{ dvswitch1 }}'
- dvswitch_0001
- dvswitch_0002
ignore_errors: yes
- name: Remove the vSwitches
vmware_vswitch:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
switch_name: "{{ switch1 }}"
state: absent
with_items: "{{ esxi_hosts }}"
ignore_errors: yes
- name: Remove ESXi Hosts to vCenter
vmware_host:
datacenter_name: '{{ dc1 }}'
cluster_name: ccr1
esxi_hostname: '{{ item }}'
esxi_username: '{{ esxi_user }}'
esxi_password: '{{ esxi_password }}'
state: absent
with_items: "{{ esxi_hosts }}"
ignore_errors: yes
- name: Umount NFS datastores to ESXi (1/2)
vmware_host_datastore:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
datastore_name: '{{ ro_datastore }}'
state: absent
with_items: "{{ esxi_hosts }}"
- name: Umount NFS datastores to ESXi (2/2)
vmware_host_datastore:
hostname: '{{ item }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
datastore_name: '{{ rw_datastore }}'
state: absent
with_items: "{{ esxi_hosts }}"

@ -1,12 +0,0 @@
---
dc1: DC0
ccr1: DC0_C0
f0: F0
switch1: switch1
esxi1: '{{ esxi_hosts[0] }}'
esxi2: '{{ esxi_hosts[1] }}'
esxi3: '{{ esxi_hosts[2] }}'
dvswitch1: DVS0
esxi_user: root
dvpg1: DC0_DVPG0
dvpg_with_slash: DVPG/1

@ -1,33 +0,0 @@
---
esxi_hosts:
- esxi1.test
rw_datastore: rw_datastore
ro_datastore: ro_datastore
esxi_password: '{{ esxi1_password }}'
esxi_user: '{{ esxi1_username }}'
infra:
datastores:
rw_datastore:
type: nfs
server: datastore.test
path: /srv/share/vms
ro: false
ro_datastore:
type: nfs
server: datastore.test
path: /srv/share/isos
ro: true
virtual_machines:
- name: DC0_H0_VM0
folder: '{{ f0 }}'
- name: DC0_H0_VM1
folder: '{{ f0 }}'
virtual_machines_in_cluster:
- name: DC0_C0_RP0_VM0
folder: '{{ f0 }}'
cluster: '{{ ccr1 }}'
- name: DC0_C0_RP0_VM1
folder: '{{ f0 }}'
cluster: '{{ ccr1 }}'
cluster_tag: test_cluster_tag_0001
cluster_category: test_cluster_cat_0001

@ -1,34 +0,0 @@
---
esxi_hosts:
- esxi1.test
- esxi2.test
rw_datastore: rw_datastore
ro_datastore: ro_datastore
esxi_password: '{{ esxi1_password }}'
esxi_user: '{{ esxi1_username }}'
infra:
datastores:
rw_datastore:
type: nfs
server: datastore.test
path: /srv/share/vms
ro: false
ro_datastore:
type: nfs
server: datastore.test
path: /srv/share/isos
ro: true
virtual_machines:
- name: DC0_H0_VM0
folder: '{{ f0 }}'
- name: DC0_H0_VM1
folder: '{{ f0 }}'
virtual_machines_in_cluster:
- name: DC0_C0_RP0_VM0
folder: '{{ f0 }}'
cluster: '{{ ccr1 }}'
- name: DC0_C0_RP0_VM1
folder: '{{ f0 }}'
cluster: '{{ ccr1 }}'
cluster_tag: test_cluster_tag_0001
cluster_category: test_cluster_cat_0001

@ -1,6 +0,0 @@
---
esxi_hosts: []
infra:
virtual_machines: []
virtual_machines_in_cluster: []
#esxi_password: ''

@ -1,19 +0,0 @@
---
esxi_hosts:
- DC0_C0_H0
- DC0_C0_H1
- DC0_C0_H2
esxi_password: 'pass'
esxi_user: 'user'
rw_datastore: LocalDS_0
ro_datastore: LocalDS_1
virtual_machines:
- name: DC0_H0_VM0
folder: /F0/DC0/vm/F0
- name: DC0_H0_VM1
folder: /F0/DC0/vm/F0
virtual_machines_in_cluster:
- name: DC0_C0_RP0_VM0
cluster: '{{ ccr1 }}'
- name: DC0_C0_RP0_VM1
cluster: '{{ ccr1 }}'

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
#!/bin/sh
# This script mimics the output from what the contrib/inventory/vmware_inventory.py
# dynamic inventory script produced.
# This ensures we are still covering the same code that the original tests gave us
# and subsequently ensures that ansible-inventory produces output consistent with
# that of a dynamic inventory script
cat inventory.json

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -eux
diff -uw <(ansible-inventory -i inventory.sh --list --export) inventory.json

@ -39,7 +39,8 @@ class InventoryModule(BaseInventoryPlugin):
def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(inventory, loader, path)
self._read_config_data(path=path)
config_data = self._read_config_data(path=path)
self._consume_options(config_data)
departments = self.get_option('departments')

@ -1,477 +0,0 @@
#
# Copyright: (c) 2018, Ansible Project
# Copyright: (c) 2018, 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
DOCUMENTATION = '''
name: vmware_vm_inventory
plugin_type: inventory
short_description: VMware Guest inventory source
version_added: "2.7"
author:
- Abhijeet Kasurde (@Akasurde)
description:
- Get virtual machines as inventory hosts from VMware environment.
- Uses any file which ends with vmware.yml, vmware.yaml, vmware_vm_inventory.yml, or vmware_vm_inventory.yaml as a YAML configuration file.
- The inventory_hostname is always the 'Name' and UUID of the virtual machine. UUID is added as VMware allows virtual machines with the same name.
extends_documentation_fragment:
- inventory_cache
requirements:
- "Python >= 2.7"
- "PyVmomi"
- "requests >= 2.3"
- "vSphere Automation SDK - For tag feature"
- "vCloud Suite SDK - For tag feature"
options:
hostname:
description: Name of vCenter or ESXi server.
required: True
env:
- name: VMWARE_HOST
- name: VMWARE_SERVER
username:
description: Name of vSphere admin user.
required: True
env:
- name: VMWARE_USER
- name: VMWARE_USERNAME
password:
description: Password of vSphere admin user.
required: True
env:
- name: VMWARE_PASSWORD
port:
description: Port number used to connect to vCenter or ESXi Server.
default: 443
env:
- name: VMWARE_PORT
validate_certs:
description:
- Allows connection when SSL certificates are not valid. Set to C(false) when certificates are not trusted.
default: True
type: boolean
env:
- name: VMWARE_VALIDATE_CERTS
with_tags:
description:
- Include tags and associated virtual machines.
- Requires 'vSphere Automation SDK' library to be installed on the given controller machine.
- Please refer following URLs for installation steps
- 'https://code.vmware.com/web/sdk/65/vsphere-automation-python'
default: False
type: boolean
properties:
description:
- Specify the list of VMware schema properties associated with the VM.
- These properties will be populated in hostvars of the given VM.
- Each value in the list specifies the path to a specific property in VM object.
type: list
default: [ 'name', 'config.cpuHotAddEnabled', 'config.cpuHotRemoveEnabled',
'config.instanceUuid', 'config.hardware.numCPU', 'config.template',
'config.name', 'guest.hostName', 'guest.ipAddress',
'guest.guestId', 'guest.guestState', 'runtime.maxMemoryUsage',
'customValue'
]
version_added: "2.9"
'''
EXAMPLES = '''
# Sample configuration file for VMware Guest dynamic inventory
plugin: vmware_vm_inventory
strict: False
hostname: 10.65.223.31
username: administrator@vsphere.local
password: Esxi@123$%
validate_certs: False
with_tags: True
# Gather minimum set of properties for VMware guest
plugin: vmware_vm_inventory
strict: False
hostname: 10.65.223.31
username: administrator@vsphere.local
password: Esxi@123$%
validate_certs: False
with_tags: False
properties:
- 'name'
- 'guest.ipAddress'
'''
import ssl
import atexit
from ansible.errors import AnsibleError, AnsibleParserError
try:
# requests is required for exception handling of the ConnectionError
import requests
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
try:
from pyVim import connect
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
try:
from com.vmware.vapi.std_client import DynamicID
from vmware.vapi.vsphere.client import create_vsphere_client
HAS_VSPHERE = True
except ImportError:
HAS_VSPHERE = False
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable
class BaseVMwareInventory:
def __init__(self, hostname, username, password, port, validate_certs, with_tags):
self.hostname = hostname
self.username = username
self.password = password
self.port = port
self.with_tags = with_tags
self.validate_certs = validate_certs
self.content = None
self.rest_content = None
def do_login(self):
"""
Check requirements and do login
"""
self.check_requirements()
self.content = self._login()
if self.with_tags:
self.rest_content = self._login_vapi()
def _login_vapi(self):
"""
Login to vCenter API using REST call
Returns: connection object
"""
session = requests.Session()
session.verify = self.validate_certs
if not self.validate_certs:
# Disable warning shown at stdout
requests.packages.urllib3.disable_warnings()
server = self.hostname
if self.port:
server += ":" + str(self.port)
client = create_vsphere_client(server=server,
username=self.username,
password=self.password,
session=session)
if client is None:
raise AnsibleError("Failed to login to %s using %s" % (server, self.username))
return client
def _login(self):
"""
Login to vCenter or ESXi server
Returns: connection object
"""
if self.validate_certs and not hasattr(ssl, 'SSLContext'):
raise AnsibleError('pyVim does not support changing verification mode with python < 2.7.9. Either update '
'python or set validate_certs to false in configuration YAML file.')
ssl_context = None
if not self.validate_certs and hasattr(ssl, 'SSLContext'):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ssl_context.verify_mode = ssl.CERT_NONE
service_instance = None
try:
service_instance = connect.SmartConnect(host=self.hostname, user=self.username,
pwd=self.password, sslContext=ssl_context,
port=self.port)
except vim.fault.InvalidLogin as e:
raise AnsibleParserError("Unable to log on to vCenter or ESXi API at %s:%s as %s: %s" % (self.hostname, self.port, self.username, e.msg))
except vim.fault.NoPermission as e:
raise AnsibleParserError("User %s does not have required permission"
" to log on to vCenter or ESXi API at %s:%s : %s" % (self.username, self.hostname, self.port, e.msg))
except (requests.ConnectionError, ssl.SSLError) as e:
raise AnsibleParserError("Unable to connect to vCenter or ESXi API at %s on TCP/%s: %s" % (self.hostname, self.port, e))
except vmodl.fault.InvalidRequest as e:
# Request is malformed
raise AnsibleParserError("Failed to get a response from server %s:%s as "
"request is malformed: %s" % (self.hostname, self.port, e.msg))
except Exception as e:
raise AnsibleParserError("Unknown error while connecting to vCenter or ESXi API at %s:%s : %s" % (self.hostname, self.port, e))
if service_instance is None:
raise AnsibleParserError("Unknown error while connecting to vCenter or ESXi API at %s:%s" % (self.hostname, self.port))
atexit.register(connect.Disconnect, service_instance)
return service_instance.RetrieveContent()
def check_requirements(self):
""" Check all requirements for this inventory are satisified"""
if not HAS_REQUESTS:
raise AnsibleParserError('Please install "requests" Python module as this is required'
' for VMware Guest dynamic inventory plugin.')
elif not HAS_PYVMOMI:
raise AnsibleParserError('Please install "PyVmomi" Python module as this is required'
' for VMware Guest dynamic inventory plugin.')
if HAS_REQUESTS:
# Pyvmomi 5.5 and onwards requires requests 2.3
# https://github.com/vmware/pyvmomi/blob/master/requirements.txt
required_version = (2, 3)
requests_version = requests.__version__.split(".")[:2]
try:
requests_major_minor = tuple(map(int, requests_version))
except ValueError:
raise AnsibleParserError("Failed to parse 'requests' library version.")
if requests_major_minor < required_version:
raise AnsibleParserError("'requests' library version should"
" be >= %s, found: %s." % (".".join([str(w) for w in required_version]),
requests.__version__))
if not HAS_VSPHERE and self.with_tags:
raise AnsibleError("Unable to find 'vSphere Automation SDK' Python library which is required."
" Please refer this URL for installation steps"
" - https://code.vmware.com/web/sdk/65/vsphere-automation-python")
if not all([self.hostname, self.username, self.password]):
raise AnsibleError("Missing one of the following : hostname, username, password. Please read "
"the documentation for more information.")
def _get_managed_objects_properties(self, vim_type, properties=None):
"""
Look up a Managed Object Reference in vCenter / ESXi Environment
:param vim_type: Type of vim object e.g, for datacenter - vim.Datacenter
:param properties: List of properties related to vim object e.g. Name
:return: local content object
"""
# Get Root Folder
root_folder = self.content.rootFolder
if properties is None:
properties = ['name']
# Create Container View with default root folder
mor = self.content.viewManager.CreateContainerView(root_folder, [vim_type], True)
# Create Traversal spec
traversal_spec = vmodl.query.PropertyCollector.TraversalSpec(
name="traversal_spec",
path='view',
skip=False,
type=vim.view.ContainerView
)
# Create Property Spec
property_spec = vmodl.query.PropertyCollector.PropertySpec(
type=vim_type, # Type of object to retrieved
all=False,
pathSet=properties
)
# Create Object Spec
object_spec = vmodl.query.PropertyCollector.ObjectSpec(
obj=mor,
skip=True,
selectSet=[traversal_spec]
)
# Create Filter Spec
filter_spec = vmodl.query.PropertyCollector.FilterSpec(
objectSet=[object_spec],
propSet=[property_spec],
reportMissingObjectsInResults=False
)
return self.content.propertyCollector.RetrieveContents([filter_spec])
@staticmethod
def _get_object_prop(vm, attributes):
"""Safely get a property or return None"""
result = vm
for attribute in attributes:
try:
result = getattr(result, attribute)
except (AttributeError, IndexError):
return None
return result
class InventoryModule(BaseInventoryPlugin, Cacheable):
NAME = 'vmware_vm_inventory'
def verify_file(self, path):
"""
Verify plugin configuration file and mark this plugin active
Args:
path: Path of configuration YAML file
Returns: True if everything is correct, else False
"""
valid = False
if super(InventoryModule, self).verify_file(path):
if path.endswith(('vmware.yaml', 'vmware.yml', 'vmware_vm_inventory.yaml', 'vmware_vm_inventory.yml')):
valid = True
return valid
def parse(self, inventory, loader, path, cache=True):
"""
Parses the inventory file
"""
super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
cache_key = self.get_cache_key(path)
config_data = self._read_config_data(path)
# set _options from config data
self._consume_options(config_data)
self.pyv = BaseVMwareInventory(
hostname=self.get_option('hostname'),
username=self.get_option('username'),
password=self.get_option('password'),
port=self.get_option('port'),
with_tags=self.get_option('with_tags'),
validate_certs=self.get_option('validate_certs')
)
self.pyv.do_login()
self.pyv.check_requirements()
source_data = None
if cache:
cache = self.get_option('cache')
update_cache = False
if cache:
try:
source_data = self._cache[cache_key]
except KeyError:
update_cache = True
using_current_cache = cache and not update_cache
cacheable_results = self._populate_from_source(source_data, using_current_cache)
if update_cache:
self._cache[cache_key] = cacheable_results
def _populate_from_cache(self, source_data):
""" Populate cache using source data """
hostvars = source_data.pop('_meta', {}).get('hostvars', {})
for group in source_data:
if group == 'all':
continue
else:
self.inventory.add_group(group)
hosts = source_data[group].get('hosts', [])
for host in hosts:
self._populate_host_vars([host], hostvars.get(host, {}), group)
self.inventory.add_child('all', group)
def _populate_from_source(self, source_data, using_current_cache):
"""
Populate inventory data from direct source
"""
if using_current_cache:
self._populate_from_cache(source_data)
return source_data
cacheable_results = {'_meta': {'hostvars': {}}}
hostvars = {}
objects = self.pyv._get_managed_objects_properties(vim_type=vim.VirtualMachine,
properties=['name'])
if self.pyv.with_tags:
tag_svc = self.pyv.rest_content.tagging.Tag
tag_association = self.pyv.rest_content.tagging.TagAssociation
tags_info = dict()
tags = tag_svc.list()
for tag in tags:
tag_obj = tag_svc.get(tag)
tags_info[tag_obj.id] = tag_obj.name
if tag_obj.name not in cacheable_results:
cacheable_results[tag_obj.name] = {'hosts': []}
self.inventory.add_group(tag_obj.name)
for vm_obj in objects:
for vm_obj_property in vm_obj.propSet:
# VMware does not provide a way to uniquely identify VM by its name
# i.e. there can be two virtual machines with same name
# Appending "_" and VMware UUID to make it unique
if not vm_obj.obj.config:
# Sometime orphaned VMs return no configurations
continue
current_host = vm_obj_property.val + "_" + vm_obj.obj.config.uuid
if current_host not in hostvars:
hostvars[current_host] = {}
self.inventory.add_host(current_host)
host_ip = vm_obj.obj.guest.ipAddress
if host_ip:
self.inventory.set_variable(current_host, 'ansible_host', host_ip)
self._populate_host_properties(vm_obj, current_host)
# Only gather facts related to tag if vCloud and vSphere is installed.
if HAS_VSPHERE and self.pyv.with_tags:
# Add virtual machine to appropriate tag group
vm_mo_id = vm_obj.obj._GetMoId()
vm_dynamic_id = DynamicID(type='VirtualMachine', id=vm_mo_id)
attached_tags = tag_association.list_attached_tags(vm_dynamic_id)
for tag_id in attached_tags:
self.inventory.add_child(tags_info[tag_id], current_host)
cacheable_results[tags_info[tag_id]]['hosts'].append(current_host)
# Based on power state of virtual machine
vm_power = str(vm_obj.obj.summary.runtime.powerState)
if vm_power not in cacheable_results:
cacheable_results[vm_power] = {'hosts': []}
self.inventory.add_group(vm_power)
cacheable_results[vm_power]['hosts'].append(current_host)
self.inventory.add_child(vm_power, current_host)
# Based on guest id
vm_guest_id = vm_obj.obj.config.guestId
if vm_guest_id and vm_guest_id not in cacheable_results:
cacheable_results[vm_guest_id] = {'hosts': []}
self.inventory.add_group(vm_guest_id)
cacheable_results[vm_guest_id]['hosts'].append(current_host)
self.inventory.add_child(vm_guest_id, current_host)
for host in hostvars:
h = self.inventory.get_host(host)
cacheable_results['_meta']['hostvars'][h.name] = h.vars
return cacheable_results
def _populate_host_properties(self, vm_obj, current_host):
# Load VM properties in host_vars
vm_properties = self.get_option('properties') or []
field_mgr = self.pyv.content.customFieldsManager.field
for vm_prop in vm_properties:
if vm_prop == 'customValue':
for cust_value in vm_obj.obj.customValue:
self.inventory.set_variable(current_host,
[y.name for y in field_mgr if y.key == cust_value.key][0],
cust_value.value)
else:
vm_value = self.pyv._get_object_prop(vm_obj.obj, vm_prop.split("."))
self.inventory.set_variable(current_host, vm_prop, vm_value)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,261 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Christian Kotte <christian.kotte@gmx.de>
#
# 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_host_hyperthreading
short_description: Enables/Disables Hyperthreading optimization for an ESXi host system
description:
- This module can be used to enable or disable Hyperthreading optimization for ESXi host systems in given vCenter infrastructure.
- It also checks if Hyperthreading is activated/deactivated and if the host needs to be restarted.
- The module informs the user if Hyperthreading is enabled but inactive because the processor is vulnerable to L1 Terminal Fault (L1TF).
version_added: 2.8
author:
- Christian Kotte (@ckotte)
notes:
- Tested on vSphere 6.5
requirements:
- python >= 2.6
- PyVmomi
options:
state:
description:
- Enable or disable Hyperthreading.
- You need to reboot the ESXi host if you change the configuration.
- Make sure that Hyperthreading is enabled in the BIOS. Otherwise, it will be enabled, but never activated.
type: str
choices: [ enabled, disabled ]
default: 'enabled'
esxi_hostname:
description:
- Name of the host system to work with.
- This parameter is required if C(cluster_name) is not specified.
type: str
cluster_name:
description:
- Name of the cluster from which all host systems will be used.
- This parameter is required if C(esxi_hostname) is not specified.
type: str
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = r'''
- name: Enable Hyperthreading for an host system
vmware_host_hyperthreading:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
esxi_hostname: '{{ esxi_hostname }}'
state: enabled
validate_certs: no
delegate_to: localhost
- name: Disable Hyperthreading for an host system
vmware_host_hyperthreading:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
esxi_hostname: '{{ esxi_hostname }}'
state: disabled
validate_certs: no
delegate_to: localhost
- name: Disable Hyperthreading for all host systems from cluster
vmware_host_hyperthreading:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
cluster_name: '{{ cluster_name }}'
state: disabled
validate_certs: no
delegate_to: localhost
'''
RETURN = r'''
results:
description: metadata about host system's Hyperthreading configuration
returned: always
type: dict
sample: {
"esxi01": {
"msg": "Hyperthreading is already enabled and active for host 'esxi01'",
"state_current": "active",
"state": "enabled",
},
}
'''
try:
from pyVmomi import vim, vmodl
except ImportError:
pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware import PyVmomi, vmware_argument_spec
from ansible.module_utils._text import to_native
class VmwareHostHyperthreading(PyVmomi):
"""Manage Hyperthreading for an ESXi host system"""
def __init__(self, module):
super(VmwareHostHyperthreading, self).__init__(module)
cluster_name = self.params.get('cluster_name')
esxi_host_name = self.params.get('esxi_hostname')
self.hosts = self.get_all_host_objs(cluster_name=cluster_name, esxi_host_name=esxi_host_name)
if not self.hosts:
self.module.fail_json(msg="Failed to find host system.")
def ensure(self):
"""Manage Hyperthreading for an ESXi host system"""
results = dict(changed=False, result=dict())
desired_state = self.params.get('state')
host_change_list = []
for host in self.hosts:
changed = False
results['result'][host.name] = dict(msg='')
hyperthreading_info = host.config.hyperThread
results['result'][host.name]['state'] = desired_state
if desired_state == 'enabled':
# Don't do anything if Hyperthreading is already enabled
if hyperthreading_info.config:
if hyperthreading_info.active:
results['result'][host.name]['changed'] = False
results['result'][host.name]['state_current'] = "active"
results['result'][host.name]['msg'] = "Hyperthreading is enabled and active"
if not hyperthreading_info.active:
# L1 Terminal Fault (L1TF)/Foreshadow mitigation workaround (https://kb.vmware.com/s/article/55806)
option_manager = host.configManager.advancedOption
try:
mitigation = option_manager.QueryOptions('VMkernel.Boot.hyperthreadingMitigation')
except vim.fault.InvalidName:
mitigation = None
if mitigation and mitigation[0].value:
results['result'][host.name]['changed'] = False
results['result'][host.name]['state_current'] = "enabled"
results['result'][host.name]['msg'] = ("Hyperthreading is enabled, but not active because the"
" processor is vulnerable to L1 Terminal Fault (L1TF).")
else:
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_current'] = "enabled"
results['result'][host.name]['msg'] = ("Hyperthreading is enabled, but not active."
" A reboot is required!")
# Enable Hyperthreading
else:
# Check if Hyperthreading is available
if hyperthreading_info.available:
if not self.module.check_mode:
try:
host.configManager.cpuScheduler.EnableHyperThreading()
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_previous'] = "disabled"
results['result'][host.name]['state_current'] = "enabled"
results['result'][host.name]['msg'] = (
"Hyperthreading enabled for host. Reboot the host to activate it."
)
except vmodl.fault.NotSupported as not_supported:
# This should never happen since Hyperthreading is available
self.module.fail_json(
msg="Failed to enable Hyperthreading for host '%s' : %s" %
(host.name, to_native(not_supported.msg))
)
except (vmodl.RuntimeFault, vmodl.MethodFault) as runtime_fault:
self.module.fail_json(
msg="Failed to enable Hyperthreading for host '%s' due to : %s" %
(host.name, to_native(runtime_fault.msg))
)
else:
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_previous'] = "disabled"
results['result'][host.name]['state_current'] = "enabled"
results['result'][host.name]['msg'] = "Hyperthreading will be enabled"
else:
self.module.fail_json(msg="Hyperthreading optimization is not available for host '%s'" % host.name)
elif desired_state == 'disabled':
# Don't do anything if Hyperthreading is already disabled
if not hyperthreading_info.config:
if not hyperthreading_info.active:
results['result'][host.name]['changed'] = False
results['result'][host.name]['state_current'] = "inactive"
results['result'][host.name]['msg'] = "Hyperthreading is disabled and inactive"
if hyperthreading_info.active:
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_current'] = "disabled"
results['result'][host.name]['msg'] = ("Hyperthreading is already disabled"
" but still active. A reboot is required!")
# Disable Hyperthreading
else:
# Check if Hyperthreading is available
if hyperthreading_info.available:
if not self.module.check_mode:
try:
host.configManager.cpuScheduler.DisableHyperThreading()
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_previous'] = "enabled"
results['result'][host.name]['state_current'] = "disabled"
results['result'][host.name]['msg'] = (
"Hyperthreading disabled. Reboot the host to deactivate it."
)
except vmodl.fault.NotSupported as not_supported:
# This should never happen since Hyperthreading is available
self.module.fail_json(
msg="Failed to disable Hyperthreading for host '%s' : %s" %
(host.name, to_native(not_supported.msg))
)
except (vmodl.RuntimeFault, vmodl.MethodFault) as runtime_fault:
self.module.fail_json(
msg="Failed to disable Hyperthreading for host '%s' due to : %s" %
(host.name, to_native(runtime_fault.msg))
)
else:
changed = results['result'][host.name]['changed'] = True
results['result'][host.name]['state_previous'] = "enabled"
results['result'][host.name]['state_current'] = "disabled"
results['result'][host.name]['msg'] = "Hyperthreading will be disabled"
else:
self.module.fail_json(msg="Hyperthreading optimization is not available for host '%s'" % host.name)
host_change_list.append(changed)
if any(host_change_list):
results['changed'] = True
self.module.exit_json(**results)
def main():
"""Main"""
argument_spec = vmware_argument_spec()
argument_spec.update(
state=dict(default='enabled', choices=['enabled', 'disabled']),
esxi_hostname=dict(type='str', required=False),
cluster_name=dict(type='str', required=False),
)
module = AnsibleModule(argument_spec=argument_spec,
required_one_of=[
['cluster_name', 'esxi_hostname'],
],
supports_check_mode=True
)
hyperthreading = VmwareHostHyperthreading(module)
hyperthreading.ensure()
if __name__ == '__main__':
main()
Loading…
Cancel
Save