目录

vSS & vSSPG

vSS(Standard vSwitch 标准交换机) 为在同一 ESXi/ESX 或不同 ESXi/ESX 上 VirtualMachine 之间的连接, 也可以让 VirtualMachine 连接到外部网络.

vSSPG(Standard vSwitch PortGroup 标准交换机端口组) 是 vSphere 的基本网络对象模型, VirtualMachine 会通过一个 PortGroup 来访问网络.

Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_openstack

使用 oslo.vmware 模块结合 vSphere API 来创建 vSSPG 是一个相对综合的调用过程, 在实现的过程中能让我们理解 vSphere SDK 定义的相关概念模型, 以及熟悉 VMware vSphere API Reference Docs.

vSphere SDK 中相关的网络对象

vSphere Web Services SDK 包括下列对象和方法来管理网络配置:

  • HostNetworkSystem(Managed Object): 代表了主机的网路配置, 拥有检索和改变网络配置的方法. 所以我们能够使用 HostNetworkSystem MO 对象来访问和控制 ESX/ESXi 的网络概念模型.
    Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_sdk_02

  • HostNetworkConfig(Data Object): 用于规划 ESXi Host 详细的网络配置.

创建 vSS PortGroup

首先我们已经知道创建标准交换机端口组需要使用 HostNetowrkSystem MO 的 AddPortGroup 方法, 所以调用该方法的前提就是能够获取到HostNetowrkSystem MO. 但遗憾的是我们无法通过 oslo.vmware 模块提供的 get_objects invoke_api 来直接获取, 这就需要我们费些心思去找到其上级且可使用 get_objects invoke_api 来获取的 MO.

NOTE: 下述多数截图出自于 VMware vSphere API Reference Docs.

从下图可知 HostNetworkSystem MO 的上级 Property 是 HostConfigManager, 那么我们首先进入到 HostConfigManager 的 Docs.

Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vss_03

然后从下图可知 HostConfigManager 是一个 Data object, 我们仍无法通过 get_object invoke_api 的方式来获取这个对象, 所以继续进入 HostConfigManager 对象的上级 Property.

Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vsphere_04

直到现在我们看到了非常熟悉的 HostSystem MO, 这是一个非常常用的 MO, 并且支持 get_object invoke_api 的获取方式, 所以从 HostSystem 开始, 我们就能够其属性, 直到得到 HostNetowrkSystem MO 为止.

  • Step 1: 连接到 vCenter 或 ESXi/ESX
from oslo_vmware import api
from oslo_vmware import vim_util

# Create the vmware session
session = api.VMwareAPISession(
    '200.21.102.7',
    'root',
    'vmware',
    1,  
    0.1)
  • Step 2: 获取 HostSystem MO
hosts = session.invoke_api(
    vim_util,        
    'get_objects',              
    session.vim,                 
    'HostSystem',                
    100)

# 我们随意选取一个 ESXi Host, 并且打印其 Object
host_obj = hosts.objects[0].obj

In [17]: hosts.objects[0].obj
Out[17]:
(obj){
   value = "host-10"
   _type = "HostSystem"
 }
  • Step 3: 从下图可以看出 HostSystem 的 Properties configManager 就是 HostConfigManager 对象, HostConfigManager 的 Properties networkSystem 就是 HostNetworkSystem 对象.

(HostSystem ==> HostConfigManager)
Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vsphere_05

(HostConfigManager ==> HostNetworkSystem)
Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vmware_06

# 获取 HostNetworkSystem MO, 并打印其 Value
host_network_system_val = session.invoke_api(
    vim_util,        
    'get_object_properties_dict',              
    session.vim,                 
    host_obj,                
    'configManager.networkSystem')

In [24]: host_network_system_val
Out[24]:
{configManager.networkSystem: (val){
   value = "networkSystem-10"
   _type = "HostNetworkSystem"
 }}
  • Step 4: 在得到了 host_network_system_val 对象之后, 我们就能够通过 session.invoke_api 来调用该对象的 AddPortGroup 方法了. 但仍有一个前提, 就是我们需要为 AddPortGroup 准备好需要传入的实参 portgrp(HostPortGroupSpec).
    Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vss_07

再如下图, 我们得知 HostPortGroupSpec 是一个 Data Object, 所以我们能够通过 session.vim.client.factory.create 方法来获取该对象的数据结构.
Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_openstack_08

# 获取 HostPortGroupSpec 对象的数据结构, 并打印
client_factory = session.vim.client.factory
vswitch_port_group_spec = client_factory.create('ns0:HostPortGroupSpec')


In [26]: vswitch_port_group_spec
Out[26]:
(HostPortGroupSpec){
   dynamicType = None
   dynamicProperty[] = <empty>
   name = None
   vlanId = None
   vswitchName = None
   policy =
      (HostNetworkPolicy){
         dynamicType = None
         dynamicProperty[] = <empty>
         security =
            (HostNetworkSecurityPolicy){
               dynamicType = None
               dynamicProperty[] = <empty>
               allowPromiscuous = None
               macChanges = None
               forgedTransmits = None
            }
         nicTeaming =
            (HostNicTeamingPolicy){
               dynamicType = None
               dynamicProperty[] = <empty>
               policy = None
               reversePolicy = None
               notifySwitches = None
               rollingOrder = None
               failureCriteria =
                  (HostNicFailureCriteria){
                     dynamicType = None
                     dynamicProperty[] = <empty>
                     checkSpeed = None
                     speed = None
                     checkDuplex = None
                     fullDuplex = None
                     checkErrorPercent = None
                     percentage = None
                     checkBeacon = None
                  }
               nicOrder =
                  (HostNicOrderPolicy){
                     dynamicType = None
                     dynamicProperty[] = <empty>
                     activeNic[] = <empty>
                     standbyNic[] = <empty>
                  }
            }
         offloadPolicy =
            (HostNetOffloadCapabilities){
               dynamicType = None
               dynamicProperty[] = <empty>
               csumOffload = None
               tcpSegmentation = None
               zeroCopyXmit = None
            }
         shapingPolicy =
            (HostNetworkTrafficShapingPolicy){
               dynamicType = None
               dynamicProperty[] = <empty>
               enabled = None
               averageBandwidth = None
               peakBandwidth = None
               burstSize = None
            }
      }
 }
  • Step 5: 通过设置 HostPortGroupSpec 的项目值来达到设置 PortGroup 属性的目的

一般我们需要关注的项目值在 Docs 中都有明确的指示:
Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_openstack_09

# 其中 policy 项的值有必须是一个 HostNetworkPolicy Data Object
# 所以我们需要使用与获取 HostPortGroupSpec 相同的方式来获取 HostNetworkPolicy 对象的数据结构.
policy = client_factory.create('ns0:HostNetworkPolicy')
nicteaming = client_factory.create('ns0:HostNicTeamingPolicy')
nicteaming.notifySwitches = True
policy.nicTeaming = nicteaming

port_group_name = 'fanguiju-test'
vswitch_name = 'vSwitch0'
vlan_id = '0'

vswitch_port_group_spec.policy = policy
vswitch_port_group_spec.name = port_group_name
vswitch_port_group_spec.vswitchName = vswitch_name
vswitch_port_group_spec.vlanId = int(vlan_id)

直到现在, 我们终于准备好了 AddPortGroup 方法的实参, 接下来就能够调用这个方法实现标准交换机端口组的创建.

  • Step 6: 调用 AddPortGroup 方法
session.invoke_api(session.vim, 
                   'AddPortGroup',
                   host_network_system_val['configManager.networkSystem'], 
                   portgrp=vswitch_port_group_spec)

#  session.invoke_api() 的使用方法:
#      - 第二个参数是我们要调用的目标方法: AddPortGroup
#      - 第三个参数是我们要调用的目标方法 AddPortGroup 的属主 MO: HostNetowrkSystem
#      - 第四个~第 n 个参数是传递给目标方法 AddPortGroup 的实参
  • Step 7: 验证结果

Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup_vsphere_10