Repository: ansible-collections/community.vmware

Issue:
vmware_host_facts: add host current time info in returned host facts
<!--- Verify first that your feature was not already discussed on GitHub -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
<!--- Describe the new feature/improvement briefly below -->

##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
vmware_host_facts

##### ADDITIONAL INFORMATION
<!--- Describe how the feature would be used, why it is needed and what it would solve -->
We want to get the host current time returned by this module "vmware_host_facts", since not get the correct property of ESXi host to get the current time property, so request to add this info in gather facts through "self.si.CurrentTime()" when host is configured to a ESXi host.

<!--- Paste example playbooks or commands between quotes below -->
```yaml

```

<!--- HINT: You can also paste gist.github.com links for larger files -->



Discussion:

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
@@ -15,6 +15,7 @@
 import ssl
 import time
 import traceback
+import datetime
 from collections import OrderedDict
 from distutils.version import StrictVersion
 from random import randint
@@ -430,6 +431,36 @@ def gather_vm_facts(content, vm):
     return facts
 
 
+def ansible_date_time_facts(timestamp):
+    # timestamp is a datetime.datetime object
+    date_time_facts = {}
+    if timestamp is None:
+        return date_time_facts
+
+    utctimestamp = timestamp.astimezone(datetime.timezone.utc)
+
+    date_time_facts['year'] = timestamp.strftime('%Y')
+    date_time_facts['month'] = timestamp.strftime('%m')
+    date_time_facts['weekday'] = timestamp.strftime('%A')
+    date_time_facts['weekday_number'] = timestamp.strftime('%w')
+    date_time_facts['weeknumber'] = timestamp.strftime('%W')
+    date_time_facts['day'] = timestamp.strftime('%d')
+    date_time_facts['hour'] = timestamp.strftime('%H')
+    date_time_facts['minute'] = timestamp.strftime('%M')
+    date_time_facts['second'] = timestamp.strftime('%S')
+    date_time_facts['epoch'] = timestamp.strftime('%s')
+    date_time_facts['date'] = timestamp.strftime('%Y-%m-%d')
+    date_time_facts['time'] = timestamp.strftime('%H:%M:%S')
+    date_time_facts['iso8601_micro'] = utctimestamp.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
+    date_time_facts['iso8601'] = utctimestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
+    date_time_facts['iso8601_basic'] = timestamp.strftime("%Y%m%dT%H%M%S%f")
+    date_time_facts['iso8601_basic_short'] = timestamp.strftime("%Y%m%dT%H%M%S")
+    date_time_facts['tz'] = timestamp.strftime("%Z")
+    date_time_facts['tz_offset'] = timestamp.strftime("%z")
+
+    return date_time_facts
+
+
 def deserialize_snapshot_obj(obj):
     return {'id': obj.id,
             'name': obj.name,
diff --git a/plugins/modules/vmware_host_facts.py b/plugins/modules/vmware_host_facts.py
--- a/plugins/modules/vmware_host_facts.py
+++ b/plugins/modules/vmware_host_facts.py
@@ -232,7 +232,12 @@
 from ansible.module_utils.basic import AnsibleModule
 from ansible.module_utils._text import to_native
 from ansible.module_utils.common.text.formatters import bytes_to_human
-from ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, vmware_argument_spec, find_obj
+from ansible_collections.community.vmware.plugins.module_utils.vmware import (
+    PyVmomi,
+    vmware_argument_spec,
+    find_obj,
+    ansible_date_time_facts
+)
 
 try:
     from pyVmomi import vim
@@ -253,8 +258,10 @@ def __init__(self, module):
             if len(self.host) > 1:
                 self.module.fail_json(msg="esxi_hostname matched multiple hosts")
             self.host = self.host[0]
+            self.esxi_time = None
         else:
             self.host = find_obj(self.content, [vim.HostSystem], None)
+            self.esxi_time = self.si.CurrentTime()
 
         if self.host is None:
             self.module.fail_json(msg="Failed to find host system.")
@@ -268,6 +275,7 @@ def all_facts(self):
         ansible_facts.update(self.get_system_facts())
         ansible_facts.update(self.get_vsan_facts())
         ansible_facts.update(self.get_cluster_facts())
+        ansible_facts.update({'host_date_time': ansible_date_time_facts(self.esxi_time)})
         if self.params.get('show_tag'):
             vmware_client = VmwareRestClient(self.module)
             tag_info = {


Test patch:
diff --git a/tests/integration/targets/vmware_host_facts/tasks/main.yml b/tests/integration/targets/vmware_host_facts/tasks/main.yml
--- a/tests/integration/targets/vmware_host_facts/tasks/main.yml
+++ b/tests/integration/targets/vmware_host_facts/tasks/main.yml
@@ -91,3 +91,32 @@
           - "'numCpuCores' in facts['ansible_facts']['hardware']['cpuInfo']"
           - "'product' in facts['ansible_facts']['config']"
           - "'apiVersion' in facts['ansible_facts']['config']['product']"
+
+    - name: check host current time through a vcenter
+      vmware_host_facts:
+        validate_certs: false
+        hostname: "{{ vcenter_hostname }}"
+        username: "{{ vcenter_username }}"
+        password: "{{ vcenter_password }}"
+        esxi_hostname: '{{ esxi1 }}'
+      register: facts
+    - debug: var=facts
+    - name: verify host_date_time
+      assert:
+        that:
+          - "'host_date_time' in facts['ansible_facts']"
+          - facts['ansible_facts']['host_date_time'] == {}
+
+    - name: check host current time through a host
+      vmware_host_facts:
+        validate_certs: false
+        hostname: '{{ esxi1 }}'
+        username: '{{ esxi_user }}'
+        password: '{{ esxi_password }}'
+      register: facts
+    - debug: var=facts
+    - name: verify host_date_time
+      assert:
+        that:
+          - "'host_date_time' in facts['ansible_facts']"
+          - facts['ansible_facts']['host_date_time'] != {}