We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
vmware_guest_tools_wait  KeyError: 'datacenter'
##### SUMMARY
vmware_guest_tools_wait throwing a KeyError: 'datacenter' because multiple vms with the same name are returned but datacenter is not being passed in from the vmware_guest_tools_wait module.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
vmware_guest_tools_wait

##### ANSIBLE VERSION
```
ansible 2.10.10
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/core/tfp-env/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
```

##### CONFIGURATION
```
None
```

##### OS / ENVIRONMENT
```
Red Hat Enterprise Linux release 8.2 (Ootpa)
```

##### STEPS TO REPRODUCE
1. Create multiple vms with the same name in different folders
2. Run community.vmware.vmware_guest_tools_wait module using the vm name with folder like below.


```
- name: Wait for {{ node }}
  community.vmware.vmware_guest_tools_wait:
    hostname: "{{ esxi.ipaddress }}"
    username: "{{ esxi.username }}"
    password: "{{ esxi.password }}"
    name: "{{ node }}"
    folder: "{{ folder }}"
    validate_certs: no
    timeout: 900
  register: vm_facts
```

##### EXPECTED RESULTS
That is doesnt blow up because of keyerror.


##### ACTUAL RESULTS
```
Traceback (most recent call last):
    File "<stdin>", line 102, in <module>
    File "<stdin>", line 94, in _ansiballz_main
    File "<stdin>", line 40, in invoke_module
    File "/usr/lib64/python3.6/runpy.py", line 205, in run_module
        return _run_module_code(code, init_globals, run_name, mod_spec)
    File "/usr/lib64/python3.6/runpy.py", line 96, in _run_module_code
        mod_name, mod_spec, pkg_name, script_name)
    File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
        exec(code, run_globals)
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py", line 205, in <module>
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py", line 183, in main
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/module_utils/vmware.py", line 1078, in get_vm
    KeyError: 'datacenter'
module_stdout: ''
msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
```

vmware_guest_tools_wait  KeyError: 'datacenter'
##### SUMMARY
vmware_guest_tools_wait throwing a KeyError: 'datacenter' because multiple vms with the same name are returned but datacenter is not being passed in from the vmware_guest_tools_wait module.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
vmware_guest_tools_wait

##### ANSIBLE VERSION
```
ansible 2.10.10
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/core/tfp-env/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
```

##### CONFIGURATION
```
None
```

##### OS / ENVIRONMENT
```
Red Hat Enterprise Linux release 8.2 (Ootpa)
```

##### STEPS TO REPRODUCE
1. Create multiple vms with the same name in different folders
2. Run community.vmware.vmware_guest_tools_wait module using the vm name with folder like below.


```
- name: Wait for {{ node }}
  community.vmware.vmware_guest_tools_wait:
    hostname: "{{ esxi.ipaddress }}"
    username: "{{ esxi.username }}"
    password: "{{ esxi.password }}"
    name: "{{ node }}"
    folder: "{{ folder }}"
    validate_certs: no
    timeout: 900
  register: vm_facts
```

##### EXPECTED RESULTS
That is doesnt blow up because of keyerror.


##### ACTUAL RESULTS
```
Traceback (most recent call last):
    File "<stdin>", line 102, in <module>
    File "<stdin>", line 94, in _ansiballz_main
    File "<stdin>", line 40, in invoke_module
    File "/usr/lib64/python3.6/runpy.py", line 205, in run_module
        return _run_module_code(code, init_globals, run_name, mod_spec)
    File "/usr/lib64/python3.6/runpy.py", line 96, in _run_module_code
        mod_name, mod_spec, pkg_name, script_name)
    File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
        exec(code, run_globals)
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py", line 205, in <module>
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py", line 183, in main
    File "/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/module_utils/vmware.py", line 1078, in get_vm
    KeyError: 'datacenter'
module_stdout: ''
msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/modules/vmware_guest_tools_wait.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 
4 # Copyright: (c) 2017, Philippe Dellaert <philippe@dellaert.org>
5 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 
7 from __future__ import (absolute_import, division, print_function)
8 __metaclass__ = type
9 
10 
11 DOCUMENTATION = r'''
12 ---
13 module: vmware_guest_tools_wait
14 short_description: Wait for VMware tools to become available
15 description:
16     - This module can be used to wait for VMware tools to become available on the given VM and return facts.
17 author:
18     - Philippe Dellaert (@pdellaert) <philippe@dellaert.org>
19 notes:
20     - Tested on vSphere 6.5
21 requirements:
22     - python >= 2.6
23     - PyVmomi
24 options:
25    name:
26      description:
27      - Name of the VM for which to wait until the tools become available.
28      - This is required if C(uuid) or C(moid) is not supplied.
29      type: str
30    name_match:
31      description:
32      - If multiple VMs match the name, use the first or last found.
33      default: 'first'
34      choices: ['first', 'last']
35      type: str
36    folder:
37      description:
38      - Destination folder, absolute or relative path to find an existing guest.
39      - This is required only, if multiple VMs with same C(name) is found.
40      - The folder should include the datacenter. ESX's datacenter is C(ha-datacenter).
41      - 'Examples:'
42      - '   folder: /ha-datacenter/vm'
43      - '   folder: ha-datacenter/vm'
44      - '   folder: /datacenter1/vm'
45      - '   folder: datacenter1/vm'
46      - '   folder: /datacenter1/vm/folder1'
47      - '   folder: datacenter1/vm/folder1'
48      - '   folder: /folder1/datacenter1/vm'
49      - '   folder: folder1/datacenter1/vm'
50      - '   folder: /folder1/datacenter1/vm/folder2'
51      type: str
52    uuid:
53      description:
54      - UUID of the VM  for which to wait until the tools become available, if known. This is VMware's unique identifier.
55      - This is required, if C(name) or C(moid) is not supplied.
56      type: str
57    moid:
58      description:
59      - Managed Object ID of the instance to manage if known, this is a unique identifier only within a single vCenter instance.
60      - This is required if C(name) or C(uuid) is not supplied.
61      type: str
62    use_instance_uuid:
63      description:
64      - Whether to use the VMware instance UUID rather than the BIOS UUID.
65      default: false
66      type: bool
67    timeout:
68      description:
69      - Max duration of the waiting period (seconds).
70      default: 500
71      type: int
72 extends_documentation_fragment:
73 - community.vmware.vmware.documentation
74 
75 '''
76 
77 EXAMPLES = r'''
78 - name: Wait for VMware tools to become available by UUID
79   vmware_guest_facts:
80     hostname: "{{ vcenter_hostname }}"
81     username: "{{ vcenter_username }}"
82     password: "{{ vcenter_password }}"
83     datacenter: "{{ datacenter }}"
84     folder: "/{{datacenter}}/vm"
85     name: "{{ vm_name }}"
86   delegate_to: localhost
87   register: vm_facts
88 
89 - name: Get UUID from previous task and pass it to this task
90   community.vmware.vmware_guest_tools_wait:
91     hostname: "{{ vcenter_hostname }}"
92     username: "{{ vcenter_username }}"
93     password: "{{ vcenter_password }}"
94     uuid: "{{ vm_facts.instance.hw_product_uuid }}"
95   delegate_to: localhost
96   register: facts
97 
98 
99 - name: Wait for VMware tools to become available by MoID
100   community.vmware.vmware_guest_tools_wait:
101     hostname: "{{ vcenter_hostname }}"
102     username: "{{ vcenter_username }}"
103     password: "{{ vcenter_password }}"
104     moid: vm-42
105   delegate_to: localhost
106   register: facts
107 
108 - name: Wait for VMware tools to become available by name
109   community.vmware.vmware_guest_tools_wait:
110     hostname: "{{ vcenter_hostname }}"
111     username: "{{ vcenter_username }}"
112     password: "{{ vcenter_password }}"
113     name: test-vm
114     folder: "/{{datacenter}}/vm"
115   delegate_to: localhost
116   register: facts
117 '''
118 
119 RETURN = r'''
120 instance:
121     description: metadata about the virtual machine
122     returned: always
123     type: dict
124     sample: None
125 '''
126 
127 import datetime
128 import time
129 
130 from ansible.module_utils.basic import AnsibleModule
131 from ansible.module_utils._text import to_native
132 from ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, gather_vm_facts, vmware_argument_spec
133 
134 
135 class PyVmomiHelper(PyVmomi):
136     def __init__(self, module):
137         super(PyVmomiHelper, self).__init__(module)
138 
139     def gather_facts(self, vm):
140         return gather_vm_facts(self.content, vm)
141 
142     def wait_for_tools(self, vm, timeout):
143         tools_running = False
144         vm_facts = {}
145         start_at = datetime.datetime.now()
146 
147         while start_at + timeout > datetime.datetime.now():
148             newvm = self.get_vm()
149             vm_facts = self.gather_facts(newvm)
150             if vm_facts['guest_tools_status'] == 'guestToolsRunning':
151                 return {'changed': True, 'failed': False, 'instance': vm_facts}
152             time.sleep(5)
153 
154         if not tools_running:
155             return {'failed': True, 'msg': 'VMware tools either not present or not running after {0} seconds'.format(timeout.total_seconds())}
156 
157 
158 def main():
159     argument_spec = vmware_argument_spec()
160     argument_spec.update(
161         name=dict(type='str'),
162         name_match=dict(type='str', default='first', choices=['first', 'last']),
163         folder=dict(type='str'),
164         uuid=dict(type='str'),
165         moid=dict(type='str'),
166         use_instance_uuid=dict(type='bool', default=False),
167         timeout=dict(type='int', default=500),
168     )
169     module = AnsibleModule(
170         argument_spec=argument_spec,
171         required_one_of=[
172             ['name', 'uuid', 'moid']
173         ]
174     )
175 
176     if module.params['folder']:
177         # FindByInventoryPath() does not require an absolute path
178         # so we should leave the input folder path unmodified
179         module.params['folder'] = module.params['folder'].rstrip('/')
180 
181     pyv = PyVmomiHelper(module)
182     # Check if the VM exists before continuing
183     vm = pyv.get_vm()
184 
185     if not vm:
186         vm_id = module.params.get('name') or module.params.get('uuid') or module.params.get('moid')
187         module.fail_json(msg="Unable to wait for VMware tools for non-existing VM '%s'." % vm_id)
188 
189     timeout = datetime.timedelta(seconds=module.params['timeout'])
190 
191     result = dict(changed=False)
192     try:
193         result = pyv.wait_for_tools(vm, timeout)
194     except Exception as e:
195         module.fail_json(msg="Waiting for VMware tools failed with"
196                              " exception: {0:s}".format(to_native(e)))
197 
198     if result['failed']:
199         module.fail_json(**result)
200     else:
201         module.exit_json(**result)
202 
203 
204 if __name__ == '__main__':
205     main()
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugins/modules/vmware_guest_tools_wait.py b/plugins/modules/vmware_guest_tools_wait.py
--- a/plugins/modules/vmware_guest_tools_wait.py
+++ b/plugins/modules/vmware_guest_tools_wait.py
@@ -69,6 +69,12 @@
      - Max duration of the waiting period (seconds).
      default: 500
      type: int
+   datacenter:
+     description:
+     - Name of the datacenter.
+     - The datacenter to search for a virtual machine.
+     type: str
+     version_added: '1.15.0'
 extends_documentation_fragment:
 - community.vmware.vmware.documentation
 
@@ -112,6 +118,7 @@
     password: "{{ vcenter_password }}"
     name: test-vm
     folder: "/{{datacenter}}/vm"
+    datacenter: "{{ datacenter }}"
   delegate_to: localhost
   register: facts
 '''
@@ -165,6 +172,7 @@
         moid=dict(type='str'),
         use_instance_uuid=dict(type='bool', default=False),
         timeout=dict(type='int', default=500),
+        datacenter=dict(type='str'),
     )
     module = AnsibleModule(
         argument_spec=argument_spec,

{"golden_diff": "diff --git a/plugins/modules/vmware_guest_tools_wait.py b/plugins/modules/vmware_guest_tools_wait.py\n--- a/plugins/modules/vmware_guest_tools_wait.py\n+++ b/plugins/modules/vmware_guest_tools_wait.py\n@@ -69,6 +69,12 @@\n      - Max duration of the waiting period (seconds).\n      default: 500\n      type: int\n+   datacenter:\n+     description:\n+     - Name of the datacenter.\n+     - The datacenter to search for a virtual machine.\n+     type: str\n+     version_added: '1.15.0'\n extends_documentation_fragment:\n - community.vmware.vmware.documentation\n \n@@ -112,6 +118,7 @@\n     password: \"{{ vcenter_password }}\"\n     name: test-vm\n     folder: \"/{{datacenter}}/vm\"\n+    datacenter: \"{{ datacenter }}\"\n   delegate_to: localhost\n   register: facts\n '''\n@@ -165,6 +172,7 @@\n         moid=dict(type='str'),\n         use_instance_uuid=dict(type='bool', default=False),\n         timeout=dict(type='int', default=500),\n+        datacenter=dict(type='str'),\n     )\n     module = AnsibleModule(\n         argument_spec=argument_spec,\n", "issue": "vmware_guest_tools_wait  KeyError: 'datacenter'\n##### SUMMARY\r\nvmware_guest_tools_wait throwing a KeyError: 'datacenter' because multiple vms with the same name are returned but datacenter is not being passed in from the vmware_guest_tools_wait module.\r\n\r\n##### ISSUE TYPE\r\n- Bug Report\r\n\r\n##### COMPONENT NAME\r\nvmware_guest_tools_wait\r\n\r\n##### ANSIBLE VERSION\r\n```\r\nansible 2.10.10\r\n  config file = None\r\n  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /opt/core/tfp-env/lib/python3.6/site-packages/ansible\r\n  executable location = /usr/bin/ansible\r\n  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]\r\n```\r\n\r\n##### CONFIGURATION\r\n```\r\nNone\r\n```\r\n\r\n##### OS / ENVIRONMENT\r\n```\r\nRed Hat Enterprise Linux release 8.2 (Ootpa)\r\n```\r\n\r\n##### STEPS TO REPRODUCE\r\n1. Create multiple vms with the same name in different folders\r\n2. Run community.vmware.vmware_guest_tools_wait module using the vm name with folder like below.\r\n\r\n\r\n```\r\n- name: Wait for {{ node }}\r\n  community.vmware.vmware_guest_tools_wait:\r\n    hostname: \"{{ esxi.ipaddress }}\"\r\n    username: \"{{ esxi.username }}\"\r\n    password: \"{{ esxi.password }}\"\r\n    name: \"{{ node }}\"\r\n    folder: \"{{ folder }}\"\r\n    validate_certs: no\r\n    timeout: 900\r\n  register: vm_facts\r\n```\r\n\r\n##### EXPECTED RESULTS\r\nThat is doesnt blow up because of keyerror.\r\n\r\n\r\n##### ACTUAL RESULTS\r\n```\r\nTraceback (most recent call last):\r\n    File \"<stdin>\", line 102, in <module>\r\n    File \"<stdin>\", line 94, in _ansiballz_main\r\n    File \"<stdin>\", line 40, in invoke_module\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 205, in run_module\r\n        return _run_module_code(code, init_globals, run_name, mod_spec)\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 96, in _run_module_code\r\n        mod_name, mod_spec, pkg_name, script_name)\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 85, in _run_code\r\n        exec(code, run_globals)\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py\", line 205, in <module>\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py\", line 183, in main\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/module_utils/vmware.py\", line 1078, in get_vm\r\n    KeyError: 'datacenter'\r\nmodule_stdout: ''\r\nmsg: |-\r\n    MODULE FAILURE\r\n    See stdout/stderr for the exact error\r\n```\r\n\nvmware_guest_tools_wait  KeyError: 'datacenter'\n##### SUMMARY\r\nvmware_guest_tools_wait throwing a KeyError: 'datacenter' because multiple vms with the same name are returned but datacenter is not being passed in from the vmware_guest_tools_wait module.\r\n\r\n##### ISSUE TYPE\r\n- Bug Report\r\n\r\n##### COMPONENT NAME\r\nvmware_guest_tools_wait\r\n\r\n##### ANSIBLE VERSION\r\n```\r\nansible 2.10.10\r\n  config file = None\r\n  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /opt/core/tfp-env/lib/python3.6/site-packages/ansible\r\n  executable location = /usr/bin/ansible\r\n  python version = 3.6.8 (default, Dec  5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]\r\n```\r\n\r\n##### CONFIGURATION\r\n```\r\nNone\r\n```\r\n\r\n##### OS / ENVIRONMENT\r\n```\r\nRed Hat Enterprise Linux release 8.2 (Ootpa)\r\n```\r\n\r\n##### STEPS TO REPRODUCE\r\n1. Create multiple vms with the same name in different folders\r\n2. Run community.vmware.vmware_guest_tools_wait module using the vm name with folder like below.\r\n\r\n\r\n```\r\n- name: Wait for {{ node }}\r\n  community.vmware.vmware_guest_tools_wait:\r\n    hostname: \"{{ esxi.ipaddress }}\"\r\n    username: \"{{ esxi.username }}\"\r\n    password: \"{{ esxi.password }}\"\r\n    name: \"{{ node }}\"\r\n    folder: \"{{ folder }}\"\r\n    validate_certs: no\r\n    timeout: 900\r\n  register: vm_facts\r\n```\r\n\r\n##### EXPECTED RESULTS\r\nThat is doesnt blow up because of keyerror.\r\n\r\n\r\n##### ACTUAL RESULTS\r\n```\r\nTraceback (most recent call last):\r\n    File \"<stdin>\", line 102, in <module>\r\n    File \"<stdin>\", line 94, in _ansiballz_main\r\n    File \"<stdin>\", line 40, in invoke_module\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 205, in run_module\r\n        return _run_module_code(code, init_globals, run_name, mod_spec)\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 96, in _run_module_code\r\n        mod_name, mod_spec, pkg_name, script_name)\r\n    File \"/usr/lib64/python3.6/runpy.py\", line 85, in _run_code\r\n        exec(code, run_globals)\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py\", line 205, in <module>\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_wait.py\", line 183, in main\r\n    File \"/tmp/ansible_community.vmware.vmware_guest_tools_wait_payload_sovyp9io/ansible_community.vmware.vmware_guest_tools_wait_payload.zip/ansible_collections/community/vmware/plugins/module_utils/vmware.py\", line 1078, in get_vm\r\n    KeyError: 'datacenter'\r\nmodule_stdout: ''\r\nmsg: |-\r\n    MODULE FAILURE\r\n    See stdout/stderr for the exact error\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2017, Philippe Dellaert <philippe@dellaert.org>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\n\nDOCUMENTATION = r'''\n---\nmodule: vmware_guest_tools_wait\nshort_description: Wait for VMware tools to become available\ndescription:\n    - This module can be used to wait for VMware tools to become available on the given VM and return facts.\nauthor:\n    - Philippe Dellaert (@pdellaert) <philippe@dellaert.org>\nnotes:\n    - Tested on vSphere 6.5\nrequirements:\n    - python >= 2.6\n    - PyVmomi\noptions:\n   name:\n     description:\n     - Name of the VM for which to wait until the tools become available.\n     - This is required if C(uuid) or C(moid) is not supplied.\n     type: str\n   name_match:\n     description:\n     - If multiple VMs match the name, use the first or last found.\n     default: 'first'\n     choices: ['first', 'last']\n     type: str\n   folder:\n     description:\n     - Destination folder, absolute or relative path to find an existing guest.\n     - This is required only, if multiple VMs with same C(name) is found.\n     - The folder should include the datacenter. ESX's datacenter is C(ha-datacenter).\n     - 'Examples:'\n     - '   folder: /ha-datacenter/vm'\n     - '   folder: ha-datacenter/vm'\n     - '   folder: /datacenter1/vm'\n     - '   folder: datacenter1/vm'\n     - '   folder: /datacenter1/vm/folder1'\n     - '   folder: datacenter1/vm/folder1'\n     - '   folder: /folder1/datacenter1/vm'\n     - '   folder: folder1/datacenter1/vm'\n     - '   folder: /folder1/datacenter1/vm/folder2'\n     type: str\n   uuid:\n     description:\n     - UUID of the VM  for which to wait until the tools become available, if known. This is VMware's unique identifier.\n     - This is required, if C(name) or C(moid) is not supplied.\n     type: str\n   moid:\n     description:\n     - Managed Object ID of the instance to manage if known, this is a unique identifier only within a single vCenter instance.\n     - This is required if C(name) or C(uuid) is not supplied.\n     type: str\n   use_instance_uuid:\n     description:\n     - Whether to use the VMware instance UUID rather than the BIOS UUID.\n     default: false\n     type: bool\n   timeout:\n     description:\n     - Max duration of the waiting period (seconds).\n     default: 500\n     type: int\nextends_documentation_fragment:\n- community.vmware.vmware.documentation\n\n'''\n\nEXAMPLES = r'''\n- name: Wait for VMware tools to become available by UUID\n  vmware_guest_facts:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    datacenter: \"{{ datacenter }}\"\n    folder: \"/{{datacenter}}/vm\"\n    name: \"{{ vm_name }}\"\n  delegate_to: localhost\n  register: vm_facts\n\n- name: Get UUID from previous task and pass it to this task\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    uuid: \"{{ vm_facts.instance.hw_product_uuid }}\"\n  delegate_to: localhost\n  register: facts\n\n\n- name: Wait for VMware tools to become available by MoID\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    moid: vm-42\n  delegate_to: localhost\n  register: facts\n\n- name: Wait for VMware tools to become available by name\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    name: test-vm\n    folder: \"/{{datacenter}}/vm\"\n  delegate_to: localhost\n  register: facts\n'''\n\nRETURN = r'''\ninstance:\n    description: metadata about the virtual machine\n    returned: always\n    type: dict\n    sample: None\n'''\n\nimport datetime\nimport time\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible.module_utils._text import to_native\nfrom ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, gather_vm_facts, vmware_argument_spec\n\n\nclass PyVmomiHelper(PyVmomi):\n    def __init__(self, module):\n        super(PyVmomiHelper, self).__init__(module)\n\n    def gather_facts(self, vm):\n        return gather_vm_facts(self.content, vm)\n\n    def wait_for_tools(self, vm, timeout):\n        tools_running = False\n        vm_facts = {}\n        start_at = datetime.datetime.now()\n\n        while start_at + timeout > datetime.datetime.now():\n            newvm = self.get_vm()\n            vm_facts = self.gather_facts(newvm)\n            if vm_facts['guest_tools_status'] == 'guestToolsRunning':\n                return {'changed': True, 'failed': False, 'instance': vm_facts}\n            time.sleep(5)\n\n        if not tools_running:\n            return {'failed': True, 'msg': 'VMware tools either not present or not running after {0} seconds'.format(timeout.total_seconds())}\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(\n        name=dict(type='str'),\n        name_match=dict(type='str', default='first', choices=['first', 'last']),\n        folder=dict(type='str'),\n        uuid=dict(type='str'),\n        moid=dict(type='str'),\n        use_instance_uuid=dict(type='bool', default=False),\n        timeout=dict(type='int', default=500),\n    )\n    module = AnsibleModule(\n        argument_spec=argument_spec,\n        required_one_of=[\n            ['name', 'uuid', 'moid']\n        ]\n    )\n\n    if module.params['folder']:\n        # FindByInventoryPath() does not require an absolute path\n        # so we should leave the input folder path unmodified\n        module.params['folder'] = module.params['folder'].rstrip('/')\n\n    pyv = PyVmomiHelper(module)\n    # Check if the VM exists before continuing\n    vm = pyv.get_vm()\n\n    if not vm:\n        vm_id = module.params.get('name') or module.params.get('uuid') or module.params.get('moid')\n        module.fail_json(msg=\"Unable to wait for VMware tools for non-existing VM '%s'.\" % vm_id)\n\n    timeout = datetime.timedelta(seconds=module.params['timeout'])\n\n    result = dict(changed=False)\n    try:\n        result = pyv.wait_for_tools(vm, timeout)\n    except Exception as e:\n        module.fail_json(msg=\"Waiting for VMware tools failed with\"\n                             \" exception: {0:s}\".format(to_native(e)))\n\n    if result['failed']:\n        module.fail_json(**result)\n    else:\n        module.exit_json(**result)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/vmware_guest_tools_wait.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2017, Philippe Dellaert <philippe@dellaert.org>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\n\nDOCUMENTATION = r'''\n---\nmodule: vmware_guest_tools_wait\nshort_description: Wait for VMware tools to become available\ndescription:\n    - This module can be used to wait for VMware tools to become available on the given VM and return facts.\nauthor:\n    - Philippe Dellaert (@pdellaert) <philippe@dellaert.org>\nnotes:\n    - Tested on vSphere 6.5\nrequirements:\n    - python >= 2.6\n    - PyVmomi\noptions:\n   name:\n     description:\n     - Name of the VM for which to wait until the tools become available.\n     - This is required if C(uuid) or C(moid) is not supplied.\n     type: str\n   name_match:\n     description:\n     - If multiple VMs match the name, use the first or last found.\n     default: 'first'\n     choices: ['first', 'last']\n     type: str\n   folder:\n     description:\n     - Destination folder, absolute or relative path to find an existing guest.\n     - This is required only, if multiple VMs with same C(name) is found.\n     - The folder should include the datacenter. ESX's datacenter is C(ha-datacenter).\n     - 'Examples:'\n     - '   folder: /ha-datacenter/vm'\n     - '   folder: ha-datacenter/vm'\n     - '   folder: /datacenter1/vm'\n     - '   folder: datacenter1/vm'\n     - '   folder: /datacenter1/vm/folder1'\n     - '   folder: datacenter1/vm/folder1'\n     - '   folder: /folder1/datacenter1/vm'\n     - '   folder: folder1/datacenter1/vm'\n     - '   folder: /folder1/datacenter1/vm/folder2'\n     type: str\n   uuid:\n     description:\n     - UUID of the VM  for which to wait until the tools become available, if known. This is VMware's unique identifier.\n     - This is required, if C(name) or C(moid) is not supplied.\n     type: str\n   moid:\n     description:\n     - Managed Object ID of the instance to manage if known, this is a unique identifier only within a single vCenter instance.\n     - This is required if C(name) or C(uuid) is not supplied.\n     type: str\n   use_instance_uuid:\n     description:\n     - Whether to use the VMware instance UUID rather than the BIOS UUID.\n     default: false\n     type: bool\n   timeout:\n     description:\n     - Max duration of the waiting period (seconds).\n     default: 500\n     type: int\n   datacenter:\n     description:\n     - Name of the datacenter.\n     - The datacenter to search for a virtual machine.\n     type: str\n     version_added: '1.15.0'\nextends_documentation_fragment:\n- community.vmware.vmware.documentation\n\n'''\n\nEXAMPLES = r'''\n- name: Wait for VMware tools to become available by UUID\n  vmware_guest_facts:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    datacenter: \"{{ datacenter }}\"\n    folder: \"/{{datacenter}}/vm\"\n    name: \"{{ vm_name }}\"\n  delegate_to: localhost\n  register: vm_facts\n\n- name: Get UUID from previous task and pass it to this task\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    uuid: \"{{ vm_facts.instance.hw_product_uuid }}\"\n  delegate_to: localhost\n  register: facts\n\n\n- name: Wait for VMware tools to become available by MoID\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    moid: vm-42\n  delegate_to: localhost\n  register: facts\n\n- name: Wait for VMware tools to become available by name\n  community.vmware.vmware_guest_tools_wait:\n    hostname: \"{{ vcenter_hostname }}\"\n    username: \"{{ vcenter_username }}\"\n    password: \"{{ vcenter_password }}\"\n    name: test-vm\n    folder: \"/{{datacenter}}/vm\"\n    datacenter: \"{{ datacenter }}\"\n  delegate_to: localhost\n  register: facts\n'''\n\nRETURN = r'''\ninstance:\n    description: metadata about the virtual machine\n    returned: always\n    type: dict\n    sample: None\n'''\n\nimport datetime\nimport time\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible.module_utils._text import to_native\nfrom ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, gather_vm_facts, vmware_argument_spec\n\n\nclass PyVmomiHelper(PyVmomi):\n    def __init__(self, module):\n        super(PyVmomiHelper, self).__init__(module)\n\n    def gather_facts(self, vm):\n        return gather_vm_facts(self.content, vm)\n\n    def wait_for_tools(self, vm, timeout):\n        tools_running = False\n        vm_facts = {}\n        start_at = datetime.datetime.now()\n\n        while start_at + timeout > datetime.datetime.now():\n            newvm = self.get_vm()\n            vm_facts = self.gather_facts(newvm)\n            if vm_facts['guest_tools_status'] == 'guestToolsRunning':\n                return {'changed': True, 'failed': False, 'instance': vm_facts}\n            time.sleep(5)\n\n        if not tools_running:\n            return {'failed': True, 'msg': 'VMware tools either not present or not running after {0} seconds'.format(timeout.total_seconds())}\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(\n        name=dict(type='str'),\n        name_match=dict(type='str', default='first', choices=['first', 'last']),\n        folder=dict(type='str'),\n        uuid=dict(type='str'),\n        moid=dict(type='str'),\n        use_instance_uuid=dict(type='bool', default=False),\n        timeout=dict(type='int', default=500),\n        datacenter=dict(type='str'),\n    )\n    module = AnsibleModule(\n        argument_spec=argument_spec,\n        required_one_of=[\n            ['name', 'uuid', 'moid']\n        ]\n    )\n\n    if module.params['folder']:\n        # FindByInventoryPath() does not require an absolute path\n        # so we should leave the input folder path unmodified\n        module.params['folder'] = module.params['folder'].rstrip('/')\n\n    pyv = PyVmomiHelper(module)\n    # Check if the VM exists before continuing\n    vm = pyv.get_vm()\n\n    if not vm:\n        vm_id = module.params.get('name') or module.params.get('uuid') or module.params.get('moid')\n        module.fail_json(msg=\"Unable to wait for VMware tools for non-existing VM '%s'.\" % vm_id)\n\n    timeout = datetime.timedelta(seconds=module.params['timeout'])\n\n    result = dict(changed=False)\n    try:\n        result = pyv.wait_for_tools(vm, timeout)\n    except Exception as e:\n        module.fail_json(msg=\"Waiting for VMware tools failed with\"\n                             \" exception: {0:s}\".format(to_native(e)))\n\n    if result['failed']:\n        module.fail_json(**result)\n    else:\n        module.exit_json(**result)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/vmware_guest_tools_wait.py"}]}