summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhijeet Kasurde <akasurde@redhat.com>2018-02-16 10:32:27 +0530
committerGitHub <noreply@github.com>2018-02-16 10:32:27 +0530
commita377302d6b26b5a112c7db2bf9e9fb1a8a676319 (patch)
tree287f21f57846649e1603b44612ffd43ab3f099e6
parent75a34f666826be988b25df41cb72bcd5d1428736 (diff)
downloadansible-a377302d6b26b5a112c7db2bf9e9fb1a8a676319.tar.gz
VMware: Fix DVPG idempotency issue (#35837)
This fixes, cloning operation where template or existing VM does not have network or DVPG. Also, adds some strict type checking in network parameters. Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
-rw-r--r--lib/ansible/modules/cloud/vmware/vmware_guest.py175
-rw-r--r--test/integration/targets/vmware_guest/tasks/main.yml3
-rw-r--r--test/integration/targets/vmware_guest/tasks/network_negative_test.yml341
-rw-r--r--test/integration/targets/vmware_guest/tasks/network_with_dvpg.yml129
4 files changed, 583 insertions, 65 deletions
diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest.py b/lib/ansible/modules/cloud/vmware/vmware_guest.py
index 2251441581..8e78fc5539 100644
--- a/lib/ansible/modules/cloud/vmware/vmware_guest.py
+++ b/lib/ansible/modules/cloud/vmware/vmware_guest.py
@@ -502,23 +502,23 @@ class PyVmomiDeviceHelper(object):
return diskspec
- def create_nic(self, device_type, device_label, device_infos):
- nic = vim.vm.device.VirtualDeviceSpec()
- if device_type == 'pcnet32':
- nic.device = vim.vm.device.VirtualPCNet32()
- elif device_type == 'vmxnet2':
- nic.device = vim.vm.device.VirtualVmxnet2()
- elif device_type == 'vmxnet3':
- nic.device = vim.vm.device.VirtualVmxnet3()
- elif device_type == 'e1000':
- nic.device = vim.vm.device.VirtualE1000()
- elif device_type == 'e1000e':
- nic.device = vim.vm.device.VirtualE1000e()
- elif device_type == 'sriov':
- nic.device = vim.vm.device.VirtualSriovEthernetCard()
+ def get_device(self, device_type, name):
+ nic_dict = dict(pcnet32=vim.vm.device.VirtualPCNet32(),
+ vmxnet2=vim.vm.device.VirtualVmxnet2(),
+ vmxnet3=vim.vm.device.VirtualVmxnet3(),
+ e1000=vim.vm.device.VirtualE1000(),
+ e1000e=vim.vm.device.VirtualE1000e(),
+ sriov=vim.vm.device.VirtualSriovEthernetCard(),
+ )
+ if device_type in nic_dict:
+ return nic_dict[device_type]
else:
- self.module.fail_json(msg='Invalid device_type "%s" for network "%s"' % (device_type, device_infos['name']))
+ self.module.fail_json(msg='Invalid device_type "%s"'
+ ' for network "%s"' % (device_type, name))
+ def create_nic(self, device_type, device_label, device_infos):
+ nic = vim.vm.device.VirtualDeviceSpec()
+ nic.device = self.get_device(device_type, device_infos['name'])
nic.device.wakeOnLanEnabled = bool(device_infos.get('wake_on_lan', True))
nic.device.deviceInfo = vim.Description()
nic.device.deviceInfo.label = device_label
@@ -544,11 +544,8 @@ class PyVmomiDeviceHelper(object):
Returns: (Boolean) True if string is valid MAC address, otherwise False
"""
- ret = False
mac_addr_regex = re.compile('[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$')
- if mac_addr_regex.match(mac_addr):
- ret = True
- return ret
+ return bool(mac_addr_regex.match(mac_addr))
class PyVmomiCache(object):
@@ -897,58 +894,93 @@ class PyVmomiHelper(PyVmomi):
return device_list
- def configure_network(self, vm_obj):
- # Ignore empty networks, this permits to keep networks when deploying a template/cloning a VM
- if len(self.params['networks']) == 0:
- return
+ def sanitize_network_params(self):
+ """
+ Function to sanitize user provided network provided params
+ Returns: A sanitized list of network params, else fails
+
+ """
network_devices = list()
+ # Clean up user data here
for network in self.params['networks']:
- if 'ip' in network or 'netmask' in network:
- if 'ip' not in network or 'netmask' not in network:
- self.module.fail_json(msg="Both 'ip' and 'netmask' are required together.")
-
- if 'name' in network:
- if find_obj(self.content, [vim.Network], network['name']) is None:
- self.module.fail_json(msg="Network '%(name)s' does not exists" % network)
+ if 'name' not in network and 'vlan' not in network:
+ self.module.fail_json(msg="Please specify at least a network name or"
+ " a VLAN name under VM network list.")
+ if 'name' in network and find_obj(self.content, [vim.Network], network['name']) is None:
+ self.module.fail_json(msg="Network '%(name)s' does not exists" % network)
elif 'vlan' in network:
dvps = self.cache.get_all_objs(self.content, [vim.dvs.DistributedVirtualPortgroup])
for dvp in dvps:
- if hasattr(dvp.config.defaultPortConfig, 'vlan') and dvp.config.defaultPortConfig.vlan.vlanId == network['vlan']:
+ if hasattr(dvp.config.defaultPortConfig, 'vlan') and \
+ dvp.config.defaultPortConfig.vlan.vlanId == network['vlan']:
network['name'] = dvp.config.name
break
if dvp.config.name == network['vlan']:
network['name'] = dvp.config.name
break
else:
- self.module.fail_json(msg="VLAN '%(vlan)s' does not exist" % network)
+ self.module.fail_json(msg="VLAN '%(vlan)s' does not exist." % network)
+
+ if 'type' in network:
+ if network['type'] not in ['dhcp', 'static']:
+ self.module.fail_json(msg="Network type '%(type)s' is not a valid parameter."
+ " Valid parameters are ['dhcp', 'static']." % network)
+ if network['type'] != 'static' and ('ip' in network or 'netmask' in network):
+ self.module.fail_json(msg='Static IP information provided for network "%(name)s",'
+ ' but "type" is set to "%(type)s".' % network)
else:
- self.module.fail_json(msg="You need to define a network name or a vlan")
+ # Type is optional parameter, if user provided IP or Subnet assume
+ # network type as 'static'
+ if 'ip' in network or 'netmask' in network:
+ network['type'] = 'static'
+
+ if network.get('type') == 'static':
+ if 'ip' in network and 'netmask' not in network:
+ self.module.fail_json(msg="'netmask' is required if 'ip' is"
+ " specified under VM network list.")
+ if 'ip' not in network and 'netmask' in network:
+ self.module.fail_json(msg="'ip' is required if 'netmask' is"
+ " specified under VM network list.")
+
+ validate_device_types = ['pcnet32', 'vmxnet2', 'vmxnet3', 'e1000', 'e1000e', 'sriov']
+ if 'device_type' in network and network['device_type'] not in validate_device_types:
+ self.module.fail_json(msg="Device type specified '%s' is not valid."
+ " Please specify correct device"
+ " type from ['%s']." % (network['device_type'],
+ "', '".join(validate_device_types)))
+
+ if 'mac' in network and not PyVmomiDeviceHelper.is_valid_mac_addr(network['mac']):
+ self.module.fail_json(msg="Device MAC address '%s' is invalid."
+ " Please provide correct MAC address." % network['mac'])
network_devices.append(network)
+ return network_devices
+
+ def configure_network(self, vm_obj):
+ # Ignore empty networks, this permits to keep networks when deploying a template/cloning a VM
+ if len(self.params['networks']) == 0:
+ return
+
+ network_devices = self.sanitize_network_params()
+
# List current device for Clone or Idempotency
current_net_devices = self.get_vm_network_interfaces(vm=vm_obj)
if len(network_devices) < len(current_net_devices):
- self.module.fail_json(msg="given network device list is lesser than current VM device list (%d < %d). "
+ self.module.fail_json(msg="Given network device list is lesser than current VM device list (%d < %d). "
"Removing interfaces is not allowed"
% (len(network_devices), len(current_net_devices)))
for key in range(0, len(network_devices)):
- # Default device type is vmxnet3, VMWare best practice
- device_type = network_devices[key].get('device_type', 'vmxnet3')
- nic = self.device_helper.create_nic(device_type,
- 'Network Adapter %s' % (key + 1),
- network_devices[key])
-
nic_change_detected = False
+ network_name = network_devices[key]['name']
if key < len(current_net_devices) and (vm_obj or self.params['template']):
+ # We are editing existing network devices, this is either when
+ # are cloning from VM or Template
+ nic = vim.vm.device.VirtualDeviceSpec()
nic.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
- # Changing mac address has no effect when editing interface
- if 'mac' in network_devices[key] and nic.device.macAddress != current_net_devices[key].macAddress:
- self.module.fail_json(msg="Changing MAC address has not effect when interface is already present. "
- "The failing new MAC address is %s" % nic.device.macAddress)
nic.device = current_net_devices[key]
if ('wake_on_lan' in network_devices[key] and
@@ -964,37 +996,56 @@ class PyVmomiHelper(PyVmomi):
nic.device.connectable.allowGuestControl = network_devices[key].get('allow_guest_control')
nic_change_detected = True
- nic.device.deviceInfo = vim.Description()
+ if nic.device.deviceInfo.summary != network_name:
+ nic.device.deviceInfo.summary = network_name
+ nic_change_detected = True
+ if 'device_type' in network_devices[key]:
+ device = self.device_helper.get_device(network_devices[key]['device_type'], network_name)
+ if nic.device != device:
+ self.module.fail_json(msg="Changing the device type is not possible when interface is already present. "
+ "The failing device type is %s" % network_devices[key]['device_type'])
+ # Changing mac address has no effect when editing interface
+ if 'mac' in network_devices[key] and nic.device.macAddress != current_net_devices[key].macAddress:
+ self.module.fail_json(msg="Changing MAC address has not effect when interface is already present. "
+ "The failing new MAC address is %s" % nic.device.macAddress)
+
else:
+ # Default device type is vmxnet3, VMWare best practice
+ device_type = network_devices[key].get('device_type', 'vmxnet3')
+ nic = self.device_helper.create_nic(device_type,
+ 'Network Adapter %s' % (key + 1),
+ network_devices[key])
nic.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
nic_change_detected = True
- if hasattr(self.cache.get_network(network_devices[key]['name']), 'portKeys'):
+ if hasattr(self.cache.get_network(network_name), 'portKeys'):
# VDS switch
- pg_obj = find_obj(self.content, [vim.dvs.DistributedVirtualPortgroup], network_devices[key]['name'])
-
- if vm_obj is None or (nic.device.backing and not hasattr(nic.device.backing, 'port')) or \
- (nic.device.backing and (nic.device.backing.port.portgroupKey != pg_obj.key or
- nic.device.backing.port.switchUuid != pg_obj.config.distributedVirtualSwitch.uuid)):
- dvs_port_connection = vim.dvs.PortConnection()
- dvs_port_connection.portgroupKey = pg_obj.key
- dvs_port_connection.switchUuid = pg_obj.config.distributedVirtualSwitch.uuid
- nic.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
- nic.device.backing.port = dvs_port_connection
+ pg_obj = find_obj(self.content, [vim.dvs.DistributedVirtualPortgroup], network_name)
+
+ if (nic.device.backing and
+ (not hasattr(nic.device.backing, 'port') or
+ (nic.device.backing.port.portgroupKey != pg_obj.key or
+ nic.device.backing.port.switchUuid != pg_obj.config.distributedVirtualSwitch.uuid))):
nic_change_detected = True
+
+ dvs_port_connection = vim.dvs.PortConnection()
+ dvs_port_connection.portgroupKey = pg_obj.key
+ dvs_port_connection.switchUuid = pg_obj.config.distributedVirtualSwitch.uuid
+ nic.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
+ nic.device.backing.port = dvs_port_connection
else:
# vSwitch
if not isinstance(nic.device.backing, vim.vm.device.VirtualEthernetCard.NetworkBackingInfo):
nic.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
nic_change_detected = True
- net_obj = self.cache.get_network(network_devices[key]['name'])
+ net_obj = self.cache.get_network(network_name)
if nic.device.backing.network != net_obj:
nic.device.backing.network = net_obj
nic_change_detected = True
- if nic.device.backing.deviceName != network_devices[key]['name']:
- nic.device.backing.deviceName = network_devices[key]['name']
+ if nic.device.backing.deviceName != network_name:
+ nic.device.backing.deviceName = network_name
nic_change_detected = True
if nic_change_detected:
@@ -1035,17 +1086,11 @@ class PyVmomiHelper(PyVmomi):
guest_map.adapter = vim.vm.customization.IPSettings()
if 'ip' in network and 'netmask' in network:
- if 'type' in network and network['type'] != 'static':
- self.module.fail_json(msg='Static IP information provided for network "%(name)s", but "type" is set to "%(type)s".' % network)
guest_map.adapter.ip = vim.vm.customization.FixedIp()
guest_map.adapter.ip.ipAddress = str(network['ip'])
guest_map.adapter.subnetMask = str(network['netmask'])
- elif 'type' in network and network['type'] == 'static':
- self.module.fail_json(msg='Network "%(name)s" was set to type "%(type)s", but "ip" and "netmask" are missing.' % network)
elif 'type' in network and network['type'] == 'dhcp':
guest_map.adapter.ip = vim.vm.customization.DhcpIpGenerator()
- else:
- self.module.fail_json(msg='Network "%(name)s" was set to unknown type "%(type)s".' % network)
if 'gateway' in network:
guest_map.adapter.gateway = network['gateway']
diff --git a/test/integration/targets/vmware_guest/tasks/main.yml b/test/integration/targets/vmware_guest/tasks/main.yml
index 83ab3ad61f..b60d5c93d1 100644
--- a/test/integration/targets/vmware_guest/tasks/main.yml
+++ b/test/integration/targets/vmware_guest/tasks/main.yml
@@ -27,4 +27,7 @@
- include: create_nw_d1_c1_f0.yml
- include: delete_vm.yml
- include: non_existent_vm_ops.yml
+- include: network_negative_test.yml
+# Currently, VCSIM doesn't support DVPG (as portkeys are not available) so commenting this test
+#- include: network_with_dvpg.yml
#- include: template_d1_c1_f0.yml
diff --git a/test/integration/targets/vmware_guest/tasks/network_negative_test.yml b/test/integration/targets/vmware_guest/tasks/network_negative_test.yml
new file mode 100644
index 0000000000..f490d2bed8
--- /dev/null
+++ b/test/integration/targets/vmware_guest/tasks/network_negative_test.yml
@@ -0,0 +1,341 @@
+# 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: Wait for Flask controller to come up online
+ wait_for:
+ host: "{{ vcsim }}"
+ port: 5000
+ state: started
+
+- name: kill vcsim
+ uri:
+ url: http://{{ vcsim }}:5000/killall
+- name: start vcsim with no folders
+ uri:
+ url: http://{{ vcsim }}:5000/spawn?datacenter=1&cluster=1&folder=0
+ register: vcsim_instance
+
+- name: Wait for Flask controller to come up online
+ wait_for:
+ host: "{{ vcsim }}"
+ port: 443
+ state: started
+
+- name: get a list of VMS from vcsim
+ uri:
+ url: http://{{ vcsim }}:5000/govc_find?filter=VM
+ register: vmlist
+
+- debug: var=vcsim_instance
+
+- debug: var=vmlist
+
+- set_fact:
+ vm1: "{{ vmlist['json'][0] }}"
+
+- debug: var=vm1
+
+- name: create new VMs with non-existent network
+ vmware_guest:
+ validate_certs: False
+ hostname: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - name: "Non existent VM"
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: non_existent_network
+ ignore_errors: yes
+
+- debug: var=non_existent_network
+
+- name: assert that no changes were made
+ assert:
+ that:
+ - "not non_existent_network.changed"
+ - "\"Network 'Non existent VM' does not exists\" in non_existent_network.msg"
+
+- name: create new VMs with network and with only IP
+ vmware_guest:
+ validate_certs: False
+ hostname: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - name: "VM Network"
+ type: static
+ ip: 10.10.10.10
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: no_netmask
+ ignore_errors: yes
+
+- debug: var=no_netmask
+
+- name: assert that no changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - name: "VM Network"
+ type: static
+ netmask: 255.255.255.0
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: no_ip
+ ignore_errors: yes
+
+- debug: var=no_ip
+
+- name: assert that changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - ip: 10.10.10.10
+ netmask: 255.255.255
+ type: static
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: no_network_name
+ ignore_errors: yes
+
+- debug: var=no_network_name
+
+- name: assert that no changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - vlan: non_existing_vlan
+ ip: 10.10.10.10
+ netmask: 255.255.255
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: no_network
+ ignore_errors: yes
+
+- debug: var=no_network
+
+- name: assert that changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - name: "VM Network"
+ ip: 10.10.10.10
+ netmask: 255.255.255
+ device_type: abc
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: invalid_device_type
+ ignore_errors: yes
+
+- debug: var=invalid_device_type
+
+- name: assert that changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ networks:
+ - name: "VM Network"
+ ip: 10.10.10.10
+ netmask: 255.255.255
+ device_type: e1000
+ mac: abcdef
+ hardware:
+ num_cpus: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: invalid_mac
+ ignore_errors: yes
+
+- debug: var=invalid_mac
+
+- name: assert that changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ 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: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: invalid_network_type
+ ignore_errors: yes
+
+- debug: var=invalid_network_type
+
+- name: assert that changes were 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: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ name: new_vm
+ guest_id: centos64Guest
+ datacenter: "{{ (vm1 | basename).split('_')[0] }}"
+ disk:
+ - size: 3mb
+ type: thin
+ autoselect_datastore: yes
+ 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: 3
+ memory_mb: 512
+ state: poweredoff
+ folder: "{{ vm1 | dirname }}"
+ register: invalid_dhcp_network_type
+ ignore_errors: yes
+
+- debug: var=invalid_dhcp_network_type
+
+- name: assert that changes were made
+ assert:
+ that:
+ - "not invalid_dhcp_network_type.changed"
+ - "\"Static IP information provided for network\" in invalid_dhcp_network_type.msg"
diff --git a/test/integration/targets/vmware_guest/tasks/network_with_dvpg.yml b/test/integration/targets/vmware_guest/tasks/network_with_dvpg.yml
new file mode 100644
index 0000000000..5e8401ed29
--- /dev/null
+++ b/test/integration/targets/vmware_guest/tasks/network_with_dvpg.yml
@@ -0,0 +1,129 @@
+# 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: Wait for Flask controller to come up online
+ wait_for:
+ host: "{{ vcsim }}"
+ port: 5000
+ state: started
+
+- name: kill vcsim
+ uri:
+ url: http://{{ vcsim }}:5000/killall
+- name: start vcsim with no folders
+ uri:
+ url: http://{{ vcsim }}:5000/spawn?datacenter=1&cluster=1&folder=0
+ register: vcsim_instance
+
+- name: Wait for Flask controller to come up online
+ wait_for:
+ host: "{{ vcsim }}"
+ port: 443
+ state: started
+
+- name: get a list of VMS from vcsim
+ uri:
+ url: http://{{ vcsim }}:5000/govc_find?filter=VM
+ register: vmlist
+
+- debug: var=vcsim_instance
+
+- debug: var=vmlist
+
+- set_fact:
+ vm1: "{{ vmlist['json'][0] }}"
+
+- debug: var=vm1
+
+- set_fact:
+ vm_name: "VM_{{ 10000 | random }}"
+
+# Clone from existing VM with DVPG
+- name: Deploy VM from template {{ vm1 | basename }}
+ vmware_guest:
+ hostname: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ validate_certs: no
+ datacenter: "{{ (vm1|basename).split('_')[0] }}"
+ state: poweredon
+ folder: "{{ vm1 | dirname }}"
+ template: "{{ vm1 | basename }}"
+ name: "{{ vm_name }}"
+ disk:
+ - size: 10mb
+ autoselect_datastore: yes
+ guest_id: rhel7_64guest
+ hardware:
+ memory_mb: 512
+ num_cpus: 1
+ networks:
+ - name: "DC0_DVPG0"
+ register: no_vm_result
+
+- debug: var=no_vm_result
+
+- assert:
+ that:
+ - "no_vm_result.changed"
+
+# New clone with DVPG
+- set_fact:
+ vm_name: "VM_{{ 10000 | random }}"
+
+- debug: var=vm_name
+
+- name: Deploy new VM with DVPG
+ vmware_guest:
+ hostname: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ validate_certs: no
+ datacenter: "{{ (vm1|basename).split('_')[0] }}"
+ state: poweredon
+ folder: "{{ vm1 | dirname }}"
+ name: "{{ vm_name }}"
+ disk:
+ - size: 10mb
+ autoselect_datastore: yes
+ guest_id: rhel7_64guest
+ hardware:
+ memory_mb: 512
+ num_cpus: 1
+ networks:
+ - name: "DC0_DVPG0"
+ register: no_vm_result
+
+- debug: var=no_vm_result
+
+- assert:
+ that:
+ - "no_vm_result.changed"
+
+- name: Deploy same {{ vm_name }} VM again
+ vmware_guest:
+ hostname: "{{ vcsim }}"
+ username: "{{ vcsim_instance['json']['username'] }}"
+ password: "{{ vcsim_instance['json']['password'] }}"
+ validate_certs: no
+ datacenter: "{{ (vm1|basename).split('_')[0] }}"
+ state: poweredon
+ folder: "{{ vm1 | dirname }}"
+ name: "{{ vm_name }}"
+ disk:
+ - size: 10mb
+ autoselect_datastore: yes
+ guest_id: rhel7_64guest
+ hardware:
+ memory_mb: 512
+ num_cpus: 1
+ networks:
+ - name: "DC0_DVPG0"
+ register: no_vm_result
+
+- debug: var=no_vm_result
+
+- assert:
+ that:
+ - "not no_vm_result.changed"