-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvmware.py
executable file
·405 lines (315 loc) · 12.9 KB
/
vmware.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# coding=utf-8
import atexit
import json
import ssl
import psycopg2
import sys
from pyVim import connect
from pyVmomi import vmodl
from pyVmomi import vim
from config import VMWARE_HOST, VMWARE_HOST_DESA, VMWARE_HOST_PROD, VMWARE_USER, VMWARE_PASS, VMWARE_DISABLE_SSL
from config import PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB
#==== print_size ===============================================================
# http://stackoverflow.com/questions/1094841/
def print_size(num):
"""
Returns the human readable version of a size in bytes
:param num:
:return:
"""
for item in ['bytes', 'KB', 'MB', 'GB']:
if num < 1024.0:
return "%3.1f %s" % (num, item)
num /= 1024.0
return "%.1f %s" % (num, 'TB')
#==== list_datastore_space =====================================================
def list_datastore_space():
"""
List all datastores and their free space
"""
sslContext = None
if VMWARE_DISABLE_SSL:
sslContext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
sslContext.verify_mode = ssl.CERT_NONE
try:
service_instance = connect.SmartConnect(host=VMWARE_HOST,
user=VMWARE_USER,
pwd=VMWARE_PASS,
sslContext=sslContext)
if not service_instance:
print("Could not connect to the specified host using specified "
"username and password")
return -1
atexit.register(connect.Disconnect, service_instance)
content = service_instance.RetrieveContent()
# Search for all Datastores
objview = content.viewManager.CreateContainerView(content.rootFolder,
[vim.Datastore],
True)
datastores = objview.view
objview.Destroy()
datastore_space = {}
for datastore in datastores:
capacity = datastore.summary.capacity
freeSpace = datastore.summary.freeSpace
datastore_details = {
'capacity': print_size(capacity),
'free': print_size(freeSpace),
'used': print_size(capacity-freeSpace),
'pfree': "%2.2f" % (freeSpace*100.0/capacity)
}
datastore_space[datastore.summary.name] = datastore_details
return datastore_space
except vmodl.MethodFault as error:
print("Caught vmodl fault : " + error.msg)
return -1
#==== last_inserted_datastore_space ============================================
def last_inserted_datastore_space():
# Retorna la última muestra insertada en la tabla "datastore_space"
datastore_space = ""
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Select the last inserted row
sqlquery = "select fecha, jdata from datastore_space where id=(select max(id) from datastore_space);"
cur.execute(sqlquery)
# Query the database and obtain data as Python objects
row = cur.fetchone()
# Close communication with the database
cur.close()
conn.close()
# Recover JSON data from Python object
datastore_space = row[1]
# Add date from row inside JSON response
datastore_space['fecha'] = row[0].strftime("%Y-%m-%d %H:%M:%S")
except:
print("Database error")
return "Database error"
return datastore_space
#==== update_datastore_space ===================================================
def update_datastore_space():
# Obtener el uso actual en formato JSON
datastore_space = json.dumps(list_datastore_space())
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Insert a new row
sqlquery = "insert into datastore_space (fecha, jdata) values (current_timestamp, '%s');" % datastore_space
cur.execute(sqlquery)
# Make the changes to the database persistent
conn.commit()
# Close communication with the database
cur.close()
conn.close()
except:
print(sys.exc_info())
return "Database error"
return "Ok"
#==== report_datastore_space ===================================================
def report_datastore_space(ds):
# Retorna las últimas muestras insertadas en la tabla "datastore_space" para un datastore
datastore_space = []
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Select the last inserted row
sqlquery = "select fecha,jdata->'%s'->'capacity',jdata->'%s'->'pfree' from datastore_space;" % (ds, ds)
cur.execute(sqlquery)
# Query the database and obtain data as Python objects
rows = cur.fetchall()
# Convert datetime to string
datastore_space = [(row[0].strftime("%d/%m/%Y"), row[1], row[2]) for row in rows]
# Close communication with the database
cur.close()
conn.close()
except:
print("Database error")
return "Database error"
# Return data in JSON format
return json.dumps(datastore_space)
#==== vm_datastore_usage =======================================================
def vm_datastore_usage():
"""
List datastore usage for each virtual machine
"""
sslContext = None
datastores = {}
if VMWARE_DISABLE_SSL:
sslContext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
sslContext.verify_mode = ssl.CERT_NONE
# Desarrollo
try:
service_instance = connect.SmartConnect(host=VMWARE_HOST_DESA,
user=VMWARE_USER,
pwd=VMWARE_PASS,
sslContext=sslContext)
if not service_instance:
print("Could not connect to the specified host using specified "
"username and password")
return -1
atexit.register(connect.Disconnect, service_instance)
content = service_instance.RetrieveContent()
# Search for all VirtualMachines
objview = content.viewManager.CreateContainerView(content.rootFolder,
[vim.VirtualMachine],
True)
vms = objview.view
objview.Destroy()
for vm in vms:
vm_name = vm.config.name
if vm.runtime.powerState == vim.VirtualMachine.PowerState.poweredOn:
# Sólo recuperar datos de máquinas encendidas
for ds in vm.storage.perDatastoreUsage:
ds_name = ds.datastore.info.name
if not ds_name in datastores:
# Crear un diccionario vacío si es la primera entrada
datastores[ds_name] = {}
if not vm_name in datastores[ds_name]:
# Crear un diccionario vacío si es la primera entrada
datastores[ds_name][vm_name] = {}
datastores[ds_name][vm_name]['committed'] = ds.committed
datastores[ds_name][vm_name]['uncommitted'] = ds.uncommitted
except vmodl.MethodFault as error:
print("Caught vmodl fault : " + error.msg)
return -1
# Producción
try:
service_instance = connect.SmartConnect(host=VMWARE_HOST_PROD,
user=VMWARE_USER,
pwd=VMWARE_PASS,
sslContext=sslContext)
if not service_instance:
print("Could not connect to the specified host using specified "
"username and password")
return -1
atexit.register(connect.Disconnect, service_instance)
content = service_instance.RetrieveContent()
# Search for all VirtualMachines
objview = content.viewManager.CreateContainerView(content.rootFolder,
[vim.VirtualMachine],
True)
vms = objview.view
objview.Destroy()
for vm in vms:
vm_name = vm.config.name
if vm.runtime.powerState == vim.VirtualMachine.PowerState.poweredOn:
# Sólo recuperar datos de máquinas encendidas
for ds in vm.storage.perDatastoreUsage:
ds_name = ds.datastore.info.name
if not ds_name in datastores:
# Crear un diccionario vacío si es la primera entrada
datastores[ds_name] = {}
if not vm_name in datastores[ds_name]:
# Crear un diccionario vacío si es la primera entrada
datastores[ds_name][vm_name] = {}
datastores[ds_name][vm_name]['committed'] = ds.committed
datastores[ds_name][vm_name]['uncommitted'] = ds.uncommitted
except vmodl.MethodFault as error:
print("Caught vmodl fault : " + error.msg)
return -1
return datastores
#==== update_vm_datastore_usage ================================================
def update_vm_datastore_usage():
# Obtener el uso actual en formato JSON
datastore_usage = json.dumps(vm_datastore_usage())
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Insert a new row
sqlquery = "insert into datastore_usage (fecha, jdata) values (current_timestamp, '%s');" % datastore_usage
cur.execute(sqlquery)
# Make the changes to the database persistent
conn.commit()
# Close communication with the database
cur.close()
conn.close()
except:
print(sys.exc_info())
return "Database error"
return "Ok"
#==== get_last_vm_datastore_usage ==============================================
def get_last_vm_datastore_usage(vm,ds):
# Obtener uso actual (committed en bytes) de una vm en un datastore en particular
datastore_usage = ""
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Select the last inserted row
sqlquery = "select fecha, jdata->'%s'->'%s'->'committed' from datastore_usage where id=(select max(id) from datastore_usage);" % (ds, vm)
cur.execute(sqlquery)
# Query the database and obtain data as Python objects
row = cur.fetchone()
# Close communication with the database
cur.close()
conn.close()
# Recover JSON data from Python object
datastore_usage = row[1]
except:
print("Database error")
return "Database error"
return datastore_usage
#==== get_vm_datastore_usage ===================================================
def get_vm_datastore_usage(vm,ds):
# Obtener historial de uso de una vm en un datastore en particular
datastore_usage = []
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Select the last inserted row
sqlquery = "select fecha, jdata->'%s'->'%s'->'committed' from datastore_usage;" % (ds, vm)
cur.execute(sqlquery)
# Query the database and obtain data as Python objects
rows = cur.fetchall()
# Convert datetime to string
datastore_usage = [(row[0].strftime("%d/%m/%Y"), row[1]) for row in rows]
# Close communication with the database
cur.close()
conn.close()
except:
print("Database error")
return "Database error"
return json.dumps(datastore_usage)
#==== get_datastore_usage ======================================================
def get_datastore_usage(ds):
# Obtener uso actual de un datastore por cada máquina virtual
datastore_usage = ""
try:
# Connect to the database
connstr = "host=%s port=%s user=%s password=%s dbname=%s" % (PSQL_HOST, PSQL_PORT, PSQL_USER, PSQL_PASS, PSQL_DB)
conn = psycopg2.connect(connstr)
# Open a cursor to perform database operations
cur = conn.cursor()
# Select the last inserted row
sqlquery = "select fecha, jdata->'%s' from datastore_usage where id=(select max(id) from datastore_usage);" % ds
cur.execute(sqlquery)
# Query the database and obtain data as Python objects
row = cur.fetchone()
# Recover JSON data from Python object
datastore_usage = row[1]
# Add date from row inside JSON response
datastore_usage['fecha'] = row[0].strftime("%Y-%m-%d %H:%M:%S")
# Close communication with the database
cur.close()
conn.close()
except:
print("Database error")
return "Database error"
return json.dumps(datastore_usage)