def get_registered_vms(self, datacenter=None, cluster=None, resource_pool=None, status=None, advanced_filters=None): """Returns a list of VM Paths. @datacenter: name or MORs to filter VMs registered in that datacenter @cluster: name or MORs to filter VMs registered in that cluster. If set datacenter is ignored. @resource_pool: name path or MORs to filter VMs registered in that resource pool. If set, both, @datacenter and @cluster are ignored. @status: either 'poweredOn', 'poweredOff', or 'suspended' to retrieve only VMs in that power state @advanced_filters: dictionary """ if not self.__logged: raise VIException( "Must call 'connect' before invoking this method", FaultTypes.NOT_CONNECTED) try: if not advanced_filters or not isinstance(advanced_filters, dict): advanced_filters = {} if status: advanced_filters['runtime.powerState'] = [status] property_filter = list(advanced_filters.keys()) if not 'config.files.vmPathName' in property_filter: property_filter.insert(0, 'config.files.vmPathName') #Root MOR filters ret = [] nodes = [None] if resource_pool and VIMor.is_mor(resource_pool): nodes = [resource_pool] elif resource_pool: nodes = [ k for k, v in self.get_resource_pools().items() if v == resource_pool ] elif cluster and VIMor.is_mor(cluster): nodes = [cluster] elif cluster: nodes = [ k for k, v in self.get_clusters().items() if v == cluster ] elif datacenter and VIMor.is_mor(datacenter): nodes = [datacenter] elif datacenter: nodes = [ k for k, v in self.get_datacenters().items() if v == datacenter ] for node in nodes: obj_content = self._retrieve_properties_traversal( property_names=property_filter, from_node=node, obj_type=MORTypes.VirtualMachine) if not obj_content: continue for obj in obj_content: try: prop_set = obj.PropSet except AttributeError: continue ppath = None filter_match = dict([(k, False) for k in advanced_filters.keys()]) for item in prop_set: if item.Name == 'config.files.vmPathName': ppath = item.Val elif item.Name in filter_match: expected = advanced_filters.get(item.Name) if not isinstance(expected, list): expected = [expected] if item.Val in expected: filter_match[item.Name] = True if all(filter_match.values()): ret.append(ppath) return ret except (VI.ZSI.FaultException) as e: raise VIApiException(e)
def _retrieve_properties_traversal(self, property_names=[], from_node=None, obj_type='ManagedEntity'): """Uses VI API's property collector to retrieve the properties defined in @property_names of Managed Objects of type @obj_type ('ManagedEntity' by default). Starts the search from the managed object reference @from_node (RootFolder by default). Returns the corresponding objectContent data object.""" try: if not from_node: from_node = self._do_service_content.RootFolder elif isinstance(from_node, tuple) and len(from_node) == 2: from_node = VIMor(from_node[0], from_node[1]) elif not VIMor.is_mor(from_node): raise VIException( "from_node must be a MOR object or a " "(<str> mor_id, <str> mor_type) tuple", FaultTypes.PARAMETER_ERROR) request, request_call = self._retrieve_property_request() _this = request.new__this( self._do_service_content.PropertyCollector) _this.set_attribute_type(MORTypes.PropertyCollector) request.set_element__this(_this) do_PropertyFilterSpec_specSet = request.new_specSet() props_set = [] do_PropertySpec_propSet = do_PropertyFilterSpec_specSet.new_propSet( ) do_PropertySpec_propSet.set_element_type(obj_type) do_PropertySpec_propSet.set_element_pathSet(property_names) props_set.append(do_PropertySpec_propSet) objects_set = [] do_ObjectSpec_objSet = do_PropertyFilterSpec_specSet.new_objectSet( ) mor_obj = do_ObjectSpec_objSet.new_obj(from_node) mor_obj.set_attribute_type(from_node.get_attribute_type()) do_ObjectSpec_objSet.set_element_obj(mor_obj) do_ObjectSpec_objSet.set_element_skip(False) #Recurse through all ResourcePools rp_to_rp = VI.ns0.TraversalSpec_Def('rpToRp').pyclass() rp_to_rp.set_element_name('rpToRp') rp_to_rp.set_element_type(MORTypes.ResourcePool) rp_to_rp.set_element_path('resourcePool') rp_to_rp.set_element_skip(False) rp_to_vm = VI.ns0.TraversalSpec_Def('rpToVm').pyclass() rp_to_vm.set_element_name('rpToVm') rp_to_vm.set_element_type(MORTypes.ResourcePool) rp_to_vm.set_element_path('vm') rp_to_vm.set_element_skip(False) spec_array_resource_pool = [ do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet() ] spec_array_resource_pool[0].set_element_name('rpToRp') spec_array_resource_pool[1].set_element_name('rpToVm') rp_to_rp.set_element_selectSet(spec_array_resource_pool) #Traversal through resource pool branch cr_to_rp = VI.ns0.TraversalSpec_Def('crToRp').pyclass() cr_to_rp.set_element_name('crToRp') cr_to_rp.set_element_type(MORTypes.ComputeResource) cr_to_rp.set_element_path('resourcePool') cr_to_rp.set_element_skip(False) spec_array_computer_resource = [ do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet() ] spec_array_computer_resource[0].set_element_name('rpToRp') spec_array_computer_resource[1].set_element_name('rpToVm') cr_to_rp.set_element_selectSet(spec_array_computer_resource) #Traversal through host branch cr_to_h = VI.ns0.TraversalSpec_Def('crToH').pyclass() cr_to_h.set_element_name('crToH') cr_to_h.set_element_type(MORTypes.ComputeResource) cr_to_h.set_element_path('host') cr_to_h.set_element_skip(False) #Traversal through hostFolder branch dc_to_hf = VI.ns0.TraversalSpec_Def('dcToHf').pyclass() dc_to_hf.set_element_name('dcToHf') dc_to_hf.set_element_type(MORTypes.Datacenter) dc_to_hf.set_element_path('hostFolder') dc_to_hf.set_element_skip(False) spec_array_datacenter_host = [do_ObjectSpec_objSet.new_selectSet()] spec_array_datacenter_host[0].set_element_name('visitFolders') dc_to_hf.set_element_selectSet(spec_array_datacenter_host) #Traversal through vmFolder branch dc_to_vmf = VI.ns0.TraversalSpec_Def('dcToVmf').pyclass() dc_to_vmf.set_element_name('dcToVmf') dc_to_vmf.set_element_type(MORTypes.Datacenter) dc_to_vmf.set_element_path('vmFolder') dc_to_vmf.set_element_skip(False) spec_array_datacenter_vm = [do_ObjectSpec_objSet.new_selectSet()] spec_array_datacenter_vm[0].set_element_name('visitFolders') dc_to_vmf.set_element_selectSet(spec_array_datacenter_vm) #Traversal through datastore branch dc_to_ds = VI.ns0.TraversalSpec_Def('dcToDs').pyclass() dc_to_ds.set_element_name('dcToDs') dc_to_ds.set_element_type(MORTypes.Datacenter) dc_to_ds.set_element_path('datastore') dc_to_ds.set_element_skip(False) spec_array_datacenter_ds = [do_ObjectSpec_objSet.new_selectSet()] spec_array_datacenter_ds[0].set_element_name('visitFolders') dc_to_ds.set_element_selectSet(spec_array_datacenter_ds) #Recurse through all hosts h_to_vm = VI.ns0.TraversalSpec_Def('hToVm').pyclass() h_to_vm.set_element_name('hToVm') h_to_vm.set_element_type(MORTypes.HostSystem) h_to_vm.set_element_path('vm') h_to_vm.set_element_skip(False) spec_array_host_vm = [do_ObjectSpec_objSet.new_selectSet()] spec_array_host_vm[0].set_element_name('visitFolders') h_to_vm.set_element_selectSet(spec_array_host_vm) #Recurse through all datastores ds_to_vm = VI.ns0.TraversalSpec_Def('dsToVm').pyclass() ds_to_vm.set_element_name('dsToVm') ds_to_vm.set_element_type(MORTypes.Datastore) ds_to_vm.set_element_path('vm') ds_to_vm.set_element_skip(False) spec_array_datastore_vm = [do_ObjectSpec_objSet.new_selectSet()] spec_array_datastore_vm[0].set_element_name('visitFolders') ds_to_vm.set_element_selectSet(spec_array_datastore_vm) #Recurse through the folders visit_folders = VI.ns0.TraversalSpec_Def('visitFolders').pyclass() visit_folders.set_element_name('visitFolders') visit_folders.set_element_type(MORTypes.Folder) visit_folders.set_element_path('childEntity') visit_folders.set_element_skip(False) spec_array_visit_folders = [ do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet(), do_ObjectSpec_objSet.new_selectSet() ] spec_array_visit_folders[0].set_element_name('visitFolders') spec_array_visit_folders[1].set_element_name('dcToHf') spec_array_visit_folders[2].set_element_name('dcToVmf') spec_array_visit_folders[3].set_element_name('crToH') spec_array_visit_folders[4].set_element_name('crToRp') spec_array_visit_folders[5].set_element_name('dcToDs') spec_array_visit_folders[6].set_element_name('hToVm') spec_array_visit_folders[7].set_element_name('dsToVm') spec_array_visit_folders[8].set_element_name('rpToVm') visit_folders.set_element_selectSet(spec_array_visit_folders) #Add all of them here spec_array = [ visit_folders, dc_to_vmf, dc_to_ds, dc_to_hf, cr_to_h, cr_to_rp, rp_to_rp, h_to_vm, ds_to_vm, rp_to_vm ] do_ObjectSpec_objSet.set_element_selectSet(spec_array) objects_set.append(do_ObjectSpec_objSet) do_PropertyFilterSpec_specSet.set_element_propSet(props_set) do_PropertyFilterSpec_specSet.set_element_objectSet(objects_set) request.set_element_specSet([do_PropertyFilterSpec_specSet]) return request_call(request) except (VI.ZSI.FaultException), e: raise VIApiException(e)
else: nodes = self.get_datacenters().iteritems() # todo: use self.get_datastores() instead, if possible for node in nodes: datacenter_mor, datacenter_name = node datastores = self._get_managed_objects(MORTypes.Datastore, from_mor=datacenter_mor) for k, v in datastores.iteritems(): if v == name: return VIDatastore(self, datacenter_name, v) except (VI.ZSI.FaultException), e: raise VIApiException(e) raise VIException("Cannot find a datastore named '%s'" % name, FaultTypes.OBJECT_NOT_FOUND) def get_clusters(self, from_mor=None): """ Returns a dictionary of the existing clusters. Keys are their ManagedObjectReference objects and values their names. @from_mor: if given, retrieves the clusters contained within the specified managed entity. """ return self._get_managed_objects(MORTypes.ClusterComputeResource, from_mor) def get_datacenters(self, from_mor=None): """ Returns a dictionary of the existing datacenters. keys are their ManagedObjectReference objects and values their names.
def connect(self, host, user, password, trace_file=None, sock_timeout=None): """Opens a session to a VC/ESX server with the given credentials: @host: is the server's hostname or address. If the web service uses another protocol or port than the default, you must use the full service URL (e.g. http://myhost:8888/sdk) @user: username to connect with @password: password to authenticate the session @trace_file: (optional) a file path to log SOAP requests and responses @sock_timeout: (optional) only for python >= 2.6, sets the connection timeout for sockets, in python 2.5 you'll have to use socket.setdefaulttimeout(secs) to change the global setting. """ self.__user = user self.__password = password #Generate server's URL if not isinstance(host, basestring): raise VIException("'host' should be a string with the ESX/VC url.", FaultTypes.PARAMETER_ERROR) elif (host.lower().startswith('http://') or host.lower().startswith('https://')): server_url = host.lower() else: server_url = 'https://%s/sdk' % host try: #get the server's proxy locator = VI.VimServiceLocator() args = {'url': server_url} if trace_file: trace = open(trace_file, 'w') args['tracefile'] = trace if sock_timeout and sys.version_info >= (2, 6): args['transdict'] = {'timeout': sock_timeout} self._proxy = locator.getVimPortType(**args) for header, value in self.__initial_headers.iteritems(): self._proxy.binding.AddHeader(header, value) #get service content from service instance request = VI.RetrieveServiceContentRequestMsg() mor_service_instance = request.new__this('ServiceInstance') mor_service_instance.set_attribute_type(MORTypes.ServiceInstance) request.set_element__this(mor_service_instance) self._do_service_content = self._proxy.RetrieveServiceContent( request)._returnval self.__server_type = self._do_service_content.About.Name self.__api_version = self._do_service_content.About.ApiVersion self.__api_type = self._do_service_content.About.ApiType #login request = VI.LoginRequestMsg() mor_session_manager = request.new__this( self._do_service_content.SessionManager) mor_session_manager.set_attribute_type(MORTypes.SessionManager) request.set_element__this(mor_session_manager) request.set_element_userName(user) request.set_element_password(password) self.__session = self._proxy.Login(request)._returnval self.__logged = True except (VI.ZSI.FaultException), e: raise VIApiException(e)
def clone(self, name, sync_run=True, folder=None, resourcepool=None, datastore=None, host=None, power_on=True, template=False, snapshot=None, linked=False, customize=None, data=None): """Clones this Virtual Machine @name: name of the new virtual machine @sync_run: if True (default) waits for the task to finish, and returns a VIVirtualMachine instance with the new VM (raises an exception if the task didn't succeed). If sync_run is set to False the task is started and a VITask instance is returned @folder: name of the folder that will contain the new VM, if not set the vm will be added to the folder the original VM belongs to @resourcepool: MOR of the resourcepool to be used for the new vm. If not set, it uses the same resourcepool than the original vm. @datastore: MOR of the datastore where the virtual machine should be located. If not specified, the current datastore is used. @host: MOR of the host where the virtual machine should be registered. IF not specified: * if resourcepool is not specified, current host is used. * if resourcepool is specified, and the target pool represents a stand-alone host, the host is used. * if resourcepool is specified, and the target pool represents a DRS-enabled cluster, a host selected by DRS is used. * if resource pool is specified and the target pool represents a cluster without DRS enabled, an InvalidArgument exception be thrown. @power_on: If the new VM will be powered on after being created. If template is set to True, this parameter is ignored. @template: Specifies whether or not the new virtual machine should be marked as a template. @snapshot: Snaphot MOR, or VISnaphost object, or snapshot name (if a name is given, then the first matching occurrence will be used). Is the snapshot reference from which to base the clone. If this parameter is set, the clone is based off of the snapshot point. This means that the newly created virtual machine will have the same configuration as the virtual machine at the time the snapshot was taken. If this parameter is not set then the clone is based off of the virtual machine's current configuration. @linked: If True (requires @snapshot to be set) creates a new child disk backing on the destination datastore. None of the virtual disk's existing files should be moved from their current locations. Note that in the case of a clone operation, this means that the original virtual machine's disks are now all being shared. This is only safe if the clone was taken from a snapshot point, because snapshot points are always read-only. Thus for a clone this option is only valid when cloning from a snapshot """ try: #get the folder to create the VM folders = self._server._retrieve_properties_traversal( property_names=['name', 'childEntity'], obj_type=MORTypes.Folder) folder_mor = None for f in folders: fname = "" children = [] for prop in f.PropSet: if prop.Name == "name": fname = prop.Val elif prop.Name == "childEntity": children = prop.Val.ManagedObjectReference if folder == fname or (not folder and self._mor in children): folder_mor = f.Obj break if not folder_mor and folder: raise VIException("Couldn't find folder %s" % folder, FaultTypes.OBJECT_NOT_FOUND) elif not folder_mor: raise VIException("Error locating current VM folder", FaultTypes.OBJECT_NOT_FOUND) request = VI.CloneVM_TaskRequestMsg() _this = request.new__this(self._mor) _this.set_attribute_type(self._mor.get_attribute_type()) request.set_element__this(_this) request.set_element_folder(folder_mor) request.set_element_name(name) spec = request.new_spec() if template: spec.set_element_powerOn(False) else: spec.set_element_powerOn(power_on) location = spec.new_location() if resourcepool: if not VIMor.is_mor(resourcepool): resourcepool = VIMor(resourcepool, MORTypes.ResourcePool) pool = location.new_pool(resourcepool) pool.set_attribute_type(resourcepool.get_attribute_type()) location.set_element_pool(pool) if datastore: if not VIMor.is_mor(datastore): datastore = VIMor(datastore, MORTypes.Datastore) ds = location.new_datastore(datastore) ds.set_attribute_type(datastore.get_attribute_type()) location.set_element_datastore(ds) if host: if not VIMor.is_mor(host): host = VIMor(host, MORTypes.HostSystem) hs = location.new_host(host) hs.set_attribute_type(host.get_attribute_type()) location.set_element_host(hs) if snapshot: sn_mor = None if VIMor.is_mor(snapshot): sn_mor = snapshot elif isinstance(snapshot, VISnapshot): sn_mor = snapshot._mor elif isinstance(snapshot, basestring): for sn in self.get_snapshots(): if sn.get_name() == snapshot: sn_mor = sn._mor break if not sn_mor: raise VIException( "Could not find snapshot '%s'" % snapshot, FaultTypes.OBJECT_NOT_FOUND) snapshot = spec.new_snapshot(sn_mor) snapshot.set_attribute_type(sn_mor.get_attribute_type()) spec.set_element_snapshot(snapshot) if linked and snapshot: location.set_element_diskMoveType("createNewChildDiskBacking") if not template and customize: if data is None: raise VIApiException( "Cannot use Customization without data") customization = spec.new_customization() spec.set_element_customization(customization) globalIPSettings = customization.new_globalIPSettings() customization.set_element_globalIPSettings(globalIPSettings) # nicSettingMap nicSetting = customization.new_nicSettingMap() adapter = nicSetting.new_adapter() nicSetting.set_element_adapter(adapter) ipAddress = data.get('ip') netmask = data.get('netmask') gateway = data.get('gateway') fixedip = VI.ns0.CustomizationFixedIp_Def( "ipAddress").pyclass() fixedip.set_element_ipAddress(ipAddress) #dhcp = VI.ns0.CustomizationDhcpIpGenerator_Def("ip").pyclass() adapter.set_element_ip(fixedip) adapter.set_element_subnetMask(netmask) #help(adapter.set_element_gateway([gateway,])) adapter.set_element_gateway([ gateway, ]) nicSetting.set_element_adapter(adapter) customization.set_element_nicSettingMap([ nicSetting, ]) if customize == "SYSPREP": # here starts windows identity = VI.ns0.CustomizationSysprep_Def( "identity").pyclass() customization.set_element_identity(identity) guiUnattended = identity.new_guiUnattended() guiUnattended.set_element_autoLogon(True) guiUnattended.set_element_autoLogonCount(1) passw = guiUnattended.new_password() guiUnattended.set_element_password(passw) passw.set_element_value(data["adminpw"]) passw.set_element_plainText(True) # http://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx # 85 is GMT Standard Time timeZone = data.get("timezone", 85) guiUnattended.set_element_timeZone(timeZone) identity.set_element_guiUnattended(guiUnattended) userData = identity.new_userData() userData.set_element_fullName( data.get("fullName", "PyShere")) userData.set_element_orgName( data.get("orgName", "PySphere")) userData.set_element_productId("") computerName = VI.ns0.CustomizationFixedName_Def( "computerName").pyclass() computerName.set_element_name(name.replace("_", "")) userData.set_element_computerName(computerName) identity.set_element_userData(userData) identification = identity.new_identification() if data.get("joinDomain", False): # join the domain identification.set_element_domainAdmin( data["domainAdmin"]) domainAdminPassword = identification.new_domainAdminPassword( ) domainAdminPassword.set_element_plainText(True) domainAdminPassword.set_element_value( data["domainAdminPassword"]) identification.set_element_domainAdminPassword( domainAdminPassword) identification.set_element_joinDomain( data["joinDomain"]) identity.set_element_identification(identification) elif customize == "SYSPREPTEXT": identity = VI.ns0.CustomizationSysprepText_Def( "identity").pyclass() customization.set_element_identity(identity) identity.set_element_value(data["value"]) elif customize == "LINUX": identity = VI.ns0.CustomizationLinuxPrep_Def( "identity").pyclass() customization.set_element_identity(identity) identity.set_element_domain(data["domain"]) hostName = VI.ns0.CustomizationFixedName_Def( "hostName").pyclass() hostName.set_element_name(name.replace("_", "")) identity.set_element_hostName(hostName) spec.set_element_location(location) spec.set_element_template(template) request.set_element_spec(spec) task = self._server._proxy.CloneVM_Task(request)._returnval vi_task = VITask(task, self._server) if sync_run: status = vi_task.wait_for_state( [vi_task.STATE_SUCCESS, vi_task.STATE_ERROR]) if status == vi_task.STATE_ERROR: raise VIException(vi_task.get_error_message(), FaultTypes.TASK_ERROR) return mianbao(self._server, vi_task.get_result()._obj) return vi_task except (VI.ZSI.FaultException), e: raise VIApiException(e)