We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
vmware_datastore_cluster_manager is always changed in checkmode
##### SUMMARY
When running in check mode the module is always reporting changed even when it is not detecting any changes.

I had a look at the code and I think there is an if statement missing to set changed=true depending on changed_datastores found or not when in check mode.

You can work around this issue by defining a changed_when clause:
```yaml
register: storage_cluster_datastore_result
changed_when: storage_cluster_datastore_result.datastore_cluster_info.changed_datastores|length > 0
```

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
vmware_datastore_cluster_manager

##### ANSIBLE VERSION
```paste below
ansible 2.10.2
  config file = None
  configured module search path = ['/Users/cneugum/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.8.5 (default, Oct 12 2020, 11:36:53) [Clang 12.0.0 (clang-1200.0.32.2)]
```

##### CONFIGURATION
Default

##### OS / ENVIRONMENT
Ansible running on: OSX 10.15.7
vCenter running on: vSphere 6.7


##### STEPS TO REPRODUCE

1. Create a play that uses the module and run it so datastores are added to the datastore cluster
2. Run the same play again
3. Run the same play in check mode

```yaml
- name: Test Datastore Cluster
  hosts: localhost
  gather_facts: no
  vars:
    vcenter:
      hostname: 'vcsa.lab.local'
      username: 'administrator@vsphere.local'
      password: 'VMware1!'
    datacenter_name: 'DC01'
    datastore_cluster_name: 'StorageCluster01'
    datastores: 
      - "DS01"
      - "DS02"
      - "DS03"
  tasks:
    - name: Create datastore cluster
      community.vmware.vmware_datastore_cluster:
        hostname: '{{ vcenter.hostname }}'
        username: '{{ vcenter.username }}'
        password: '{{ vcenter.password }}'
        validate_certs: no
        datacenter_name: '{{ datacenter_name }}'
        datastore_cluster_name: '{{ datastore_cluster_name }}'
    - name: Add Datastores to datastore cluster
      community.vmware.vmware_datastore_cluster_manager:
        hostname: '{{ vcenter.hostname }}'
        username: '{{ vcenter.username }}'
        password: '{{ vcenter.password }}'
        validate_certs: no
        datacenter_name: '{{ datacenter_name }}'
        datastore_cluster_name: '{{ datastore_cluster_name }}'
        datastores: '{{ datastores }}'
```

##### EXPECTED RESULTS

1. Play Recap should report changed tasks
2. Play Recap should report no changed tasks
3. Play Recap should report no changed tasks


##### ACTUAL RESULTS

1. Play Recap reports changed tasks
2. Play Recap reports no changed tasks
3. **_Play Recap reports changed tasks_**


--- 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_datastore_cluster_manager.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # Copyright (c) 2018, Ansible Project
4 # Copyright (c) 2020, Abhijeet Kasurde <akasurde@redhat.com>
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_datastore_cluster_manager
14 short_description: Manage VMware vSphere datastore cluster's members
15 description:
16     - This module can be used to add datastore in the datastore cluster.
17     - All parameters and VMware object values are case sensitive.
18 author:
19 -  Abhijeet Kasurde (@Akasurde)
20 notes:
21     - Tested on vSphere 6.0, 6.5
22 requirements:
23     - "python >= 2.7"
24     - PyVmomi
25 options:
26     datacenter_name:
27       description:
28       - The name of the datacenter.
29       required: False
30       aliases: [ datacenter ]
31       type: str
32     datastore_cluster_name:
33       description:
34       - The name of the datastore cluster.
35       required: True
36       type: str
37       aliases: [ datastore_cluster ]
38     state:
39       description:
40       - If set to I(present), datastores specified by I(datastores) will be added to the given datastore cluster.
41       - If set to I(absent), datastores specified by I(datastores) will be moved from the given datastore cluster to datstore folder of the parent datacenter.
42       choices: [ present, absent ]
43       default: present
44       type: str
45     datastores:
46         description:
47         - A list of datastores to be manage.
48         type: list
49         elements: str
50         required: True
51 extends_documentation_fragment:
52 - community.vmware.vmware.documentation
53 '''
54 
55 EXAMPLES = r'''
56 - name: Add datastore to the given datastore cluster
57   community.vmware.vmware_datastore_cluster_manager:
58     hostname: '{{ vcenter_hostname }}'
59     username: '{{ vcenter_username }}'
60     password: '{{ vcenter_password }}'
61     datacenter_name: '{{ datacenter_name }}'
62     datastore_cluster_name: '{{ datastore_cluster_name }}'
63     datastores:
64     - ds_001
65     - ds_002
66     - ds_003
67     state: present
68   delegate_to: localhost
69 
70 - name: Move datastore from the given datastore cluster
71   community.vmware.vmware_datastore_cluster_manager:
72     hostname: '{{ vcenter_hostname }}'
73     username: '{{ vcenter_username }}'
74     password: '{{ vcenter_password }}'
75     datacenter_name: '{{ datacenter_name }}'
76     datastore_cluster_name: '{{ datastore_cluster_name }}'
77     datastores:
78     - ds_001
79     state: absent
80   delegate_to: localhost
81 '''
82 
83 RETURN = r'''
84 datastore_cluster_info:
85     description: information about datastore cluster
86     returned: always
87     type: str
88     sample: {
89         "changed_datastores": ["ds_171_1"],
90         "current_datastores": [],
91         "msg": null,
92         "previous_datastores": ["ds_171_1"]
93     }
94 '''
95 
96 try:
97     from pyVmomi import vim
98 except ImportError:
99     pass
100 
101 from ansible.module_utils.basic import AnsibleModule
102 from ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, vmware_argument_spec, wait_for_task, TaskError
103 from ansible.module_utils._text import to_native
104 
105 
106 class VMwareDatastoreClusterManager(PyVmomi):
107     def __init__(self, module):
108         """
109         Constructor
110 
111         """
112         super(VMwareDatastoreClusterManager, self).__init__(module)
113         datacenter_name = self.params.get('datacenter_name')
114         datacenter_obj = self.find_datacenter_by_name(datacenter_name)
115         if not datacenter_obj:
116             self.module.fail_json(msg="Failed to find datacenter '%s' required"
117                                       " for managing datastore cluster." % datacenter_name)
118         self.folder_obj = datacenter_obj.datastoreFolder
119 
120         self.datastore_cluster_name = self.params.get('datastore_cluster_name')
121         self.datastore_cluster_obj = self.find_datastore_cluster_by_name(self.datastore_cluster_name, datacenter=datacenter_obj)
122         if not self.datastore_cluster_obj:
123             self.module.fail_json(msg="Failed to find the datastore cluster '%s'" % self.datastore_cluster_name)
124 
125     def get_datastore_cluster_children(self):
126         """
127         Return Datastore from the given datastore cluster object
128 
129         """
130         return [ds for ds in self.datastore_cluster_obj.childEntity if isinstance(ds, vim.Datastore)]
131 
132     def ensure(self):
133         """
134         Manage internal state of datastore cluster
135 
136         """
137         changed = False
138         results = dict(
139             changed=changed,
140         )
141         temp_result = dict(
142             previous_datastores=[],
143             current_datastores=[],
144             msg=""
145         )
146         state = self.module.params.get('state')
147         datastores = self.module.params.get('datastores') or []
148         datastore_obj_list = []
149         dsc_child_obj = self.get_datastore_cluster_children()
150 
151         if state == 'present':
152             temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]
153             for datastore_name in datastores:
154                 datastore_obj = self.find_datastore_by_name(datastore_name)
155                 if not datastore_obj:
156                     self.module.fail_json(msg="Failed to find datastore '%s'" % datastore_name)
157                 if datastore_obj not in dsc_child_obj and datastore_obj not in datastore_obj_list:
158                     datastore_obj_list.append(datastore_obj)
159 
160             if self.module.check_mode:
161                 changed_list = [ds.name for ds in datastore_obj_list]
162                 temp_result['current_datastores'] = temp_result['previous_datastores'].extend(changed_list)
163                 temp_result['changed_datastores'] = changed_list
164                 results['changed'] = True
165                 results['datastore_cluster_info'] = temp_result
166                 self.module.exit_json(**results)
167 
168             try:
169                 if datastore_obj_list:
170                     task = self.datastore_cluster_obj.MoveIntoFolder_Task(list=datastore_obj_list)
171                     changed, result = wait_for_task(task)
172                     temp_result['msg'] = result
173                 temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]
174                 temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]
175             except TaskError as generic_exc:
176                 self.module.fail_json(msg=to_native(generic_exc))
177             except Exception as task_e:
178                 self.module.fail_json(msg=to_native(task_e))
179         elif state == 'absent':
180             temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]
181             temp_result['current_datastores'] = [ds.name for ds in dsc_child_obj]
182             for datastore_name in datastores:
183                 datastore_obj = self.find_datastore_by_name(datastore_name)
184                 if not datastore_obj:
185                     self.module.fail_json(msg="Failed to find datastore '%s'" % datastore_name)
186                 if datastore_obj in dsc_child_obj and datastore_obj not in datastore_obj_list:
187                     datastore_obj_list.append(datastore_obj)
188 
189             if self.module.check_mode:
190                 changed_list = [ds.name for ds in datastore_obj_list]
191                 for ds in changed_list:
192                     temp_result['current_datastores'].pop(ds)
193                 temp_result['changed_datastores'] = changed_list
194                 results['changed'] = True
195                 results['datastore_cluster_info'] = temp_result
196                 self.module.exit_json(**results)
197 
198             try:
199                 if datastore_obj_list:
200                     task = self.folder_obj.MoveIntoFolder_Task(list=datastore_obj_list)
201                     changed, result = wait_for_task(task)
202                     temp_result['msg'] = result
203                 temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]
204                 temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]
205             except TaskError as generic_exc:
206                 self.module.fail_json(msg=to_native(generic_exc))
207             except Exception as task_e:
208                 self.module.fail_json(msg=to_native(task_e))
209 
210         results['changed'] = changed
211         results['datastore_cluster_info'] = temp_result
212         self.module.exit_json(**results)
213 
214 
215 def main():
216     argument_spec = vmware_argument_spec()
217     argument_spec.update(
218         dict(
219             datacenter_name=dict(type='str', required=False, aliases=['datacenter']),
220             datastore_cluster_name=dict(type='str', required=True, aliases=['datastore_cluster']),
221             state=dict(default='present', choices=['present', 'absent'], type='str'),
222             datastores=dict(type='list', required=True, elements='str'),
223         )
224     )
225     module = AnsibleModule(
226         argument_spec=argument_spec,
227         supports_check_mode=True,
228     )
229 
230     datastore_cluster_mgr = VMwareDatastoreClusterManager(module)
231     datastore_cluster_mgr.ensure()
232 
233 
234 if __name__ == '__main__':
235     main()
236
```
--- 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_datastore_cluster_manager.py b/plugins/modules/vmware_datastore_cluster_manager.py
--- a/plugins/modules/vmware_datastore_cluster_manager.py
+++ b/plugins/modules/vmware_datastore_cluster_manager.py
@@ -161,7 +161,7 @@
                 changed_list = [ds.name for ds in datastore_obj_list]
                 temp_result['current_datastores'] = temp_result['previous_datastores'].extend(changed_list)
                 temp_result['changed_datastores'] = changed_list
-                results['changed'] = True
+                results['changed'] = len(datastore_obj_list) > 0
                 results['datastore_cluster_info'] = temp_result
                 self.module.exit_json(**results)
 
@@ -191,7 +191,7 @@
                 for ds in changed_list:
                     temp_result['current_datastores'].pop(ds)
                 temp_result['changed_datastores'] = changed_list
-                results['changed'] = True
+                results['changed'] = len(datastore_obj_list) > 0
                 results['datastore_cluster_info'] = temp_result
                 self.module.exit_json(**results)

{"golden_diff": "diff --git a/plugins/modules/vmware_datastore_cluster_manager.py b/plugins/modules/vmware_datastore_cluster_manager.py\n--- a/plugins/modules/vmware_datastore_cluster_manager.py\n+++ b/plugins/modules/vmware_datastore_cluster_manager.py\n@@ -161,7 +161,7 @@\n                 changed_list = [ds.name for ds in datastore_obj_list]\n                 temp_result['current_datastores'] = temp_result['previous_datastores'].extend(changed_list)\n                 temp_result['changed_datastores'] = changed_list\n-                results['changed'] = True\n+                results['changed'] = len(datastore_obj_list) > 0\n                 results['datastore_cluster_info'] = temp_result\n                 self.module.exit_json(**results)\n \n@@ -191,7 +191,7 @@\n                 for ds in changed_list:\n                     temp_result['current_datastores'].pop(ds)\n                 temp_result['changed_datastores'] = changed_list\n-                results['changed'] = True\n+                results['changed'] = len(datastore_obj_list) > 0\n                 results['datastore_cluster_info'] = temp_result\n                 self.module.exit_json(**results)\n", "issue": "vmware_datastore_cluster_manager is always changed in checkmode\n##### SUMMARY\r\nWhen running in check mode the module is always reporting changed even when it is not detecting any changes.\r\n\r\nI had a look at the code and I think there is an if statement missing to set changed=true depending on changed_datastores found or not when in check mode.\r\n\r\nYou can work around this issue by defining a changed_when clause:\r\n```yaml\r\nregister: storage_cluster_datastore_result\r\nchanged_when: storage_cluster_datastore_result.datastore_cluster_info.changed_datastores|length > 0\r\n```\r\n\r\n##### ISSUE TYPE\r\n- Bug Report\r\n\r\n##### COMPONENT NAME\r\nvmware_datastore_cluster_manager\r\n\r\n##### ANSIBLE VERSION\r\n```paste below\r\nansible 2.10.2\r\n  config file = None\r\n  configured module search path = ['/Users/cneugum/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible\r\n  executable location = /usr/local/bin/ansible\r\n  python version = 3.8.5 (default, Oct 12 2020, 11:36:53) [Clang 12.0.0 (clang-1200.0.32.2)]\r\n```\r\n\r\n##### CONFIGURATION\r\nDefault\r\n\r\n##### OS / ENVIRONMENT\r\nAnsible running on: OSX 10.15.7\r\nvCenter running on: vSphere 6.7\r\n\r\n\r\n##### STEPS TO REPRODUCE\r\n\r\n1. Create a play that uses the module and run it so datastores are added to the datastore cluster\r\n2. Run the same play again\r\n3. Run the same play in check mode\r\n\r\n```yaml\r\n- name: Test Datastore Cluster\r\n  hosts: localhost\r\n  gather_facts: no\r\n  vars:\r\n    vcenter:\r\n      hostname: 'vcsa.lab.local'\r\n      username: 'administrator@vsphere.local'\r\n      password: 'VMware1!'\r\n    datacenter_name: 'DC01'\r\n    datastore_cluster_name: 'StorageCluster01'\r\n    datastores: \r\n      - \"DS01\"\r\n      - \"DS02\"\r\n      - \"DS03\"\r\n  tasks:\r\n    - name: Create datastore cluster\r\n      community.vmware.vmware_datastore_cluster:\r\n        hostname: '{{ vcenter.hostname }}'\r\n        username: '{{ vcenter.username }}'\r\n        password: '{{ vcenter.password }}'\r\n        validate_certs: no\r\n        datacenter_name: '{{ datacenter_name }}'\r\n        datastore_cluster_name: '{{ datastore_cluster_name }}'\r\n    - name: Add Datastores to datastore cluster\r\n      community.vmware.vmware_datastore_cluster_manager:\r\n        hostname: '{{ vcenter.hostname }}'\r\n        username: '{{ vcenter.username }}'\r\n        password: '{{ vcenter.password }}'\r\n        validate_certs: no\r\n        datacenter_name: '{{ datacenter_name }}'\r\n        datastore_cluster_name: '{{ datastore_cluster_name }}'\r\n        datastores: '{{ datastores }}'\r\n```\r\n\r\n##### EXPECTED RESULTS\r\n\r\n1. Play Recap should report changed tasks\r\n2. Play Recap should report no changed tasks\r\n3. Play Recap should report no changed tasks\r\n\r\n\r\n##### ACTUAL RESULTS\r\n\r\n1. Play Recap reports changed tasks\r\n2. Play Recap reports no changed tasks\r\n3. **_Play Recap reports changed tasks_**\r\n\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n# Copyright (c) 2018, Ansible Project\n# Copyright (c) 2020, Abhijeet Kasurde <akasurde@redhat.com>\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_datastore_cluster_manager\nshort_description: Manage VMware vSphere datastore cluster's members\ndescription:\n    - This module can be used to add datastore in the datastore cluster.\n    - All parameters and VMware object values are case sensitive.\nauthor:\n-  Abhijeet Kasurde (@Akasurde)\nnotes:\n    - Tested on vSphere 6.0, 6.5\nrequirements:\n    - \"python >= 2.7\"\n    - PyVmomi\noptions:\n    datacenter_name:\n      description:\n      - The name of the datacenter.\n      required: False\n      aliases: [ datacenter ]\n      type: str\n    datastore_cluster_name:\n      description:\n      - The name of the datastore cluster.\n      required: True\n      type: str\n      aliases: [ datastore_cluster ]\n    state:\n      description:\n      - If set to I(present), datastores specified by I(datastores) will be added to the given datastore cluster.\n      - If set to I(absent), datastores specified by I(datastores) will be moved from the given datastore cluster to datstore folder of the parent datacenter.\n      choices: [ present, absent ]\n      default: present\n      type: str\n    datastores:\n        description:\n        - A list of datastores to be manage.\n        type: list\n        elements: str\n        required: True\nextends_documentation_fragment:\n- community.vmware.vmware.documentation\n'''\n\nEXAMPLES = r'''\n- name: Add datastore to the given datastore cluster\n  community.vmware.vmware_datastore_cluster_manager:\n    hostname: '{{ vcenter_hostname }}'\n    username: '{{ vcenter_username }}'\n    password: '{{ vcenter_password }}'\n    datacenter_name: '{{ datacenter_name }}'\n    datastore_cluster_name: '{{ datastore_cluster_name }}'\n    datastores:\n    - ds_001\n    - ds_002\n    - ds_003\n    state: present\n  delegate_to: localhost\n\n- name: Move datastore from the given datastore cluster\n  community.vmware.vmware_datastore_cluster_manager:\n    hostname: '{{ vcenter_hostname }}'\n    username: '{{ vcenter_username }}'\n    password: '{{ vcenter_password }}'\n    datacenter_name: '{{ datacenter_name }}'\n    datastore_cluster_name: '{{ datastore_cluster_name }}'\n    datastores:\n    - ds_001\n    state: absent\n  delegate_to: localhost\n'''\n\nRETURN = r'''\ndatastore_cluster_info:\n    description: information about datastore cluster\n    returned: always\n    type: str\n    sample: {\n        \"changed_datastores\": [\"ds_171_1\"],\n        \"current_datastores\": [],\n        \"msg\": null,\n        \"previous_datastores\": [\"ds_171_1\"]\n    }\n'''\n\ntry:\n    from pyVmomi import vim\nexcept ImportError:\n    pass\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, vmware_argument_spec, wait_for_task, TaskError\nfrom ansible.module_utils._text import to_native\n\n\nclass VMwareDatastoreClusterManager(PyVmomi):\n    def __init__(self, module):\n        \"\"\"\n        Constructor\n\n        \"\"\"\n        super(VMwareDatastoreClusterManager, self).__init__(module)\n        datacenter_name = self.params.get('datacenter_name')\n        datacenter_obj = self.find_datacenter_by_name(datacenter_name)\n        if not datacenter_obj:\n            self.module.fail_json(msg=\"Failed to find datacenter '%s' required\"\n                                      \" for managing datastore cluster.\" % datacenter_name)\n        self.folder_obj = datacenter_obj.datastoreFolder\n\n        self.datastore_cluster_name = self.params.get('datastore_cluster_name')\n        self.datastore_cluster_obj = self.find_datastore_cluster_by_name(self.datastore_cluster_name, datacenter=datacenter_obj)\n        if not self.datastore_cluster_obj:\n            self.module.fail_json(msg=\"Failed to find the datastore cluster '%s'\" % self.datastore_cluster_name)\n\n    def get_datastore_cluster_children(self):\n        \"\"\"\n        Return Datastore from the given datastore cluster object\n\n        \"\"\"\n        return [ds for ds in self.datastore_cluster_obj.childEntity if isinstance(ds, vim.Datastore)]\n\n    def ensure(self):\n        \"\"\"\n        Manage internal state of datastore cluster\n\n        \"\"\"\n        changed = False\n        results = dict(\n            changed=changed,\n        )\n        temp_result = dict(\n            previous_datastores=[],\n            current_datastores=[],\n            msg=\"\"\n        )\n        state = self.module.params.get('state')\n        datastores = self.module.params.get('datastores') or []\n        datastore_obj_list = []\n        dsc_child_obj = self.get_datastore_cluster_children()\n\n        if state == 'present':\n            temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]\n            for datastore_name in datastores:\n                datastore_obj = self.find_datastore_by_name(datastore_name)\n                if not datastore_obj:\n                    self.module.fail_json(msg=\"Failed to find datastore '%s'\" % datastore_name)\n                if datastore_obj not in dsc_child_obj and datastore_obj not in datastore_obj_list:\n                    datastore_obj_list.append(datastore_obj)\n\n            if self.module.check_mode:\n                changed_list = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = temp_result['previous_datastores'].extend(changed_list)\n                temp_result['changed_datastores'] = changed_list\n                results['changed'] = True\n                results['datastore_cluster_info'] = temp_result\n                self.module.exit_json(**results)\n\n            try:\n                if datastore_obj_list:\n                    task = self.datastore_cluster_obj.MoveIntoFolder_Task(list=datastore_obj_list)\n                    changed, result = wait_for_task(task)\n                    temp_result['msg'] = result\n                temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]\n            except TaskError as generic_exc:\n                self.module.fail_json(msg=to_native(generic_exc))\n            except Exception as task_e:\n                self.module.fail_json(msg=to_native(task_e))\n        elif state == 'absent':\n            temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]\n            temp_result['current_datastores'] = [ds.name for ds in dsc_child_obj]\n            for datastore_name in datastores:\n                datastore_obj = self.find_datastore_by_name(datastore_name)\n                if not datastore_obj:\n                    self.module.fail_json(msg=\"Failed to find datastore '%s'\" % datastore_name)\n                if datastore_obj in dsc_child_obj and datastore_obj not in datastore_obj_list:\n                    datastore_obj_list.append(datastore_obj)\n\n            if self.module.check_mode:\n                changed_list = [ds.name for ds in datastore_obj_list]\n                for ds in changed_list:\n                    temp_result['current_datastores'].pop(ds)\n                temp_result['changed_datastores'] = changed_list\n                results['changed'] = True\n                results['datastore_cluster_info'] = temp_result\n                self.module.exit_json(**results)\n\n            try:\n                if datastore_obj_list:\n                    task = self.folder_obj.MoveIntoFolder_Task(list=datastore_obj_list)\n                    changed, result = wait_for_task(task)\n                    temp_result['msg'] = result\n                temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]\n            except TaskError as generic_exc:\n                self.module.fail_json(msg=to_native(generic_exc))\n            except Exception as task_e:\n                self.module.fail_json(msg=to_native(task_e))\n\n        results['changed'] = changed\n        results['datastore_cluster_info'] = temp_result\n        self.module.exit_json(**results)\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(\n        dict(\n            datacenter_name=dict(type='str', required=False, aliases=['datacenter']),\n            datastore_cluster_name=dict(type='str', required=True, aliases=['datastore_cluster']),\n            state=dict(default='present', choices=['present', 'absent'], type='str'),\n            datastores=dict(type='list', required=True, elements='str'),\n        )\n    )\n    module = AnsibleModule(\n        argument_spec=argument_spec,\n        supports_check_mode=True,\n    )\n\n    datastore_cluster_mgr = VMwareDatastoreClusterManager(module)\n    datastore_cluster_mgr.ensure()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/vmware_datastore_cluster_manager.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n# Copyright (c) 2018, Ansible Project\n# Copyright (c) 2020, Abhijeet Kasurde <akasurde@redhat.com>\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_datastore_cluster_manager\nshort_description: Manage VMware vSphere datastore cluster's members\ndescription:\n    - This module can be used to add datastore in the datastore cluster.\n    - All parameters and VMware object values are case sensitive.\nauthor:\n-  Abhijeet Kasurde (@Akasurde)\nnotes:\n    - Tested on vSphere 6.0, 6.5\nrequirements:\n    - \"python >= 2.7\"\n    - PyVmomi\noptions:\n    datacenter_name:\n      description:\n      - The name of the datacenter.\n      required: False\n      aliases: [ datacenter ]\n      type: str\n    datastore_cluster_name:\n      description:\n      - The name of the datastore cluster.\n      required: True\n      type: str\n      aliases: [ datastore_cluster ]\n    state:\n      description:\n      - If set to I(present), datastores specified by I(datastores) will be added to the given datastore cluster.\n      - If set to I(absent), datastores specified by I(datastores) will be moved from the given datastore cluster to datstore folder of the parent datacenter.\n      choices: [ present, absent ]\n      default: present\n      type: str\n    datastores:\n        description:\n        - A list of datastores to be manage.\n        type: list\n        elements: str\n        required: True\nextends_documentation_fragment:\n- community.vmware.vmware.documentation\n'''\n\nEXAMPLES = r'''\n- name: Add datastore to the given datastore cluster\n  community.vmware.vmware_datastore_cluster_manager:\n    hostname: '{{ vcenter_hostname }}'\n    username: '{{ vcenter_username }}'\n    password: '{{ vcenter_password }}'\n    datacenter_name: '{{ datacenter_name }}'\n    datastore_cluster_name: '{{ datastore_cluster_name }}'\n    datastores:\n    - ds_001\n    - ds_002\n    - ds_003\n    state: present\n  delegate_to: localhost\n\n- name: Move datastore from the given datastore cluster\n  community.vmware.vmware_datastore_cluster_manager:\n    hostname: '{{ vcenter_hostname }}'\n    username: '{{ vcenter_username }}'\n    password: '{{ vcenter_password }}'\n    datacenter_name: '{{ datacenter_name }}'\n    datastore_cluster_name: '{{ datastore_cluster_name }}'\n    datastores:\n    - ds_001\n    state: absent\n  delegate_to: localhost\n'''\n\nRETURN = r'''\ndatastore_cluster_info:\n    description: information about datastore cluster\n    returned: always\n    type: str\n    sample: {\n        \"changed_datastores\": [\"ds_171_1\"],\n        \"current_datastores\": [],\n        \"msg\": null,\n        \"previous_datastores\": [\"ds_171_1\"]\n    }\n'''\n\ntry:\n    from pyVmomi import vim\nexcept ImportError:\n    pass\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible_collections.community.vmware.plugins.module_utils.vmware import PyVmomi, vmware_argument_spec, wait_for_task, TaskError\nfrom ansible.module_utils._text import to_native\n\n\nclass VMwareDatastoreClusterManager(PyVmomi):\n    def __init__(self, module):\n        \"\"\"\n        Constructor\n\n        \"\"\"\n        super(VMwareDatastoreClusterManager, self).__init__(module)\n        datacenter_name = self.params.get('datacenter_name')\n        datacenter_obj = self.find_datacenter_by_name(datacenter_name)\n        if not datacenter_obj:\n            self.module.fail_json(msg=\"Failed to find datacenter '%s' required\"\n                                      \" for managing datastore cluster.\" % datacenter_name)\n        self.folder_obj = datacenter_obj.datastoreFolder\n\n        self.datastore_cluster_name = self.params.get('datastore_cluster_name')\n        self.datastore_cluster_obj = self.find_datastore_cluster_by_name(self.datastore_cluster_name, datacenter=datacenter_obj)\n        if not self.datastore_cluster_obj:\n            self.module.fail_json(msg=\"Failed to find the datastore cluster '%s'\" % self.datastore_cluster_name)\n\n    def get_datastore_cluster_children(self):\n        \"\"\"\n        Return Datastore from the given datastore cluster object\n\n        \"\"\"\n        return [ds for ds in self.datastore_cluster_obj.childEntity if isinstance(ds, vim.Datastore)]\n\n    def ensure(self):\n        \"\"\"\n        Manage internal state of datastore cluster\n\n        \"\"\"\n        changed = False\n        results = dict(\n            changed=changed,\n        )\n        temp_result = dict(\n            previous_datastores=[],\n            current_datastores=[],\n            msg=\"\"\n        )\n        state = self.module.params.get('state')\n        datastores = self.module.params.get('datastores') or []\n        datastore_obj_list = []\n        dsc_child_obj = self.get_datastore_cluster_children()\n\n        if state == 'present':\n            temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]\n            for datastore_name in datastores:\n                datastore_obj = self.find_datastore_by_name(datastore_name)\n                if not datastore_obj:\n                    self.module.fail_json(msg=\"Failed to find datastore '%s'\" % datastore_name)\n                if datastore_obj not in dsc_child_obj and datastore_obj not in datastore_obj_list:\n                    datastore_obj_list.append(datastore_obj)\n\n            if self.module.check_mode:\n                changed_list = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = temp_result['previous_datastores'].extend(changed_list)\n                temp_result['changed_datastores'] = changed_list\n                results['changed'] = len(datastore_obj_list) > 0\n                results['datastore_cluster_info'] = temp_result\n                self.module.exit_json(**results)\n\n            try:\n                if datastore_obj_list:\n                    task = self.datastore_cluster_obj.MoveIntoFolder_Task(list=datastore_obj_list)\n                    changed, result = wait_for_task(task)\n                    temp_result['msg'] = result\n                temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]\n            except TaskError as generic_exc:\n                self.module.fail_json(msg=to_native(generic_exc))\n            except Exception as task_e:\n                self.module.fail_json(msg=to_native(task_e))\n        elif state == 'absent':\n            temp_result['previous_datastores'] = [ds.name for ds in dsc_child_obj]\n            temp_result['current_datastores'] = [ds.name for ds in dsc_child_obj]\n            for datastore_name in datastores:\n                datastore_obj = self.find_datastore_by_name(datastore_name)\n                if not datastore_obj:\n                    self.module.fail_json(msg=\"Failed to find datastore '%s'\" % datastore_name)\n                if datastore_obj in dsc_child_obj and datastore_obj not in datastore_obj_list:\n                    datastore_obj_list.append(datastore_obj)\n\n            if self.module.check_mode:\n                changed_list = [ds.name for ds in datastore_obj_list]\n                for ds in changed_list:\n                    temp_result['current_datastores'].pop(ds)\n                temp_result['changed_datastores'] = changed_list\n                results['changed'] = len(datastore_obj_list) > 0\n                results['datastore_cluster_info'] = temp_result\n                self.module.exit_json(**results)\n\n            try:\n                if datastore_obj_list:\n                    task = self.folder_obj.MoveIntoFolder_Task(list=datastore_obj_list)\n                    changed, result = wait_for_task(task)\n                    temp_result['msg'] = result\n                temp_result['changed_datastores'] = [ds.name for ds in datastore_obj_list]\n                temp_result['current_datastores'] = [ds.name for ds in self.get_datastore_cluster_children()]\n            except TaskError as generic_exc:\n                self.module.fail_json(msg=to_native(generic_exc))\n            except Exception as task_e:\n                self.module.fail_json(msg=to_native(task_e))\n\n        results['changed'] = changed\n        results['datastore_cluster_info'] = temp_result\n        self.module.exit_json(**results)\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(\n        dict(\n            datacenter_name=dict(type='str', required=False, aliases=['datacenter']),\n            datastore_cluster_name=dict(type='str', required=True, aliases=['datastore_cluster']),\n            state=dict(default='present', choices=['present', 'absent'], type='str'),\n            datastores=dict(type='list', required=True, elements='str'),\n        )\n    )\n    module = AnsibleModule(\n        argument_spec=argument_spec,\n        supports_check_mode=True,\n    )\n\n    datastore_cluster_mgr = VMwareDatastoreClusterManager(module)\n    datastore_cluster_mgr.ensure()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/vmware_datastore_cluster_manager.py"}]}