python pyvmomi操作VMware(4):仮想マシンをクローンし、IPを構成し、vlanセグメントを変更する
13416 ワード
環境の準備
インストールパッケージ:
コード#コード#
クローン仮想マシンは、仮想マシンテンプレートに依存します.仮想マシンテンプレートが正常な場合、上記のコードは、仮想マシンをクローンしてIPを指定する操作を完了することができます.まず、クローン仮想マシンのピットについて説明します.
現象1:仮想マシンのクローンが成功し、仮想マシンは自動的に正常に起動するが、ネットワークIPを指定していない.
現象2:仮想マシンのクローンは成功したが、自動的に起動せず、指定ネットワークIPも失敗し、vSphereにidentが報告された.hostName.name異常.
現象3:仮想マシンのクローン化に成功し、仮想マシンは自動的に正常に起動し、ネットワークの指定に成功したが、仮想マシンのネットワークが通じず、正常にネットワークを使用できない.
仮想マシンのクローン作成に成功した後、仮想マシンIPとネットワークアダプタのネットワークセグメントが一致しない場合、ネットワークセグメント、すなわちvlanセグメントを変更できます.
ここでの修正はvdsとvssタイプのセグメントに分けられ,vssは標準スイッチを指し,vdsは分散スイッチを指し,両者の修正セグメント方式は異なる.
インストールパッケージ:
pyVim==0.0.21
pyvmomi==6.7.1
:pip install pyVim==0.0.21 pyvmomi==6.7.1
コード#コード#
# -*- coding: utf-8 -*-
import traceback
from pyVim.connect import SmartConnectNoSSL, Disconnect
from pyVmomi import vim, vmodl
class VmManage(object):
def __init__(self, host, user, password, port, ssl):
self.config = None
self.host = host
self.user = user
self.pwd = password
self.port = port
self.sslContext = ssl
try:
self.client = SmartConnectNoSSL(host=host,
user=user,
pwd=password,
port=443
)
self.content = self.client.RetrieveContent()
self.result = True
except Exception as e:
self.result = e
def _get_all_objs(self, obj_type, folder=None):
"""
"""
if folder is None:
container = self.content.viewManager.CreateContainerView(self.content.rootFolder, obj_type, True)
else:
container = self.content.viewManager.CreateContainerView(folder, obj_type, True)
return container.view
def _get_obj(self, obj_type, name):
"""
"""
obj = None
content = self.client.RetrieveContent()
container = content.viewManager.CreateContainerView(content.rootFolder, obj_type, True)
for c in container.view:
if c.name == name:
obj = c
break
return obj
def get_datacenters(self):
"""
"""
return self._get_all_objs([vim.Datacenter])
# vcenter
def wait_for_task(self, task):
""" wait for a vCenter task to finish """
task_done = False
while not task_done:
print "task.....%s " % task.info.state
if task.info.state == 'success':
return {'message': u' ', 'status': True}
if task.info.state == 'error':
print "there was an error"
return {'message': task.info.error.msg, 'status': True}
def handleTask(self, tasks=None):
if tasks is None:
return False
else:
from pyVim.task import WaitForTasks
try:
WaitForTasks(tasks=tasks, si=self.client)
except Exception as e:
traceback.print_exc()
print str(e)
return False
def get_cluster_by_name(self, name=None, datacenter=None):
if datacenter:
folder = datacenter.hostFolder
else:
folder = self.content.rootFolder
container = self.content.viewManager.CreateContainerView(folder, [vim.ClusterComputeResource], True)
clusters = container.view
for cluster in clusters:
if cluster.name == name:
return cluster
return None
def get_datastore_by_name(self, name, datacenter):
datastores = datacenter.datastore
for datastore in datastores:
if datastore.name == name:
return datastore
return None
def get_host_by_name(self, name, datastore):
hosts = datastore.host
for host in hosts:
if host.key.summary.config.name == name:
return host.key
return None
def get_vms_by_cluster(self, vmFolder):
content = self.client.content
objView = content.viewManager.CreateContainerView(vmFolder, [vim.VirtualMachine], True)
vmList = objView.view
objView.Destroy()
return vmList
def get_customspec(self, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None,
vm_domain=None, vm_hostname=None):
# guest NIC settings dns
adaptermaps = []
guest_map = vim.vm.customization.AdapterMapping()
guest_map.adapter = vim.vm.customization.IPSettings()
guest_map.adapter.ip = vim.vm.customization.FixedIp()
guest_map.adapter.ip.ipAddress = vm_ip
guest_map.adapter.subnetMask = vm_subnetmask
guest_map.adapter.gateway = vm_gateway
if vm_domain:
guest_map.adapter.dnsDomain = vm_domain
adaptermaps.append(guest_map)
# DNS settings
globalip = vim.vm.customization.GlobalIPSettings()
if vm_dns:
globalip.dnsServerList = [vm_dns]
globalip.dnsSuffixList = vm_domain
# Hostname settings
ident = vim.vm.customization.LinuxPrep()
if vm_domain:
ident.domain = vm_domain
ident.hostName = vim.vm.customization.FixedName()
if vm_hostname:
ident.hostName.name = vm_hostname
customspec = vim.vm.customization.Specification()
customspec.nicSettingMap = adaptermaps
customspec.globalIPSettings = globalip
customspec.identity = ident
return customspec
def clone(self, template_name, vm_name, datacenter_name,
datastore_name, cluster_name, host_name=None,
cup_num=None, memory=None, vm_ip=None, vm_subnetmask=None,
vm_gateway=None, vm_dns, vm_domain=None,
vm_hostname=None):
#
template = self._get_obj([vim.VirtualMachine], template_name)
#
if template is None:
return {'message': u' : ', 'result': False}
# ,
datacenter = self._get_obj([vim.Datacenter], datacenter_name)
#
if datacenter is None:
return {'message': u' : ', 'result': False}
vmfolder = datacenter.vmFolder
#
if datastore_name:
datastore = self.get_datastore_by_name(datastore_name, datacenter)
if datastore is None:
return {'message': u' : %s ' % datastore_name, 'result': False}
else:
datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter)
if datastore is None:
return {'message': u' : %s ' % template_name, 'result': False}
#
cluster = self.get_cluster_by_name(cluster_name, datacenter)
if cluster is None:
return {'message': u' : %s ' % cluster_name, 'result': False}
vms = self.get_vms_by_cluster(cluster)
vms_name = [i.name for i in vms]
if vm_name in vms_name:
return {'message': u' : %s ' % vm_name, 'result': False}
resource_pool = cluster.resourcePool
relospec = vim.vm.RelocateSpec()
relospec.datastore = datastore
relospec.pool = resource_pool
#
if host_name:
host = self.get_host_by_name(host_name, datastore)
if host is None:
return {'message': u' : %s ' % host_name, 'result': False}
else:
relospec.host = host
clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
clonespec.powerOn = True
# cpu
if all([vm_ip, vm_subnetmask, vm_gateway, vm_domain]):
clonespec.customization = self.get_customspec(vm_ip, vm_subnetmask, vm_gateway, vm_domain, vm_dns, vm_hostname)
vmconf = vim.vm.ConfigSpec()
if cup_num:
vmconf.numCPUs = cup_num
if memory:
vmconf.memoryMB = memory
if vmconf is not None:
clonespec.config = vmconf
print "cloning VM..."
task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec)
result = self.wait_for_task(task)
if result['status']:
data = {'message': u' ', 'result': True}
else:
data = {'message': u' : %s' % result['message'], 'result': False}
return data
if __name__ == '__main__':
ip = 'xxx.xxx.xxx.xxx'
user = 'xxxx'
password = 'xxx'
port = 443
template_name = u' - -CentOS74-1qaz!QAZ-100G'
vm_name = u'20-xuwei_testxxx2222'
data_center_name = u' '
datastore_name = None
cluster_name = u' '
host_name = None
cup_num = None
memory = None
resource_pool = None
power_on = True
vm_ip = '192.168.10.11'
vm_subnetmask = '255.255.255.0'
vm_gateway = '192.168.10.1'
vm_dns = 'xxx.xxx.xxx.xxx'
vm_domain = 'baidu.com'
vm_hostname = 'xuwei'
vm = VmManage(host=ip,
user=user,
password=password,
port=port, ssl=None)
data = vm.clone(
template_name=template_name,
vm_name=vm_name,
datacenter_name=data_center_name,
cluster_name=cluster_name,
datastore_name=datastore_name,
host_name=host_name,
cup_num=cup_num,
memory=memory,
vm_ip=vm_ip,
vm_subnetmask=vm_subnetmask,
vm_gateway=vm_gateway,
vm_dns=vm_dns,
vm_domain=vm_domain,
vm_hostname=vm_hostname
)
クローン仮想マシンは、仮想マシンテンプレートに依存します.仮想マシンテンプレートが正常な場合、上記のコードは、仮想マシンをクローンしてIPを指定する操作を完了することができます.まず、クローン仮想マシンのピットについて説明します.
現象1:仮想マシンのクローンが成功し、仮想マシンは自動的に正常に起動するが、ネットワークIPを指定していない.
:
現象2:仮想マシンのクローンは成功したが、自動的に起動せず、指定ネットワークIPも失敗し、vSphereにidentが報告された.hostName.name異常.
:
① :
②
現象3:仮想マシンのクローン化に成功し、仮想マシンは自動的に正常に起動し、ネットワークの指定に成功したが、仮想マシンのネットワークが通じず、正常にネットワークを使用できない.
:
IP , 。
仮想マシンのクローン作成に成功した後、仮想マシンIPとネットワークアダプタのネットワークセグメントが一致しない場合、ネットワークセグメント、すなわちvlanセグメントを変更できます.
def edit_nic(self, vm, network_name, is_vss):
device_change = []
data = {'message': None, 'result': False, 'code': 1}
for device in vm.config.hardware.device:
if isinstance(device, vim.vm.device.VirtualEthernetCard):
nicspec = vim.vm.device.VirtualDeviceSpec()
nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
nicspec.device = device
nicspec.device.wakeOnLanEnabled = True
if is_vss:
nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
nicspec.device.backing.network = self._get_obj([vim.Network], network_name)
nicspec.device.backing.deviceName = network_name
else:
network = self._get_obj([vim.dvs.DistributedVirtualPortgroup], network_name)
dvs_port_connection = vim.dvs.PortConnection()
dvs_port_connection.portgroupKey = network.key
dvs_port_connection.switchUuid = network.config.distributedVirtualSwitch.uuid
nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
nicspec.device.backing.port = dvs_port_connection
nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
nicspec.device.connectable.startConnected = True
nicspec.device.connectable.allowGuestControl = True
device_change.append(nicspec)
nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
nicspec.device.connectable.startConnected = True
nicspec.device.connectable.allowGuestControl = True
device_change.append(nicspec)
break
if device_change:
config_spec = vim.vm.ConfigSpec(deviceChange=device_change)
task = vm.ReconfigVM_Task(config_spec)
result = self.wait_for_task(task)
if result['status']:
power_state = vm.runtime.powerState
if power_state == 'poweredOn':
stop_task = vm.PowerOff()
stop_result = self.wait_for_task(stop_task)
# if stop_result['status']:
# start_task = vm.PowerOn()
# self.wait_for_task(start_task)
# else:
start_task = vm.PowerOn()
self.wait_for_task(start_task)
data["message"] = u' '
data["result"] = True
data["code"] = 0
else:
data["message"] = u' '
else:
data["message"] = u' , '
return data
ここでの修正はvdsとvssタイプのセグメントに分けられ,vssは標準スイッチを指し,vdsは分散スイッチを指し,両者の修正セグメント方式は異なる.