VMware: Handle slash in network name in vmware_guest module (#64494)

Encode slash in network name to work with vSphere API.

Fixes: #64399

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
Abhijeet Kasurde 2019-11-12 17:13:57 +05:30 committed by GitHub
parent 575116a584
commit 47f9873eab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 121 additions and 35 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Handle slashes in VMware network name (https://github.com/ansible/ansible/issues/64399).

View file

@ -40,9 +40,7 @@ except ImportError:
from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.six import integer_types, iteritems, string_types, raise_from
from ansible.module_utils.six.moves.urllib.parse import urlparse
from ansible.module_utils.basic import env_fallback, missing_required_lib
from ansible.module_utils.urls import generic_urlparse
class TaskError(Exception):
@ -117,7 +115,7 @@ def find_obj(content, vimtype, name, first=True, folder=None):
def find_dvspg_by_name(dv_switch, portgroup_name):
portgroup_name = quote_obj_name(portgroup_name)
portgroups = dv_switch.portgroup
for pg in portgroups:
@ -185,7 +183,7 @@ def find_resource_pool_by_name(content, resource_pool_name):
def find_network_by_name(content, network_name):
return find_object_by_name(content, network_name, [vim.Network])
return find_object_by_name(content, quote_obj_name(network_name), [vim.Network])
def find_vm_by_id(content, vm_id, vm_id_type="vm_name", datacenter=None,
@ -842,6 +840,28 @@ def is_truthy(value):
return False
def quote_obj_name(object_name=None):
"""
Replace special characters in object name
with urllib quote equivalent
"""
if not object_name:
return None
from collections import OrderedDict
SPECIAL_CHARS = OrderedDict({
'%': '%25',
'/': '%2f',
'\\': '%5c'
})
for key in SPECIAL_CHARS.keys():
if key in object_name:
object_name = object_name.replace(key, SPECIAL_CHARS[key])
return object_name
class PyVmomi(object):
def __init__(self, module):
"""

View file

@ -633,7 +633,7 @@ from ansible.module_utils.vmware import (find_obj, gather_vm_facts, get_all_objs
compile_folder_path_for_object, serialize_spec,
vmware_argument_spec, set_vm_power_state, PyVmomi,
find_dvs_by_name, find_dvspg_by_name, wait_for_vm_ip,
wait_for_task, TaskError)
wait_for_task, TaskError, quote_obj_name)
def list_or_dict(value):
@ -862,6 +862,8 @@ class PyVmomiCache(object):
return objects
def get_network(self, network):
network = quote_obj_name(network)
if network not in self.networks:
self.networks[network] = self.find_obj(self.content, [vim.Network], network)

View file

@ -27,3 +27,5 @@
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

View file

@ -0,0 +1,18 @@
---
- 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

View file

@ -33,6 +33,19 @@
- 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 }}'

View file

@ -10,3 +10,5 @@ esxi2: '{{ esxi_hosts[1] }}'
esxi3: '{{ esxi_hosts[2] }}'
dvswitch1: DVS0
esxi_user: root
dvpg1: DC0_DVPG0
dvpg_with_slash: DVPG/1

View file

@ -11,6 +11,7 @@
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 }}'

View file

@ -5,20 +5,6 @@
# Clone from existing VM with DVPG
- when: vcsim is not defined
block:
- name: create basic DVS portgroup
vmware_dvs_portgroup:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
switch_name: "{{ dvswitch1 }}"
portgroup_name: DC0_DVPG0
vlan_id: 0
num_ports: 32
portgroup_type: earlyBinding
state: present
register: dvs_pg_result_0001
- name: Deploy VM from template
vmware_guest:
hostname: "{{ vcenter_hostname }}"
@ -38,7 +24,7 @@
memory_mb: 128
num_cpus: 1
networks:
- name: DC0_DVPG0
- name: '{{ dvpg1 }}'
register: no_vm_result
- debug: var=no_vm_result
- assert:
@ -65,7 +51,7 @@
memory_mb: 128
num_cpus: 1
networks:
- name: "DC0_DVPG0"
- name: '{{ dvpg1 }}'
dvswitch_name: "{{ dvswitch1 }}"
register: no_vm_result
- debug: var=no_vm_result
@ -91,7 +77,59 @@
memory_mb: 128
num_cpus: 1
networks:
- name: "DC0_DVPG0"
- 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: 10gb
autoselect_datastore: yes
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: 10gb
autoselect_datastore: yes
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:
@ -111,16 +149,4 @@
with_items:
- test_vm1
- test_vm2
- when: vcsim is not defined
name: delete basic portgroup
vmware_dvs_portgroup:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
switch_name: "{{ dvswitch1 }}"
portgroup_name: DC0_DVPG0
vlan_id: 0
num_ports: 32
portgroup_type: earlyBinding
state: absent
- test_vm3