def connect_bulk(self, si, logger, vcenter_data_model, request): """ :param si: :param logger: :param VMwarevCenterResourceModel vcenter_data_model: :param request: :return: """ self.vcenter_data_model = vcenter_data_model if vcenter_data_model.reserved_networks: self.reserved_networks = [name.strip() for name in vcenter_data_model.reserved_networks.split(',')] dvswitch_location = VMLocation.create_from_full_path(vcenter_data_model.default_dvswitch) self.dv_switch_path = VMLocation.combine([vcenter_data_model.default_datacenter, dvswitch_location.path]) self.dv_switch_name = dvswitch_location.name self.port_group_path = vcenter_data_model.default_port_group_location self.default_network = VMLocation.combine( [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network]) holder = DeployDataHolder(jsonpickle.decode(request)) mappings = self._map_requsets(holder.driverRequest.actions) pool = ThreadPool() async_results = self._run_async_connection_actions(si, mappings, pool, logger) results = self._get_async_results(async_results, pool) return results
def _update_deploy_from_image_vm_location(self, data_holder, folder_manager, logger, si, vcenter_resource_model): vm_location = data_holder.image_params.vm_location or vcenter_resource_model.vm_location folder_path = VMLocation.combine([vcenter_resource_model.default_datacenter, vm_location]) folder_manager.get_or_create_vcenter_folder(si, logger, folder_path, DEPLOYED_APPS) data_holder.image_params.vm_location = VMLocation.combine([vm_location, DEPLOYED_APPS]) logger.info('VM will be deployed to {0}'.format(data_holder.image_params.vm_location))
def connect_bulk(self, si, logger, vcenter_data_model, request): """ :param si: :param logger: :param VMwarevCenterResourceModel vcenter_data_model: :param request: :return: """ self.logger = logger self.logger.info('Apply connectivity changes has started') self.logger.debug( 'Apply connectivity changes has started with the requet: {0}'. format(request)) holder = DeployDataHolder(jsonpickle.decode(request)) self.vcenter_data_model = vcenter_data_model if vcenter_data_model.reserved_networks: self.reserved_networks = [ name.strip() for name in vcenter_data_model.reserved_networks.split(',') ] if not vcenter_data_model.default_dvswitch: return self._handle_no_dvswitch_error(holder) dvswitch_location = VMLocation.create_from_full_path( vcenter_data_model.default_dvswitch) self.dv_switch_path = VMLocation.combine( [vcenter_data_model.default_datacenter, dvswitch_location.path]) self.dv_switch_name = dvswitch_location.name self.default_network = VMLocation.combine([ vcenter_data_model.default_datacenter, vcenter_data_model.holding_network ]) mappings = self._map_requsets(holder.driverRequest.actions) self.logger.debug('Connectivity actions mappings: {0}'.format( jsonpickle.encode(mappings, unpicklable=False))) pool = ThreadPool() async_results = self._run_async_connection_actions( si, mappings, pool, logger) results = self._get_async_results(async_results, pool) self.logger.info('Apply connectivity changes done') self.logger.debug( 'Apply connectivity has finished with the results: {0}'.format( jsonpickle.encode(results, unpicklable=False))) return results
def disconnect_from_networks(self, si, logger, vcenter_data_model, vm_uuid, vm_network_remove_mappings): default_network = VMLocation.combine( [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network]) vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) if not vm: raise ValueError('VM having UUID {0} not found'.format(vm_uuid)) default_network = self.pyvmomi_service.get_network_by_full_name(si, default_network) mappings = [] vnics = [] for vm_network_remove_mapping in vm_network_remove_mappings: vnic = self.pyvmomi_service.get_vnic_by_mac_address(vm, vm_network_remove_mapping.mac_address) if vnic is None: raise KeyError('VNIC having MAC address {0} not found on VM having UUID {1}' .format(vm_network_remove_mapping.mac_address, vm_uuid)) vnics.append(vnic) mappings.append(VNicDeviceMapper(connect=False, network=default_network, requested_vnic=vm_network_remove_mapping.mac_address, vnic=vnic, mac=vm_network_remove_mapping.mac_address)) networks_to_remove = self.port_group_configurer.get_networks_on_vnics(vm, vnics, logger) res = self.port_group_configurer.update_vnic_by_mapping(vm, mappings, logger) self.port_group_configurer.erase_network_by_mapping(networks_to_remove, vcenter_data_model.reserved_networks, logger) return res
def refresh_ip(self, si, logger, session, vcenter_data_model, vm_uuid, resource_name, cancellation_context,app_request_json): """ Refreshes IP address of virtual machine and updates Address property on the resource :param vim.ServiceInstance si: py_vmomi service instance :param logger: :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session :param str vm_uuid: UUID of Virtual Machine :param str resource_name: Logical resource name to update address property on :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes :param cancellation_context: """ self._do_not_run_on_static_vm(app_request_json=app_request_json) default_network = VMLocation.combine( [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network]) resource = session.GetResourceDetails(resource_name) match_function = self.ip_manager.get_ip_match_function(self._get_ip_refresh_ip_regex(resource)) timeout = self._get_ip_refresh_timeout(resource) vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) ip_res = self.ip_manager.get_ip(vm, default_network, match_function, cancellation_context, timeout, logger) if ip_res.reason == IpReason.Timeout: raise ValueError('IP address of VM \'{0}\' could not be obtained during {1} seconds' .format(resource_name, timeout)) if ip_res.reason == IpReason.Success: session.UpdateResourceAddress(resource_name, ip_res.ip_address) return ip_res.ip_address
def get_vm_full_path(self, si, vm): """ :param vm: vim.VirtualMachine :return: """ folder_name = None folder = vm.parent if folder: folder_name = folder.name folder_parent = folder.parent while folder_parent and folder_parent.name and folder_parent != si.content.rootFolder and not isinstance( folder_parent, vim.Datacenter): folder_name = folder_parent.name + '/' + folder_name try: folder_parent = folder_parent.parent except Exception: break # at this stage we receive a path like this: vm/FOLDER1/FOLDER2; # we're not interested in the "vm" part, so we throw that away folder_name = '/'.join(folder_name.split('/')[1:]) # ok, now we're adding the vm name; btw, if there is no folder, that's cool, just return vm.name return VMLocation.combine([folder_name, vm.name ]) if folder_name else vm.name
def get_or_create_vcenter_folder(self, si, logger, path, folder_name): logger.info('Getting or creating {0} in {1}'.format(folder_name, path)) folder_parent = self.pv_service.get_folder(si, path) if not folder_parent: logger.error('Could not find {0}'.format(path)) raise Exception("Could not find " + path) vcenter_folder_path = VMLocation.combine([path, folder_name]) if vcenter_folder_path not in self.locks.keys(): with self.locks_lock: if vcenter_folder_path not in self.locks.keys(): self.locks[vcenter_folder_path] = Lock() vcenter_folder = self.pv_service.get_folder(si, vcenter_folder_path) if not vcenter_folder: with self.locks[vcenter_folder_path]: vcenter_folder = self.pv_service.get_folder(si, vcenter_folder_path) if not vcenter_folder: logger.info('{0} was not found under {1}, creating...'.format(folder_name, path)) folder_parent.CreateFolder(folder_name) logger.info('{0} created in path {1}'.format(folder_name, path)) else: logger.info('{0} already exists'.format(folder_name)) return vcenter_folder
def _deploy_a_clone(self, si, logger, app_name, template_name, other_params, vcenter_data_model, snapshot=''): # generate unique name vm_name = self.name_generator(app_name) VCenterDetailsFactory.set_deplyment_vcenter_params( vcenter_resource_model=vcenter_data_model, deploy_params=other_params) template_name = VMLocation.combine([other_params.default_datacenter, template_name]) params = self.pv_service.CloneVmParameters(si=si, template_name=template_name, vm_name=vm_name, vm_folder=other_params.vm_location, datastore_name=other_params.vm_storage, cluster_name=other_params.vm_cluster, resource_pool=other_params.vm_resource_pool, power_on=other_params.auto_power_on, snapshot=snapshot) clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger) if clone_vm_result.error: raise Exception(clone_vm_result.error) return DeployResult(vm_name=vm_name, vm_uuid=clone_vm_result.vm.summary.config.uuid, cloud_provider_resource_name=other_params.vcenter_name, ip_regex=other_params.ip_regex, refresh_ip_timeout=other_params.refresh_ip_timeout, auto_power_on=other_params.auto_power_on, auto_power_off=other_params.auto_power_off, wait_for_ip=other_params.wait_for_ip, auto_delete=other_params.auto_delete, autoload=other_params.autoload )
def clone_vm(self, clone_params, logger): """ Clone a VM from a template/VM and return the vm oject or throws argument is not valid :param clone_params: CloneVmParameters = :param logger: """ result = self.CloneVmResult() if not isinstance(clone_params.si, self.vim.ServiceInstance): result.error = 'si must be init as ServiceInstance' return result if clone_params.template_name is None: result.error = 'template_name param cannot be None' return result if clone_params.vm_name is None: result.error = 'vm_name param cannot be None' return result if clone_params.vm_folder is None: result.error = 'vm_folder param cannot be None' return result datacenter = self.get_datacenter(clone_params) dest_folder = self._get_destination_folder(clone_params) vm_location = VMLocation.create_from_full_path(clone_params.template_name) template = self._get_template(clone_params, vm_location) datastore = self._get_datastore(clone_params) resource_pool, host = self._get_resource_pool(datacenter.name, clone_params) if not resource_pool and not host: raise ValueError('The specifed host, cluster or resource pool could not be found') '# set relo_spec' placement = self.vim.vm.RelocateSpec() placement.datastore = datastore if resource_pool: placement.pool = resource_pool if host: placement.host = host clone_spec = self.vim.vm.CloneSpec() clone_spec.location = placement clone_spec.powerOn = clone_params.power_on logger.info("cloning VM...") task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec) vm = self.wait_for_task(task, logger) result.vm = vm return result
def load_vm_uuid_by_name(self, si, vcenter_data_model, vm_name): """ Returns the vm uuid :param si: Service instance to the vcenter :param vcenter_data_model: vcenter data model :param vm_name: the vm name :return: str uuid """ path = VMLocation.combine([vcenter_data_model.default_datacenter, vm_name]) paths = path.split('/') name = paths[len(paths) - 1] path = VMLocation.combine(paths[:len(paths) - 1]) vm = self.pv_service.find_vm_by_name(si, path, name) if not vm: raise ValueError('Could not find the vm in the given path: {0}/{1}'.format(path, name)) if isinstance(vm, vim.VirtualMachine): return vm.config.uuid raise ValueError('The given object is not a vm: {0}/{1}'.format(path, name))
def disconnect(self, si, logger, vcenter_data_model, vm_uuid, network_name=None, vm=None): """ disconnect network adapter of the vm. If 'network_name' = None - disconnect ALL interfaces :param <str> si: :param logger: :param VMwarevCenterResourceModel vcenter_data_model: :param <str> vm_uuid: the uuid of the vm :param <str | None> network_name: the name of the specific network to disconnect :param <pyvmomi vm object> vm: If the vm obj is None will use vm_uuid to fetch the object :return: Started Task """ logger.debug( "Disconnect Interface VM: '{0}' Network: '{1}' ...".format( vm_uuid, network_name or "ALL")) if vm is None: vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) if not vm: return "Warning: failed to locate vm {0} in vCenter".format( vm_uuid) if network_name: network = self.pyvmomi_service.vm_get_network_by_name( vm, network_name) if network is None: raise KeyError('Network not found ({0})'.format(network_name)) else: network = None network_full_name = VMLocation.combine([ vcenter_data_model.default_datacenter, vcenter_data_model.holding_network ]) default_network = self.pyvmomi_service.get_network_by_full_name( si, network_full_name) if network: return self.port_group_configurer.disconnect_network( vm, network, default_network, vcenter_data_model.reserved_networks, logger=logger) else: return self.port_group_configurer.disconnect_all_networks( vm, default_network, vcenter_data_model.reserved_networks, logger=logger)
def connect_bulk(self, si, logger, vcenter_data_model, request): """ :param si: :param logger: :param VMwarevCenterResourceModel vcenter_data_model: :param request: :return: """ self.logger = logger self.logger.info('Apply connectivity changes has started') self.logger.debug('Apply connectivity changes has started with the requet: {0}'.format(request)) holder = DeployDataHolder(jsonpickle.decode(request)) self.vcenter_data_model = vcenter_data_model if vcenter_data_model.reserved_networks: self.reserved_networks = [name.strip() for name in vcenter_data_model.reserved_networks.split(',')] if not vcenter_data_model.default_dvswitch: return self._handle_no_dvswitch_error(holder) dvswitch_location = VMLocation.create_from_full_path(vcenter_data_model.default_dvswitch) self.dv_switch_path = VMLocation.combine([vcenter_data_model.default_datacenter, dvswitch_location.path]) self.dv_switch_name = dvswitch_location.name self.default_network = VMLocation.combine( [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network]) mappings = self._map_requsets(holder.driverRequest.actions) self.logger.debug('Connectivity actions mappings: {0}'.format(jsonpickle.encode(mappings, unpicklable=False))) pool = ThreadPool() async_results = self._run_async_connection_actions(si, mappings, pool, logger) results = self._get_async_results(async_results, pool) self.logger.info('Apply connectivity changes done') self.logger.debug('Apply connectivity has finished with the results: {0}'.format(jsonpickle.encode(results, unpicklable=False))) return results
def delete(self, delete_saved_app_actions, cancellation_context, pool): self.logger.info('Delete saved sandbox started') tasks = self._get_delete_tasks(delete_saved_app_actions) if self.cs.check_if_cancelled(cancellation_context): raise Exception('Delete saved sandbox was cancelled') artifacts = [(artifact, cancellation_context) for task in tasks for artifact in task.artifacts] pool.map(self._get_rid_of_vm_if_found, artifacts) if self.cs.check_if_cancelled(cancellation_context): raise Exception('Delete saved sandbox was cancelled') root_path = VMLocation.combine([ self.vcenter_data_model.default_datacenter, self.vcenter_data_model.vm_location ]) saved_sandbox_paths = { self._get_saved_sandbox_id_full_path( root_path, task.action.actionParams.savedSandboxId) for task in tasks } self.logger.info('Saved sandbox path/s: {0}'.format( ', '.join(saved_sandbox_paths))) for path in saved_sandbox_paths: self.logger.info( 'Going to dispose of saved sandbox {0}'.format(path)) folder = self.pv_service.get_folder(self.si, path) if not folder: folder_not_found_msg = 'Could not find folder: {0}'.format( path) self.logger.info(folder_not_found_msg) result = SUCCESS msg = folder_not_found_msg else: self.logger.info('Found folder: {0}'.format(path)) result = self.folder_manager.delete_folder(folder, self.logger) msg = '' [ task.set_result(result) and task.set_msg(msg) for task in tasks if task.action.actionParams.savedSandboxId in path ] return [task.DeleteSavedAppResult() for task in tasks]
def load_vm_uuid_by_name(self, si, vcenter_data_model, vm_name): """ Returns the vm uuid :param si: Service instance to the vcenter :param vcenter_data_model: vcenter data model :param vm_name: the vm name :return: str uuid """ path = VMLocation.combine( [vcenter_data_model.default_datacenter, vm_name]) paths = path.split('/') name = paths[len(paths) - 1] path = VMLocation.combine(paths[:len(paths) - 1]) vm = self.pv_service.find_vm_by_name(si, path, name) if not vm: raise ValueError( 'Could not find the vm in the given path: {0}/{1}'.format( path, name)) if isinstance(vm, vim.VirtualMachine): return vm.config.uuid raise ValueError('The given object is not a vm: {0}/{1}'.format( path, name))
def _deploy_a_clone(self, si, logger, app_name, template_name, other_params, vcenter_data_model, reservation_id, cancellation_context, snapshot=''): """ :rtype DeployAppResult: """ # generate unique name vm_name = self.name_generator(app_name, reservation_id) VCenterDetailsFactory.set_deplyment_vcenter_params( vcenter_resource_model=vcenter_data_model, deploy_params=other_params) template_name = VMLocation.combine([other_params.default_datacenter, template_name]) params = self.pv_service.CloneVmParameters(si=si, template_name=template_name, vm_name=vm_name, vm_folder=other_params.vm_location, datastore_name=other_params.vm_storage, cluster_name=other_params.vm_cluster, resource_pool=other_params.vm_resource_pool, power_on=False, snapshot=snapshot) if cancellation_context.is_cancelled: raise Exception("Action 'Clone VM' was cancelled.") clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger, cancellation_context=cancellation_context) if clone_vm_result.error: raise Exception(clone_vm_result.error) # remove a new created vm due to cancellation if cancellation_context.is_cancelled: self.pv_service.destroy_vm(vm=clone_vm_result.vm, logger=logger) raise Exception("Action 'Clone VM' was cancelled.") vm_details_data = self._safely_get_vm_details(clone_vm_result.vm, vm_name, vcenter_data_model, other_params, logger) return DeployAppResult(vmName=vm_name, vmUuid=clone_vm_result.vm.summary.config.uuid, vmDetailsData=vm_details_data, deployedAppAdditionalData={'ip_regex': other_params.ip_regex, 'refresh_ip_timeout': other_params.refresh_ip_timeout, 'auto_power_off': convert_to_bool(other_params.auto_power_off), 'auto_delete': convert_to_bool(other_params.auto_delete)})
def _disconnect_all_quali_created_networks(self, result): thread_id = threading.current_thread().ident self.logger.info( '{0} clearing networks configured by cloudshell on saved sandbox source app {1}' .format(thread_id, result.vmName)) network_full_name = VMLocation.combine([ self.vcenter_data_model.default_datacenter, self.vcenter_data_model.holding_network ]) self.logger.info('{0} Holding network is {1}'.format( thread_id, network_full_name)) default_network = self.pv_service.get_network_by_full_name( self.si, network_full_name) vm = self.pv_service.get_vm_by_uuid(self.si, result.vmUuid) self.pg_configurer.disconnect_all_networks_if_created_by_quali( vm, default_network, self.vcenter_data_model.reserved_networks, self.logger)
def deploy_from_template(self, si, logger, data_holder, resource_context): """ :param si: :param logger: :type data_holder: DeployFromTemplateDetails :type resource_context :return: """ # generate unique name vm_name = self.name_generator(data_holder.app_name) vcenter_resource_model = self.resource_model_parser.convert_to_resource_model(resource_context, VMwarevCenterResourceModel) template_resource_model = data_holder.template_resource_model VCenterDetailsFactory.set_deplyment_vcenter_params( vcenter_resource_model=vcenter_resource_model, deploy_params=template_resource_model) template_name = VMLocation.combine([template_resource_model.default_datacenter, template_resource_model.vcenter_template]) params = self.pv_service.CloneVmParameters(si=si, template_name=template_name, vm_name=vm_name, vm_folder=template_resource_model.vm_location, datastore_name=template_resource_model.vm_storage, cluster_name=template_resource_model.vm_cluster, resource_pool=template_resource_model.vm_resource_pool, power_on=template_resource_model.auto_power_on) clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger) if clone_vm_result.error: raise Exception(clone_vm_result.error) return DeployResult(vm_name=vm_name, vm_uuid=clone_vm_result.vm.summary.config.uuid, cloud_provider_resource_name=template_resource_model.vcenter_name, ip_regex=template_resource_model.ip_regex, refresh_ip_timeout=template_resource_model.refresh_ip_timeout, auto_power_on=template_resource_model.auto_power_on, auto_power_off=template_resource_model.auto_power_off, wait_for_ip=template_resource_model.wait_for_ip, auto_delete=template_resource_model.auto_delete, autoload=template_resource_model.autoload )
def disconnect_from_networks(self, si, logger, vcenter_data_model, vm_uuid, vm_network_remove_mappings): default_network = VMLocation.combine([ vcenter_data_model.default_datacenter, vcenter_data_model.holding_network ]) vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) if not vm: raise ValueError('VM having UUID {0} not found'.format(vm_uuid)) default_network = self.pyvmomi_service.get_network_by_full_name( si, default_network) mappings = [] vnics = [] for vm_network_remove_mapping in vm_network_remove_mappings: vnic = self.pyvmomi_service.get_vnic_by_mac_address( vm, vm_network_remove_mapping.mac_address) if vnic is None: raise KeyError( 'VNIC having MAC address {0} not found on VM having UUID {1}' .format(vm_network_remove_mapping.mac_address, vm_uuid)) vnics.append(vnic) mappings.append( VNicDeviceMapper( connect=False, network=default_network, requested_vnic=vm_network_remove_mapping.mac_address, vnic=vnic, mac=vm_network_remove_mapping.mac_address)) networks_to_remove = self.port_group_configurer.get_networks_on_vnics( vm, vnics, logger) res = self.port_group_configurer.update_vnic_by_mapping( vm, mappings, logger) self.port_group_configurer.erase_network_by_mapping( networks_to_remove, vcenter_data_model.reserved_networks, logger) return res
def refresh_ip(self, si, logger, session, vcenter_data_model, resource_model, cancellation_context, app_request_json): """ Refreshes IP address of virtual machine and updates Address property on the resource :param vim.ServiceInstance si: py_vmomi service instance :param logger: :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session :param GenericDeployedAppResourceModel resource_model: UUID of Virtual Machine :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes :param cancellation_context: """ self._do_not_run_on_static_vm(app_request_json=app_request_json) default_network = VMLocation.combine([ vcenter_data_model.default_datacenter, vcenter_data_model.holding_network ]) match_function = self.ip_manager.get_ip_match_function( self._get_ip_refresh_ip_regex(resource_model.vm_custom_params)) timeout = self._get_ip_refresh_timeout(resource_model.vm_custom_params) vm = self.pyvmomi_service.find_by_uuid(si, resource_model.vm_uuid) ip_res = self.ip_manager.get_ip(vm, default_network, match_function, cancellation_context, timeout, logger) if ip_res.reason == IpReason.Timeout: raise ValueError( 'IP address of VM \'{0}\' could not be obtained during {1} seconds' .format(resource_model.fullname, timeout)) if ip_res.reason == IpReason.Success: self._update_resource_address_with_retry( session=session, resource_name=resource_model.fullname, ip_address=ip_res.ip_address) return ip_res.ip_address
def refresh_ip(self, si, logger, session, vcenter_data_model, vm_uuid, resource_name, cancellation_context): """ Refreshes IP address of virtual machine and updates Address property on the resource :param vim.ServiceInstance si: py_vmomi service instance :param logger: :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session :param str vm_uuid: UUID of Virtual Machine :param str resource_name: Logical resource name to update address property on :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes :param cancellation_context: """ default_network = VMLocation.combine([ vcenter_data_model.default_datacenter, vcenter_data_model.holding_network ]) resource = session.GetResourceDetails(resource_name) match_function = self.ip_manager.get_ip_match_function( self._get_ip_refresh_ip_regex(resource)) timeout = self._get_ip_refresh_timeout(resource) vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) ip_res = self.ip_manager.get_ip(vm, default_network, match_function, cancellation_context, timeout, logger) if ip_res.reason == IpReason.Timeout: raise ValueError( 'IP address of VM \'{0}\' could not be obtained during {1} seconds' .format(resource_name, timeout)) if ip_res.reason == IpReason.Success: session.UpdateResourceAddress(resource_name, ip_res.ip_address) return ip_res.ip_address
def set_deplyment_vcenter_params(vcenter_resource_model, deploy_params): """ Sets the vcenter parameters if not already set at the deployment option :param deploy_params: vCenterVMFromTemplateResourceModel or vCenterVMFromImageResourceModel :type vcenter_resource_model: VMwarevCenterResourceModel """ # Override attributes deploy_params.vm_cluster = deploy_params.vm_cluster or vcenter_resource_model.vm_cluster deploy_params.vm_storage = deploy_params.vm_storage or vcenter_resource_model.vm_storage deploy_params.vm_resource_pool = deploy_params.vm_resource_pool or vcenter_resource_model.vm_resource_pool deploy_params.vm_location = deploy_params.vm_location or vcenter_resource_model.vm_location deploy_params.default_datacenter = vcenter_resource_model.default_datacenter if not deploy_params.vm_cluster: raise ValueError('VM Cluster is empty') if not deploy_params.vm_storage: raise ValueError('VM Storage is empty') if not deploy_params.vm_location: raise ValueError('VM Location is empty') if not deploy_params.default_datacenter: raise ValueError('Default Datacenter attribute on VMWare vCenter is empty') deploy_params.vm_location = VMLocation.combine([deploy_params.default_datacenter, deploy_params.vm_location])
def disconnect(self, si, logger, vcenter_data_model, vm_uuid, network_name=None, vm=None): """ disconnect network adapter of the vm. If 'network_name' = None - disconnect ALL interfaces :param <str> si: :param logger: :param VMwarevCenterResourceModel vcenter_data_model: :param <str> vm_uuid: the uuid of the vm :param <str | None> network_name: the name of the specific network to disconnect :param <pyvmomi vm object> vm: If the vm obj is None will use vm_uuid to fetch the object :return: Started Task """ logger.debug("Disconnect Interface VM: '{0}' Network: '{1}' ...".format(vm_uuid, network_name or "ALL")) if vm is None: vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid) if not vm: return "Warning: failed to locate vm {0} in vCenter".format(vm_uuid) if network_name: network = self.pyvmomi_service.vm_get_network_by_name(vm, network_name) if network is None: raise KeyError('Network not found ({0})'.format(network_name)) else: network = None network_full_name = VMLocation.combine( [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network]) default_network = self.pyvmomi_service.get_network_by_full_name(si, network_full_name) if network: return self.port_group_configurer.disconnect_network(vm, network, default_network, vcenter_data_model.reserved_networks, logger=logger) else: return self.port_group_configurer.disconnect_all_networks(vm, default_network, vcenter_data_model.reserved_networks, logger=logger)
def test_create_from_full_path(self): vm_location = VMLocation.create_from_full_path('QualiSB/Alex/test') self.assertEqual(vm_location.path, 'QualiSB/Alex') self.assertEqual(vm_location.name, 'test')
def clone_vm(self, clone_params, logger): """ Clone a VM from a template/VM and return the vm oject or throws argument is not valid :param clone_params: CloneVmParameters = :param logger: """ result = self.CloneVmResult() if not isinstance(clone_params.si, self.vim.ServiceInstance): result.error = 'si must be init as ServiceInstance' return result if clone_params.template_name is None: result.error = 'template_name param cannot be None' return result if clone_params.vm_name is None: result.error = 'vm_name param cannot be None' return result if clone_params.vm_folder is None: result.error = 'vm_folder param cannot be None' return result datacenter = self.get_datacenter(clone_params) dest_folder = self._get_destination_folder(clone_params) vm_location = VMLocation.create_from_full_path(clone_params.template_name) template = self._get_template(clone_params, vm_location) snapshot = self._get_snapshot(clone_params, template) resource_pool, host = self._get_resource_pool(datacenter.name, clone_params) if not resource_pool and not host: raise ValueError('The specifed host, cluster or resource pool could not be found') '# set relo_spec' placement = self.vim.vm.RelocateSpec() if resource_pool: placement.pool = resource_pool if host: placement.host = host clone_spec = self.vim.vm.CloneSpec() if snapshot: clone_spec.snapshot = snapshot clone_spec.template = False placement.diskMoveType = 'createNewChildDiskBacking' placement.datastore = self._get_datastore(clone_params) # after deployment the vm must be powered off and will be powered on if needed by orchestration driver clone_spec.location = placement # clone_params.power_on # due to hotfix 1 for release 1.0, clone_spec.powerOn = False logger.info("cloning VM...") try: task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec) vm = self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Clone VM') except vim.fault.NoPermission as error: logger.error("vcenter returned - no permission: {0}".format(error)) raise Exception('Permissions is not set correctly, please check the log for more info.') except Exception as e: logger.error("error deploying: {0}".format(e)) raise Exception('Error has occurred while deploying, please look at the log for more info.') result.vm = vm return result
def clone_vm(self, clone_params, logger, cancellation_context): """ Clone a VM from a template/VM and return the vm oject or throws argument is not valid :param cancellation_context: :param clone_params: CloneVmParameters = :param logger: """ result = self.CloneVmResult() if not isinstance(clone_params.si, self.vim.ServiceInstance): result.error = 'si must be init as ServiceInstance' return result if clone_params.template_name is None: result.error = 'template_name param cannot be None' return result if clone_params.vm_name is None: result.error = 'vm_name param cannot be None' return result if clone_params.vm_folder is None: result.error = 'vm_folder param cannot be None' return result datacenter = self.get_datacenter(clone_params) dest_folder = self._get_destination_folder(clone_params) vm_location = VMLocation.create_from_full_path( clone_params.template_name) template = self._get_template(clone_params, vm_location) snapshot = self._get_snapshot(clone_params, template) resource_pool, host = self.get_resource_pool(datacenter.name, clone_params) if not resource_pool and not host: raise ValueError( 'The specifed host, cluster or resource pool could not be found' ) '# set relo_spec' placement = self.vim.vm.RelocateSpec() if resource_pool: placement.pool = resource_pool if host: placement.host = host clone_spec = self.vim.vm.CloneSpec() if snapshot: clone_spec.snapshot = snapshot clone_spec.template = False placement.diskMoveType = 'createNewChildDiskBacking' placement.datastore = self._get_datastore(clone_params) # after deployment the vm must be powered off and will be powered on if needed by orchestration driver clone_spec.location = placement # clone_params.power_on # due to hotfix 1 for release 1.0, clone_spec.powerOn = False logger.info("cloning VM...") try: task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec) vm = self.task_waiter.wait_for_task( task=task, logger=logger, action_name='Clone VM', cancellation_context=cancellation_context) except TaskFaultException: raise except vim.fault.NoPermission as error: logger.error("vcenter returned - no permission: {0}".format(error)) raise Exception( 'Permissions is not set correctly, please check the log for more info.' ) except Exception as e: logger.error("error deploying: {0}".format(e)) raise Exception( 'Error has occurred while deploying, please look at the log for more info.' ) result.vm = vm return result
def test_combine(self): combined_path = VMLocation.combine(['QualiSB', 'Alex']) self.assertEqual(combined_path, 'QualiSB/Alex')
def _get_saved_sandbox_id_full_path(self, vm_location, saved_sandbox_id): saved_sandbox_path = VMLocation.combine( [vm_location, SAVED_SANDBOXES, saved_sandbox_id]) return saved_sandbox_path