class DeployFromImage(ResourceDriverInterface): def cleanup(self): pass def __init__(self): self.cs_helper = CloudshellDriverHelper() self.resource_model_parser = ResourceModelParser() def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from image :type context: models.QualiDriverModels.ResourceCommandContext """ session = self.cs_helper.get_session( context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) # get vCenter resource name, template name, template folder vcenter_image_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromImageResourceModel) vcenter_res = vcenter_image_resource_model.vcenter_name if not Name: Name = jsonpickle.decode( context.resource.app_context.app_request_json)['name'] deployment_info = self._get_deployment_info( vcenter_image_resource_model, Name) result = session.ExecuteCommand( context.reservation.reservation_id, vcenter_res, "Resource", "deploy_from_image", self._get_command_inputs_list(deployment_info), False) return result.Output def _get_deployment_info(self, image_model, name): """ :type image_model: vCenterVMFromImageResourceModel """ return DeployDataHolder({ 'app_name': name, 'image_params': image_model }) def _get_command_inputs_list(self, data_holder): return [ InputNameValue('deploy_data', jsonpickle.encode(data_holder, unpicklable=False)) ]
class DeployFromImage(ResourceDriverInterface): def cleanup(self): pass def __init__(self): self.cs_helper = CloudshellDriverHelper() self.resource_model_parser = ResourceModelParser() def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from image :type context: models.QualiDriverModels.ResourceCommandContext """ session = self.cs_helper.get_session(context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) # get vCenter resource name, template name, template folder vcenter_image_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromImageResourceModel) vcenter_res = vcenter_image_resource_model.vcenter_name if not Name: Name = jsonpickle.decode(context.resource.app_context.app_request_json)['name'] deployment_info = self._get_deployment_info(vcenter_image_resource_model, Name) result = session.ExecuteCommand(context.reservation.reservation_id, vcenter_res, "Resource", "deploy_from_image", self._get_command_inputs_list(deployment_info), False) return result.Output def _get_deployment_info(self, image_model, name): """ :type image_model: vCenterVMFromImageResourceModel """ return DeployDataHolder({'app_name': name, 'image_params': image_model }) def _get_command_inputs_list(self, data_holder): return [InputNameValue('deploy_data', jsonpickle.encode(data_holder, unpicklable=False))]
def test_parse_resource_info_model(self): resource_model_parser = ResourceModelParser() resource_info = create_autospec(ResourceInfo) resource_info.ResourceModelName = 'VLAN Auto' resource_info.ResourceAttributes = {'Access Mode': 'Trunk', 'VLAN Id': '123', 'Allocation Ranges': '2-4094', 'Virtual Network': '', 'Isolation Level': 'Exclusive'} resource_model = resource_model_parser.convert_to_resource_model(resource_info, None) self.assertEqual(resource_model.access_mode, 'Trunk') self.assertEqual(resource_model.vlan_id, '123') self.assertEqual(resource_model.isolation_level, 'Exclusive') self.assertEqual(resource_model.allocation_ranges, '2-4094') self.assertEqual(resource_model.virtual_network, '') self.assertEqual(resource_model.virtual_network_attribute, 'Virtual Network')
class DeployFromTemplateDriver(ResourceDriverInterface): def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper() def cleanup(self): pass def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from template :type context: models.QualiDriverModels.ResourceCommandContext :param Name: Name of the Deployment :type Name: str :rtype: str """ session = self.cs_helper.get_session( context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) vcenter_template_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromTemplateResourceModel) if not Name: Name = jsonpickle.decode( context.resource.app_context.app_request_json)['name'] deploy_from_template_details = DeployFromTemplateDetails( vcenter_template_resource_model, Name) params = [ InputNameValue( 'deploy_data', jsonpickle.encode(deploy_from_template_details, unpicklable=False)) ] reservation_id = context.reservation.reservation_id result = session.ExecuteCommand( reservation_id, vcenter_template_resource_model.vcenter_name, "Resource", "deploy_from_template", params, False) return result.Output
def test_parse_response_info(self): resource_info = create_autospec(ResourceInfo) resource_info.ResourceModelName = 'Generic Deployed App' vm_uuid_attribute = create_autospec(ResourceAttribute) vm_uuid_attribute.Name = 'VM_UUID' vm_uuid_attribute.Value = '422258cd-8b76-e375-8c3b-8e1bf86a4713' cloud_provider_attribute = create_autospec(ResourceAttribute) cloud_provider_attribute.Name = 'Cloud Provider' cloud_provider_attribute.Value = 'vCenter' resource_info.ResourceAttributes = [vm_uuid_attribute, cloud_provider_attribute] resource_model_parser = ResourceModelParser() resource_model = resource_model_parser.convert_to_resource_model(resource_info, None) self.assertEqual(resource_model.vm_uuid, '422258cd-8b76-e375-8c3b-8e1bf86a4713')
class DeployCloneFromVMDriver(ResourceDriverInterface): def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper() def cleanup(self): pass def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from template :type context: models.QualiDriverModels.ResourceCommandContext :param Name: Name of the Deployment :type Name: str :rtype: str """ session = self.cs_helper.get_session(context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) vcenter_template_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, VCenterDeployVMFromLinkedCloneResourceModel) if not Name: Name = jsonpickle.decode(context.resource.app_context.app_request_json)['name'] deploy_from_template_details = DeployFromTemplateDetails(vcenter_template_resource_model, Name) params = [InputNameValue('deploy_data', jsonpickle.encode(deploy_from_template_details, unpicklable=False))] reservation_id = context.reservation.reservation_id result = session.ExecuteCommand(reservation_id, vcenter_template_resource_model.vcenter_name, "Resource", "deploy_from_linked_clone", params, False) return result.Output
def test_parse_resource_info_model(self): resource_model_parser = ResourceModelParser() attributes = { 'Access Mode': 'Trunk', 'VLAN Id': '123', 'Allocation Ranges': '2-4094', 'Virtual Network': '', 'Isolation Level': 'Exclusive' } resource_model = resource_model_parser.convert_to_resource_model( attributes, VLANAutoResourceModel) self.assertEqual(resource_model.access_mode, 'Trunk') self.assertEqual(resource_model.vlan_id, '123') self.assertEqual(resource_model.isolation_level, 'Exclusive') self.assertEqual(resource_model.allocation_ranges, '2-4094') self.assertEqual(resource_model.virtual_network, '') self.assertEqual(resource_model.virtual_network_attribute, 'Virtual Network')
class CommandOrchestrator(object): def __init__(self): """ Initialize the driver session, this function is called everytime a new instance of the driver is created in here the driver is going to be bootstrapped """ synchronous_task_waiter = SynchronousTaskWaiter() cancellation_service = CommandCancellationService() pv_service = pyVmomiService(connect=SmartConnect, disconnect=Disconnect, task_waiter=synchronous_task_waiter) self.resource_model_parser = ResourceModelParser() port_group_name_generator = DvPortGroupNameGenerator() vnic_to_network_mapper = VnicToNetworkMapper( quali_name_generator=port_group_name_generator) resource_remover = CloudshellResourceRemover() ovf_service = OvfImageDeployerService(self.resource_model_parser) self.vm_loader = VMLoader(pv_service) ip_manager = VMIPManager() vm_details_provider = VmDetailsProvider(pyvmomi_service=pv_service, ip_manager=ip_manager) vm_deployer = VirtualMachineDeployer( pv_service=pv_service, name_generator=generate_unique_name, ovf_service=ovf_service, resource_model_parser=self.resource_model_parser, vm_details_provider=vm_details_provider) dv_port_group_creator = DvPortGroupCreator( pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) virtual_machine_port_group_configurer = \ VirtualMachinePortGroupConfigurer(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter, vnic_to_network_mapper=vnic_to_network_mapper, vnic_service=VNicService(), name_gen=port_group_name_generator) virtual_switch_to_machine_connector = VirtualSwitchToMachineConnector( dv_port_group_creator, virtual_machine_port_group_configurer) # Command Wrapper self.command_wrapper = CommandWrapper( pv_service=pv_service, resource_model_parser=self.resource_model_parser, context_based_logger_factory=ContextBasedLoggerFactory()) # Deploy Command self.deploy_command = DeployCommand(deployer=vm_deployer) # Virtual Switch Revoke self.virtual_switch_disconnect_command = \ VirtualSwitchToMachineDisconnectCommand( pyvmomi_service=pv_service, port_group_configurer=virtual_machine_port_group_configurer, resource_model_parser=self.resource_model_parser) # Virtual Switch Connect virtual_switch_connect_command = \ VirtualSwitchConnectCommand( pv_service=pv_service, virtual_switch_to_machine_connector=virtual_switch_to_machine_connector, dv_port_group_name_generator=DvPortGroupNameGenerator(), vlan_spec_factory=VlanSpecFactory(), vlan_id_range_parser=VLanIdRangeParser()) self.connection_orchestrator = ConnectionCommandOrchestrator( connector=virtual_switch_connect_command, disconnector=self.virtual_switch_disconnect_command, resource_model_parser=self.resource_model_parser) self.folder_manager = FolderManager( pv_service=pv_service, task_waiter=synchronous_task_waiter) # Destroy VM Command self.destroy_virtual_machine_command = \ DestroyVirtualMachineCommand(pv_service=pv_service, resource_remover=resource_remover, disconnector=self.virtual_switch_disconnect_command) # Power Command self.vm_power_management_command = \ VirtualMachinePowerManagementCommand(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) # Refresh IP command self.refresh_ip_command = RefreshIpCommand( pyvmomi_service=pv_service, resource_model_parser=self.resource_model_parser, ip_manager=ip_manager) # Get Vm Details command self.vm_details = VmDetailsCommand( pyvmomi_service=pv_service, vm_details_provider=vm_details_provider) # Save Snapshot self.snapshot_saver = SaveSnapshotCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) # Snapshot Restorer self.snapshot_restorer = SnapshotRestoreCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) self.snapshots_retriever = RetrieveSnapshotsCommand( pyvmomi_service=pv_service) self.save_app_command = SaveAppCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter, deployer=vm_deployer, resource_model_parser=self.resource_model_parser, snapshot_saver=self.snapshot_saver, folder_manager=self.folder_manager, cancellation_service=cancellation_service, port_group_configurer=virtual_machine_port_group_configurer) self.delete_saved_sandbox_command = DeleteSavedSandboxCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter, deployer=vm_deployer, resource_model_parser=self.resource_model_parser, snapshot_saver=self.snapshot_saver, folder_manager=self.folder_manager, cancellation_service=cancellation_service, port_group_configurer=virtual_machine_port_group_configurer) def connect_bulk(self, context, request): results = self.command_wrapper.execute_command_with_connection( context, self.connection_orchestrator.connect_bulk, request) driver_response = DriverResponse() driver_response.actionResults = results driver_response_root = DriverResponseRoot() driver_response_root.driverResponse = driver_response return set_command_result(result=driver_response_root, unpicklable=False) def save_sandbox(self, context, save_actions, cancellation_context): """ Save sandbox command, persists an artifact of existing VMs, from which new vms can be restored :param ResourceCommandContext context: :param list[SaveApp] save_actions: :param CancellationContext cancellation_context: :return: list[SaveAppResult] save_app_results """ connection = self.command_wrapper.execute_command_with_connection( context, self.save_app_command.save_app, save_actions, cancellation_context, ) save_app_results = connection return save_app_results def delete_saved_sandbox(self, context, delete_saved_apps, cancellation_context): """ Delete a saved sandbox, along with any vms associated with it :param ResourceCommandContext context: :param list[DeleteSavedApp] delete_saved_apps: :param CancellationContext cancellation_context: :return: list[SaveAppResult] save_app_results """ connection = self.command_wrapper.execute_command_with_connection( context, self.delete_saved_sandbox_command.delete_sandbox, delete_saved_apps, cancellation_context) delete_saved_apps_results = connection return delete_saved_apps_results def deploy_from_template(self, context, deploy_action, cancellation_context): """ Deploy From Template Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ deploy_from_template_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterVMFromTemplateResourceModel) data_holder = DeployFromTemplateDetails( deploy_from_template_model, deploy_action.actionParams.appName) deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_template, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_clone_from_vm(self, context, deploy_action, cancellation_context): """ Deploy Cloned VM From VM Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ deploy_from_vm_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterCloneVMFromVMResourceModel) data_holder = DeployFromTemplateDetails( deploy_from_vm_model, deploy_action.actionParams.appName) deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_clone_from_vm, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_from_linked_clone(self, context, deploy_action, cancellation_context): """ Deploy Cloned VM From VM Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ linked_clone_from_vm_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=VCenterDeployVMFromLinkedCloneResourceModel) data_holder = DeployFromTemplateDetails( linked_clone_from_vm_model, deploy_action.actionParams.appName) if not linked_clone_from_vm_model.vcenter_vm_snapshot: raise ValueError( 'Please insert snapshot to deploy an app from a linked clone') deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_linked_clone, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_from_image(self, context, deploy_action, cancellation_context): """ Deploy From Image Command, will deploy vm from ovf image :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return str deploy results """ deploy_action.actionParams.deployment.attributes[ 'vCenter Name'] = context.resource.name deploy_from_image_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterVMFromImageResourceModel) data_holder = DeployFromImageDetails( deploy_from_image_model, deploy_action.actionParams.appName) # execute command deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_image, data_holder, context.resource, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action # remote command def disconnect_all(self, context, ports): """ Disconnect All Command, will the assign all the vnics on the vm to the default network, which is sign to be disconnected :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.virtual_switch_disconnect_command.disconnect_all, resource_details.vm_uuid) return set_command_result(result=res, unpicklable=False) # remote command def disconnect(self, context, ports, network_name): """ Disconnect Command, will disconnect the a specific network that is assign to the vm, the command will assign the default network for all the vnics that is assigned to the given network :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param str network_name: the name of the network to disconnect from :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.virtual_switch_disconnect_command.disconnect, resource_details.vm_uuid, network_name) return set_command_result(result=res, unpicklable=False) # remote command def DeleteInstance(self, context, ports): """ Destroy Vm Command, will only destroy the vm and will not remove the resource :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.destroy_virtual_machine_command.DeleteInstance, resource_details.vm_uuid, resource_details.fullname) return set_command_result(result=res, unpicklable=False) # remote command def refresh_ip(self, context, cancellation_context, ports): """ Refresh IP Command, will refresh the ip of the vm and will update it on the resource :param ResourceRemoteCommandContext context: the context the command runs on :param cancellation_context: :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.refresh_ip_command.refresh_ip, resource_details, cancellation_context, context.remote_endpoints[0].app_context.app_request_json) return set_command_result(result=res, unpicklable=False) # remote command def power_off(self, context, ports): """ Powers off the remote vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ return self._power_command(context, ports, self.vm_power_management_command.power_off) # remote command def power_on(self, context, ports): """ Powers on the remote vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ return self._power_command(context, ports, self.vm_power_management_command.power_on) # remote command def power_cycle(self, context, ports, delay): """ preforms a restart to the vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! :param number delay: the time to wait between the power on and off """ self.power_off(context, ports) time.sleep(float(delay)) return self.power_on(context, ports) def _power_command(self, context, ports, command): resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, command, resource_details.vm_uuid, resource_details.fullname) return set_command_result(result=res, unpicklable=False) def _parse_remote_model(self, context): """ parse the remote resource model and adds its full name :type context: models.QualiDriverModels.ResourceRemoteCommandContext """ if not context.remote_endpoints: raise Exception('no remote resources found in context: {0}', jsonpickle.encode(context, unpicklable=False)) resource = context.remote_endpoints[0] dictionary = jsonpickle.decode(resource.app_context.deployed_app_json) holder = DeployDataHolder(dictionary) app_resource_detail = GenericDeployedAppResourceModel() app_resource_detail.vm_uuid = holder.vmdetails.uid app_resource_detail.cloud_provider = context.resource.fullname app_resource_detail.fullname = resource.fullname if hasattr(holder.vmdetails, 'vmCustomParams'): app_resource_detail.vm_custom_params = holder.vmdetails.vmCustomParams return app_resource_detail def power_on_not_roemote(self, context, vm_uuid, resource_fullname): # get connection details res = self.command_wrapper.execute_command_with_connection( context, self.vm_power_management_command.power_on, vm_uuid, resource_fullname) return set_command_result(result=res, unpicklable=False) def get_vm_uuid_by_name(self, context, vm_name): res = self.command_wrapper.execute_command_with_connection( context, self.vm_loader.load_vm_uuid_by_name, vm_name) return set_command_result(result=res, unpicklable=False) def get_vm_details(self, context, cancellation_context, requests_json): requests = DeployDataHolder(jsonpickle.decode(requests_json)).items res = self.command_wrapper.execute_command_with_connection( context, self.vm_details.get_vm_details, context.resource, requests, cancellation_context) return set_command_result(result=res, unpicklable=False) def save_snapshot(self, context, snapshot_name, save_memory='No'): """ Saves virtual machine to a snapshot :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :param snapshot_name: snapshot name to save to :type snapshot_name: str :param save_memory: Snapshot the virtual machine's memory. Lookup, Yes / No :type save_memory: str :return: """ resource_details = self._parse_remote_model(context) created_snapshot_path = self.command_wrapper.execute_command_with_connection( context, self.snapshot_saver.save_snapshot, resource_details.vm_uuid, snapshot_name, save_memory) return set_command_result(created_snapshot_path) def restore_snapshot(self, context, snapshot_name): """ Restores virtual machine from a snapshot :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :param snapshot_name: snapshot name to save to :type snapshot_name: str :return: """ resource_details = self._parse_remote_model(context) self.command_wrapper.execute_command_with_connection( context, self.snapshot_restorer.restore_snapshot, resource_details.vm_uuid, resource_details.fullname, snapshot_name) def get_snapshots(self, context): """ Returns list of snapshots :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :return: """ resource_details = self._parse_remote_model(context) res = self.command_wrapper.execute_command_with_connection( context, self.snapshots_retriever.get_snapshots, resource_details.vm_uuid) return set_command_result(result=res, unpicklable=False) def orchestration_save(self, context, mode="shallow", custom_params=None): """ Creates a snapshot with a unique name and returns SavedResults as JSON :param context: resource context of the vCenterShell :param mode: Snapshot save mode, default shallow. Currently not it use :param custom_params: Set of custom parameter to be supported in the future :return: SavedResults serialized as JSON :rtype: SavedResults """ resource_details = self._parse_remote_model(context) created_date = datetime.now() snapshot_name = created_date.strftime('%y_%m_%d %H_%M_%S_%f') created_snapshot_path = self.save_snapshot(context=context, snapshot_name=snapshot_name) created_snapshot_path = self._strip_double_quotes( created_snapshot_path) orchestration_saved_artifact = OrchestrationSavedArtifact() orchestration_saved_artifact.artifact_type = 'vcenter_snapshot' orchestration_saved_artifact.identifier = created_snapshot_path saved_artifacts_info = OrchestrationSavedArtifactsInfo( resource_name=resource_details.cloud_provider, created_date=created_date, restore_rules={'requires_same_resource': True}, saved_artifact=orchestration_saved_artifact) orchestration_save_result = OrchestrationSaveResult( saved_artifacts_info) return set_command_result(result=orchestration_save_result, unpicklable=False) @staticmethod def _strip_double_quotes(created_snapshot_path): if created_snapshot_path.startswith( '"') and created_snapshot_path.endswith('"'): created_snapshot_path = created_snapshot_path[1:-1] return created_snapshot_path def orchestration_restore(self, context, saved_details): """ :param context: :param saved_details: :return: """ saved_artifacts_info = get_result_from_command_output(saved_details) snapshot_name = saved_artifacts_info['saved_artifacts_info'][ 'saved_artifact']['identifier'] return self.restore_snapshot(context=context, snapshot_name=snapshot_name)