예제 #1
0
class VCenterShellDriver(ResourceDriverInterface):
    def cleanup(self):
        pass

    def __init__(self):
        """
        ctor must be without arguments, it is created with reflection at run time
        """
        self.request_parser = DriverRequestParser()
        self.command_orchestrator = CommandOrchestrator(
        )  # type: CommandOrchestrator
        self.deployments = dict()
        self.deployments[
            'vCenter Clone VM From VM'] = self.deploy_clone_from_vm
        self.deployments[
            'VCenter Deploy VM From Linked Clone'] = self.deploy_from_linked_clone
        self.deployments[
            'vCenter VM From Template'] = self.deploy_from_template
        self.deployments['vCenter VM From Image'] = self.deploy_from_image

    def initialize(self, **kwargs):
        pass

    def ApplyConnectivityChanges(self, context, request):
        return self.command_orchestrator.connect_bulk(context, request)

    def disconnect_all(self, context, ports):
        return self.command_orchestrator.disconnect_all(context, ports)

    def disconnect(self, context, ports, network_name):
        return self.command_orchestrator.disconnect(context, ports,
                                                    network_name)

    def DeleteInstance(self, context, ports):
        return self.command_orchestrator.DeleteInstance(context, ports)

    def remote_refresh_ip(self, context, cancellation_context, ports):
        return self.command_orchestrator.refresh_ip(context,
                                                    cancellation_context,
                                                    ports)

    def PowerOff(self, context, ports):
        return self.command_orchestrator.power_off(context, ports)

    # the name is by the Qualisystems conventions
    def PowerOn(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.command_orchestrator.power_on(context, ports)

    # the name is by the Qualisystems conventions
    def PowerCycle(self, context, ports, delay):
        return self.command_orchestrator.power_cycle(context, ports, delay)

    def Deploy(self, context, request=None, cancellation_context=None):
        """

        :param ResourceCommandContext context:
        :param str request: json string to be parsed
        :param cancellation_context:
        :return:
        """

        RESOURCE_POOL_ATTR = "App Pool Name"
        CP_RESTRICTED_ATTR = "Restricted App Model Pools"

        api = CloudShellSessionContext(context).get_api()
        res_id = context.reservation.reservation_id

        # VALIDATE THAT CLOUD PROVIDER RESOURCE HAS POOL LIST Attribute
        cp_attrs = context.resource.attributes
        try:
            cp_pool_list_val = cp_attrs[CP_RESTRICTED_ATTR]
        except KeyError:
            pass
        else:
            api.WriteMessageToReservationOutput(res_id,
                                                "=== full request json ===")
            api.WriteMessageToReservationOutput(res_id, request)
            request_obj = json.loads(request)
            request_action_params = request_obj["driverRequest"]["actions"][0][
                "actionParams"]
            app_name = request_action_params["appName"]
            deployment = request_action_params["deployment"]
            app_resource = request_action_params["appResource"]
            app_resource_attrs = app_resource["attributes"]

            pool_attr_search = [
                attr for attr in app_resource_attrs
                if attr["attributeName"] == RESOURCE_POOL_ATTR
            ]
            if pool_attr_search:
                app_pool_attr_val = pool_attr_search[0]["attributeValue"]
                restricted_attrs_dict = get_cp_restricted_attrs_dict(
                    cp_pool_list_val)
                try:
                    app_pool_limit = restricted_attrs_dict[app_pool_attr_val]
                except KeyError:
                    not_found_msg = "{} pool name key not in cp restricted list {}".format(
                        app_pool_attr_val, restricted_attrs_dict)
                    api.WriteMessageToReservationOutput(res_id, not_found_msg)
                else:
                    # count deployed apps
                    all_generic_app_resources = api.FindResources(
                        resourceFamily="Generic App Family").Resources

                    # collect matching apps
                    matching_apps = []
                    for resource in all_generic_app_resources:
                        attrs = api.GetResourceDetails(
                            resource.Name).ResourceAttributes
                        attr_search = [
                            attr for attr in attrs
                            if attr.Name == RESOURCE_POOL_ATTR
                        ]
                        if attr_search:
                            attr_val = attr_search[0].Value
                            if attr_val == app_pool_attr_val:
                                matching_apps.append(resource)

                    # PERFORM VALIDATION
                    if len(matching_apps) >= int(app_pool_limit):
                        matching_app_names = [r.Name for r in matching_apps]
                        exc_msg = "Can not deploy '{}'. The pool '{}' has reached it's limit of {}. Current Apps in Pool: {}".format(
                            app_name, app_pool_attr_val, app_pool_limit,
                            matching_app_names)
                        api.WriteMessageToReservationOutput(
                            res_id, '<span style="color:red">{}</span>'.format(
                                exc_msg))
                        raise AppLimitDeploymentError(exc_msg)

        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        deploy_action = single(actions, lambda x: isinstance(x, DeployApp))
        deployment_name = deploy_action.actionParams.deployment.deploymentPath

        if deployment_name in self.deployments.keys():
            deploy_method = self.deployments[deployment_name]
            deploy_result = deploy_method(context, deploy_action,
                                          cancellation_context)
            return DriverResponse([deploy_result]).to_driver_response_json()
        else:
            raise Exception('Could not find the deployment')

    def SaveApp(self, context, request, cancellation_context=None):
        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        save_actions = [x for x in actions if isinstance(x, SaveApp)]
        save_app_results = self.command_orchestrator.save_sandbox(
            context, save_actions, cancellation_context)
        return DriverResponse(save_app_results).to_driver_response_json()

    def DeleteSavedApps(self, context, request, cancellation_context=None):
        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        delete_actions = [x for x in actions if isinstance(x, DeleteSavedApp)]
        save_app_results = self.command_orchestrator.delete_saved_sandbox(
            context, delete_actions, cancellation_context)
        return DriverResponse(save_app_results).to_driver_response_json()

    def deploy_from_template(self, context, deploy_action,
                             cancellation_context):
        return self.command_orchestrator.deploy_from_template(
            context, deploy_action, cancellation_context)

    def deploy_clone_from_vm(self, context, deploy_action,
                             cancellation_context):
        return self.command_orchestrator.deploy_clone_from_vm(
            context, deploy_action, cancellation_context)

    def deploy_from_linked_clone(self, context, deploy_action,
                                 cancellation_context):
        return self.command_orchestrator.deploy_from_linked_clone(
            context, deploy_action, cancellation_context)

    def deploy_from_image(self, context, deploy_action, cancellation_context):
        if cancellation_context is None:
            cancellation_context = CancellationContext()
        return self.command_orchestrator.deploy_from_image(
            context, deploy_action, cancellation_context)

    def get_inventory(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """

        validator = VCenterAutoModelDiscovery()
        return validator.validate_and_discover(context)

    def remote_save_snapshot(self, context, ports, snapshot_name, save_memory):
        """
        Saves virtual machine to a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :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:
        """
        return self.command_orchestrator.save_snapshot(context, snapshot_name,
                                                       save_memory)

    def remote_restore_snapshot(self, context, ports, snapshot_name):
        """
        Restores virtual machine from a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: Snapshot name to restore from
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.restore_snapshot(
            context, snapshot_name)

    def remote_get_snapshots(self, context, ports):
        """
        Returns list of snapshots
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :return: list
        """
        return self.command_orchestrator.get_snapshots(context)

    def orchestration_save(self,
                           context,
                           ports,
                           mode="shallow",
                           custom_params=None):
        return self.command_orchestrator.orchestration_save(
            context, mode, custom_params)

    def orchestration_restore(self, context, ports, saved_details):
        return self.command_orchestrator.orchestration_restore(
            context, saved_details)

    def get_vm_uuid(self, context, vm_name):
        return self.command_orchestrator.get_vm_uuid_by_name(context, vm_name)

    def GetVmDetails(self, context, cancellation_context, requests):
        return self.command_orchestrator.get_vm_details(
            context, cancellation_context, requests)
예제 #2
0
class TestCommandOrchestrator(TestCase):
    def setUp(self):
        self.resource = create_autospec(ResourceInfo)
        self.resource.ResourceModelName = 'VMwarev Center'
        self.resource.ResourceAttributes = {
            'User': '******',
            'Password': '******',
            'Default dvSwitch': 'switch1',
            'Holding Network': 'anetwork',
            'Default Port Group Location': 'Quali',
            'VM Cluster': 'Quali',
            'VM Location': 'Quali',
            'VM Resource Pool': 'Quali',
            'VM Storage': 'Quali',
            'Shutdown Method': 'hard',
            'OVF Tool Path': 'C\\program files\ovf',
            'Execution Server Selector': '',
            'Reserved Networks': 'vlan65',
            'Default Datacenter': 'QualiSB'
        }
        self.context = Mock()
        session = Mock()
        remote_resource = Mock()
        remote_resource.fullname = 'this is full name of the remote resource'
        remote_resource.uuid = 'this is full uuis of the remote resource'
        self.connection_details = Mock()
        self.context.resource = self.resource
        self.context.remote_endpoints = [self.resource]
        self.command_orchestrator = CommandOrchestrator()
        self.command_orchestrator.command_wrapper.execute_command_with_connection = Mock(
            return_value=True)
        self.command_orchestrator.cs_helper = Mock()
        self.command_orchestrator.cs_helper.get_session = Mock(
            return_value=session)
        self.command_orchestrator.cs_helper.get_connection_details = Mock(
            return_value=self.connection_details)
        self.ports = [Mock()]
        self.command_orchestrator._parse_remote_model = Mock(
            return_value=remote_resource)

    def test_disconnect_all(self):
        # act
        self.command_orchestrator.disconnect_all(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_disconnect(self):
        # act
        self.command_orchestrator.disconnect(self.context, self.ports,
                                             'network')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_destroy_vm_only(self):
        # act
        self.command_orchestrator.destroy_vm_only(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_template(self):
        # act
        self.command_orchestrator.deploy_from_template(
            self.context,
            '{"name": "name", "template_resource_model": {"vcenter_template": ""}}'
        )
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_vm_from_vm(self):
        # act
        self.command_orchestrator.deploy_clone_from_vm(
            self.context,
            '{"name": "name", "template_resource_model": {"vcenter_vm": ""}}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_snapshot(self):
        # act
        self.command_orchestrator.deploy_from_linked_clone(
            self.context,
            '{"name": "name", "template_resource_model": {"vcenter_vm": "name", "vcenter_vm_snapshot": "snap"}}'
        )
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_image(self):
        # act
        self.command_orchestrator.deploy_from_image(self.context,
                                                    '{"name": "name"}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_off(self):
        # act
        self.command_orchestrator.power_off(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_on(self):
        # act
        self.command_orchestrator.power_on(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_cycle(self):
        # act
        self.command_orchestrator.power_cycle(self.context, self.ports, 0.0001)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_refresh_ip(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.refresh_ip(
            self.context,
            cancellation_context=cancellation_context,
            ports=self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_get_uuid(self):
        self.command_orchestrator.get_vm_uuid_by_name(self.context, 'Name')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_save_snapshot(self):
        self.command_orchestrator.save_snapshot(self.context, 'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_restore_snapshot(self):
        self.command_orchestrator.restore_snapshot(self.context,
                                                   'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_get_snapshots(self):
        self.command_orchestrator.get_snapshots(self.context)
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_orchestration_save(self):
        # Arrange
        with patch(SAVE_SNAPSHOT) as save_snapshot_mock:
            save_snapshot_mock.return_value = '"new_snapshot"'

            remote_command_context = create_autospec(
                ResourceRemoteCommandContext)
            remote_command_context.resource = create_autospec(
                ResourceContextDetails)
            remote_command_context.resource.fullname = 'vcenter'
            endpoint = create_autospec(ResourceContextDetails)
            endpoint.fullname = 'vm_111'
            endpoint.app_context = create_autospec(AppContext)
            endpoint.app_context.deployed_app_json = '{"vmdetails": {"uid": "vm_uuid1"}}'
            remote_command_context.remote_endpoints = [endpoint]

            # Act
            saved_result = CommandOrchestrator().orchestration_save(
                context=remote_command_context,
                mode='shallow',
                custom_params=None)

            # Assert
            save_snapshot_mock.assert_called_once()
            saved_result_dict = jsonpickle.decode(saved_result)
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['saved_artifact']
                ['artifact_type'], 'vcenter_snapshot')
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['saved_artifact']
                ['identifier'], 'new_snapshot')
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['resource_name'],
                'vcenter')
            self.assertIsNotNone(
                saved_result_dict['saved_artifacts_info']['created_date'])

    def test_orchestration_restore(self):
        # Arrange
        with patch(RESTORE_SNAPSHOT) as mock_restore_snapshot:
            # Act
            self.command_orchestrator.orchestration_restore(
                self.context, '''{
      "saved_artifacts_info": {
        "resource_name": "ex cillum sed laboris",
        "created_date": "4313-10-12T18:03:15.053Z",
        "restore_rules": {
          "requires_same_resource": false
        },
        "saved_artifact": {
          "artifact_type": "veniam in qui",
          "identifier": "deserunt1"
        }
      }
    }''')
            # Assert
            mock_restore_snapshot.assert_called_once_with(
                context=self.context, snapshot_name='deserunt1')
예제 #3
0
class VCenterShellDriver (ResourceDriverInterface):

    def cleanup(self):
        pass

    def __init__(self):
        """
        ctor must be without arguments, it is created with reflection at run time
        """
        self.command_orchestrator = CommandOrchestrator()  # type: CommandOrchestrator

    def initialize(self):
        pass

    def ApplyConnectivityChanges(self, context, request):
        return self.command_orchestrator.connect_bulk(context, request)

    def disconnect_all(self, context, ports):
        return self.command_orchestrator.disconnect_all(context, ports)

    def disconnect(self, context, ports, network_name):
        return self.command_orchestrator.disconnect(context, ports, network_name)

    def destroy_vm(self, context, ports):
        return self.command_orchestrator.destroy_vm(context, ports)

    def destroy_vm_only(self, context, ports):
        return self.command_orchestrator.destroy_vm_only(context, ports)

    def remote_refresh_ip(self, context, cancellation_context, ports):
        return self.command_orchestrator.refresh_ip(context, cancellation_context, ports)

    def PowerOff(self, context, ports):
        return self.command_orchestrator.power_off(context, ports)

    # the name is by the Qualisystems conventions
    def PowerOn(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.command_orchestrator.power_on(context, ports)

    # the name is by the Qualisystems conventions
    def PowerCycle(self, context, ports, delay):
        return self.command_orchestrator.power_cycle(context, ports, delay)

    def deploy_from_template(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_template(context, deploy_data)

    def deploy_from_image(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_image(context, deploy_data)

    def get_inventory(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """

        validator = VCenterAutoModelDiscovery()
        return validator.validate_and_discover(context)
예제 #4
0
class VCenterShellDriver(ResourceDriverInterface):
    def cleanup(self):
        pass

    def __init__(self):
        """
        ctor must be without arguments, it is created with reflection at run time
        """
        self.command_orchestrator = CommandOrchestrator(
        )  # type: CommandOrchestrator

    def initialize(self):
        pass

    def ApplyConnectivityChanges(self, context, request):
        return self.command_orchestrator.connect_bulk(context, request)

    def disconnect_all(self, context, ports):
        return self.command_orchestrator.disconnect_all(context, ports)

    def disconnect(self, context, ports, network_name):
        return self.command_orchestrator.disconnect(context, ports,
                                                    network_name)

    def destroy_vm_only(self, context, ports):
        return self.command_orchestrator.destroy_vm_only(context, ports)

    def remote_refresh_ip(self, context, cancellation_context, ports):
        return self.command_orchestrator.refresh_ip(context,
                                                    cancellation_context,
                                                    ports)

    def PowerOff(self, context, ports):
        return self.command_orchestrator.power_off(context, ports)

    # the name is by the Qualisystems conventions
    def PowerOn(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.command_orchestrator.power_on(context, ports)

    # the name is by the Qualisystems conventions
    def PowerCycle(self, context, ports, delay):
        return self.command_orchestrator.power_cycle(context, ports, delay)

    def deploy_from_template(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_template(
            context, deploy_data)

    def deploy_clone_from_vm(self, context, deploy_data):
        return self.command_orchestrator.deploy_clone_from_vm(
            context, deploy_data)

    def deploy_from_linked_clone(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_linked_clone(
            context, deploy_data)

    def deploy_from_image(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_image(
            context, deploy_data)

    def get_inventory(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """

        validator = VCenterAutoModelDiscovery()
        return validator.validate_and_discover(context)

    def remote_save_snapshot(self, context, ports, snapshot_name):
        """
        Saves virtual machine to a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: snapshot name to save to
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.save_snapshot(context, snapshot_name)

    def remote_restore_snapshot(self, context, ports, snapshot_name):
        """
        Restores virtual machine from a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: Snapshot name to restore from
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.restore_snapshot(
            context, snapshot_name)

    def remote_get_snapshots(self, context, ports):
        """
        Returns list of snapshots
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :return: list
        """
        return self.command_orchestrator.get_snapshots(context)

    def orchestration_save(self,
                           context,
                           ports,
                           mode="shallow",
                           custom_params=None):
        return self.command_orchestrator.orchestration_save(
            context, mode, custom_params)

    def orchestration_restore(self, context, ports, saved_details):
        return self.command_orchestrator.orchestration_restore(
            context, saved_details)

    def get_vm_uuid(self, context, vm_name):
        return self.command_orchestrator.get_vm_uuid_by_name(context, vm_name)
class TestCommandOrchestrator(TestCase):
    def setUp(self):
        self.resource = create_autospec(ResourceInfo)
        self.resource.ResourceModelName = 'VMwarev Center'
        self.resource.ResourceAttributes = {'User': '******',
                                            'Password': '******',
                                            'Default dvSwitch': 'switch1',
                                            'Holding Network': 'anetwork',
                                            'Default Port Group Location': 'Quali',
                                            'VM Cluster': 'Quali',
                                            'VM Location': 'Quali',
                                            'VM Resource Pool': 'Quali',
                                            'VM Storage': 'Quali',
                                            'Shutdown Method': 'hard',
                                            'OVF Tool Path': 'C\\program files\ovf',
                                            'Execution Server Selector': '',
                                            'Reserved Networks': 'vlan65',
                                            'Default Datacenter': 'QualiSB'
                                            }
        self.context = Mock()
        session = Mock()
        remote_resource = Mock()
        remote_resource.fullname = 'this is full name of the remote resource'
        remote_resource.uuid = 'this is full uuis of the remote resource'
        self.connection_details = Mock()
        self.context.resource = self.resource
        self.context.remote_endpoints = [self.resource]
        self.command_orchestrator = CommandOrchestrator()
        self.command_orchestrator.command_wrapper.execute_command_with_connection = Mock(return_value=True)
        self.command_orchestrator.cs_helper = Mock()
        self.command_orchestrator.cs_helper.get_session = Mock(return_value=session)
        self.command_orchestrator.cs_helper.get_connection_details = Mock(return_value=self.connection_details)
        self.ports = [Mock()]
        self.command_orchestrator._parse_remote_model = Mock(return_value=remote_resource)

    def test_disconnect_all(self):
        # act
        self.command_orchestrator.disconnect_all(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_disconnect(self):
        # act
        self.command_orchestrator.disconnect(self.context,  self.ports, 'network')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_destroy_vm(self):
        # act
        self.command_orchestrator.destroy_vm(self.context,  self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_from_template(self):
        # act
        self.command_orchestrator.deploy_from_template(self.context, '{"name": "name", "template_resource_model": {"vcenter_template": ""}}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_from_image(self):
        # act
        self.command_orchestrator.deploy_from_image(self.context, '{"name": "name"}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_off(self):
        # act
        self.command_orchestrator.power_off(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_on(self):
        # act
        self.command_orchestrator.power_on(self.context,  self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_cycle(self):
        # act
        self.command_orchestrator.power_cycle(self.context, self.ports, 0.0001)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_refresh_ip(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.refresh_ip(self.context, cancellation_context=cancellation_context, ports=self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)
예제 #6
0
class TestCommandOrchestrator(TestCase):
    def setUp(self):
        self.deploy_action = DeployApp()
        self.deploy_action.actionId = '0a21384c-5620-4e6a-b162-c726681865a9'
        self.deploy_action.actionParams = DeployAppParams()
        self.deploy_action.actionParams.appName = 'myApp'
        self.deploy_action.actionParams.appResource = AppResourceInfo()
        self.deploy_action.actionParams.appResource.attributes = {
            "Public IP": "",
            "Password": "******",
            "User": "******"
        }
        self.deploy_action.actionParams.deployment = DeployAppDeploymentInfo()
        self.deploy_action.actionParams.deployment.deploymentPath = 'deployment model name'
        self.deploy_action.actionParams.deployment.attributes = {
            "Default Datacenter": "",
            "Auto Power Off": "True",
            "Auto Power On": "True",
            "Wait for IP": "True",
            "VM Cluster": "",
            "VM Location": "",
            "VM Storage": "",
            "VM Resource Pool": "",
            "vCenter Image": "c:\\tinyvm1.ova",
            "vCenter Image Arguments": "",
            "IP Regex": "",
            "Refresh IP Timeout": "600",
            "Auto Delete": "True",
            "Autoload": "True",
            "VCenter VM": "sds",
            "VCenter VM Snapshot": "sds",
            "VCenter Template": "dsds",
            "Behavior during save": "Powered Off"
        }

        self.resource = create_autospec(ResourceInfo)
        self.resource.name = 'Cloud1'
        self.resource.ResourceModelName = 'VMwarev Center'
        self.resource.ResourceAttributes = {
            'User': '******',
            'Password': '******',
            'Default dvSwitch': 'switch1',
            'Holding Network': 'anetwork',
            'Default Port Group Location': 'Quali',
            'VM Cluster': 'Quali',
            'VM Location': 'Quali',
            'VM Resource Pool': 'Quali',
            'VM Storage': 'Quali',
            'Shutdown Method': 'hard',
            'OVF Tool Path': 'C\\program files\ovf',
            'Execution Server Selector': '',
            'Reserved Networks': 'vlan65',
            'Default Datacenter': 'QualiSB'
        }
        self.context = Mock()
        session = Mock()
        remote_resource = Mock()
        remote_resource.fullname = 'this is full name of the remote resource'
        remote_resource.uuid = 'this is full uuis of the remote resource'
        self.connection_details = Mock()
        self.context.resource = self.resource
        self.context.resource.app_context = Mock()
        self.context.remote_endpoints = Mock()
        self.context.remote_endpoints = [self.resource]
        self.command_orchestrator = CommandOrchestrator()
        self.command_orchestrator.command_wrapper.execute_command_with_connection = Mock(
            return_value=DeployAppResult())
        self.ports = [Mock()]
        self.command_orchestrator._parse_remote_model = Mock(
            return_value=remote_resource)

    def test_disconnect_all(self):
        # act
        self.command_orchestrator.disconnect_all(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_disconnect(self):
        # act
        self.command_orchestrator.disconnect(self.context, self.ports,
                                             'network')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_DeleteInstance(self):
        # act
        self.command_orchestrator.DeleteInstance(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_template(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.deploy_from_template(self.context,
                                                       self.deploy_action,
                                                       cancellation_context)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_vm_from_vm(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.deploy_clone_from_vm(self.context,
                                                       self.deploy_action,
                                                       cancellation_context)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_snapshot(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.deploy_from_linked_clone(
            self.context, self.deploy_action, cancellation_context)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_deploy_from_image(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.deploy_from_image(self.context,
                                                    self.deploy_action,
                                                    cancellation_context)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_off(self):
        # act
        self.command_orchestrator.power_off(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_on(self):
        # act
        self.command_orchestrator.power_on(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_power_cycle(self):
        # act
        self.command_orchestrator.power_cycle(self.context, self.ports, 0.0001)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_refresh_ip(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.refresh_ip(
            self.context,
            cancellation_context=cancellation_context,
            ports=self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_get_uuid(self):
        self.command_orchestrator.get_vm_uuid_by_name(self.context, 'Name')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_save_snapshot(self):
        self.command_orchestrator.save_snapshot(self.context, 'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_restore_snapshot(self):
        self.command_orchestrator.restore_snapshot(self.context,
                                                   'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_get_snapshots(self):
        self.command_orchestrator.get_snapshots(self.context)
        self.assertTrue(self.command_orchestrator.command_wrapper.
                        execute_command_with_connection.called)

    def test_orchestration_save_double_quotes_in_snapshot_name_should_be_stripped(
            self):
        # Arrange
        with patch(SAVE_SNAPSHOT) as save_snapshot_mock:
            save_snapshot_mock.return_value = '"new_snapshot"'

            remote_command_context = create_autospec(
                ResourceRemoteCommandContext)
            remote_command_context.resource = create_autospec(
                ResourceContextDetails)
            remote_command_context.resource.fullname = 'vcenter'
            endpoint = create_autospec(ResourceContextDetails)
            endpoint.fullname = 'vm_111'
            endpoint.app_context = create_autospec(AppContext)
            endpoint.app_context.deployed_app_json = '{"vmdetails": {"uid": "vm_uuid1"}}'
            remote_command_context.remote_endpoints = [endpoint]

            # Act
            saved_result = CommandOrchestrator().orchestration_save(
                context=remote_command_context,
                mode='shallow',
                custom_params=None)

            # Assert
            save_snapshot_mock.assert_called_once()
            saved_result_dict = jsonpickle.decode(saved_result)
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['saved_artifact']
                ['artifact_type'], 'vcenter_snapshot')
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['saved_artifact']
                ['identifier'], 'new_snapshot')
            self.assertEqual(
                saved_result_dict['saved_artifacts_info']['resource_name'],
                'vcenter')
            self.assertIsNotNone(
                saved_result_dict['saved_artifacts_info']['created_date'])

    @freeze_time("1984-12-31 11:12:13.4567")
    def test_orchestration_save_snapshot_name_should_contain_full_datetime(
            self):
        # Arrange
        with patch(SAVE_SNAPSHOT) as save_snapshot_mock:
            save_snapshot_mock.return_value = '"new_snapshot"'

            remote_command_context = create_autospec(
                ResourceRemoteCommandContext)
            remote_command_context.resource = create_autospec(
                ResourceContextDetails)
            remote_command_context.resource.fullname = 'vcenter'
            endpoint = create_autospec(ResourceContextDetails)
            endpoint.fullname = 'vm_111'
            endpoint.app_context = create_autospec(AppContext)
            endpoint.app_context.deployed_app_json = '{"vmdetails": {"uid": "vm_uuid1"}}'
            remote_command_context.remote_endpoints = [endpoint]

            # Act
            CommandOrchestrator().orchestration_save(
                context=remote_command_context,
                mode='shallow',
                custom_params=None)

            # Assert
            args, kwargs = save_snapshot_mock.call_args
            self.assertEqual(kwargs['snapshot_name'],
                             "84_12_31 11_12_13_456700")

    def test_orchestration_restore(self):
        # Arrange
        with patch(RESTORE_SNAPSHOT) as mock_restore_snapshot:
            # Act
            self.command_orchestrator.orchestration_restore(
                self.context, '''{
      "saved_artifacts_info": {
        "resource_name": "ex cillum sed laboris",
        "created_date": "4313-10-12T18:03:15.053Z",
        "restore_rules": {
          "requires_same_resource": false
        },
        "saved_artifact": {
          "artifact_type": "veniam in qui",
          "identifier": "deserunt1"
        }
      }
    }''')
            # Assert
            mock_restore_snapshot.assert_called_once_with(
                context=self.context, snapshot_name='deserunt1')
예제 #7
0
class VCenterShellDriver (ResourceDriverInterface):

    def cleanup(self):
        pass

    def __init__(self):
        """
        ctor must be without arguments, it is created with reflection at run time
        """
        self.command_orchestrator = CommandOrchestrator()  # type: CommandOrchestrator

    def initialize(self):
        pass

    def ApplyConnectivityChanges(self, context, request):
        return self.command_orchestrator.connect_bulk(context, request)

    def disconnect_all(self, context, ports):
        return self.command_orchestrator.disconnect_all(context, ports)

    def disconnect(self, context, ports, network_name):
        return self.command_orchestrator.disconnect(context, ports, network_name)

    def destroy_vm_only(self, context, ports):
        return self.command_orchestrator.destroy_vm_only(context, ports)

    def remote_refresh_ip(self, context, cancellation_context, ports):
        return self.command_orchestrator.refresh_ip(context, cancellation_context, ports)

    def PowerOff(self, context, ports):
        return self.command_orchestrator.power_off(context, ports)

    # the name is by the Qualisystems conventions
    def PowerOn(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.command_orchestrator.power_on(context, ports)

    # the name is by the Qualisystems conventions
    def PowerCycle(self, context, ports, delay):
        return self.command_orchestrator.power_cycle(context, ports, delay)

    def deploy_from_template(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_template(context, deploy_data)

    def deploy_clone_from_vm(self, context, deploy_data):
        return self.command_orchestrator.deploy_clone_from_vm(context, deploy_data)

    def deploy_from_linked_clone(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_linked_clone(context, deploy_data)

    def deploy_from_image(self, context, deploy_data):
        return self.command_orchestrator.deploy_from_image(context, deploy_data)

    def get_inventory(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """

        validator = VCenterAutoModelDiscovery()
        return validator.validate_and_discover(context)

    def remote_save_snapshot(self, context, ports, snapshot_name):
        """
        Saves virtual machine to a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: snapshot name to save to
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.save_snapshot(context, snapshot_name)

    def remote_restore_snapshot(self, context, ports, snapshot_name):
        """
        Restores virtual machine from a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: Snapshot name to restore from
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.restore_snapshot(context, snapshot_name)

    def remote_get_snapshots(self, context, ports):
        """
        Returns list of snapshots
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :return: list
        """
        return self.command_orchestrator.get_snapshots(context)

    def orchestration_save(self, context, ports, mode="shallow", custom_params=None):
        return self.command_orchestrator.orchestration_save(context, mode, custom_params)

    def orchestration_restore(self, context, ports, saved_details):
        return self.command_orchestrator.orchestration_restore(context, saved_details)

    def get_vm_uuid(self, context, vm_name):
        return self.command_orchestrator.get_vm_uuid_by_name(context, vm_name)
예제 #8
0
class VCenterShellDriver(ResourceDriverInterface):
    def cleanup(self):
        pass

    def __init__(self):
        """
        ctor must be without arguments, it is created with reflection at run time
        """
        self.request_parser = DriverRequestParser()
        self.command_orchestrator = CommandOrchestrator(
        )  # type: CommandOrchestrator
        self.deployments = dict()
        self.deployments[
            'vCenter Clone VM From VM'] = self.deploy_clone_from_vm
        self.deployments[
            'VCenter Deploy VM From Linked Clone'] = self.deploy_from_linked_clone
        self.deployments[
            'vCenter VM From Template'] = self.deploy_from_template
        self.deployments['vCenter VM From Image'] = self.deploy_from_image

    def initialize(self, **kwargs):
        pass

    def ApplyConnectivityChanges(self, context, request):
        return self.command_orchestrator.connect_bulk(context, request)

    def disconnect_all(self, context, ports):
        return self.command_orchestrator.disconnect_all(context, ports)

    def disconnect(self, context, ports, network_name):
        return self.command_orchestrator.disconnect(context, ports,
                                                    network_name)

    def DeleteInstance(self, context, ports):
        return self.command_orchestrator.DeleteInstance(context, ports)

    def remote_refresh_ip(self, context, cancellation_context, ports):
        return self.command_orchestrator.refresh_ip(context,
                                                    cancellation_context,
                                                    ports)

    def PowerOff(self, context, ports):
        return self.command_orchestrator.power_off(context, ports)

    # the name is by the Qualisystems conventions
    def PowerOn(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.command_orchestrator.power_on(context, ports)

    # the name is by the Qualisystems conventions
    def PowerCycle(self, context, ports, delay):
        return self.command_orchestrator.power_cycle(context, ports, delay)

    def Deploy(self, context, request=None, cancellation_context=None):
        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        deploy_action = single(actions, lambda x: isinstance(x, DeployApp))
        deployment_name = deploy_action.actionParams.deployment.deploymentPath

        if deployment_name in self.deployments.keys():
            deploy_method = self.deployments[deployment_name]
            deploy_result = deploy_method(context, deploy_action,
                                          cancellation_context)
            return DriverResponse([deploy_result]).to_driver_response_json()
        else:
            raise Exception('Could not find the deployment')

    def SaveApp(self, context, request, cancellation_context=None):
        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        save_actions = [x for x in actions if isinstance(x, SaveApp)]
        save_app_results = self.command_orchestrator.save_sandbox(
            context, save_actions, cancellation_context)
        return DriverResponse(save_app_results).to_driver_response_json()

    def DeleteSavedApps(self, context, request, cancellation_context=None):
        actions = self.request_parser.convert_driver_request_to_actions(
            request)
        delete_actions = [x for x in actions if isinstance(x, DeleteSavedApp)]
        save_app_results = self.command_orchestrator.delete_saved_sandbox(
            context, delete_actions, cancellation_context)
        return DriverResponse(save_app_results).to_driver_response_json()

    def deploy_from_template(self, context, deploy_action,
                             cancellation_context):
        return self.command_orchestrator.deploy_from_template(
            context, deploy_action, cancellation_context)

    def deploy_clone_from_vm(self, context, deploy_action,
                             cancellation_context):
        return self.command_orchestrator.deploy_clone_from_vm(
            context, deploy_action, cancellation_context)

    def deploy_from_linked_clone(self, context, deploy_action,
                                 cancellation_context):
        return self.command_orchestrator.deploy_from_linked_clone(
            context, deploy_action, cancellation_context)

    def deploy_from_image(self, context, deploy_action, cancellation_context):
        if cancellation_context is None:
            cancellation_context = CancellationContext()
        return self.command_orchestrator.deploy_from_image(
            context, deploy_action, cancellation_context)

    def get_inventory(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """

        validator = VCenterAutoModelDiscovery()
        return validator.validate_and_discover(context)

    def remote_save_snapshot(self, context, ports, snapshot_name, save_memory):
        """
        Saves virtual machine to a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :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:
        """
        return self.command_orchestrator.save_snapshot(context, snapshot_name,
                                                       save_memory)

    def remote_restore_snapshot(self, context, ports, snapshot_name):
        """
        Restores virtual machine from a snapshot
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :param snapshot_name: Snapshot name to restore from
        :type snapshot_name: str
        :return:
        """
        return self.command_orchestrator.restore_snapshot(
            context, snapshot_name)

    def remote_get_snapshots(self, context, ports):
        """
        Returns list of snapshots
        :param context: resource context of the vCenterShell
        :type context: models.QualiDriverModels.ResourceCommandContext
        :param ports:list[string] ports: the ports of the connection between the remote resource and the local resource
        :type ports: list[string]
        :return: list
        """
        return self.command_orchestrator.get_snapshots(context)

    def orchestration_save(self,
                           context,
                           ports,
                           mode="shallow",
                           custom_params=None):
        return self.command_orchestrator.orchestration_save(
            context, mode, custom_params)

    def orchestration_restore(self, context, ports, saved_details):
        return self.command_orchestrator.orchestration_restore(
            context, saved_details)

    def get_vm_uuid(self, context, vm_name):
        return self.command_orchestrator.get_vm_uuid_by_name(context, vm_name)

    def GetVmDetails(self, context, cancellation_context, requests):
        return self.command_orchestrator.get_vm_details(
            context, cancellation_context, requests)
class TestCommandOrchestrator(TestCase):
    def setUp(self):
        self.resource = create_autospec(ResourceInfo)
        self.resource.ResourceModelName = 'VMwarev Center'
        self.resource.ResourceAttributes = {'User': '******',
                                            'Password': '******',
                                            'Default dvSwitch': 'switch1',
                                            'Holding Network': 'anetwork',
                                            'Default Port Group Location': 'Quali',
                                            'VM Cluster': 'Quali',
                                            'VM Location': 'Quali',
                                            'VM Resource Pool': 'Quali',
                                            'VM Storage': 'Quali',
                                            'Shutdown Method': 'hard',
                                            'OVF Tool Path': 'C\\program files\ovf',
                                            'Execution Server Selector': '',
                                            'Reserved Networks': 'vlan65',
                                            'Default Datacenter': 'QualiSB'
                                            }
        self.context = Mock()
        session = Mock()
        remote_resource = Mock()
        remote_resource.fullname = 'this is full name of the remote resource'
        remote_resource.uuid = 'this is full uuis of the remote resource'
        self.connection_details = Mock()
        self.context.resource = self.resource
        self.context.resource.app_context = Mock()
        self.context.remote_endpoints = Mock()
        self.context.remote_endpoints = [self.resource]
        self.command_orchestrator = CommandOrchestrator()
        self.command_orchestrator.command_wrapper.execute_command_with_connection = Mock(return_value=True)
        self.command_orchestrator.cs_helper = Mock()
        self.command_orchestrator.cs_helper.get_session = Mock(return_value=session)
        self.command_orchestrator.cs_helper.get_connection_details = Mock(return_value=self.connection_details)
        self.ports = [Mock()]
        self.command_orchestrator._parse_remote_model = Mock(return_value=remote_resource)

    def test_disconnect_all(self):
        # act
        self.command_orchestrator.disconnect_all(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_disconnect(self):
        # act
        self.command_orchestrator.disconnect(self.context, self.ports, 'network')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_destroy_vm_only(self):
        # act
        self.command_orchestrator.destroy_vm_only(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_from_template(self):
        # act
        self.command_orchestrator.deploy_from_template(self.context,
                                                       '{"name": "name", "template_resource_model": {"vcenter_template": ""}}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_vm_from_vm(self):
        # act
        self.command_orchestrator.deploy_clone_from_vm(self.context,
                                                       '{"name": "name", "template_resource_model": {"vcenter_vm": ""}}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_from_snapshot(self):
        # act
        self.command_orchestrator.deploy_from_linked_clone(self.context,
                                                           '{"name": "name", "template_resource_model": {"vcenter_vm": "name", "vcenter_vm_snapshot": "snap"}}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_deploy_from_image(self):
        # act
        self.command_orchestrator.deploy_from_image(self.context, '{"name": "name"}')
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_off(self):
        # act
        self.command_orchestrator.power_off(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_on(self):
        # act
        self.command_orchestrator.power_on(self.context, self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_power_cycle(self):
        # act
        self.command_orchestrator.power_cycle(self.context, self.ports, 0.0001)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_refresh_ip(self):
        # act
        cancellation_context = object()
        self.command_orchestrator.refresh_ip(self.context, cancellation_context=cancellation_context, ports=self.ports)
        # assert
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_get_uuid(self):
        self.command_orchestrator.get_vm_uuid_by_name(self.context, 'Name')
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_save_snapshot(self):
        self.command_orchestrator.save_snapshot(self.context, 'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_restore_snapshot(self):
        self.command_orchestrator.restore_snapshot(self.context, 'new_snapshot')
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_get_snapshots(self):
        self.command_orchestrator.get_snapshots(self.context)
        self.assertTrue(self.command_orchestrator.command_wrapper.execute_command_with_connection.called)

    def test_orchestration_save_double_quotes_in_snapshot_name_should_be_stripped(self):
        # Arrange
        with patch(SAVE_SNAPSHOT) as save_snapshot_mock:
            save_snapshot_mock.return_value = '"new_snapshot"'

            remote_command_context = create_autospec(ResourceRemoteCommandContext)
            remote_command_context.resource = create_autospec(ResourceContextDetails)
            remote_command_context.resource.fullname = 'vcenter'
            endpoint = create_autospec(ResourceContextDetails)
            endpoint.fullname = 'vm_111'
            endpoint.app_context = create_autospec(AppContext)
            endpoint.app_context.deployed_app_json = '{"vmdetails": {"uid": "vm_uuid1"}}'
            remote_command_context.remote_endpoints = [endpoint]

            # Act
            saved_result = CommandOrchestrator().orchestration_save(context=remote_command_context,
                                                                    mode='shallow',
                                                                    custom_params=None)

            # Assert
            save_snapshot_mock.assert_called_once()
            saved_result_dict = jsonpickle.decode(saved_result)
            self.assertEqual(saved_result_dict['saved_artifacts_info']['saved_artifact']['artifact_type'],
                             'vcenter_snapshot')
            self.assertEqual(saved_result_dict['saved_artifacts_info']['saved_artifact']['identifier'], 'new_snapshot')
            self.assertEqual(saved_result_dict['saved_artifacts_info']['resource_name'], 'vcenter')
            self.assertIsNotNone(saved_result_dict['saved_artifacts_info']['created_date'])

    @freeze_time("1984-12-31 11:12:13.4567")
    def test_orchestration_save_snapshot_name_should_contain_full_datetime(self):
        # Arrange
        with patch(SAVE_SNAPSHOT) as save_snapshot_mock:
            save_snapshot_mock.return_value = '"new_snapshot"'

            remote_command_context = create_autospec(ResourceRemoteCommandContext)
            remote_command_context.resource = create_autospec(ResourceContextDetails)
            remote_command_context.resource.fullname = 'vcenter'
            endpoint = create_autospec(ResourceContextDetails)
            endpoint.fullname = 'vm_111'
            endpoint.app_context = create_autospec(AppContext)
            endpoint.app_context.deployed_app_json = '{"vmdetails": {"uid": "vm_uuid1"}}'
            remote_command_context.remote_endpoints = [endpoint]

            # Act
            CommandOrchestrator().orchestration_save(context=remote_command_context,
                                                     mode='shallow',
                                                     custom_params=None)

            # Assert
            args, kwargs = save_snapshot_mock.call_args
            self.assertEqual(kwargs['snapshot_name'], "84_12_31 11_12_13_456700")

    def test_orchestration_restore(self):
        # Arrange
        with patch(RESTORE_SNAPSHOT) as mock_restore_snapshot:
            # Act
            self.command_orchestrator.orchestration_restore(self.context, '''{
      "saved_artifacts_info": {
        "resource_name": "ex cillum sed laboris",
        "created_date": "4313-10-12T18:03:15.053Z",
        "restore_rules": {
          "requires_same_resource": false
        },
        "saved_artifact": {
          "artifact_type": "veniam in qui",
          "identifier": "deserunt1"
        }
      }
    }''')
            # Assert
            mock_restore_snapshot.assert_called_once_with(context=self.context, snapshot_name='deserunt1')