Пример #1
0
    def test_execute_command_with_params_and_vcetner_data_model_with_session_inject(self):
        # arrange
        def fake_command_with_connection_return_true_1(si, vcenter_data_model, session, fake1, fake2):
            return True
        def fake_command_with_connection_return_true_2(si, session, vcenter_data_model, fake1, fake2):
            return True

        wrapper = CommandWrapper(pv_service=self.pv_service,
                                 cloud_shell_helper=self.cloud_shell_helper,
                                 resource_model_parser= self.resource_model_parser,
                                 context_based_logger_factory=Mock())
        context = self._create_resource_command_context()

        # act
        res_1 = wrapper.execute_command_with_connection(context,
                                                      fake_command_with_connection_return_true_1,
                                                      'param 1',
                                                      'param2')
        res_2 = wrapper.execute_command_with_connection(context,
                                                      fake_command_with_connection_return_true_2,
                                                      'param 1',
                                                      'param2')
        # assert
        self.assertTrue(res_1)
        self.assertTrue(res_2)
Пример #2
0
    def test_execute_command_with_params_and_vcetner_data_model_with_session_inject(
            self):
        # arrange
        def fake_command_with_connection_return_true_1(si, vcenter_data_model,
                                                       session, fake1, fake2):
            return True

        def fake_command_with_connection_return_true_2(si, session,
                                                       vcenter_data_model,
                                                       fake1, fake2):
            return True

        wrapper = CommandWrapper(
            pv_service=self.pv_service,
            cloud_shell_helper=self.cloud_shell_helper,
            resource_model_parser=self.resource_model_parser,
            context_based_logger_factory=Mock())
        context = self._create_resource_command_context()

        # act
        res_1 = wrapper.execute_command_with_connection(
            context, fake_command_with_connection_return_true_1, 'param 1',
            'param2')
        res_2 = wrapper.execute_command_with_connection(
            context, fake_command_with_connection_return_true_2, 'param 1',
            'param2')
        # assert
        self.assertTrue(res_1)
        self.assertTrue(res_2)
Пример #3
0
    def test_execute_command_with_params(self):
        # arrange
        def fake_command_with_connection_return_true(si, fake1, fake2):
            return True

        wrapper = CommandWrapper(pv_service=self.pv_service,
                                 cloud_shell_helper=self.cloud_shell_helper,
                                 resource_model_parser= self.resource_model_parser,
                                 context_based_logger_factory=Mock())
        context = self._create_resource_command_context()

        # act
        res = wrapper.execute_command_with_connection(context,
                                                      fake_command_with_connection_return_true,
                                                      'param 1',
                                                      'param2')
        # assert
        self.assertTrue(res)
Пример #4
0
    def test_execute_command_with_params(self):
        # arrange
        def fake_command_with_connection_return_true(si, fake1, fake2):
            return True

        wrapper = CommandWrapper(
            pv_service=self.pv_service,
            cloud_shell_helper=self.cloud_shell_helper,
            resource_model_parser=self.resource_model_parser,
            context_based_logger_factory=Mock())
        context = self._create_resource_command_context()

        # act
        res = wrapper.execute_command_with_connection(
            context, fake_command_with_connection_return_true, 'param 1',
            'param2')
        # assert
        self.assertTrue(res)
Пример #5
0
    def test_execute_command_with_params(self):
        # arrange
        def fake_command_with_connection_return_true(si, fake1, fake2):
            return True

        with patch(
                'cloudshell.cp.vcenter.common.wrappers.command_wrapper.CloudShellSessionContext'
        ) as session:
            wrapper = CommandWrapper(
                pv_service=self.pv_service,
                resource_model_parser=self.resource_model_parser,
                context_based_logger_factory=Mock())
            context = self._create_resource_command_context()

            # act
            res = wrapper.execute_command_with_connection(
                context, fake_command_with_connection_return_true, 'param 1',
                'param2')
            # assert
            self.assertTrue(res)
            session.assert_called_with(context)
Пример #6
0
    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

        :param context: models.QualiDriverModels.InitCommandContext
        """
        self.cs_helper = CloudshellDriverHelper()
        synchronous_task_waiter = SynchronousTaskWaiter()
        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)

        vm_deployer = VirtualMachineDeployer(
            pv_service=pv_service,
            name_generator=generate_unique_name,
            ovf_service=ovf_service,
            cs_helper=self.cs_helper,
            resource_model_parser=ResourceModelParser())

        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,
            cloud_shell_helper=self.cs_helper,
            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)

        # 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)

        ip_manager = VMIPManager()

        # Refresh IP command
        self.refresh_ip_command = RefreshIpCommand(
            pyvmomi_service=pv_service,
            resource_model_parser=ResourceModelParser(),
            ip_manager=ip_manager)

        # 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)
Пример #7
0
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

        :param context: models.QualiDriverModels.InitCommandContext
        """
        self.cs_helper = CloudshellDriverHelper()
        synchronous_task_waiter = SynchronousTaskWaiter()
        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)

        vm_deployer = VirtualMachineDeployer(
            pv_service=pv_service,
            name_generator=generate_unique_name,
            ovf_service=ovf_service,
            cs_helper=self.cs_helper,
            resource_model_parser=ResourceModelParser())

        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,
            cloud_shell_helper=self.cs_helper,
            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)

        # 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)

        ip_manager = VMIPManager()

        # Refresh IP command
        self.refresh_ip_command = RefreshIpCommand(
            pyvmomi_service=pv_service,
            resource_model_parser=ResourceModelParser(),
            ip_manager=ip_manager)

        # 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)

    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 deploy_from_template(self, context, deploy_data):
        """
        Deploy From Template Command, will deploy vm from template

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {"template_resource_model": {"vm_location": "", "vcenter_name": "VMware vCenter", "refresh_ip_timeout": "600", "auto_delete": "True", "vm_storage": "", "auto_power_on": "True", "autoload": "True", "ip_regex": "", "auto_power_off": "True", "vcenter_template": "Alex\\test", "vm_cluster": "", "vm_resource_pool": "", "wait_for_ip": "True"}, "app_name": "Temp"}
        :return str deploy results
        """

        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)
        data_holder.template_resource_model.vcenter_template = \
            back_slash_to_front_converter(data_holder.template_resource_model.vcenter_template)

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context, self.deploy_command.execute_deploy_from_template,
            data_holder)

        return set_command_result(result=result, unpicklable=False)

    def deploy_clone_from_vm(self, context, deploy_data):
        """
        Deploy Cloned VM From VM Command, will deploy vm from template

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {"template_resource_model": {"vm_location": "", "vcenter_name": "VMware vCenter", "refresh_ip_timeout": "600", "auto_delete": "True", "vm_storage": "", "auto_power_on": "True", "autoload": "True", "ip_regex": "", "auto_power_off": "True", "vcenter_template": "Alex\\test", "vm_cluster": "", "vm_resource_pool": "", "wait_for_ip": "True"}, "app_name": "Temp"}
        :return str deploy results
        """

        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)
        data_holder.template_resource_model.vcenter_vm = \
            back_slash_to_front_converter(data_holder.template_resource_model.vcenter_vm)

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context, self.deploy_command.execute_deploy_clone_from_vm,
            data_holder)

        return set_command_result(result=result, unpicklable=False)

    def deploy_from_linked_clone(self, context, deploy_data):
        """
        Deploy Cloned VM From VM Command, will deploy vm from template

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {"template_resource_model": {"vm_location": "", "vcenter_name": "VMware vCenter", "refresh_ip_timeout": "600", "auto_delete": "True", "vm_storage": "", "auto_power_on": "True", "autoload": "True", "ip_regex": "", "auto_power_off": "True", "vcenter_template": "Alex\\test", "vm_cluster": "", "vm_resource_pool": "", "wait_for_ip": "True"}, "app_name": "Temp"}
        :return str deploy results
        """

        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)

        if not data_holder.template_resource_model.vcenter_vm:
            raise ValueError('Please insert vm to deploy from')

        data_holder.template_resource_model.vcenter_vm = \
            back_slash_to_front_converter(data_holder.template_resource_model.vcenter_vm)

        if not data_holder.template_resource_model.vcenter_vm_snapshot:
            raise ValueError('Please insert snapshot to deploy from')

        data_holder.template_resource_model.vcenter_vm_snapshot = \
            back_slash_to_front_converter(data_holder.template_resource_model.vcenter_vm_snapshot)

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context, self.deploy_command.execute_deploy_from_linked_clone,
            data_holder)

        return set_command_result(result=result, unpicklable=False)

    def deploy_from_image(self, context, deploy_data):
        """
        Deploy From Image Command, will deploy vm from ovf image

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {
                "image_url": "c:\image.ovf" or
                             "\\nas\shared\image.ovf" or
                             "http://192.168.65.88/ovf/Debian%2064%20-%20Yoav.ovf",
                "cluster_name": "QualiSB Cluster",
                "resource_pool": "LiverPool",
                "datastore_name": "eric ds cluster",
                "datacenter_name": "QualiSB"
                "power_on": False
                "app_name": "appName"
                "user_arguments": ["--compress=9", " --schemaValidate", "--etc"]
            }
        :return str deploy results
        """
        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context, self.deploy_command.execute_deploy_from_image,
            data_holder, context.resource)

        return set_command_result(result=result, unpicklable=False)

    # 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 destroy_vm_only(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.destroy_vm_only,
            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 models.QualiDriverModels.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.vm_uuid, resource_details.fullname,
            cancellation_context)
        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
        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 save_snapshot(self, context, snapshot_name):
        """
        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
        :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)
        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 = date.today()
        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)
Пример #8
0
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)
    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

        :param context: models.QualiDriverModels.InitCommandContext
        """
        self.cs_helper = CloudshellDriverHelper()
        pv_service = pyVmomiService(SmartConnect, Disconnect)
        synchronous_task_waiter = SynchronousTaskWaiter()
        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)

        vm_deployer = VirtualMachineDeployer(pv_service=pv_service,
                                             name_generator=generate_unique_name,
                                             ovf_service=ovf_service,
                                             cs_helper=self.cs_helper,
                                             resource_model_parser=ResourceModelParser())

        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,
                                              cloud_shell_helper=self.cs_helper,
                                              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)

        # 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=ResourceModelParser())
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

        :param context: models.QualiDriverModels.InitCommandContext
        """
        self.cs_helper = CloudshellDriverHelper()
        pv_service = pyVmomiService(SmartConnect, Disconnect)
        synchronous_task_waiter = SynchronousTaskWaiter()
        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)

        vm_deployer = VirtualMachineDeployer(pv_service=pv_service,
                                             name_generator=generate_unique_name,
                                             ovf_service=ovf_service,
                                             cs_helper=self.cs_helper,
                                             resource_model_parser=ResourceModelParser())

        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,
                                              cloud_shell_helper=self.cs_helper,
                                              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)

        # 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=ResourceModelParser())

    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 deploy_from_template(self, context, deploy_data):
        """
        Deploy From Template Command, will deploy vm from template

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {"template_resource_model": {"vm_location": "", "vcenter_name": "VMware vCenter", "refresh_ip_timeout": "600", "auto_delete": "True", "vm_storage": "", "auto_power_on": "True", "autoload": "True", "ip_regex": "", "auto_power_off": "True", "vcenter_template": "Alex\\test", "vm_cluster": "", "vm_resource_pool": "", "wait_for_ip": "True"}, "app_name": "Temp"}
        :return str deploy results
        """

        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)
        data_holder.template_resource_model.vcenter_template = \
            data_holder.template_resource_model.vcenter_template.replace('\\', '/')

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context,
            self.deploy_command.execute_deploy_from_template,
            data_holder,
            context.resource)

        return set_command_result(result=result, unpicklable=False)

    def deploy_from_image(self, context, deploy_data):
        """
        Deploy From Image Command, will deploy vm from ovf image

        :param models.QualiDriverModels.ResourceCommandContext context: the context of the command
        :param str deploy_data: represent a json of the parameters, example: {
                "image_url": "c:\image.ovf" or
                             "\\nas\shared\image.ovf" or
                             "http://192.168.65.88/ovf/Debian%2064%20-%20Yoav.ovf",
                "cluster_name": "QualiSB Cluster",
                "resource_pool": "LiverPool",
                "datastore_name": "eric ds cluster",
                "datacenter_name": "QualiSB"
                "power_on": False
                "app_name": "appName"
                "user_arguments": ["--compress=9", " --schemaValidate", "--etc"]
            }
        :return str deploy results
        """
        # get command parameters from the environment
        data = jsonpickle.decode(deploy_data)
        data_holder = DeployDataHolder(data)

        # execute command
        result = self.command_wrapper.execute_command_with_connection(
            context,
            self.deploy_command.execute_deploy_from_image,
            data_holder,
            context.resource)

        return set_command_result(result=result, unpicklable=False)

    # 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 destroy_vm(self, context, ports):
        """
        Destroy Vm Command, will destroy the vm and 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)
        reservation_id = context.remote_reservation.reservation_id
        # execute command
        res = self.command_wrapper.execute_command_with_connection(
            context,
            self.destroy_virtual_machine_command.destroy,
            resource_details.vm_uuid,
            resource_details.fullname,
            reservation_id)
        return set_command_result(result=res, unpicklable=False)

    # remote command
    def destroy_vm_only(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)
        reservation_id = context.remote_reservation.reservation_id
        # execute command
        res = self.command_wrapper.execute_command_with_connection(
            context,
            self.destroy_virtual_machine_command.destroy_vm_only,
            resource_details.vm_uuid,
            resource_details.fullname,
            reservation_id)
        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 models.QualiDriverModels.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.vm_uuid,
                                                                   resource_details.fullname,
                                                                   cancellation_context)
        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
        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)