VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析
目录
前文列表
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 所提供的文档,并熟练掌握其使用技巧,也能够很好的完成实现。
VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析的更多相关文章
- VMware 虚拟化编程(15) — VMware 虚拟机的恢复方案设计
目录 目录 前文列表 将已存在的虚拟机恢复到指定时间点 恢复为新建虚拟机 灾难恢复 恢复细节 恢复增量备份数据 以 RDM 的方式创建虚拟磁盘 创建虚拟机 Sample of VirtualMachi ...
- VMware 虚拟化编程(13) — VMware 虚拟机的备份方案设计
目录 目录 前文列表 备份思路 备份算法 备份细节 连接到 vCenter 还是 ESXi 如何选择快照类型 是否开启 CBT 如何获取备份数据 如何提高备份数据的传输率 备份厚置备磁盘和精简置备磁盘 ...
- VMware 虚拟化编程(11) — VMware 虚拟机的全量备份与增量备份方案
目录 目录 前文列表 全量备份数据的获取方式 增量备份数据的获取过程 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/VADP 概念简析 VMware 虚拟化编 ...
- VMware 虚拟化编程(10) — VMware 数据块修改跟踪技术 CBT
目录 目录 前文列表 数据块修改跟踪技术 CBT 为虚拟机开启 CBT CBT 修改数据块偏移量获取函数 QueryChangedDiskAreas changeId 一个 QueryChangedD ...
- VMware 虚拟化编程(9) — VMware 虚拟机的快照
目录 目录 前文列表 VMware 虚拟机的快照 快照的执行过程 删除快照 快照类型 Quiseced Snapshot 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDis ...
- VMware 虚拟化编程(14) — VDDK 的高级传输模式详解
目录 目录 前文列表 虚拟磁盘数据的传输方式 Transport Methods Local File Access NBD and NBDSSL Transport SAN Transport Ho ...
- VMware 虚拟化编程(12) — VixDiskLib Sample 程序使用
目录 目录 前文列表 vixDiskLibSample 安装 Sample 程序 Sample 程序使用方法 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/V ...
- VMware 虚拟化编程(8) — 多线程中的 VixDiskLib
目录 目录 前文列表 多线程注意事项 多线程中的 VixDiskLib 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/VADP 概念简析 VMware 虚拟化 ...
- VMware 虚拟化编程(7) — VixDiskLib 虚拟磁盘库详解之三
目录 目录 前文列表 VixDiskLib 虚拟磁盘库 VixDiskLib_GetMetadataKeys VixDiskLib_ReadMetadata 获取虚拟磁盘元数据 VixDiskLib_ ...
随机推荐
- jquery做一个小的轮播插件---有BUG,后续修改
//首页无缝轮播 ; (function($, window, document, undefined) { $.fn.slider = function(options) { var default ...
- 1. Docker快速入门(仓库,镜像,容器)
参考阿里云文档:https://help.aliyun.com/document_detail/51853.html?spm=a2c4g.11186623.6.820.RaToNY 参考菜鸟教程文档: ...
- gomock
参考 使用Golang的官方mock工具--gomock
- RNN, LSTM, GRU cells
项目需要,先简记cell,有时间再写具体改进原因 RNN cell LSTM cell: GRU cell: reference: 1.https://towardsdatascience.com/a ...
- git error: failed to push some refs to 'git@github.com:xxx/xxx.git'
本地仓库中和远程仓库不一致,缺少readme.md文件 解决方式参见:https://blog.csdn.net/qq_37281252/article/details/79044798
- IO同步阻塞与同步非阻塞
BIO.NIO.AIO IO(BIO)和NIO区别:其本质就是阻塞和非阻塞的区别 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等待,直到传输完毕为止. 非阻塞概念:应用程序直 ...
- Hadoop本地模式搭建
官方文档,不同版本修改url地址中的数字即可 http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/Single ...
- JVM 虚拟机栈
虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“this”,所以实例方法可以访问 ...
- python如何导入自定义文件和模块$PYTHONHOME$\Lib\site-packages 方法
python 中如何引用自己创建的源文件(*.py)呢? 也就是所谓的模块. 假如,你有一个自定义的源文件,文件名:saySomething.py .里面有个函数,函数名:sayHello.如下图: ...
- Python的命令行参数(argparse)
参考:https://www.cnblogs.com/lindaxin/p/7975697.html 参考:https://www.cnblogs.com/dengtou/p/8413609.html ...