【问题标题】:Get a filtered list of vCenter VMs using the REST API and Python?使用 REST API 和 Python 获取经过筛选的 vCenter VM 列表?
【发布时间】:2021-04-25 00:26:52
【问题描述】:

我需要获取基于通配符的 VMware vCenter VM 列表。从我一直在阅读的内容来看,vCenter 不支持通配符。我无法提取完整的 VM 列表,因为我的环境中有超过一千个 VM。

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

请原谅我的代码,我是 Python 新手,我正在尝试找出 API。我是一名操作系统工程师,但我想在编程方面做得更好。 :) 这是我到目前为止 think 工作的代码。有一些打印语句可以在程序运行时转储数据,以便我可以看到 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}')

【问题讨论】:

    标签: python vmware vcenter


    【解决方案1】:

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

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

    【讨论】:

    • 我正在努力的目标实际上是一个服务器部署脚本,我希望该脚本能够找到下一个我可以使用的 VM 名称。我们使用非常标准的命名约定,因此人类很容易确定下一个 VM 名称。令人沮丧的是,vCenter 的 API 无法为 VM 名称提供简单的过滤器。
    【解决方案2】:

    无法按通配符过滤。您可以做的是下拉每个主机的所有虚拟机并从那里过滤,如下所示:

    import requests
    import json
    
    vcenter_host = 'https://vcenter.example.com'
    session = requests.Session()
    session.post(f"{vcenter_host}/rest/com/vmware/cis/session",
                 auth=(username, password), verify=False)
    
    # Reasonable assumption you have less that 1000 hosts
    hosts =json.loads(session.get(f"{vcenter_host}/rest/vcenter/hosts").text)
    
    vms = {i['host']: session.get(f"{vcenter_host}/rest/vcenter/vm",
                                 params={'filter.hosts': i['host']})
          for i in hosts['value']}
    

    然后使用正则表达式模块和/或 jmespath 完成您的过滤器。

    【讨论】:

      猜你喜欢
      • 2023-03-15
      • 1970-01-01
      • 2021-11-28
      • 2021-08-07
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 2019-06-10
      • 2019-04-17
      相关资源
      最近更新 更多