diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 57d75deb..debab84d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -14,7 +14,7 @@ releases: release_date: '2024-05-07' 1.1.0: changes: - major_changes: + minor_changes: - Added module vm_list_group_by_clusters fragments: - 16-vm_list_group_by_clusters.yml diff --git a/changelogs/fragments/25-deprecated_module_vm_list_goup_by_clusters.yml b/changelogs/fragments/25-deprecated_module_vm_list_goup_by_clusters.yml new file mode 100644 index 00000000..ecf159d7 --- /dev/null +++ b/changelogs/fragments/25-deprecated_module_vm_list_goup_by_clusters.yml @@ -0,0 +1,2 @@ +deprecated_features: + - vm_list_group_by_clusters - deprecate the module since it was renamed to `vm_list_group_by_clusters_info` \ No newline at end of file diff --git a/meta/runtime.yml b/meta/runtime.yml index 898ad8ff..3ee095a5 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,9 @@ --- requires_ansible: '>=2.15.0' +plugin_routing: + modules: + vm_list_group_by_clusters: + redirect: vmware.vmware.vm_list_group_by_clusters_info + deprecation: + removal_version: 2.0.0 + warning_text: Use vmware.vmware.vm_list_group_by_clusters_info instead. \ No newline at end of file diff --git a/plugins/modules/_vm_list_group_by_clusters.py b/plugins/modules/_vm_list_group_by_clusters.py new file mode 100644 index 00000000..349c1aec --- /dev/null +++ b/plugins/modules/_vm_list_group_by_clusters.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2023, Ansible Cloud Team (@ansible-collections) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: vm_list_group_by_clusters +version_added: '1.1.0' +short_description: Returns information about the virtual machines grouping by clusters and folders +description: + - Returns information about the virtual machines grouping by clusters and folders. +author: + - Ansible Cloud Team (@ansible-collections) +deprecated: + removed_in: '2.0.0' + why: Was replaced with new module vm_list_group_by_clusters_info. + alternative: Use M(vm_list_group_by_clusters_info) instead. +options: + detailed_vms: + default: true + description: + - If I(true) gather detailed information about virtual machines. + type: bool +extends_documentation_fragment: +- vmware.vmware.vmware_rest_client.documentation + +''' + +EXAMPLES = r''' +- name: Gather list of VMs group by clusters and folders + vmware.vmware.vm_list_group_by_clusters: + hostname: "https://vcenter" + username: "username" + password: "password" +''' + +RETURN = r''' +vm_list_group_by_clusters: + description: + - Dictionary of vm list by folders and clusters + returned: On success + type: dict + sample: { + "cluster_name1": { + "folder1": [ + { + "advanced_settings": {}, + "annotation": "", + "current_snapshot": null, + "customvalues": {}, + "guest_consolidation_needed": false, + "guest_question": null, + "guest_tools_status": "guestToolsNotRunning", + "guest_tools_version": "10247", + "hw_cores_per_socket": 1, + "hw_datastores": [ + "ds_226_3" + ], + "hw_esxi_host": "10.76.33.226", + "hw_eth0": { + "addresstype": "assigned", + "ipaddresses": null, + "label": "Network adapter 1", + "macaddress": "00:50:56:87:a5:9a", + "macaddress_dash": "00-50-56-87-a5-9a", + "portgroup_key": null, + "portgroup_portkey": null, + "summary": "VM Network" + }, + "hw_files": [ + "[ds_226_3] ubuntu_t/ubuntu_t.vmx", + "[ds_226_3] ubuntu_t/ubuntu_t.nvram", + "[ds_226_3] ubuntu_t/ubuntu_t.vmsd", + "[ds_226_3] ubuntu_t/vmware.log", + "[ds_226_3] u0001/u0001.vmdk" + ], + "hw_folder": "/DC0/vm/Discovered virtual machine", + "hw_guest_full_name": null, + "hw_guest_ha_state": null, + "hw_guest_id": null, + "hw_interfaces": [ + "eth0" + ], + "hw_is_template": false, + "hw_memtotal_mb": 1024, + "hw_name": "ubuntu_t", + "hw_power_status": "poweredOff", + "hw_processor_count": 1, + "hw_product_uuid": "4207072c-edd8-3bd5-64dc-903fd3a0db04", + "hw_version": "vmx-13", + "instance_uuid": "5007769d-add3-1e12-f1fe-225ae2a07caf", + "ipv4": null, + "ipv6": null, + "module_hw": true, + "snapshots": [], + "tags": [ + "backup" + ], + "vnc": {}, + "moid": "vm-42", + "vimref": "vim.VirtualMachine:vm-42" + }] + } + } +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.vmware.plugins.module_utils.vmware_rest_client import VmwareRestClient + + +class VmwareVMList(VmwareRestClient): + def __init__(self, module): + super(VmwareVMList, self).__init__(module) + self.module = module + self.params = module.params + self.detailed_vms = self.params['detailed_vms'] + + def get_all_clusters(self): + return self.api_client.vcenter.Cluster.list() + + def get_all_folders(self): + folder_filter_spec = self.api_client.vcenter.Folder.FilterSpec( + type=self.api_client.vcenter.Folder.Type.VIRTUAL_MACHINE) + return self.api_client.vcenter.Folder.list(folder_filter_spec) + + def get_all_vms_in_cluster_and_folder(self, cluster, folder, host): + vms_filter = self.api_client.vcenter.VM.FilterSpec(clusters=set([cluster]), + folders=set([folder]), + hosts=set([host])) + + return self.api_client.vcenter.VM.list(vms_filter) + + def get_vm_detailed(self, vm): + return self.api_client.vcenter.VM.get(vm=vm) + + def get_cluster_hosts(self, cluster): + host_filter = self.api_client.vcenter.Host.FilterSpec( + clusters=set([cluster])) + return self.api_client.vcenter.Host.list(host_filter) + + def get_vm_list_group_by_clusters(self): + clusters = self.get_all_clusters() + folders = self.get_all_folders() + result_dict = {} + for cluster in clusters: + vm_list_group_by_folder_dict = {} + hosts = self.get_cluster_hosts(cluster.cluster) + for folder in folders: + vms = [] + # iterate each host due to an error too_many_matches when looking at all vms on a cluster + # https://github.com/vmware/vsphere-automation-sdk-python/issues/142 + for host in hosts: + vms.extend(self.get_all_vms_in_cluster_and_folder(cluster.cluster, folder.folder, host.host)) + vms_detailed = [] + for vm in vms: + if self.detailed_vms: + vm = self.get_vm_detailed(vm=vm.vm) + + vms_detailed.append(self._vvars(vm)) + + if vms_detailed: + vm_list_group_by_folder_dict[folder.name] = vms_detailed + + if vm_list_group_by_folder_dict: + result_dict[cluster.name] = vm_list_group_by_folder_dict + + return result_dict + + def _vvars(self, vmware_obj): + return {k: str(v) for k, v in vars(vmware_obj).items() if not k.startswith('_')} + + +def main(): + argument_spec = VmwareRestClient.vmware_client_argument_spec() + argument_spec.update( + dict( + detailed_vms=dict(type='bool', default=True), + ) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + vmware_vm_list_group_by_clusters_mgr = VmwareVMList(module) + vm_list_group_by_clusters = vmware_vm_list_group_by_clusters_mgr.get_vm_list_group_by_clusters() + module.exit_json(changed=False, vm_list_group_by_clusters=vm_list_group_by_clusters) + + +if __name__ == '__main__': + main() \ No newline at end of file