VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析

简介: 目录目录前文列表VMware vSphere Web Services APIVMware vSphere Web Services SDKvSphere WS API 中的托管对象 Managed Object托管对象引用 Managed Object ...

目录

前文列表

VMware 虚拟化编程(1) — VMDK/VDDK/VixDiskLib/VADP 概念简析
VMware 虚拟化编程(2) — 虚拟磁盘文件类型详解

VMware vSphere Web Services API

VMware vSphere Web Services API (vSphere WS API),是官方提供的 ESX/ESXi Host 和 vCenter Server 开发者接口。通过调用 vSphere WS API,开发者能够实现 vSphere Web Client 上所提供的绝大部分管理操作功能,所以熟练使用 vSphere WS API 是面向 VMware 相关编程的必备技能之一。

vSphere WS API 应用了一种基于 Web 服务的编程模型,客户端会生成 Web 服务的 WSDL 网络服务描述语言请求,然后通过 SOAP 简单对象访问协议将请求封装成 XML 格式消息,最后再发送到到服务端。而在 ESX/ESXi Host 或 vCenter Server 端中,则由 vSphere 层负责应答客户端的请求,并返回 SOAP 响应。这是区别于面向对象函数调用的一种编程模型。

VMware vSphere Web Services SDK

摘自官方文档:The VMware vSphere Management SDK is a bundle that contains a set of VMware vSphere SDKs (vSphere Web Services SDK, vSphere Storage Management SDK, vSphere ESX Agent Manager SDK, SSO Client SDK and vSphere Storage Policy SDK) The vSphere Software Development Kits provide all the documentation, libraries, and code examples needed to developers to rapidly build solutions integrated with the industry’s leading virtualization platform.

VMware vSphere Web Services SDK (vSphere WS SDK),是官方提供的标准开发工具,其中包含了 Web Services、Storage Management、ESX Agent Manager、SSO Client、Storage Policy 等多方面编程相关的文档、Lib 库以及示例代码。能够帮助开发者快速搭建 Python、Microsoft C#、Java、C/C++ 的应用端开发环境,并且这些示例代码大部分都是使用 Java 编写的,还单独提供了 JAX-WS 开发框架,可以说是很照顾 Java Developer了。不过奈何我是一位 Pythoner,所以我们后面的所有 Sample 均为 Python 实现。

VMware vSphere Web Services SDK Docs

vSphere WS API 中的托管对象 Managed Object

VMware vSphere API Reference Docs 中记录了大量的托管对象 Managed Object,这些托管对象充当着 API 信息容器的角色,开发者通过处理这些信息容器中的内容来最终实现对 vSphere 系统的操作。

这里写图片描述

每个托管对象都拥有一个唯一专属的句柄(Handle),称为托管对象引用(Managed Object Referenct),简称 moRef。开发者能够通过 moRef + PropertyCollector(获取对象详细属性信息的机制) 的方式来获取一个托管对象的详细状态信息。

下面列出的是五种基本托管对象类型,它们描述了 vSphere 系统的组织结构,其他的托管对象可以看作是这五种基本对象的详细扩展。

  • 目录(Folder)
  • 数据中心(Datacenter)
  • 计算资源(ComputeResource)
  • 资源池(ResourcePool)
  • 虚拟机(VirtualMachine)

托管对象引用 Managed Object References

托管对象引用 moRef 实际上是一个句柄,它就像是一个信息容器的入口,而非容器本身。并且 moRef 具有唯一性,但这种唯一性是取决于你的连接方式的。当你的连接的对象为 ESX/ESXi Host 时,那么 moRef 的命名空间由 ESX/ESXi Host 来维护,这很简单;但如果你的连接对象是 vCenter,并且 vCenter 管理着 ESX/ESXi Host 集群时,moRef 的唯一性就需要由 vCenter 来确保。这就意味着即便是同一个 MO,当你的连接方式不同时,可能会获得不一样的 moRef 唯一值,从而使得后续的操作产生混乱。

官方文档中也明确指出了 A vSphere instance (vCenter or ESXi) tries to keep the moRef for a virtual machine consistent across sessions, however consistency is not guaranteed.,这里是一个坑,要求开发者应该始终贯彻同一种连接方式,并且不建议持久化 moRef。

托管对象属性收集器 PropertyCollector

PropertyCollector 的功能是帮助开发者取得一个托管对象的配置状态信息。PropertyCollector 具有两个非常重要的形参 PropertySpec, ObjectSpec。PropertyCollector 返回的数据是一个 PropertyFilterUpdate 容器类,它包含一个 ObjectSet。

  • ObjectSpec:用于指定自何处查找所需的属性信息。 由于 vSphere 使用目录树的形式来组织配置信息,所以 ObjectSpec 必须描述如何遍历树以获取所需的信息。
  • PropertySpec:用于指定所需获取的属性信息列表。

连接 vCenter 并获取 MO

常见的 Python SDK 有 oslo_vmware 和 pyVmomi 两种,前者是 OpenStack Nova 项目为了纳管 VMware 资源所开发出来的基础通用库,后者则是 VMware 官方提供的 Python SDK。就个人而言会更加偏向在正式项目中使用 pyVmomi,主要原因在于其提供了非常完备的 文档 和许多实用的 Sample 实现,这些都是非常重要的技术选型考量点。

但是,为了更直观方便的辅助理解上述概念,我们这里还是选择使用封装程度较低的 oslo_vmware 结合 IPython CLI 来作为示例。 oslo_vmware 的具体使用细节,请移步《Python Module_oslo.vmware_连接 vCenter》

  • Step 1: 建立连接
In [10]: from oslo_vmware import api
In [11]: from oslo_vmware import vim_util

In [12]: session = api.VMwareAPISession(
   ....:             '192.168.10.105',
   ....:             'administrator@vsphere.local',
   ....:             'Root123.',
   ....:              1,
   ....:              0.1)
  • Step 2:获取你期望的 Managed Object
    其中 HostSystem 就是该托管对象的名字,我们可以自 vSphere WS API 中找到相应的 API 文档。

这里写图片描述

In [15]: hosts = session.invoke_api(
   ....:     vim_util,
   ....:     'get_objects',
   ....:     session.vim,
   ....:     'HostSystem',
   ....:     100)

In [16]: hosts
Out[16]:
(RetrieveResult){
   objects[] =
      (ObjectContent){
         obj =
            (obj){
               value = "host-2068"
               _type = "HostSystem"
            }
         propSet[] =
            (DynamicProperty){
               name = "name"
               val = "192.168.10.103"
            },
      },
 }

In [19]: hosts.objects[0].obj
Out[19]:
(obj){
   value = "host-2068"
   _type = "HostSystem"
 }

这里我们获得了一个 HostSystem Managed Object 的一个句柄也就是 moRef:hosts.objects[0].obj,其中包含了唯一值 host-2068

  • Step3:获取你期望的托管对象中所含有的配置状态信息。
    通过 moRef 结合应用 PropertyCollector 机制,就能得到该托管对象的配置状态信息。我们可以在 API 文档中浏览该托管对象的属性项目。

这里写图片描述

In [26]: host = hosts.objects[0].obj

In [27]: nets = session.invoke_api(vim_util, 'get_object_properties_dict', session.vim,
                                   host, 'config.network.portgroup')

在上述代码中,host 实参就是一个 ObjectSpec,指定了从 moRef host-2068 中查找所需要的信息。而 config.network.portgroup 实参则是 PropertySpec,指定了所需要获取的属性信息。最终获取到 ESXi/ESX Host 192.168.10.103 的网络信息如下:


In [28]: nets
Out[28]:
{config.network.portgroup: (ArrayOfHostPortGroup){
   HostPortGroup[] =
      (HostPortGroup){
         key = "key-vim.host.PortGroup-VM Network"
         port[] =
            (HostPortGroupPort){
               key = "key-vim.host.PortGroup.Port-33554439"
               mac[] =
                  "00:0c:29:de:9b:d6",
               type = "virtualMachine"
            },
            (HostPortGroupPort){
               key = "key-vim.host.PortGroup.Port-33554441"
               mac[] =
                  "00:50:56:9d:6e:09",
               type = "virtualMachine"
            },
            (HostPortGroupPort){
               key = "key-vim.host.PortGroup.Port-33554463"
               mac[] =
                  "00:50:56:9d:4d:69",
               type = "virtualMachine"
            },
         vswitch = "key-vim.host.VirtualSwitch-vSwitch0"
         computedPolicy =
            (HostNetworkPolicy){
               security =
                  (HostNetworkSecurityPolicy){
                     allowPromiscuous = False
                     macChanges = True
                     forgedTransmits = True
                  }
               nicTeaming =
                  (HostNicTeamingPolicy){
                     policy = "loadbalance_srcid"
                     reversePolicy = True
                     notifySwitches = True
                     rollingOrder = False
                     failureCriteria =
                        (HostNicFailureCriteria){
                           checkSpeed = "minimum"
                           speed = 10
                           checkDuplex = False
                           fullDuplex = False
                           checkErrorPercent = False
                           percentage = 0
                           checkBeacon = False
                        }
                     nicOrder =
                        (HostNicOrderPolicy){
                           activeNic[] =
                              "vmnic0",
                        }
                  }
               offloadPolicy =
                  (HostNetOffloadCapabilities){
                     csumOffload = True
                     tcpSegmentation = True
                     zeroCopyXmit = True
                  }
               shapingPolicy =
                  (HostNetworkTrafficShapingPolicy){
                     enabled = False
                  }
            }
         spec =
            (HostPortGroupSpec){
               name = "VM Network"
               vlanId = 0
               vswitchName = "vSwitch0"
               policy =
                  (HostNetworkPolicy){
                     security = ""
                     nicTeaming =
                        (HostNicTeamingPolicy){
                           failureCriteria = ""
                        }
                     offloadPolicy = ""
                     shapingPolicy = ""
                  }
            }
      },
      (HostPortGroup){
         key = "key-vim.host.PortGroup-Management Network"
         port[] =
            (HostPortGroupPort){
               key = "key-vim.host.PortGroup.Port-33554438"
               mac[] =
                  "c8:1f:66:b9:33:32",
               type = "host"
            },
         vswitch = "key-vim.host.VirtualSwitch-vSwitch0"
         computedPolicy =
            (HostNetworkPolicy){
               security =
                  (HostNetworkSecurityPolicy){
                     allowPromiscuous = False
                     macChanges = True
                     forgedTransmits = True
                  }
               nicTeaming =
                  (HostNicTeamingPolicy){
                     policy = "loadbalance_srcid"
                     reversePolicy = True
                     notifySwitches = True
                     rollingOrder = False
                     failureCriteria =
                        (HostNicFailureCriteria){
                           checkSpeed = "minimum"
                           speed = 10
                           checkDuplex = False
                           fullDuplex = False
                           checkErrorPercent = False
                           percentage = 0
                           checkBeacon = False
                        }
                     nicOrder =
                        (HostNicOrderPolicy){
                           activeNic[] =
                              "vmnic0",
                        }
                  }
               offloadPolicy =
                  (HostNetOffloadCapabilities){
                     csumOffload = True
                     tcpSegmentation = True
                     zeroCopyXmit = True
                  }
               shapingPolicy =
                  (HostNetworkTrafficShapingPolicy){
                     enabled = False
                  }
            }
         spec =
            (HostPortGroupSpec){
               name = "Management Network"
               vlanId = 0
               vswitchName = "vSwitch0"
               policy =
                  (HostNetworkPolicy){
                     security = ""
                     nicTeaming =
                        (HostNicTeamingPolicy){
                           policy = "loadbalance_srcid"
                           notifySwitches = True
                           rollingOrder = False
                           failureCriteria =
                              (HostNicFailureCriteria){
                                 checkBeacon = False
                              }
                           nicOrder =
                              (HostNicOrderPolicy){
                                 activeNic[] =
                                    "vmnic0",
                              }
                        }
                     offloadPolicy = ""
                     shapingPolicy = ""
                  }
            }
      },
      (HostPortGroup){
         key = "key-vim.host.PortGroup-iscsi01"
         port[] =
            (HostPortGroupPort){
               key = "key-vim.host.PortGroup.Port-50331656"
               mac[] =
                  "00:50:56:65:ca:28",
               type = "host"
            },
         vswitch = "key-vim.host.VirtualSwitch-vSwitch1"
         computedPolicy =
            (HostNetworkPolicy){
               security =
                  (HostNetworkSecurityPolicy){
                     allowPromiscuous = False
                     macChanges = True
                     forgedTransmits = True
                  }
               nicTeaming =
                  (HostNicTeamingPolicy){
                     policy = "loadbalance_srcid"
                     reversePolicy = True
                     notifySwitches = True
                     rollingOrder = False
                     failureCriteria =
                        (HostNicFailureCriteria){
                           checkSpeed = "minimum"
                           speed = 10
                           checkDuplex = False
                           fullDuplex = False
                           checkErrorPercent = False
                           percentage = 0
                           checkBeacon = False
                        }
                     nicOrder =
                        (HostNicOrderPolicy){
                           activeNic[] =
                              "vmnic1",
                        }
                  }
               offloadPolicy =
                  (HostNetOffloadCapabilities){
                     csumOffload = True
                     tcpSegmentation = True
                     zeroCopyXmit = True
                  }
               shapingPolicy =
                  (HostNetworkTrafficShapingPolicy){
                     enabled = False
                  }
            }
         spec =
            (HostPortGroupSpec){
               name = "iscsi01"
               vlanId = 0
               vswitchName = "vSwitch1"
               policy =
                  (HostNetworkPolicy){
                     security = ""
                     nicTeaming =
                        (HostNicTeamingPolicy){
                           failureCriteria = ""
                        }
                     offloadPolicy = ""
                     shapingPolicy = ""
                  }
            }
      },
      (HostPortGroup){
         key = "key-vim.host.PortGroup-iscsivspg"
         vswitch = "key-vim.host.VirtualSwitch-vSwitch1"
         computedPolicy =
            (HostNetworkPolicy){
               security =
                  (HostNetworkSecurityPolicy){
                     allowPromiscuous = False
                     macChanges = True
                     forgedTransmits = True
                  }
               nicTeaming =
                  (HostNicTeamingPolicy){
                     policy = "loadbalance_srcid"
                     reversePolicy = True
                     notifySwitches = True
                     rollingOrder = False
                     failureCriteria =
                        (HostNicFailureCriteria){
                           checkSpeed = "minimum"
                           speed = 10
                           checkDuplex = False
                           fullDuplex = False
                           checkErrorPercent = False
                           percentage = 0
                           checkBeacon = False
                        }
                     nicOrder =
                        (HostNicOrderPolicy){
                           activeNic[] =
                              "vmnic1",
                        }
                  }
               offloadPolicy =
                  (HostNetOffloadCapabilities){
                     csumOffload = True
                     tcpSegmentation = True
                     zeroCopyXmit = True
                  }
               shapingPolicy =
                  (HostNetworkTrafficShapingPolicy){
                     enabled = False
                  }
            }
         spec =
            (HostPortGroupSpec){
               name = "iscsivspg"
               vlanId = 0
               vswitchName = "vSwitch1"
               policy = ""
            }
      },
      (HostPortGroup){
         key = "key-vim.host.PortGroup-aju-test"
         vswitch = "key-vim.host.VirtualSwitch-vSwitch0"
         computedPolicy =
            (HostNetworkPolicy){
               security =
                  (HostNetworkSecurityPolicy){
                     allowPromiscuous = False
                     macChanges = True
                     forgedTransmits = True
                  }
               nicTeaming =
                  (HostNicTeamingPolicy){
                     policy = "loadbalance_srcid"
                     reversePolicy = True
                     notifySwitches = True
                     rollingOrder = False
                     failureCriteria =
                        (HostNicFailureCriteria){
                           checkSpeed = "minimum"
                           speed = 10
                           checkDuplex = False
                           fullDuplex = False
                           checkErrorPercent = False
                           percentage = 0
                           checkBeacon = False
                        }
                     nicOrder =
                        (HostNicOrderPolicy){
                           activeNic[] =
                              "vmnic0",
                        }
                  }
               offloadPolicy =
                  (HostNetOffloadCapabilities){
                     csumOffload = True
                     tcpSegmentation = True
                     zeroCopyXmit = True
                  }
               shapingPolicy =
                  (HostNetworkTrafficShapingPolicy){
                     enabled = False
                  }
            }
         spec =
            (HostPortGroupSpec){
               name = "aju-test"
               vlanId = 0
               vswitchName = "vSwitch0"
               policy = ""
            }
      },
 }}

最后

最后需要注意的是,这里使用 oslo_vmware 是为了让示例更加贴近所提到的概念。而这些概念在实际的生成中完全是可以透明的,只需要浏览 pyVmomi 所提供的文档,并熟练掌握其使用技巧,也能够很好的完成实现。

相关文章
|
16天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。
|
23天前
|
API 数据库 C语言
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
163 0
|
2月前
|
Java 程序员 API
Java并发基础:concurrent Flow API全面解析
java.util.concurrent.Flow定义了响应式编程的核心接口,促进了Java在异步数据处理和背压机制方面的标准化,这使得第三方库如Reactor和RxJava能够基于这些接口提供丰富的实现和功能,同时简化了响应式编程在Java中的使用,Flow API增强了Java在并发编程领域的灵活性,使得处理异步数据流变得更加自然和高效。
107 0
Java并发基础:concurrent Flow API全面解析
|
1天前
|
机器学习/深度学习 API TensorFlow
TensorFlow的高级API:tf.keras深度解析
【4月更文挑战第17天】本文深入解析了TensorFlow的高级API `tf.keras`,包括顺序模型和函数式API的模型构建,以及模型编译、训练、评估和预测的步骤。`tf.keras`结合了Keras的易用性和TensorFlow的性能,支持回调函数、模型保存与加载等高级特性,助力提升深度学习开发效率。
|
30天前
|
前端开发 开发者 UED
构建响应式Web界面:Flexbox与Grid布局的深度解析
【2月更文挑战第28天】 在现代前端开发中,打造灵活且适应不同屏幕尺寸的用户界面是至关重要的。随着移动设备的普及,响应式设计已经成为网页制作不可或缺的一部分。本文将深入探讨两种强大的CSS布局模块——Flexbox和Grid,它们如何简化布局创建过程,并赋予设计师更大的灵活性去构建动态和流畅的响应式界面。通过对这两种技术的比较、使用场景分析以及代码示例,读者将能够更好地理解何时以及如何使用这些工具来提升前端项目的质量和效率。
16 0
|
1月前
|
物联网 调度 开发者
构建高效Python Web应用:异步编程与Tornado框架解析
【2月更文挑战第27天】 在处理高并发的Web应用场景时,传统的同步阻塞模型往往难以满足性能需求。本文将深入探讨Python世界中的异步编程概念,并结合Tornado这一轻量级、非阻塞式Web服务器及框架,展示如何构建高性能的Web应用。通过实例驱动的方法论,我们将剖析Tornado的核心组件,包括其IOLoop、异步HTTP客户端和服务器端处理机制,以及与协程集成的细节。文章旨在为开发者提供一套实践指南,帮助他们利用Python实现快速响应和资源高效的Web服务。
28 2
|
1月前
|
监控 调度 开发者
构建高效Python Web应用:异步编程与Tornado框架深度解析
【2月更文挑战第20天】在处理高并发的Web应用时,传统的同步阻塞模型往往难以满足性能要求。本文将深入探讨Python异步编程的原理及其优势,并通过Tornado框架的案例分析,展示如何构建一个高效的异步Web服务。我们将从异步IO的基础讲起,逐步过渡到Tornado的核心组件,最终实现一个能够承载大量并发连接的Web服务器,为追求高性能Web解决方案的开发者提供实践指南。
|
1月前
|
Java 应用服务中间件
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
107 1
|
1月前
|
前端开发 开发者 UED
构建响应式Web界面:Flexbox与Grid布局的深度解析
【2月更文挑战第15天】在现代前端开发中,创建灵活且响应式的用户界面至关重要。本文深入探讨了两种强大的CSS布局模块——Flexbox和Grid,它们如何帮助我们实现复杂布局的挑战。通过比较这两种技术的特点、适用场景及其兼容性问题,我们将理解如何有效地将它们应用于日常开发中,以提升界面设计的灵活性和用户体验。
|
1月前
|
前端开发 开发者 UED
构建响应式Web界面:Flexbox与Grid布局的深度解析
【2月更文挑战第14天】 在现代前端开发中,为了适配不同设备并提供流畅的用户体验,理解并掌握响应式设计变得至关重要。本文将深入探讨两种主要的CSS布局模式——Flexbox和Grid。我们将剖析它们的核心概念、使用场景以及如何结合它们来创建复杂且灵活的响应式界面。通过实例演示和对比分析,帮助开发者提升界面布局技能,从而设计出能够适应多变设备的Web界面。
22 0

推荐镜像

更多