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:
parent
575116a584
commit
47f9873eab
9 changed files with 121 additions and 35 deletions
2
changelogs/fragments/64399_vmware_guest.yml
Normal file
2
changelogs/fragments/64399_vmware_guest.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- Handle slashes in VMware network name (https://github.com/ansible/ansible/issues/64399).
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 }}'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}'
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue