Skip to content

Instantly share code, notes, and snippets.

@Akasurde
Created March 20, 2020 07:20
Show Gist options
  • Save Akasurde/a103484d3785f00d7bb7fa60a88dc9c2 to your computer and use it in GitHub Desktop.
Save Akasurde/a103484d3785f00d7bb7fa60a88dc9c2 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, Abhijeet Kasurde <[email protected]>
# Copyright: (c) 2020, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: vmware_datacenter_info
short_description: Gather information about VMware vSphere Datacenters
description:
- This module can be used to gather information VMware vSphere Datacenters.
author:
- Abhijeet Kasurde (@Akasurde)
notes:
- Tested on vSphere 6.5
requirements:
- "python >= 2.7"
- PyVmomi
options:
datacenter:
description:
- The name of the datacenter to gather information for.
- If not provided, will gather information about all datacenters from the VMware infra.
type: str
aliases: ['datacenter_name']
schema:
description:
- Specify the output schema desired.
- The 'summary' output schema is the legacy output from the module.
- The 'vsphere' output schema is the vSphere API class definition which requires pyvmomi>6.7.1.
choices: ['summary', 'vsphere']
default: 'summary'
type: str
properties:
description:
- Specify the properties to retrieve.
- If not specified, all properties are retrieved (deeply).
- Results are returned in a structure identical to the vSphere API.
- 'Example:'
- ' properties: ['
- ' "overallStatus"'
- ' ]'
- Only valid when C(schema) is C(vsphere).
type: list
elements: str
show_tag:
description:
- Tags related to Datacenter are shown if set to C(True).
default: False
type: bool
extends_documentation_fragment:
- community.vmware.vmware.documentation
'''
EXAMPLES = r'''
- name: Gather information about all datacenters
vmware_datacenter_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
delegate_to: localhost
- name: Gather information about a particular datacenter
vmware_datacenter_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
datacenter: '{{ datacenter_name }}'
delegate_to: localhost
- name: Gather information about a particular datacenter
vmware_datacenter_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
datacenter: '{{ datacenter_name }}'
show_tag: True
delegate_to: localhost
- name: Gather vSphere schema information
vmware_datacenter_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
datacenter: '{{ datacenter_name }}'
schema: vsphere
properties:
- configStatus
- overallStatus
'''
RETURN = r"""
datacenter_info:
description: Information about datacenter
returned: always
type: list
sample:
[
{
"configStatus": "gray",
"moid": "datacenter-2",
"name": "Asia-Datacenter1"
}
]
"""
try:
from pyVmomi import vim
except ImportError:
pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
from ansible.module_utils.vmware import PyVmomi, vmware_argument_spec
from ansible.module_utils.vmware_rest_client import VmwareRestClient
class VmwareDatacenterInfo(PyVmomi):
def __init__(self, module):
super(VmwareDatacenterInfo, self).__init__(module)
if self.params.get('show_tag'):
self.vmware_client = VmwareRestClient(self.module)
def get_datacenter_info(self):
self.datacenter_name = self.params.get('datacenter')
results = dict(
changed=False,
datacenter_info=[],
)
datacenter_objs = self.get_managed_objects_properties(vim_type=vim.Datacenter, properties=['name'])
dcs = []
for dc_obj in datacenter_objs:
if len(dc_obj.propSet) == 1:
if self.datacenter_name is not None:
if dc_obj.propSet[0].val == to_native(self.datacenter_name):
dcs.append(dc_obj.obj)
continue
else:
dcs.append(dc_obj.obj)
for obj in dcs:
if obj is None:
continue
temp_dc = dict(
name=obj.name,
moid=obj._moId,
)
if self.module.params['schema'] == 'summary':
temp_dc.update(
dict(
config_status=obj.configStatus,
overall_status=obj.overallStatus,
)
)
else:
temp_dc.update(self.to_json(obj, self.params.get('properties')))
if self.params.get('show_tag'):
temp_dc.update({
'tags': self.vmware_client.get_tags_for_datacenter(datacenter_mid=obj._moId)
})
results['datacenter_info'].append(temp_dc)
self.module.exit_json(**results)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(
dict(
datacenter=dict(type='str', aliases=['datacenter_name']),
schema=dict(type='str', choices=['summary', 'vsphere'], default='summary'),
properties=dict(type='list', elements='str'),
show_tag=dict(type='bool', default=False),
)
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
)
vmware_datacenter_mgr = VmwareDatacenterInfo(module)
vmware_datacenter_mgr.get_datacenter_info()
if __name__ == '__main__':
main()
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Ansible Project
# Copyright: (c) 2018, Abhijeet Kasurde <[email protected]>
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import traceback
REQUESTS_IMP_ERR = None
try:
import requests
HAS_REQUESTS = True
except ImportError:
REQUESTS_IMP_ERR = traceback.format_exc()
HAS_REQUESTS = False
PYVMOMI_IMP_ERR = None
try:
from pyVim import connect
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
PYVMOMI_IMP_ERR = traceback.format_exc()
HAS_PYVMOMI = False
VSPHERE_IMP_ERR = None
try:
from com.vmware.vapi.std_client import DynamicID
from vmware.vapi.vsphere.client import create_vsphere_client
from com.vmware.vapi.std.errors_client import Unauthorized
from com.vmware.content.library_client import Item
from com.vmware.vcenter_client import (Folder,
Datacenter,
ResourcePool,
Datastore,
Cluster,
Host)
HAS_VSPHERE = True
except ImportError:
VSPHERE_IMP_ERR = traceback.format_exc()
HAS_VSPHERE = False
from ansible.module_utils.basic import env_fallback, missing_required_lib
class VmwareRestClient(object):
def __init__(self, module):
"""
Constructor
"""
self.module = module
self.params = module.params
self.check_required_library()
self.api_client = self.connect_to_vsphere_client()
# Helper function
def get_error_message(self, error):
"""
Helper function to show human readable error messages.
"""
err_msg = []
if not error.messages:
if isinstance(error, Unauthorized):
return "Authorization required."
return "Generic error occurred."
for err in error.messages:
err_msg.append(err.default_message % err.args)
return " ,".join(err_msg)
def check_required_library(self):
"""
Check required libraries
"""
if not HAS_REQUESTS:
self.module.fail_json(msg=missing_required_lib('requests'),
exception=REQUESTS_IMP_ERR)
if not HAS_PYVMOMI:
self.module.fail_json(msg=missing_required_lib('PyVmomi'),
exception=PYVMOMI_IMP_ERR)
if not HAS_VSPHERE:
self.module.fail_json(
msg=missing_required_lib('vSphere Automation SDK',
url='https://code.vmware.com/web/sdk/65/vsphere-automation-python'),
exception=VSPHERE_IMP_ERR)
@staticmethod
def vmware_client_argument_spec():
return dict(
hostname=dict(type='str',
fallback=(env_fallback, ['VMWARE_HOST'])),
username=dict(type='str',
fallback=(env_fallback, ['VMWARE_USER']),
aliases=['user', 'admin']),
password=dict(type='str',
fallback=(env_fallback, ['VMWARE_PASSWORD']),
aliases=['pass', 'pwd'],
no_log=True),
protocol=dict(type='str',
default='https',
choices=['https', 'http']),
validate_certs=dict(type='bool',
fallback=(env_fallback, ['VMWARE_VALIDATE_CERTS']),
default=True),
)
def connect_to_vsphere_client(self):
"""
Connect to vSphere API Client with Username and Password
"""
username = self.params.get('username')
password = self.params.get('password')
hostname = self.params.get('hostname')
session = requests.Session()
session.verify = self.params.get('validate_certs')
if not all([hostname, username, password]):
self.module.fail_json(msg="Missing one of the following : hostname, username, password."
" Please read the documentation for more information.")
client = create_vsphere_client(
server=hostname,
username=username,
password=password,
session=session)
if client is None:
self.module.fail_json(msg="Failed to login to %s" % hostname)
return client
def get_tags_for_object(self, tag_service=None, tag_assoc_svc=None, dobj=None):
"""
Return list of tag objects associated with an object
Args:
dobj: Dynamic object
tag_service: Tag service object
tag_assoc_svc: Tag Association object
Returns: List of tag objects associated with the given object
"""
# This method returns list of tag objects only,
# Please use get_tags_for_dynamic_obj for more object details
tags = []
if not dobj:
return tags
if not tag_service:
tag_service = self.api_client.tagging.Tag
if not tag_assoc_svc:
tag_assoc_svc = self.api_client.tagging.TagAssociation
tag_ids = tag_assoc_svc.list_attached_tags(dobj)
for tag_id in tag_ids:
tags.append(tag_service.get(tag_id))
return tags
def get_tags_for_dynamic_obj(self, mid=None, type=None):
"""
Return list of tag object details associated with object
Args:
mid: Dynamic object for specified object
type: Type of DynamicID to lookup
Returns: List of tag object details associated with the given object
"""
tags = []
if mid is None:
return tags
dynamic_managed_object = DynamicID(type=type, id=mid)
temp_tags_model = self.get_tags_for_object(dobj=dynamic_managed_object)
category_service = self.api_client.tagging.Category
for tag_obj in temp_tags_model:
tags.append({
'id': tag_obj.id,
'category_name': category_service.get(tag_obj.category_id).name,
'name': tag_obj.name,
'description': tag_obj.description,
'category_id': tag_obj.category_id,
})
return tags
def get_tags_for_datacenter(self, datacenter_mid=None):
return self.get_tags_for_dynamic_obj(mid=datacenter_mid, type='Datacenter')
def get_tags_for_cluster(self, cluster_mid=None):
"""
Return list of tag object associated with cluster
Args:
cluster_mid: Dynamic object for cluster
Returns: List of tag object associated with the given cluster
"""
return self.get_tags_for_dynamic_obj(mid=cluster_mid, type='ClusterComputeResource')
def get_tags_for_hostsystem(self, hostsystem_mid=None):
"""
Return list of tag object associated with host system
Args:
hostsystem_mid: Dynamic object for host system
Returns: List of tag object associated with the given host system
"""
return self.get_tags_for_dynamic_obj(mid=hostsystem_mid, type='HostSystem')
def get_tags_for_vm(self, vm_mid=None):
"""
Return list of tag object associated with virtual machine
Args:
vm_mid: Dynamic object for virtual machine
Returns: List of tag object associated with the given virtual machine
"""
return self.get_tags_for_dynamic_obj(mid=vm_mid, type='VirtualMachine')
def get_vm_tags(self, tag_service=None, tag_association_svc=None, vm_mid=None):
"""
Return list of tag name associated with virtual machine
Args:
tag_service: Tag service object
tag_association_svc: Tag association object
vm_mid: Dynamic object for virtual machine
Returns: List of tag names associated with the given virtual machine
"""
# This API returns just names of tags
# Please use get_tags_for_vm for more tag object details
tags = []
if vm_mid is None:
return tags
dynamic_managed_object = DynamicID(type='VirtualMachine', id=vm_mid)
temp_tags_model = self.get_tags_for_object(tag_service, tag_association_svc, dynamic_managed_object)
for tag_obj in temp_tags_model:
tags.append(tag_obj.name)
return tags
def get_library_item_by_name(self, name):
"""
Returns the identifier of the library item with the given name.
Args:
name (str): The name of item to look for
Returns:
str: The item ID or None if the item is not found
"""
find_spec = Item.FindSpec(name=name)
item_ids = self.api_client.content.library.Item.find(find_spec)
item_id = item_ids[0] if item_ids else None
return item_id
def get_datacenter_by_name(self, datacenter_name):
"""
Returns the identifier of a datacenter
Note: The method assumes only one datacenter with the mentioned name.
"""
filter_spec = Datacenter.FilterSpec(names=set([datacenter_name]))
datacenter_summaries = self.api_client.vcenter.Datacenter.list(filter_spec)
datacenter = datacenter_summaries[0].datacenter if len(datacenter_summaries) > 0 else None
return datacenter
def get_folder_by_name(self, datacenter_name, folder_name):
"""
Returns the identifier of a folder
with the mentioned names.
"""
datacenter = self.get_datacenter_by_name(datacenter_name)
if not datacenter:
return None
filter_spec = Folder.FilterSpec(type=Folder.Type.VIRTUAL_MACHINE,
names=set([folder_name]),
datacenters=set([datacenter]))
folder_summaries = self.api_client.vcenter.Folder.list(filter_spec)
folder = folder_summaries[0].folder if len(folder_summaries) > 0 else None
return folder
def get_resource_pool_by_name(self, datacenter_name, resourcepool_name):
"""
Returns the identifier of a resource pool
with the mentioned names.
"""
datacenter = self.get_datacenter_by_name(datacenter_name)
if not datacenter:
return None
names = set([resourcepool_name]) if resourcepool_name else None
filter_spec = ResourcePool.FilterSpec(datacenters=set([datacenter]),
names=names)
resource_pool_summaries = self.api_client.vcenter.ResourcePool.list(filter_spec)
resource_pool = resource_pool_summaries[0].resource_pool if len(resource_pool_summaries) > 0 else None
return resource_pool
def get_datastore_by_name(self, datacenter_name, datastore_name):
"""
Returns the identifier of a datastore
with the mentioned names.
"""
datacenter = self.get_datacenter_by_name(datacenter_name)
if not datacenter:
return None
names = set([datastore_name]) if datastore_name else None
filter_spec = Datastore.FilterSpec(datacenters=set([datacenter]),
names=names)
datastore_summaries = self.api_client.vcenter.Datastore.list(filter_spec)
datastore = datastore_summaries[0].datastore if len(datastore_summaries) > 0 else None
return datastore
def get_cluster_by_name(self, datacenter_name, cluster_name):
"""
Returns the identifier of a cluster
with the mentioned names.
"""
datacenter = self.get_datacenter_by_name(datacenter_name)
if not datacenter:
return None
names = set([cluster_name]) if cluster_name else None
filter_spec = Cluster.FilterSpec(datacenters=set([datacenter]),
names=names)
cluster_summaries = self.api_client.vcenter.Cluster.list(filter_spec)
cluster = cluster_summaries[0].cluster if len(cluster_summaries) > 0 else None
return cluster
def get_host_by_name(self, datacenter_name, host_name):
"""
Returns the identifier of a Host
with the mentioned names.
"""
datacenter = self.get_datacenter_by_name(datacenter_name)
if not datacenter:
return None
names = set([host_name]) if host_name else None
filter_spec = Host.FilterSpec(datacenters=set([datacenter]),
names=names)
host_summaries = self.api_client.vcenter.Host.list(filter_spec)
host = host_summaries[0].host if len(host_summaries) > 0 else None
return host
@staticmethod
def search_svc_object_by_name(service, svc_obj_name=None):
"""
Return service object by name
Args:
service: Service object
svc_obj_name: Name of service object to find
Returns: Service object if found else None
"""
if not svc_obj_name:
return None
for svc_object in service.list():
svc_obj = service.get(svc_object)
if svc_obj.name == svc_obj_name:
return svc_obj
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment