本文共 15443 字,大约阅读时间需要 51 分钟。
###Vmware控制台: 为了方便管理vmware,尽量摆脱vSphere,目前实现了对虚拟机的增、删、改(硬件配置)、快照管理、Console控制台、克隆等功能,本文只详细的介绍下Console功能。先上一张效果图:
#一、 环境准备
- pyvmovi 对应你的python版本,下载地址https://github.com/vmware/pyvmomi/releases
- 保证python环境大于2.7.11
#二、食用方法
代码如下:
# -*- coding: utf8 -*-from pyVmomi import vim,vmodlfrom pyVim.connect import SmartConnect, Disconnectimport atexitimport sysimport timeimport sslclass VCenter: def __init__(self): self.pyVmomi = __import__("pyVmomi") self.vcenter_server = '1.1.1.1' self.vcenter_username = 'test' self.vcenter_password = 'test' self.port = 443 self.isDHCP=False, self.vm_ip='10.7.42.91', self.subnet= '255.255.255.0', self.gateway= '10.7.42.40', self.dns= ['company.com', 'company.com'], self.domain= 'esx10g.company.com' def add_nic(vm, network): spec = vim.vm.ConfigSpec() # add Switch here dev_changes = [] switch_spec = vim.vm.device.VirtualDeviceSpec() switch_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add switch_spec.device = vim.vm.device.VirtualVmxnet3() switch_spec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() switch_spec.device.backing.useAutoDetect = False switch_spec.device.backing.deviceName = network.name switch_spec.device.backing.network = network switch_spec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() switch_spec.device.connectable.startConnected = True switch_spec.device.connectable.connected = True dev_changes.append(switch_spec) spec.deviceChange = dev_changes output = vm.ReconfigVM_Task(spec=spec) time.sleep(2) print output.info def connect_to_vcenter(self): context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_NONE self.service_instance = SmartConnect( host = self.vcenter_server, user = self.vcenter_username, pwd = self.vcenter_password, port = self.port, sslContext = context) self.content = self.service_instance.RetrieveContent() atexit.register(Disconnect, self.service_instance) def wait_for_task(self, task, actionName='job', hideResult=False): while task.info.state == (self.pyVmomi.vim.TaskInfo.State.running or self.pyVmomi.vim.TaskInfo.State.queued): time.sleep(2) if task.info.state == self.pyVmomi.vim.TaskInfo.State.success: if task.info.result is not None and not hideResult: out = '%s completed successfully, result: %s' % (actionName, task.info.result) print out else: out = '%s completed successfully.' % actionName print out elif task.info.state == self.pyVmomi.vim.TaskInfo.State.error: out = 'Error - %s did not complete successfully: %s' % (actionName, task.info.error) raise ValueError(out) return task.info.result def answer_vm_question(self,vm): choices = vm.runtime.question.choice.choiceInfo default_option = None choice = "" if vm.runtime.question.choice.defaultIndex is not None: ii = vm.runtime.question.choice.defaultIndex default_option = choices[ii] choice = None while choice not in [o.key for o in choices]: print "VM power on is paused by this question:\n\n" for option in choices: print "\t %s: %s " % (option.key, option.label) if default_option is not None: print "default (%s): %s\n" % (default_option.label, default_option.key) choice = raw_input("\nchoice number: ").strip() print "..." return choice def poweroff(self, si, vm): task = vm.PowerOff() actionName = 'job' while task.info.state not in [self.pyVmomi.vim.TaskInfo.State.success or self.pyVmomi.vim.TaskInfo.State.error]: time.sleep(2) if task.info.state == self.pyVmomi.vim.TaskInfo.State.success: out = '%s completed successfully.' % actionName print out elif task.info.state == self.pyVmomi.vim.TaskInfo.State.error: out = 'Error - %s did not complete successfully: %s' % (actionName, task.info.error) raise ValueError(out) return def poweron(self, si, vm): task = vm.PowerOn() actionName = 'job' answers = {} while task.info.state not in [self.pyVmomi.vim.TaskInfo.State.success or self.pyVmomi.vim.TaskInfo.State.error]: if vm.runtime.question is not None: question_id = vm.runtime.question.id if question_id not in answers.keys(): answers[question_id] = self.answer_vm_question(vm) vm.AnswerVM(question_id, answers[question_id]) time.sleep(2) if task.info.state == self.pyVmomi.vim.TaskInfo.State.success: out = '%s completed successfully.' % actionName print out elif task.info.state == self.pyVmomi.vim.TaskInfo.State.error: out = 'Error - %s did not complete successfully: %s' % (actionName, task.info.error) raise ValueError(out) return def set_dvs_mtu(self, dvs, mtu): dvs_config_spec = self.pyVmomi.vim.VmwareDistributedVirtualSwitch.ConfigSpec() dvs_config_spec.configVersion = dvs.config.configVersion dvs_config_spec.maxMtu = int(mtu) task = dvs.ReconfigureDvs_Task(dvs_config_spec) self.wait_for_task(task) print "Successfully reconfigured DVS %s with mtu %s" %(dvs.name, mtu) return dvs def get_dvs_portgroup(self, vimtype, portgroup_name, dvs_name): obj = None container = self.content.viewManager.CreateContainerView(self.content.rootFolder, vimtype, True) for c in container.view: if c.name == portgroup_name: if c.config.distributedVirtualSwitch.name == dvs_name: obj = c break return obj def list_obj(self, vimtype): container = self.content.viewManager.CreateContainerView(self.content.rootFolder, vimtype, True) return container.view def get_obj(self, vimtype, name): obj = None container = self.content.viewManager.CreateContainerView(self.content.rootFolder, vimtype, True) for c in container.view: if c.name == name: obj = c break return obj def get_folder(self, folder_name=''): """获取文件夹""" folder_list = [] if folder_name == '': listOBJ = self.list_obj([vim.Folder]) else: listOBJ = self.get_obj([vim.Folder],folder_name) for each in listOBJ: folder_list.append(each) return folder_list def get_vcenters(self): """获取所有数据中心""" listOBJ = self.list_obj([vim.Datacenter]) vcenters_list = [] for each in listOBJ: vcenters_list.append(each) return each def get_vcenters_alarm(self): """获取所有数据中心报警""" listOBJ = self.list_obj([vim.Datacenter]) vcenters_alarm_dict = {} for i in listOBJ[0].triggeredAlarmState: vcenters_alarm_dict[i.entity.name] = i.alarm.info.name.decode() return vcenters_alarm_dict def get_datastore(self, datastore_name=''): """获取存储""" datastore_list = [] if datastore_name == '': listOBJ = self.list_obj([vim.Datastore]) else: listOBJ = self.get_obj([vim.Datastore],datastore_name) for each in listOBJ: datastore_list.append(each.name) return datastore_list def get_clusters(self,clusters_name=''): """获取所有的集群""" clusters_list = [] if clusters_name == '': listOBJ = self.list_obj([vim.ClusterComputeResource]) else: listOBJ = self.get_obj([vim.ClusterComputeResource],clusters_name) for each in listOBJ: clusters_list.append(each.name) return clusters_list def get_resource_pool(self,resource_pool_name=''): """获取所有的资源池""" resource_pool_list = [] if resource_pool_name == '': listOBJ = self.list_obj([vim.ResourcePool]) else: listOBJ = self.get_obj([vim.ResourcePool],resource_pool_name) for each in listOBJ: resource_pool_list.append(each.name) return resource_pool_list def get_hosts(self): """获取所有的宿主机""" listOBJ = self.list_obj([vim.HostSystem]) index = 0 for each in listOBJ: tupleVNic=sys._getframe().f_code.co_name, index, each.config.network.vnic for eachvnic in tupleVNic[2]: index = index + 1 print sys._getframe().f_code.co_name, \ index, \ each, \ eachvnic.portgroup, \ eachvnic.spec.mac, \ eachvnic.spec.ip.ipAddress, eachvnic.spec.ip.subnetMask def get_pnic(self): """获取所有的上行口""" listOBJ = self.list_obj([vim.HostSystem]) index = 0 for each in listOBJ: tuplePNic=sys._getframe().f_code.co_name, index, each.config.network.pnic for eachpnic in tuplePNic[2]: index = index + 1 print sys._getframe().f_code.co_name, index, each, eachpnic.device def get_vswitchs(self): """获取所有的交换机(包括标准交换机和分布式交换机)""" listOBJ = self.list_obj([vim.HostSystem]) index = 0 for each in listOBJ: tupleVswitch = sys._getframe().f_code.co_name, index, each.config.network.vswitch for eachsw in tupleVswitch[2]: index = index + 1 print sys._getframe().f_code.co_name, index, eachsw.name def get_portgroups(self): """获取所有的交换机端口组(包括标准交换机和分布式交换机)""" listOBJ = self.list_obj([vim.Network]) index = 0 for each in listOBJ: index = index + 1 print sys._getframe().f_code.co_name, index, each def get_vns(self): """获取所有的虚拟网络(包括标准交换机端口组和分布式交换机端口组)""" listOBJ = self.list_obj([vim.Network]) index = 0 for each in listOBJ: index = index + 1 print sys._getframe().f_code.co_name, index, each def get_dvswitchs(self): """获取所有的分布式交换机""" listOBJ = self.list_obj([vim.DistributedVirtualSwitch]) index = 0 for each in listOBJ: index = index + 1 print sys._getframe().f_code.co_name,index,each def get_dvportgroups(self): """获取所有的分布式交换机端口组""" listOBJ = self.list_obj([vim.DistributedVirtualSwitch]) index = 0 for each in listOBJ: for eachportgroup in each.portgroup: index = index + 1 print sys._getframe().f_code.co_name,index,eachportgroup def get_vnic(self): """获取所有的虚拟网卡""" listOBJ = self.list_obj([vim.VirtualMachine]) index = 0 for each in listOBJ: index = index + 1 vmdeviceList = each.config.hardware.device for eachdevice in vmdeviceList: index = index + 1 if isinstance(eachdevice, vim.vm.device.VirtualEthernetCard ): if isinstance( eachdevice.backing,vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo ): print sys._getframe().f_code.co_name,\ index, \ eachdevice.deviceInfo.label, \ eachdevice.macAddress, \ eachdevice.deviceInfo.summary, \ eachdevice.backing.port.portgroupKey else: print sys._getframe().f_code.co_name,\ index, \ eachdevice.deviceInfo.label, \ eachdevice.macAddress, \ eachdevice.backing.deviceName, \ eachdevice.backing.network def get_allvms(self): """获取所有的虚机""" listOBJ = self.list_obj([vim.VirtualMachine]) index = 0 for each in listOBJ: index = index + 1 print sys._getframe().f_code.co_name,index,each.name def print_vm_info(self, virtual_machine, depth=1): """打印虚机信息""" maxdepth = 10 if hasattr(virtual_machine, 'childEntity'): if depth > maxdepth: return vmList = virtual_machine.childEntity for c in vmList: self.print_vm_info(c, depth + 1) return summary = virtual_machine.summary print "Name : ", summary.config.name print "Path : ", summary.config.vmPathName print "Guest : ", summary.config.guestFullName annotation = summary.config.annotation if annotation: print "Annotation : ", annotation print "State : ", summary.runtime.powerState if summary.guest is not None: ip_address = summary.guest.ipAddress if ip_address: print "IP : ", ip_address if summary.runtime.question is not None: print "Question : ", summary.runtime.question.text print "" def get_acquireTicket(self,virtual_machine): """获取主机Console授权""" acquireTickets_dict = {} listOBJ = self.get_obj([vim.VirtualMachine],virtual_machine) try: acquireTickets = listOBJ.AcquireTicket('webmks') except Exception as err: print 'acquireTickets_err:',err acquireTickets_dict['host'] = acquireTickets.host acquireTickets_dict['port'] = acquireTickets.port acquireTickets_dict['ticket'] = acquireTickets.ticket print acquireTickets_dict return acquireTickets_dict def get_hosts_exsi_version(self,virtual_machine): """获得主机Esxi版本""" try: hosts_name = self.get_obj([vim.VirtualMachine],virtual_machine).summary.runtime.host for i in self.list_obj([vim.HostSystem]): if i == hosts_name: hosts_ip = i.name listOBJ = self.get_obj([vim.HostSystem],hosts_ip) try: exsi_version = listOBJ.summary.config.product.fullName except Exception as err: print err exsi_version = '' except Exception as err: print err exsi_version = '' return exsi_version
捡一些重要的说:包含了添加网卡、获取所有虚拟机、获取集群、获取存储、获取主机Console授权、获取虚拟交换机、获取宿主机、获取宿主机Esxi版本、获取Vcenter、获取Vcenter所有报警、获取虚拟机存放文件夹等等
在下面的Console功能中,我们需要到的功能有:获取宿主机Esxi版本、获取主机Console授权,后端代码如下:
vcenter = VCenter()vcenter.connect_to_vcenter()vm_exsi_version = ss.get_hosts_exsi_version(vm) //获取宿主机的Esxi版本,进行判断,目前只支持 Exsi 6.xvm_console_info = ss.get_acquireTicket(vm) //获取一些Console授权的信息vm_console_host = vm_console_info['host']vm_console_port = vm_console_info['port']vm_console_ticket = vm_console_info['ticket']
前端通过html5+Websokct,部分代码如下:
####这里踩过的坑:
很有可能打开之后无法链接到wss://宿主机IP/ticket/xxxxxxxxxxx,原因是该网站的证书不被浏览器支持。可以先在浏览器打开https://宿主机IP,并信任ssl证书即可。转载于:https://blog.51cto.com/qdream/2405078