· 5 years ago · Jun 08, 2020, 08:12 PM
1#!/usr/bin/env python
2# -----------------------------------------------------------------------------
3# Archive: script_integracao_vmware.py
4# Function: Collect your host information from VMware API with this custom script.
5#
6# Autor: Lucas Afonso Kremer
7#
8#
9# Review: June/2020
10# Reviwed by: Lucas Afonso Kremer
11# -----------------------------------------------------------------------------
12# Versions:
13# 1.0 - Collect VMware information for AWX inventories
14#
15# Examples:
16# Run: python script_integracao_vmware.py or python3 script_integracao_vmware.py
17#
18# Required:
19# - Lib:
20# pyVmomi
21#
22# - ENVIROMENT Variables:
23# VMWARE_USERNAME
24# VMWARE_PASSWORD
25# VMWARE_SERVER
26# VMWARE_VALIDATE_CERTS (true or false)
27#
28# Additional Information (base script from AWX):
29# https://github.com/ansible-collections/vmware/blob/master/scripts/inventory/vmware_inventory.py
30# https://github.com/ansible-collections/vmware/blob/master/scripts/inventory/vmware_inventory.ini
31#
32# -----------------------------------------------------------------------------
33import os
34import json
35import ssl
36
37from pyVmomi import vim
38from pyVim.connect import SmartConnect, Disconnect
39
40
41def main():
42 try:
43 username = os.environ["VMWARE_USERNAME"]
44 password = os.environ["VMWARE_PASSWORD"]
45 host = os.environ["VMWARE_SERVER"]
46 except KeyError as error:
47 raise KeyError("Environment variables VMWARE_USERNAME, VMWARE_PASSWORD, and VMWARE_SERVER required") from error
48 port = int(os.environ.get("VMWARE_PORT", "443"))
49 validate = os.environ.get("VMWARE_VALIDATE_CERTS", "True").lower()
50
51 ssl_context = None
52 if validate in ["false", "f", "no", "0"]:
53 ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
54 ssl_context.verify_mode = ssl.CERT_NONE
55
56 si = SmartConnect(host=host, user=username, pwd=password, port=port, sslContext=ssl_context)
57
58 ca_group_name_template = "vmware_tag_{key}_{value}"
59
60 # Build a lookup table for custom attributes to go from id to name
61 ca_lookup = {}
62 for field in si.content.customFieldsManager.field:
63 ca_lookup[field.key] = field.name
64
65 inventory = {
66 "all": {
67 "hosts": []
68 },
69 "_meta": {
70 "hostvars": {}
71 }
72 }
73
74 # Load all data recursively from the root folder, limiting to only vim.VirtualMachine objects
75 container = si.content.rootFolder
76 view_type = [vim.VirtualMachine]
77 recursive = True
78 container_view = si.content.viewManager.CreateContainerView(container, view_type, recursive)
79 children = container_view.view
80
81 # For each VM discovered
82 for child in children:
83 # Templates appear as VirtualMachines to the API, ignore them
84 if child.summary.config.template:
85 continue
86
87 # Read the .ini on top of this script for more details
88 # To pull the VM name: child.summary.config.name
89 # To pull the VM IP: child.summary.guest.ipAddress
90 name = child.summary.config.name
91 ip = child.summary.guest.ipAddress
92
93 # It would be better to use something like IP address, but I am not sure how reliable ESXi is at getting that
94 # when VMWare tools is not installed.
95 hostvars = {
96 "ansible_host": name,
97 "ansible_host_ssh": ip,
98 "custom_attributes": {}
99 }
100
101 # Go through the VM's custom attributes, add them to the hostvars and to the appropriate group
102 for value in child.summary.customValue:
103 ca_key = ca_lookup[value.key]
104 ca_value = value.value
105 hostvars["custom_attributes"][ca_key] = ca_value
106
107 # Generate the target group name
108 ca_group_name = ca_group_name_template.format(key=ca_key, value=ca_value)
109 # Check that the group name exists and create it if it doesn't
110 if ca_group_name not in inventory:
111 inventory[ca_group_name] = {
112 "hosts": []
113 }
114 inventory[ca_group_name]["hosts"].append(name)
115
116 inventory["_meta"]["hostvars"][name] = hostvars
117 inventory["all"]["hosts"].append(name)
118
119 print(json.dumps(inventory))
120
121
122if __name__ == "__main__":
123 main()