Repository: ansible-collections/community.vmware

Issue:
VMware: Unable to create vSphere Cluster in idempotent manner
_From @kclinden on Nov 03, 2019 01:58_

<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
Playbook fails on create vSphere Cluster when running second time

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
vmware_cluster

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.9.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/klinden/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/klinden/.local/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.15+ (default, Oct  7 2019, 17:39:04) [GCC 7.4.0]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = [u'/home/klinden/hosts']
```

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
Ubuntu on Windows 2019 WSL
```
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```
##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->
Run playbook a second time on an empty vCenter instance.
<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
# Configure vCenter

- name: Configure vCenter
  hosts: localhost
  gather_facts: false
  connection: local
  vars:
    vcenter_hostname: vcsa-01a.corp.local
    vcenter_username: 'administrator@regiona.local'
    vcenter_password: 'VMware1!'
    datacenter_name: 'OneCloud'
    cluster_name: 'Cluster-01'
    esxi_hostname: esx-01a.corp.local
    esxi_username: 'root'
    esxi_password: 'VMware1!'
    validate_certs: false
    state: present
  tasks:
    - name: Create Datacenter
      vmware_datacenter:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        datacenter_name: '{{ datacenter_name }}'
        validate_certs: '{{ validate_certs }}'
        state: present
    - name: Create Cluster
      vmware_cluster:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        validate_certs: '{{ validate_certs }}'
        datacenter_name: '{{ datacenter_name }}'
        cluster_name: '{{ cluster_name }} '
        state: present
    - name: Add ESXi Host to vCenter
      vmware_host:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        validate_certs: '{{ validate_certs }}'
        datacenter: '{{ datacenter_name }}'
        cluster: '{{ cluster_name }} '
        esxi_hostname: '{{ esxi_hostname }}'
        esxi_username: '{{ esxi_username }}'
        esxi_password: '{{ esxi_password }}'
        state: present

```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->


##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```paste below

```


_Copied from original issue: ansible/ansible#64354_


Discussion:
_From @Akasurde on Nov 15, 2019 11:21_

@kclinden Thanks for reporting this issue. Could you please provide `-vvvv` output for cluster task for second run ? 

Thanks

needs_info
_From @kclinden on Nov 21, 2019 17:32_

> @kclinden Thanks for reporting this issue. Could you please provide `-vvvv` output for cluster task for second run ?
> 
> Thanks
> 
> needs_info

I will try to get more verbosity for you in the next week.
_From @Akasurde on Jan 19, 2020 05:25_

@kclinden Any news?
_From @kclinden on Jan 19, 2020 05:44_

Unfortunately I haven’t had any time to dive back into this and have since started to focus on terraform instead. 
@Akasurde 

Please close this issue. I neither see an expected nor an actual result, and anyway @kclinden moved to Terraform and therefor won't work with us on this.

I don't even understand the problem. The issue is called "Unable to create vSphere Cluster in idempotent manner", but this doesn't make any sense if the steps to reproduce are "run playbook a second time on an empty vCenter instance". If you run the playbook on a _empty_ vCenter, there's no question about idempotency.

Sorry, but I really don't get the problem. If you understand it, please explain it... otherwise, I think you should close this issue.
So the issue that I was seeing was that when I tried to run the same playbook to create a vSphere Cluster with name "Foo" it would error the second time cause the cluster already existed. I would think that I could run the same playbook over and over. If a cluster with the name "Foo" already existed then it would have no changes.
@kclinden 

I wanted to have a look into this today but, unfortunately, didn't find the time. I hope I will next week.

You ran into this problem with ansible 2.9.0, correct? This is quite old, the latest stable release is 2.9.12. Do you run into the same problem with this version?

Anyway, seeing your actually results would be quite helpful.

I'll try to have a closer look at this next week, but I won't promise anything ;-)
cc @Tomorrow9 @goneri @lparkes @pgbidkar @warthog9
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
@kclinden Is this really correct: `cluster_name: '{{ cluster_name }} '`? I think we have a problem with the trailing space, can you please remove it (`cluster_name: '{{ cluster_name }}'`) and try again?

You see, I think the module searchs for 'Cluster-01 ' (literally, that is with a trailing space) and doesn't find it, but when trying to create the cluster the vCenter trims this to 'Cluster-01' and the module fails because the cluster already exists.

@Akasurde @Tomorrow9 @goneri @lparkes @pgbidkar @warthog9
I think the problem is that we just pass a vim.fault.DuplicateName exception instead of failing the module:

https://github.com/ansible-collections/vmware/blob/aee551dc1d1f8a57f58f2da47bef7678b2461973/plugins/modules/vmware_cluster.py#L414-L416

However, in theory `state_create_cluster` shouldn't even be called. I think we have a general problem with trailing or leading whitespace, and I also think it's possible that other modules might be affected, too.
Thank you @mariolenz for raising this point. vCenter indeed silently removes the trailing whitespace. So we must do the same operation ourselves if we want to do a resource look up.

I agree, the `vim.fault.DuplicateName` exception should not ignore.
@goneri 
> Thank you @mariolenz for raising this point. vCenter indeed silently removes the trailing whitespace. So we must do the same operation ourselves if we want to do a resource look up.

The problem is that I'm not sure where to do it. I see three possibilities:

1. trim the parameter in the module: quick'n'dirty, but this doesn't prevent us from running into similar issues with other modules
2. trim in module_utils/vmware.py: tricky; might avoid similar problems with other modules in the future, but might also introduce new ones
3. ansible-base could optionally trim (a parameter option `trim` that can be set to true?) parameters: a lot of modules could possibly use this instead of trimming parameters themselves, but this would mean a change in ansible itself

Another possibility: A parameter option `whitespace_problematic` that would give a warning if a parameter has leading or trailing whitespace; pros and cons similar to 3.

> I agree, the `vim.fault.DuplicateName` exception should not ignore.

I consider this a different issue and opened #375 to address this.

I would go with Option 2. But I agree, this can also be address at the `argument_spec` level.

Resolving patch:
diff --git a/plugins/module_utils/vmware.py b/plugins/module_utils/vmware.py
--- a/plugins/module_utils/vmware.py
+++ b/plugins/module_utils/vmware.py
@@ -131,6 +131,8 @@ def find_object_by_name(content, name, obj_type, folder=None, recurse=True):
     if not isinstance(obj_type, list):
         obj_type = [obj_type]
 
+    name = name.strip()
+
     objects = get_all_objs(content, obj_type, folder=folder, recurse=recurse)
     for obj in objects:
         if unquote(obj.name) == name:


Test patch: