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

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 目录目录前文列表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 所提供的文档,并熟练掌握其使用技巧,也能够很好的完成实现。

相关文章
|
3天前
|
程序员 C++
C++编程:While与For循环的流程控制全解析
总结而言,`while`循环和 `for`循环各有千秋,它们在C++编程中扮演着重要的角色。选择哪一种循环结构应根据具体的应用场景、循环逻辑的复杂性以及个人的编程风格偏好来决定。理解这些循环结构的内在机制和它们之间的差异,对于编写高效、易于维护的代码至关重要。
9 1
|
13天前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
23 11
|
15天前
|
缓存 开发者 Python
Python编程中的装饰器深入解析
【9月更文挑战第20天】本文将带领读者深入了解Python编程中一个强大且神秘的功能——装饰器。我们将从装饰器的基本概念出发,逐步探索它的工作原理、使用场景以及如何自定义装饰器。文章不仅会用通俗易懂的语言解释复杂的技术概念,还将通过实际代码示例展示装饰器的强大功能和灵活性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往更高效、更优雅代码编写的大门。
33 11
|
18天前
|
安全 Java 开发者
Java并发编程中的锁机制解析
本文深入探讨了Java中用于管理多线程同步的关键工具——锁机制。通过分析synchronized关键字和ReentrantLock类等核心概念,揭示了它们在构建线程安全应用中的重要性。同时,文章还讨论了锁机制的高级特性,如公平性、类锁和对象锁的区别,以及锁的优化技术如锁粗化和锁消除。此外,指出了在高并发环境下锁竞争可能导致的问题,并提出了减少锁持有时间和使用无锁编程等策略来优化性能的建议。最后,强调了理解和正确使用Java锁机制对于开发高效、可靠并发应用程序的重要性。
16 3
|
23天前
|
存储 SQL 数据挖掘
虚拟化数据恢复—VMware虚拟机vmdk文件被误删除的数据恢复案例
虚拟化数据恢复环境: 某品牌服务器(部署VMware EXSI虚拟机)+同品牌存储(存放虚拟机文件)。 虚拟化故障: 意外断电导致服务器上某台虚拟机无法正常启动。查看虚拟机配置文件发现这台故障虚拟机除了磁盘文件以外其他配置文件全部丢失,xxx-flat.vmdk磁盘文件和xxx-000001-delta.vmdk快照文件还在。管理员联系VMware工程师寻求帮助。VMware工程师尝试新建一个虚拟机来解决故障,但发现ESXi存储空间不足。于是将故障虚拟机下的xxx-flat.vmdk磁盘文件删除,然后重建一个虚拟机并且分配固定大小的虚拟磁盘。
|
11天前
|
数据安全/隐私保护 开发者 Python
Python 编程中的装饰器深入解析
【9月更文挑战第23天】本文将带你进入Python编程世界中一个既神秘又强大的工具——装饰器的探索旅程。我们将从基础定义出发,逐步深入到装饰器的应用实例和高级用法,让你在阅读中不仅理解装饰器的概念,更能掌握如何在实际项目中运用它们来简化代码和提高开发效率。文章最后还将探讨装饰器在现代Web框架中的应用,为你展示其背后的设计哲学和实用价值。
|
28天前
|
存储 JSON API
Python编程:解析HTTP请求返回的JSON数据
使用Python处理HTTP请求和解析JSON数据既直接又高效。`requests`库的简洁性和强大功能使得发送请求、接收和解析响应变得异常简单。以上步骤和示例提供了一个基础的框架,可以根据你的具体需求进行调整和扩展。通过合适的异常处理,你的代码将更加健壮和可靠,为用户提供更加流畅的体验。
65 0
|
2月前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
105 0
|
2月前
|
开发者 编解码
界面适应奥秘:从自适应布局到图片管理,Xamarin响应式设计全解析
【8月更文挑战第31天】在 Xamarin 的世界里,构建灵活且适应性强的界面是每位开发者的必修课。本文将带您探索 Xamarin 的响应式设计技巧,包括自适应布局、设备服务协商和高效图片管理,帮助您的应用在各种设备上表现出色。通过 Grid 和 StackLayout 实现弹性空间分配,利用 Device 类检测设备类型以加载最优布局,以及使用 Image 控件自动选择合适图片资源,让您轻松应对不同屏幕尺寸的挑战。掌握这些技巧,让您的应用在多变的市场中持续领先。
26 0
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式深度解析
【8月更文挑战第31天】 单例模式,作为设计模式中的经典之一,在Java编程实践中扮演着重要的角色。本文将通过简洁易懂的语言,逐步引导读者理解单例模式的本质、实现方法及其在实际应用中的重要性。从基础概念出发,到代码示例,再到高级应用,我们将一起探索这一模式如何优雅地解决资源共享和性能优化的问题。

推荐镜像

更多
下一篇
无影云桌面