· 4 years ago · Mar 19, 2021, 08:06 PM
1# noinspection PyUnresolvedReferences
2from pyVmomi import vim
3from pyVim.connect import SmartConnect, Disconnect
4import ssl
5import sys
6import requests
7import json
8import base64
9import urllib3
10import psycopg2
11
12urllib3.disable_warnings()
13nsxIp = 'https://mia-m01-nsx01.mcgautomation.com'
14
15
16# "Windows2016-Training002"
17def main():
18 ssl._create_default_https_context = ssl._create_unverified_context
19 create_tables()
20
21 userPass = 'admin' + ':' + 'c@F2021ICG!!'
22 credBytes = userPass.encode('ascii')
23 encodedAuth64 = base64.b64encode(credBytes)
24 encodedAuth64String = str(encodedAuth64, 'ascii')
25
26 try:
27 # server = SmartConnect(host=vCenterIp, user=vUser, pwd=vPassword)
28 server = SmartConnect(host='vcf.mcgautomation.com', user='administrator@vsphere.local', pwd='c@F2021ICG!!')
29 print("connected!")
30 except Exception as e:
31 sys.exit(e)
32
33 vCenterAPI_VM = uploadVMs(server.content, [vim.VirtualMachine], "CentOS7-Training001")
34
35 if vCenterAPI_VM is not None:
36
37 vmNetwork = vCenterAPI_VM.network[0].name
38 print("vCenter RESULTS")
39 print("----------------------------------------------------------------------------------------------------")
40 print("Virtual Machine: ")
41 print(vCenterAPI_VM.name)
42 print("Network: " + vmNetwork)
43 else:
44 print("VM NOT FOUND OR IS INVALID.")
45
46 # uploadServices(encodedAuth64String)
47 updateServicesForVM(encodedAuth64String)
48 updateVMsinDB(server.content)
49 updateServiceInDB(encodedAuth64String)
50
51
52# CREATE TABLES FOR DATABASE
53def create_tables():
54 commands = (
55 """
56 CREATE TABLE IF NOT EXISTS outboundPorts (
57 port_number VARCHAR(255) NOT NULL,
58 service_name VARCHAR(255) NOT NULL,
59 vm_name VARCHAR(255) NOT NULL
60 )
61 """,
62 """
63 CREATE TABLE IF NOT EXISTS service(
64 name VARCHAR(255) PRIMARY KEY NOT NULL,
65 ports VARCHAR(255) NOT NULL,
66 id VARCHAR(255) NOT NULL,
67 unique_id VARCHAR(255),
68 active BOOLEAN NOT NULL
69 )
70 """,
71 """
72 CREATE TABLE IF NOT EXISTS VM(
73 name VARCHAR(255) PRIMARY KEY,
74 active BOOLEAN NOT NULL,
75 service_id text
76 )
77 """
78 )
79
80 try:
81 # connect to the PostgreSQL server
82 print('Connecting to the PostgreSQL database...')
83 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
84
85 cur = conn.cursor()
86 # create table
87 for command in commands:
88 cur.execute(command)
89 # close communication with the PostgreSQL database server
90 cur.close()
91 # commit the changes
92 conn.commit()
93
94 conn.close()
95 except (Exception, psycopg2.DatabaseError) as error:
96 print(error)
97
98
99def addToVMObj(auth, rule, vmsObj, policy, servicesMaster):
100 for scope in rule['scope']:
101 if scope != "ANY":
102 groupName = scope.split('/')[-1]
103 groupVms = nsxApiCaller(
104 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
105 auth)
106 for vm in groupVms:
107 if vm['display_name'] not in vmsObj.keys():
108 vmsObj[vm['display_name']] = servicesMaster
109 else:
110 for service in list(servicesMaster):
111 if service not in vmsObj[vm['display_name']]:
112 vmsObj[vm['display_name']].append(service)
113
114 if 'RULES DISABLED' in vmsObj[vm['display_name']]:
115 vmsObj[vm['display_name']].remove('RULES DISABLED')
116
117 else:
118 for scopeP in policy['scope']:
119 groupName = scopeP.split('/')[-1]
120 groupVms = nsxApiCaller(
121 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
122 auth)
123
124 for vm in groupVms:
125 if vm['display_name'] not in vmsObj.keys():
126 vmsObj[vm['display_name']] = servicesMaster
127 else:
128 for service in list(servicesMaster):
129 if service not in vmsObj[vm['display_name']]:
130 vmsObj[vm['display_name']].append(service)
131
132 if 'RULES DISABLED' in vmsObj[vm['display_name']]:
133 vmsObj[vm['display_name']].remove('RULES DISABLED')
134 return vmsObj
135
136
137def removeFromVMObj(auth, rule, vmsObj, policy, servicesMaster):
138 for scope in rule['scope']:
139 if scope != "ANY":
140 groupName = scope.split('/')[-1]
141 groupVms = nsxApiCaller(
142 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
143 auth)
144 for vm in groupVms:
145 if vm['display_name'] in vmsObj.keys():
146 for service in list(servicesMaster):
147 if service not in vmsObj[vm['display_name']]:
148 vmsObj[vm['display_name']].remove(service)
149 else:
150 for scopeP in policy['scope']:
151 groupName = scopeP.split('/')[-1]
152 groupVms = nsxApiCaller(
153 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
154 auth)
155
156 for vm in groupVms:
157 if vm['display_name'] in vmsObj.keys():
158 for service in list(servicesMaster):
159 if service in vmsObj[vm['display_name']]:
160 vmsObj[vm['display_name']].remove(service)
161
162 return vmsObj
163
164
165def updateServicesForVM(auth):
166 vmsObj = {}
167 if auth is not None:
168 # Get policies for east-west firewall
169 policies = nsxApiCaller('/policy/api/v1/infra/domains/default/security-policies', auth)
170 # Get groups from API
171 groups = nsxApiCaller('/policy/api/v1/infra/domains/default/groups', auth)
172 try:
173
174 # Cross reference the policy with the groups that the vm is a part of and then grab 'services' and rules
175
176 for policy in policies:
177 rules = nsxApiCaller(
178 '/policy/api/v1/infra/domains/default/security-policies/' + policy['id'] + '/rules', auth)
179
180 if policy['scope'][0] != 'ANY':
181 for rule in rules:
182 servicesMaster = []
183 if rule['action'] == 'ALLOW' and rule['disabled'] is False:
184 services = rule['services']
185 for service in services: servicesMaster.append(service.split('/')[-1])
186 vmsObj = addToVMObj(auth, rule, vmsObj, policy, servicesMaster)
187 elif rule['disabled'] is False:
188 services = rule['services']
189 for service in services: servicesMaster.append(service.split('/')[-1])
190 vmsObj = removeFromVMObj(auth, rule, vmsObj, policy, servicesMaster)
191 elif rule['disabled'] is True:
192 servicesMaster = ['RULES DISABLED']
193 for scope in rule['scope']:
194 if scope != "ANY":
195 groupName = scope.split('/')[-1]
196 groupVms = nsxApiCaller(
197 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
198 auth)
199 for vm in groupVms:
200 if vm['display_name'] not in vmsObj.keys():
201 vmsObj[vm['display_name']] = servicesMaster
202
203 else:
204 for scopeP in policy['scope']:
205 groupName = scopeP.split('/')[-1]
206 groupVms = nsxApiCaller(
207 '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
208 auth)
209
210 for vm in groupVms:
211 if vm['display_name'] not in vmsObj.keys():
212 vmsObj[vm['display_name']] = servicesMaster
213
214 print(vmsObj)
215 print(servicesMaster)
216
217
218 vmsFromDB = getVmsFromDBSQL()
219 for vm in vmsFromDB:
220 if vm[0] not in vmsObj.keys():
221 vmsObj[vm[0]] = ['NO SERVICES']
222 for k, v in vmsObj.items():
223 updateDBServicesForVMSQL(' '.join(v), k)
224 except Exception as e:
225 return e
226
227
228# def updateServicesForVM(auth):
229# if auth is not None:
230# # Get policies for east-west firewall
231# policies = nsxApiCaller('/policy/api/v1/infra/domains/default/security-policies', auth)
232# # Get groups from API
233# groups = nsxApiCaller('/policy/api/v1/infra/domains/default/groups', auth)
234#
235# try:
236#
237# # Cross reference the policy with the groups that the vm is a part of and then grab 'services' and rules
238#
239# for policy in policies:
240# rules = nsxApiCaller(
241# '/policy/api/v1/infra/domains/default/security-policies/' + policy['id'] + '/rules', auth)
242#
243# for scope in policy['scope']:
244# if scope != "ANY":
245# groupName = scope.split('/')[-1]
246# groupVms = nsxApiCaller(
247# '/policy/api/v1/infra/domains/default/groups/' + groupName + '/members/virtual-machines',
248# auth)
249#
250# for rule in rules:
251# if rule['action'] == 'ALLOW':
252# services = rule['services']
253#
254# serviceNames = []
255# for vm in groupVms:
256# servicesFromDB = getServicesForVMSQL(vm['display_name'])[0]
257#
258# for service in services:
259# serviceNames.append(service.split('/')[-1])
260#
261# for name in list(serviceNames):
262# if name in servicesFromDB:
263# serviceNames.remove(name)
264# updateDBServicesForVMSQL(servicesFromDB + " " + ' '.join(serviceNames),
265# vm['display_name'])
266# else:
267# services = rule['services']
268#
269# if services[0] != 'ANY':
270# for vm in groupVms:
271#
272# servicesFromDB = getServicesForVMSQL(vm['display_name'])[0].split(' ')
273# for service in services:
274# serviceName = service.split('/')[-1]
275# if serviceName in servicesFromDB:
276# servicesFromDB.remove(serviceName)
277# if ' '.join(servicesFromDB) == '':
278# updateDBServicesForVMSQL("NO OUTBOUND PORTS", vm['display_name'])
279# else:
280# updateDBServicesForVMSQL(' '.join(servicesFromDB), vm['display_name'])
281#
282#
283#
284#
285#
286# except Exception as e:
287# return e
288
289
290# INSERT NEW VM"S INTO DB
291def uploadVMs(content, vimtype, name):
292 """
293 Return an object by name, if name is None the
294 first found object is returned
295 """
296 obj = None
297 container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
298
299 for c in container.view:
300 if c.runtime.powerState == 'poweredOn':
301 insertVMInDBSQL(c.name, True, "")
302 else:
303 insertVMInDBSQL(c.name, False, "")
304 if name:
305 if c.name == name:
306 obj = c
307 else:
308 obj = c
309
310 return obj
311
312
313def updateVMsinDB(content):
314 container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
315 vmsFromDB = getVmsFromDBSQL()
316 if vmsFromDB is not None:
317 for vm in vmsFromDB:
318
319 active = False
320
321 for c in container.view:
322 if vm[0] == 'test2':
323 print("")
324
325 if vm[0] == c.name:
326 active = True
327 if c.runtime.powerState != 'poweredOn':
328 active = False
329 break
330 else:
331 active = False
332
333 updateVMStatusSQL(vm[0], active)
334
335
336def updateServiceInDB(auth):
337 servicesCurrent = nsxApiCaller('/policy/api/v1/infra/services/', auth)
338 servicesFromDB = getServicesFromDBSQL()
339
340 if servicesFromDB is not None:
341 for serviceD in servicesFromDB:
342 active = True
343 for serviceC in servicesCurrent:
344
345 if serviceD[0] == 'TEST':
346 print("ok")
347
348 if serviceD[0] == serviceC['display_name']:
349 active = True
350 break
351 else:
352 active = False
353
354 updateServiceStatusSQL(serviceD, active)
355
356
357def nsxApiCaller(endpoint, auth):
358 url = nsxIp + endpoint
359 results = requests.get(url, headers={'Authorization': 'Basic ' + auth,
360 'Content-Type': 'application/json',
361 'Accept': 'application/json'}, verify=False)
362 return results.json()['results']
363
364
365# GET SERVICES ROW VALUES FROM VM TABLE
366def getServicesForVMSQL(vm_name):
367 getServices = """ SELECT service_id FROM vm WHERE name = '""" + vm_name + "';"
368
369 try:
370 # connect to the PostgreSQL server
371 print('Connecting to the PostgreSQL database...')
372 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
373 cur = conn.cursor()
374 # insert data into table
375 cur.execute(getServices)
376 if cur.rowcount > 0:
377 return cur.fetchone()
378 # close communication with the PostgreSQL database server
379 cur.close()
380 # commit the changes
381 conn.commit()
382 conn.close()
383 except (Exception, psycopg2.DatabaseError) as error:
384 print(error)
385
386 return print("DONE")
387
388
389# SET SERVICES ROW IN VM TABLE
390def updateDBServicesForVMSQL(id, vm_name):
391 updateVmServiceID = """ UPDATE vm
392 SET service_id = %s
393 WHERE name = %s"""
394
395 try:
396 # connect to the PostgreSQL server
397 print('Connecting to the PostgreSQL database...')
398 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
399 cur = conn.cursor()
400 # insert data into table
401 cur.execute(updateVmServiceID, (id, vm_name))
402 # cur.execute(updateServices, (id, service_name))
403 # close communication with the PostgreSQL database server
404 cur.close()
405 # commit the changes
406 conn.commit()
407 conn.close()
408 except (Exception, psycopg2.DatabaseError) as error:
409 print(error)
410
411 return print("DONE")
412
413
414# GET VMS FROM DB
415def getVmsFromDBSQL():
416 getVms = """ SELECT name FROM vm """
417
418 try:
419 # connect to the PostgreSQL server
420 print('Connecting to the PostgreSQL database...')
421 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
422 cur = conn.cursor()
423 # insert data into table
424 cur.execute(getVms)
425 if cur.rowcount > 0:
426 return cur.fetchall()
427 # close communication with the PostgreSQL database server
428 cur.close()
429 # commit the changes
430 conn.commit()
431 conn.close()
432 except (Exception, psycopg2.DatabaseError) as error:
433 print(error)
434
435 return None
436
437
438# GET ALL SERVICES FROM SERVICE TABLE DB
439def getServicesFromDBSQL():
440 getVms = """ SELECT name FROM service """
441
442 try:
443 # connect to the PostgreSQL server
444 print('Connecting to the PostgreSQL database...')
445 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
446 cur = conn.cursor()
447 # insert data into table
448 cur.execute(getVms)
449 if cur.rowcount > 0:
450 return cur.fetchall()
451 # close communication with the PostgreSQL database server
452 cur.close()
453 # commit the changes
454 conn.commit()
455 conn.close()
456 except (Exception, psycopg2.DatabaseError) as error:
457 print(error)
458
459 return None
460
461
462# UPDATE SERVICES TABLE
463def uploadServices(auth):
464 services = nsxApiCaller('/policy/api/v1/infra/services/', auth)
465 print("OUTBOUND PORTS AND SERVICES")
466
467 for service in services:
468 print("````````````" + service['id'] + "``````````````````````````")
469 ports = ""
470 for serviceEntry in service["service_entries"]:
471 if "destination_ports" in serviceEntry:
472 des_ports = serviceEntry["destination_ports"]
473
474 for port in des_ports:
475 print(port)
476 ports += " " + port
477 insertServiceInDBSQL(service['display_name'], ports.strip(), service['id'], service['unique_id'], True)
478
479
480def updateVMStatusSQL(vm_name, active):
481 updateStatus = """ UPDATE vm
482 SET active = %s
483 WHERE name = %s"""
484
485 try:
486 # connect to the PostgreSQL server
487 print('Connecting to the PostgreSQL database...')
488 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
489 cur = conn.cursor()
490 # insert data into table
491 cur.execute(updateStatus, (active, vm_name))
492
493 cur.close()
494 # commit the changes
495 conn.commit()
496 conn.close()
497 except (Exception, psycopg2.DatabaseError) as error:
498 print(error)
499
500 return print("DONE")
501
502
503def updateServiceStatusSQL(service_name, active):
504 updateStatus = """ UPDATE service
505 SET active = %s
506 WHERE name = %s"""
507
508 try:
509 # connect to the PostgreSQL server
510 print('Connecting to the PostgreSQL database...')
511 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
512 cur = conn.cursor()
513 # insert data into table
514 cur.execute(updateStatus, (active, service_name))
515
516 cur.close()
517 # commit the changes
518 conn.commit()
519 conn.close()
520 except (Exception, psycopg2.DatabaseError) as error:
521 print(error)
522
523 return print("DONE")
524
525
526def insertServiceInDBSQL(name, ports, id, unique_id, active):
527 sql = """INSERT INTO service(name,ports,id,unique_id,active) VALUES(%s,%s,%s,%s,%s)"""
528
529 try:
530 # connect to the PostgreSQL server
531 print('Connecting to the PostgreSQL database...')
532 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
533
534 cur = conn.cursor()
535 # insert data into table
536 cur.execute(sql, (name, ports, id, unique_id, active))
537 # close communication with the PostgreSQL database server
538 cur.close()
539 # commit the changes
540 conn.commit()
541 conn.close()
542 except (Exception, psycopg2.DatabaseError) as error:
543 print(error)
544
545
546def insertVMInDBSQL(name, active, id):
547 sql = """INSERT INTO VM(name,active,service_id) VALUES(%s,%s,%s)"""
548
549 try:
550 # connect to the PostgreSQL server
551 print('Connecting to the PostgreSQL database...')
552 conn = psycopg2.connect("host = localhost dbname=vcf_network user=postgres password=Pshep1570144#")
553
554 cur = conn.cursor()
555 # insert data into table
556 cur.execute(sql, (name, active, id))
557 # close communication with the PostgreSQL database server
558 cur.close()
559 # commit the changes
560 conn.commit()
561 conn.close()
562 except (Exception, psycopg2.DatabaseError) as error:
563 print(error)
564
565
566# c@F2021ICG!!
567main()
568