Wednesday, May 8, 2024

Python3 used to query vCenter server v8 for virtual Machines and their provisioned CPU, Memory, Disk space and Network information.  The results are saved as CSV file.  Hopefully can help someone getting started.  Nothing complicated with the search for the bound IP address.  Since the network interfaces are stored as an array with each interface having an array of IP addresses, I settled on the first IPv4 address that is retrieved.  There may be better ways to do this such as using Powershell or other API calls.  The intent is show the possibility of using python with vCenter server.

import requests

import csv

import json

import configparser

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


def get_vm_netInterface(auth,vcip,vm):

try:

response = requests.get("https://"+vcip+"/api/vcenter/vm/"+vm+"/guest/networking/interfaces", headers={"vmware-api-session-id": auth}, verify=False)

except requests.exceptions.RequestException as Err:

raise SystemExit(Err)


if response.ok:

i = 0;

while i < len(response.json()):

if (response.json()[i]['ip']['ip_addresses']):

j = 0;

while j < len(response.json()[i]['ip']['ip_addresses']):

if "." in response.json()[i]['ip']['ip_addresses'][j]['ip_address']:

guestIP = response.json()[i]['ip']['ip_addresses'][j]['ip_address']

guestPrefix = response.json()[i]['ip']['ip_addresses'][j]['prefix_length']

message = guestIP+"/"+str(guestPrefix)

return (message)

j += 1;

i += 1;

return ("")


def get_vm_netinfo(auth,vcip,vm):

try:

response = requests.get("https://"+vcip+"/api/vcenter/vm/"+vm+"/guest/networking", headers={"vmware-api-session-id": auth}, verify=False)

except requests.exceptions.RequestException as Err:

raise SystemExit(Err)


if response.ok and 'dns' in response.json():

# print(response.json())

HostName = response.json()['dns_values']['host_name']

HostDomain = response.json()['dns_values']['domain_name']

if "." in HostName:

message = HostName.split('.')[0]+"."+HostDomain

else:

message = HostName+"."+HostDomain

return (message)

return ("")


def get_vm_config(outFile,auth,vcip,vm):

try:

response = requests.get("https://"+vcip+"/api/vcenter/vm/"+vm, headers={"vmware-api-session-id": auth}, verify=False)

except requests.exceptions.RequestException as Err:

raise SystemExit(Err)


if response.ok:

vmFQDN = ""

vmNet = ""

capB = 0

dict = response.json()['disks']


for keys,item in dict.items():

capB += dict[keys]['capacity']

Identity = response.json()['identity']['name']

cpuCount= response.json()['cpu']['count']

memGB = response.json()['memory']['size_MiB']/1024

capGB = capB / (1024 ** 3)

guestOS = response.json()['guest_OS']


if (response.json()['power_state'] == 'POWERED_ON'):

vmFQDN = get_vm_netinfo(auth,vcip,vm)

vmNet = get_vm_netInterface(auth,vcip,vm)

else:

raise Exception ("Unable to retrieve VM config.")


with open(outFile, 'a', newline='') as file:

writer = csv.writer(file, quoting=csv.QUOTE_NONNUMERIC)

writer.writerow([Identity,vcip,str(int(memGB))+" GB",cpuCount,str(int(capGB))+" GB",vmFQDN,vmNet,guestOS])


def list_vm_names(outFile,auth,vcip,jsonData):

x = 0;

while x < len(jsonData):

# print (jsonData[x])

get_vm_config(outFile,auth,vcip,jsonData[x]['vm'])

x += 1;


def get_vms(auth,vcip):

try:

response = requests.get("https://"+vcip+"/api/vcenter/vm", headers={"vmware-api-session-id": auth}, verify=False)

except requests.exceptions.RequestException as Err:

raise SystemExit(Err)


if response.ok:

return response.json()


# Get the vCenter server session

def get_vc_session(vcip,username,password):

try:

response = requests.post("https://"+vcip+"/api/session", auth=(username, password), verify=False)

except requests.exceptions.RequestException as Err:

raise SystemExit(Err)


if response.ok:

return response.json()


def main():

outFile = 'Inventory.csv'

f = open(outFile,"w")

f.close()

#Read Config parameters

config = configparser.ConfigParser()

config.read('config.ini')


usrName = config['vCenter']['usrName']

usrPass = config['vCenter']['usrPass']

srvName = config['vCenter']['srvName']


vcList = srvName.split(',')

for vcServ in vcList:

auth=get_vc_session(vcServ,usrName,usrPass)

vmList=get_vms(auth,vcServ)

list_vm_names(outFile,auth,vcServ,vmList)


# Script Starts Here

if __name__ == "__main__":

main()

     


I use configparser to store credentials and other variables.  Here is an example of the config.ini file referenced in the script:

[vCenter]
srvName=VCserverName1,VCserverName2,VCserverName3
usrName=vcenter-user-name
usrPass=vcenter-user-password

Saturday, May 30, 2020

vRealize Operations API and Identity Manager Authentication

My vRealize Operations' posts prior to this one, have  shown local user authentication.  This post will demonstrate how to use VMware Identity Manager within a Python script that authenticates to vRealize Operations.

I'm going to assume that vIDM is already running and configured within vRealize Operations.  If you view the authentication sources in vRealize Operations, at a minimum you should see something like the following if vIDM is configured:



In the screen capture above, the 'Source Display Name' will be used during the authentication configuration later.

In the script below, I'm using configparser to read a file named 'config.ini'.  In the example below, I'm showing the local authentication as well as the vIDM authentication.  The local stuff is commented out.  For the vIDM user, I could have combined the user name and user domain into a single parameter.  I opted to leave them separated here and combine them in the Python script.

<--- Begin config.ini --->


[vrops user]

#usrName=vrops-adm

#usrPass=adminpassword

#authSource=Local

usrName=idm-user

usrPass=idm-user-password

authSource=VM-IDM

usrDomain=thewhiteshouse.net


[vrops server]

srvName=vm-vrops.thewhiteshouse.net

<--- End config.ini --->

For my environment, I'm only considering a local authentication or a vIDM authentication.  For vIDM, I need to use the 'Source Display Name' that we viewed in the screen capture above.  Now that we have the necessary parameters in the config.ini, we can look at the authentication process in the script.  

In the 'Authenticate' routine below, I grab the server name, user name, password and authentication source from the INI file.  If the authentication source is not 'Local', I grab the domain parameter and append that to the user name.  I can now acquire the token and run the rest of the script.

The script results are basic.  It will show the authenticated user's permissions and the configured authentication sources in vROps.  I show the results of the script at the bottom of this blog.

Here is the script:

<--- Begin opstest.py --->

#!/usr/bin/python3


#imports

import getopt, sys, json, requests, configparser

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


def Authenticate():

# Read Config parameters

config = configparser.ConfigParser()

config.read('config.ini')


#Your vROps environment parameters

srvName = config['vrops server']['srvName']

usrName = config['vrops user']['usrName']

usrPass = config['vrops user']['usrPass']

authSource = config['vrops user']['authSource']


if authSource.lower() != "local":

usrDom = config['vrops user']['usrDomain']

usrName = usrName+"@"+usrDom


global baseURL

baseURL = "https://" + srvName


apiURL = baseURL + "/suite-api/api/auth/token/acquire"

apiData = {"username": usrName,"authSource": authSource,"password": usrPass,"others": [],"otherAttributes": {}}

apiHeaders = {"Content-Type":"application/json","Accept":"application/json"}

apiReq = requests.post(apiURL,data=json.dumps(apiData),headers=apiHeaders,verify=False)

if (apiReq.status_code != 200):

print('probably invalid credentials')

print('Returned Status Code: ' + str(apiReq.status_code))

sys.exit(2)

else:

token = "vRealizeOpsToken " + apiReq.json()['token']

return token


# Get Current Users Permissions

def GetPermissions(token):

apiURL = baseURL + "/suite-api/api/auth/currentuser/permissions"

apiHeaders = {"Content-Type":"application/json","Authorization":token,"Accept":"application/json"}

apiReq = requests.get(apiURL,headers=apiHeaders,verify=False)

# print(json.dumps(apiReq.json(),indent=4))

print("Current User Permissions:")

for x in range(len(apiReq.json()['permissions'])):

print(" Role Name: "+apiReq.json()['permissions'][x]['roleName'])

print(" Allow All Objects: "+str(apiReq.json()['permissions'][x]['allowAllObjects']))


# Get Auth Sources

def GetAuthSources(token):

apiURL = baseURL + "/suite-api/api/auth/sources"

apiHeaders = {"Content-Type":"application/json","Authorization":token,"Accept":"application/json"}

apiReq = requests.get(apiURL,headers=apiHeaders,verify=False)

# print(json.dumps(apiReq.json(),indent=4))

if (apiReq.status_code == 200):

for x in range(len(apiReq.json()['sources'])):

msg = "\nAuthorization Source: "+ str(x+1)

msg += "\n\tname: "+apiReq.json()['sources'][x]['name']

msg += "\n\tid: "+apiReq.json()['sources'][x]['id']

msg += "\n\tsource type name: "+apiReq.json()['sources'][x]['sourceType']['name']

print(msg)

GetAuthSourcesType(token, apiReq.json()['sources'][x]['id'])


# Get Auth Source Type

def GetAuthSourcesType(token, id):

apiURL = baseURL + "/suite-api/api/auth/sources/"+id

apiHeaders = {"Content-Type":"application/json","Authorization":token,"Accept":"application/json"}

apiReq = requests.get(apiURL,headers=apiHeaders,verify=False)

# print(json.dumps(apiReq.json(),indent=4))

if (apiReq.status_code == 200):

msg = " Propterties about the source:"

# msg += "\n\t\tid: "+apiReq.json()['id']

# msg += "\n\t\tname: "+apiReq.json()['name']

for x in range(len(apiReq.json()['property'])):

if 'value' in apiReq.json()['property'][x]:

msg += "\n\t\tprop: "+apiReq.json()['property'][x]['name']

msg += "\n\t\tvalue: "+apiReq.json()['property'][x]['value']

else:

msg += "\n\t\tprop: "+apiReq.json()['property'][x]['name']

msg += "\n\t\tvalue: "


print(msg)


def Logout(token):

releaseURL = baseURL + "/suite-api/api/auth/token/release"

apiHeaders = {"Content-Type":"application/json","Authorization":token,"Accept":"application/json"}

authResponse = requests.post(releaseURL,headers=apiHeaders,verify=False)


def main():

token = Authenticate()

GetPermissions(token)

GetAuthSources(token)

Logout(token)


if __name__ == "__main__":

main()


<--- End opstest.py --->


These are the results of the script above:

<--- Script Results --->

jwhite@vm-linux:~/bin$ ./opstest.py 

Current User Permissions:

Role Name: Administrator

Allow All Objects: True


Authorization Source: 1

name: All vCenter Servers

id: d082d766-b28b-43e9-85cf-030ff82dcff1

source type name: VC_GROUP

Propterties about the source:


Authorization Source: 2

name: VM-IDM

id: acca9a62-4869-4404-b8b7-3a702a63df3f

source type name: VIDM

Propterties about the source:

prop: redirect-host

value: https://vm-idm.thewhiteshouse.net/ui/vidmClient/vidm/

prop: display-name

value: VM-IDM

prop: port

value: 443

prop: host

value: vm-idm.thewhiteshouse.net

prop: tenant

value: default-tenant

prop: certificate-thumprint

value: 7007a6e4811bbc4657846fe9b6c2f56193a76f25


Authorization Source: 3

name: vCenter

id: 894a97aa-c2b7-4022-8e87-298b952f6afa

source type name: VC

Propterties about the source:

prop: vc-guid

value: 335c8073-3c15-48ae-b291-0c29af38f896


Thanks for taking a look at this blog.