使用 REST API 和 Python 获取经过筛选的 vCenter VM 列表?

问题描述

我需要获取基于通配符的 VMware vCenter VM 列表。据我所知,vCenter 不支持通配符。我无法提取完整的 VM 列表,因为我的环境中有超过一千个 VM。

还有一个与我类似的问题,“如何在 vmware vSphere 客户端 REST API 中使用部分虚拟机名称(字符串)进行过滤?”从去年开始,但答案是一个我无法理解的 C# 程序,因为我真的不知道 C#。基本上,C# 程序直接访问 UI 中的搜索功能提取数据(太棒了!)。当作者开始使用 cookie 时,我迷失在 C# 程序中。

请原谅我的代码,我是 Python 新手,我正在尝试找出 API。我是一名操作系统工程师,但我想在编程方面变得更好。 :) 这是我目前认为正在工作的代码。有一些打印语句可以在程序运行时转储数据,以便我可以看到 API 响应:

import json
from base64 import b64encode
import base64
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
from urllib.parse import parse_qs,urlparse
from bs4 import BeautifulSoup

vcip="myvcenter.fqdn.local" # vCenter server ip address/FQDN
vcid = "testuser@testdomain" # TESTING: Username
vcpw = "SeekretPassword" # TESTING: password

def get_loginurl(vcip):
         vcurl = requests.get('https://'+vcip+'/ui/login',allow_redirects=True,verify=False)
         return vcurl.url

# Encode the username and password. 
vccred64enc = base64.urlsafe_b64encode(bytes(f'{vcid}:{vcpw}',encoding='utf-8')).decode('utf-8')
# Create the authentication header
auth_header = f'Basic {vccred64enc}'
print(auth_header)
print("="*60)

# DEBUG: display the SAML URL
vcuilogin = get_loginurl(vcip)
print(vcuilogin)
print("="*60)

# DEBUG: Authenticate to the redirected URL
saml1response = requests.post(vcuilogin,headers={"Authorization": auth_header},verify=False)
print(saml1response.url)
print("="*60)

# Castle Authorization - idk what this means
headers2 = {
      'Authorization': auth_header,'Content-type': 'application/x-www-form-urlencoded','CastleAuthorization=': auth_header
    }

# Parse the URL and then separate the query section
samlparsed = urlparse(saml1response.url)
saml_qs_parse = parse_qs(samlparsed.query)

# Convert from a list item to a single string
samlrequest = ''.join(saml_qs_parse['SAMLRequest'])
samlparams = {'SAMLRequest': samlrequest}

buildurl1 = f"https://{samlparsed.netloc}{samlparsed.path}"

response = requests.post(buildurl1,params=samlparams,headers=headers2,verify=False)

# Make some Soup so that we can find the SAMLResponse
soup = BeautifulSoup(response.text,"html.parser")
#Extract the SAMLResponse value
saml_respvalue = soup.find('input',{'name': 'SAMLResponse'})['value']

print(f'SAMLResponse: {saml_respvalue}')

解决方法

长话短说,vSphere REST API 并不真正用于服务器端搜索。然而,有一个分页功能可以让您分页浏览您拥有的 1000 多个虚拟机,然后在客户端本地过滤它们。

可能值得研究的一件事,适用于 Python 的 vSphere 自动化 SDK。您在示例代码中的操作方式没有任何问题,但 SDK 是为与适用于 vSphere 的 REST API 服务配合使用而构建的,并且在 repo 中还有一些示例代码可能对您有所帮助。